diff options
author | Tim Peters <tim.peters@gmail.com> | 2001-09-22 06:10:55 (GMT) |
---|---|---|
committer | Tim Peters <tim.peters@gmail.com> | 2001-09-22 06:10:55 (GMT) |
commit | e0b2d7ac9aea548d0bee1cdabd5d7b1254a6569d (patch) | |
tree | 277d3df4bdf475df490eb652e387707951c945ab | |
parent | c377b16d12ba325bb108eca575447d66f19294c0 (diff) | |
download | cpython-e0b2d7ac9aea548d0bee1cdabd5d7b1254a6569d.zip cpython-e0b2d7ac9aea548d0bee1cdabd5d7b1254a6569d.tar.gz cpython-e0b2d7ac9aea548d0bee1cdabd5d7b1254a6569d.tar.bz2 |
Add a function to compute a class's method resolution order. This is
easy for 2.2 new-style classes, but trickier for classic classes, and
different approaches are needed "depending". The function will allow
later code to treat all flavors of classes uniformly.
-rw-r--r-- | Doc/lib/libinspect.tex | 10 | ||||
-rw-r--r-- | Lib/inspect.py | 18 | ||||
-rw-r--r-- | Lib/test/test_inspect.py | 20 |
3 files changed, 47 insertions, 1 deletions
diff --git a/Doc/lib/libinspect.tex b/Doc/lib/libinspect.tex index e5ec9ca..24a181a 100644 --- a/Doc/lib/libinspect.tex +++ b/Doc/lib/libinspect.tex @@ -238,7 +238,7 @@ you can expect to find the following special attributes: \begin{funcdesc}{formatargspec}{args\optional{, varargs, varkw, defaults, argformat, varargsformat, varkwformat, defaultformat}} - + Format a pretty argument spec from the four values returned by \function{getargspec()}. The other four arguments are the corresponding optional formatting functions that are called to turn @@ -253,6 +253,14 @@ you can expect to find the following special attributes: names and values into strings. \end{funcdesc} +\begin{funcdesc}{getmro}{cls} + Return a tuple of class cls's base classes, including cls, in + method resolution order. No class appears more than once in this tuple. + Note that the method resolution order depends on cls's type. Unless a + very peculiar user-defined metatype is in use, cls will be the first + element of the tuple. +\end{funcdesc} + \subsection{The interpreter stack \label{inspect-stack}} diff --git a/Lib/inspect.py b/Lib/inspect.py index 1102c3b..3febf18 100644 --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -163,6 +163,24 @@ def getmembers(object, predicate=None): results.sort() return results +# ----------------------------------------------------------- class helpers +def _searchbases(cls, accum): + # Simulate the "classic class" search order. + if cls in accum: + return + accum.append(cls) + for base in cls.__bases__: + _searchbases(base, accum) + +def getmro(cls): + "Return tuple of base classes (including cls) in method resolution order." + if hasattr(cls, "__mro__"): + return cls.__mro__ + else: + result = [] + _searchbases(cls, result) + return tuple(result) + # -------------------------------------------------- source code extraction def indentsize(line): """Return the indent size, in spaces, at the start of a line of text.""" diff --git a/Lib/test/test_inspect.py b/Lib/test/test_inspect.py index 130fa8e..dbb6609 100644 --- a/Lib/test/test_inspect.py +++ b/Lib/test/test_inspect.py @@ -213,3 +213,23 @@ for fname in files_to_clean_up: os.unlink(fname) except: pass + +# Test classic-class method resolution order. +class A: pass +class B(A): pass +class C(A): pass +class D(B, C): pass + +expected = (D, B, A, C) +got = inspect.getmro(D) +test(expected == got, "expected %r mro, got %r", expected, got) + +# The same w/ new-class MRO. +class A(object): pass +class B(A): pass +class C(A): pass +class D(B, C): pass + +expected = (D, B, C, A, object) +got = inspect.getmro(D) +test(expected == got, "expected %r mro, got %r", expected, got) |