Add itersubclasses() method that allows to iter through all subclass
Add to rally.utils one new method. This method is required at least to build deploy EngineFactory.
This commit is contained in:
parent
1888c3d2cf
commit
0c0c85d971
@ -18,6 +18,8 @@
|
||||
import StringIO
|
||||
import sys
|
||||
|
||||
from rally.openstack.common.gettextutils import _ # noqa
|
||||
|
||||
|
||||
class StdOutCapture(object):
|
||||
def __init__(self):
|
||||
@ -41,3 +43,22 @@ class StdErrCapture(object):
|
||||
|
||||
def __exit__(self, type, value, traceback):
|
||||
sys.stderr = self.stderr
|
||||
|
||||
|
||||
def itersubclasses(cls, _seen=None):
|
||||
"""Generator over all subclasses of a given class in depth first order."""
|
||||
|
||||
if not isinstance(cls, type):
|
||||
raise TypeError(_('itersubclasses must be called with '
|
||||
'new-style classes, not %.100r') % cls)
|
||||
_seen = _seen or set()
|
||||
try:
|
||||
subs = cls.__subclasses__()
|
||||
except TypeError: # fails only when cls is type
|
||||
subs = cls.__subclasses__(cls)
|
||||
for sub in subs:
|
||||
if sub not in _seen:
|
||||
_seen.add(sub)
|
||||
yield sub
|
||||
for sub in itersubclasses(sub, _seen):
|
||||
yield sub
|
||||
|
@ -46,3 +46,21 @@ class StdIOCaptureTestCase(test.NoDBTestCase):
|
||||
|
||||
self.assertEqual(err.getvalue().rstrip('\n').split('\n'), messages)
|
||||
self.assertEqual(stderr, sys.stderr)
|
||||
|
||||
|
||||
class IterSubclassesTestCase(test.NoDBTestCase):
|
||||
|
||||
def test_itersubclasses(self):
|
||||
class A(object):
|
||||
pass
|
||||
|
||||
class B(A):
|
||||
pass
|
||||
|
||||
class C(A):
|
||||
pass
|
||||
|
||||
class D(C):
|
||||
pass
|
||||
|
||||
self.assertEqual([B, C, D], list(utils.itersubclasses(A)))
|
||||
|
Loading…
Reference in New Issue
Block a user