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:
Boris Pavlovic 2013-09-01 02:10:18 +04:00
parent 1888c3d2cf
commit 0c0c85d971
2 changed files with 39 additions and 0 deletions

View File

@ -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

View File

@ -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)))