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.
This commit is contained in:
parent
c377b16d12
commit
e0b2d7ac9a
|
@ -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}}
|
||||
|
||||
|
|
|
@ -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."""
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue