Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e0b2d7a

Browse files
committed
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.
1 parent c377b16 commit e0b2d7a

3 files changed

Lines changed: 47 additions & 1 deletion

File tree

Doc/lib/libinspect.tex

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ \subsection{Classes and functions
238238

239239
\begin{funcdesc}{formatargspec}{args\optional{, varargs, varkw, defaults,
240240
argformat, varargsformat, varkwformat, defaultformat}}
241-
241+
242242
Format a pretty argument spec from the four values returned by
243243
\function{getargspec()}. The other four arguments are the
244244
corresponding optional formatting functions that are called to turn
@@ -253,6 +253,14 @@ \subsection{Classes and functions
253253
names and values into strings.
254254
\end{funcdesc}
255255

256+
\begin{funcdesc}{getmro}{cls}
257+
Return a tuple of class cls's base classes, including cls, in
258+
method resolution order. No class appears more than once in this tuple.
259+
Note that the method resolution order depends on cls's type. Unless a
260+
very peculiar user-defined metatype is in use, cls will be the first
261+
element of the tuple.
262+
\end{funcdesc}
263+
256264
\subsection{The interpreter stack
257265
\label{inspect-stack}}
258266

Lib/inspect.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,24 @@ def getmembers(object, predicate=None):
163163
results.sort()
164164
return results
165165

166+
# ----------------------------------------------------------- class helpers
167+
def _searchbases(cls, accum):
168+
# Simulate the "classic class" search order.
169+
if cls in accum:
170+
return
171+
accum.append(cls)
172+
for base in cls.__bases__:
173+
_searchbases(base, accum)
174+
175+
def getmro(cls):
176+
"Return tuple of base classes (including cls) in method resolution order."
177+
if hasattr(cls, "__mro__"):
178+
return cls.__mro__
179+
else:
180+
result = []
181+
_searchbases(cls, result)
182+
return tuple(result)
183+
166184
# -------------------------------------------------- source code extraction
167185
def indentsize(line):
168186
"""Return the indent size, in spaces, at the start of a line of text."""

Lib/test/test_inspect.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,3 +213,23 @@ def sourcerange(top, bottom):
213213
os.unlink(fname)
214214
except:
215215
pass
216+
217+
# Test classic-class method resolution order.
218+
class A: pass
219+
class B(A): pass
220+
class C(A): pass
221+
class D(B, C): pass
222+
223+
expected = (D, B, A, C)
224+
got = inspect.getmro(D)
225+
test(expected == got, "expected %r mro, got %r", expected, got)
226+
227+
# The same w/ new-class MRO.
228+
class A(object): pass
229+
class B(A): pass
230+
class C(A): pass
231+
class D(B, C): pass
232+
233+
expected = (D, B, C, A, object)
234+
got = inspect.getmro(D)
235+
test(expected == got, "expected %r mro, got %r", expected, got)

0 commit comments

Comments
 (0)