123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892 |
- # Copyright (c) Twisted Matrix Laboratories.
- # See LICENSE for details.
-
- """
- Test cases for the L{twisted.python.reflect} module.
- """
-
- from __future__ import division, absolute_import
-
- import os
- import weakref
- from collections import deque
-
- from twisted.python.compat import _PY3
- from twisted.trial import unittest
- from twisted.trial.unittest import SynchronousTestCase as TestCase
- from twisted.python import reflect
- from twisted.python.reflect import (
- accumulateMethods, prefixedMethods, prefixedMethodNames,
- addMethodNamesToDict, fullyQualifiedName)
-
-
- class Base(object):
- """
- A no-op class which can be used to verify the behavior of
- method-discovering APIs.
- """
-
- def method(self):
- """
- A no-op method which can be discovered.
- """
-
-
-
- class Sub(Base):
- """
- A subclass of a class with a method which can be discovered.
- """
-
-
-
- class Separate(object):
- """
- A no-op class with methods with differing prefixes.
- """
-
- def good_method(self):
- """
- A no-op method which a matching prefix to be discovered.
- """
-
-
- def bad_method(self):
- """
- A no-op method with a mismatched prefix to not be discovered.
- """
-
-
-
- class AccumulateMethodsTests(TestCase):
- """
- Tests for L{accumulateMethods} which finds methods on a class hierarchy and
- adds them to a dictionary.
- """
-
- def test_ownClass(self):
- """
- If x is and instance of Base and Base defines a method named method,
- L{accumulateMethods} adds an item to the given dictionary with
- C{"method"} as the key and a bound method object for Base.method value.
- """
- x = Base()
- output = {}
- accumulateMethods(x, output)
- self.assertEqual({"method": x.method}, output)
-
-
- def test_baseClass(self):
- """
- If x is an instance of Sub and Sub is a subclass of Base and Base
- defines a method named method, L{accumulateMethods} adds an item to the
- given dictionary with C{"method"} as the key and a bound method object
- for Base.method as the value.
- """
- x = Sub()
- output = {}
- accumulateMethods(x, output)
- self.assertEqual({"method": x.method}, output)
-
-
- def test_prefix(self):
- """
- If a prefix is given, L{accumulateMethods} limits its results to
- methods beginning with that prefix. Keys in the resulting dictionary
- also have the prefix removed from them.
- """
- x = Separate()
- output = {}
- accumulateMethods(x, output, 'good_')
- self.assertEqual({'method': x.good_method}, output)
-
-
-
- class PrefixedMethodsTests(TestCase):
- """
- Tests for L{prefixedMethods} which finds methods on a class hierarchy and
- adds them to a dictionary.
- """
-
- def test_onlyObject(self):
- """
- L{prefixedMethods} returns a list of the methods discovered on an
- object.
- """
- x = Base()
- output = prefixedMethods(x)
- self.assertEqual([x.method], output)
-
-
- def test_prefix(self):
- """
- If a prefix is given, L{prefixedMethods} returns only methods named
- with that prefix.
- """
- x = Separate()
- output = prefixedMethods(x, 'good_')
- self.assertEqual([x.good_method], output)
-
-
-
- class PrefixedMethodNamesTests(TestCase):
- """
- Tests for L{prefixedMethodNames}.
- """
- def test_method(self):
- """
- L{prefixedMethodNames} returns a list including methods with the given
- prefix defined on the class passed to it.
- """
- self.assertEqual(["method"], prefixedMethodNames(Separate, "good_"))
-
-
- def test_inheritedMethod(self):
- """
- L{prefixedMethodNames} returns a list included methods with the given
- prefix defined on base classes of the class passed to it.
- """
- class Child(Separate):
- pass
- self.assertEqual(["method"], prefixedMethodNames(Child, "good_"))
-
-
-
- class AddMethodNamesToDictTests(TestCase):
- """
- Tests for L{addMethodNamesToDict}.
- """
- def test_baseClass(self):
- """
- If C{baseClass} is passed to L{addMethodNamesToDict}, only methods which
- are a subclass of C{baseClass} are added to the result dictionary.
- """
- class Alternate(object):
- pass
-
- class Child(Separate, Alternate):
- def good_alternate(self):
- pass
-
- result = {}
- addMethodNamesToDict(Child, result, 'good_', Alternate)
- self.assertEqual({'alternate': 1}, result)
-
-
-
- class Summer(object):
- """
- A class we look up as part of the LookupsTests.
- """
-
- def reallySet(self):
- """
- Do something.
- """
-
-
-
- class LookupsTests(TestCase):
- """
- Tests for L{namedClass}, L{namedModule}, and L{namedAny}.
- """
-
- def test_namedClassLookup(self):
- """
- L{namedClass} should return the class object for the name it is passed.
- """
- self.assertIs(
- reflect.namedClass("twisted.test.test_reflect.Summer"),
- Summer)
-
-
- def test_namedModuleLookup(self):
- """
- L{namedModule} should return the module object for the name it is
- passed.
- """
- from twisted.python import monkey
- self.assertIs(
- reflect.namedModule("twisted.python.monkey"), monkey)
-
-
- def test_namedAnyPackageLookup(self):
- """
- L{namedAny} should return the package object for the name it is passed.
- """
- import twisted.python
- self.assertIs(
- reflect.namedAny("twisted.python"), twisted.python)
-
-
- def test_namedAnyModuleLookup(self):
- """
- L{namedAny} should return the module object for the name it is passed.
- """
- from twisted.python import monkey
- self.assertIs(
- reflect.namedAny("twisted.python.monkey"), monkey)
-
-
- def test_namedAnyClassLookup(self):
- """
- L{namedAny} should return the class object for the name it is passed.
- """
- self.assertIs(
- reflect.namedAny("twisted.test.test_reflect.Summer"),
- Summer)
-
-
- def test_namedAnyAttributeLookup(self):
- """
- L{namedAny} should return the object an attribute of a non-module,
- non-package object is bound to for the name it is passed.
- """
- # Note - not assertIs because unbound method lookup creates a new
- # object every time. This is a foolishness of Python's object
- # implementation, not a bug in Twisted.
- self.assertEqual(
- reflect.namedAny(
- "twisted.test.test_reflect.Summer.reallySet"),
- Summer.reallySet)
-
-
- def test_namedAnySecondAttributeLookup(self):
- """
- L{namedAny} should return the object an attribute of an object which
- itself was an attribute of a non-module, non-package object is bound to
- for the name it is passed.
- """
- self.assertIs(
- reflect.namedAny(
- "twisted.test.test_reflect."
- "Summer.reallySet.__doc__"),
- Summer.reallySet.__doc__)
-
-
- def test_importExceptions(self):
- """
- Exceptions raised by modules which L{namedAny} causes to be imported
- should pass through L{namedAny} to the caller.
- """
- self.assertRaises(
- ZeroDivisionError,
- reflect.namedAny, "twisted.test.reflect_helper_ZDE")
- # Make sure that there is post-failed-import cleanup
- self.assertRaises(
- ZeroDivisionError,
- reflect.namedAny, "twisted.test.reflect_helper_ZDE")
- self.assertRaises(
- ValueError,
- reflect.namedAny, "twisted.test.reflect_helper_VE")
- # Modules which themselves raise ImportError when imported should
- # result in an ImportError
- self.assertRaises(
- ImportError,
- reflect.namedAny, "twisted.test.reflect_helper_IE")
-
-
- def test_attributeExceptions(self):
- """
- If segments on the end of a fully-qualified Python name represents
- attributes which aren't actually present on the object represented by
- the earlier segments, L{namedAny} should raise an L{AttributeError}.
- """
- self.assertRaises(
- AttributeError,
- reflect.namedAny, "twisted.nosuchmoduleintheworld")
- # ImportError behaves somewhat differently between "import
- # extant.nonextant" and "import extant.nonextant.nonextant", so test
- # the latter as well.
- self.assertRaises(
- AttributeError,
- reflect.namedAny, "twisted.nosuch.modulein.theworld")
- self.assertRaises(
- AttributeError,
- reflect.namedAny,
- "twisted.test.test_reflect.Summer.nosuchattribute")
-
-
- def test_invalidNames(self):
- """
- Passing a name which isn't a fully-qualified Python name to L{namedAny}
- should result in one of the following exceptions:
- - L{InvalidName}: the name is not a dot-separated list of Python
- objects
- - L{ObjectNotFound}: the object doesn't exist
- - L{ModuleNotFound}: the object doesn't exist and there is only one
- component in the name
- """
- err = self.assertRaises(reflect.ModuleNotFound, reflect.namedAny,
- 'nosuchmoduleintheworld')
- self.assertEqual(str(err), "No module named 'nosuchmoduleintheworld'")
-
- # This is a dot-separated list, but it isn't valid!
- err = self.assertRaises(reflect.ObjectNotFound, reflect.namedAny,
- "@#$@(#.!@(#!@#")
- self.assertEqual(str(err), "'@#$@(#.!@(#!@#' does not name an object")
-
- err = self.assertRaises(reflect.ObjectNotFound, reflect.namedAny,
- "tcelfer.nohtyp.detsiwt")
- self.assertEqual(
- str(err),
- "'tcelfer.nohtyp.detsiwt' does not name an object")
-
- err = self.assertRaises(reflect.InvalidName, reflect.namedAny, '')
- self.assertEqual(str(err), 'Empty module name')
-
- for invalidName in ['.twisted', 'twisted.', 'twisted..python']:
- err = self.assertRaises(
- reflect.InvalidName, reflect.namedAny, invalidName)
- self.assertEqual(
- str(err),
- "name must be a string giving a '.'-separated list of Python "
- "identifiers, not %r" % (invalidName,))
-
-
- def test_requireModuleImportError(self):
- """
- When module import fails with ImportError it returns the specified
- default value.
- """
- for name in ['nosuchmtopodule', 'no.such.module']:
- default = object()
-
- result = reflect.requireModule(name, default=default)
-
- self.assertIs(result, default)
-
-
- def test_requireModuleDefaultNone(self):
- """
- When module import fails it returns L{None} by default.
- """
- result = reflect.requireModule('no.such.module')
-
- self.assertIsNone(result)
-
-
- def test_requireModuleRequestedImport(self):
- """
- When module import succeed it returns the module and not the default
- value.
- """
- from twisted.python import monkey
- default = object()
-
- self.assertIs(
- reflect.requireModule('twisted.python.monkey', default=default),
- monkey,
- )
-
-
-
- class Breakable(object):
-
- breakRepr = False
- breakStr = False
-
- def __str__(self):
- if self.breakStr:
- raise RuntimeError("str!")
- else:
- return '<Breakable>'
-
-
- def __repr__(self):
- if self.breakRepr:
- raise RuntimeError("repr!")
- else:
- return 'Breakable()'
-
-
-
- class BrokenType(Breakable, type):
- breakName = False
-
- def get___name__(self):
- if self.breakName:
- raise RuntimeError("no name")
- return 'BrokenType'
- __name__ = property(get___name__)
-
-
-
- BTBase = BrokenType('BTBase', (Breakable,),
- {"breakRepr": True,
- "breakStr": True})
-
-
-
- class NoClassAttr(Breakable):
- __class__ = property(lambda x: x.not_class)
-
-
-
- class SafeReprTests(TestCase):
- """
- Tests for L{reflect.safe_repr} function.
- """
-
- def test_workingRepr(self):
- """
- L{reflect.safe_repr} produces the same output as C{repr} on a working
- object.
- """
- xs = ([1, 2, 3], b'a')
- self.assertEqual(list(map(reflect.safe_repr, xs)), list(map(repr, xs)))
-
-
- def test_brokenRepr(self):
- """
- L{reflect.safe_repr} returns a string with class name, address, and
- traceback when the repr call failed.
- """
- b = Breakable()
- b.breakRepr = True
- bRepr = reflect.safe_repr(b)
- self.assertIn("Breakable instance at 0x", bRepr)
- # Check that the file is in the repr, but without the extension as it
- # can be .py/.pyc
- self.assertIn(os.path.splitext(__file__)[0], bRepr)
- self.assertIn("RuntimeError: repr!", bRepr)
-
-
- def test_brokenStr(self):
- """
- L{reflect.safe_repr} isn't affected by a broken C{__str__} method.
- """
- b = Breakable()
- b.breakStr = True
- self.assertEqual(reflect.safe_repr(b), repr(b))
-
-
- def test_brokenClassRepr(self):
- class X(BTBase):
- breakRepr = True
- reflect.safe_repr(X)
- reflect.safe_repr(X())
-
-
- def test_brokenReprIncludesID(self):
- """
- C{id} is used to print the ID of the object in case of an error.
-
- L{safe_repr} includes a traceback after a newline, so we only check
- against the first line of the repr.
- """
- class X(BTBase):
- breakRepr = True
-
- xRepr = reflect.safe_repr(X)
- xReprExpected = ('<BrokenType instance at 0x%x with repr error:'
- % (id(X),))
- self.assertEqual(xReprExpected, xRepr.split('\n')[0])
-
-
- def test_brokenClassStr(self):
- class X(BTBase):
- breakStr = True
- reflect.safe_repr(X)
- reflect.safe_repr(X())
-
-
- def test_brokenClassAttribute(self):
- """
- If an object raises an exception when accessing its C{__class__}
- attribute, L{reflect.safe_repr} uses C{type} to retrieve the class
- object.
- """
- b = NoClassAttr()
- b.breakRepr = True
- bRepr = reflect.safe_repr(b)
- self.assertIn("NoClassAttr instance at 0x", bRepr)
- self.assertIn(os.path.splitext(__file__)[0], bRepr)
- self.assertIn("RuntimeError: repr!", bRepr)
-
-
- def test_brokenClassNameAttribute(self):
- """
- If a class raises an exception when accessing its C{__name__} attribute
- B{and} when calling its C{__str__} implementation, L{reflect.safe_repr}
- returns 'BROKEN CLASS' instead of the class name.
- """
- class X(BTBase):
- breakName = True
- xRepr = reflect.safe_repr(X())
- self.assertIn("<BROKEN CLASS AT 0x", xRepr)
- self.assertIn(os.path.splitext(__file__)[0], xRepr)
- self.assertIn("RuntimeError: repr!", xRepr)
-
-
-
- class SafeStrTests(TestCase):
- """
- Tests for L{reflect.safe_str} function.
- """
-
- def test_workingStr(self):
- x = [1, 2, 3]
- self.assertEqual(reflect.safe_str(x), str(x))
-
-
- def test_brokenStr(self):
- b = Breakable()
- b.breakStr = True
- reflect.safe_str(b)
-
-
- def test_workingAscii(self):
- """
- L{safe_str} for C{str} with ascii-only data should return the
- value unchanged.
- """
- x = 'a'
- self.assertEqual(reflect.safe_str(x), 'a')
-
-
- def test_workingUtf8_2(self):
- """
- L{safe_str} for C{str} with utf-8 encoded data should return the
- value unchanged.
- """
- x = b't\xc3\xbcst'
- self.assertEqual(reflect.safe_str(x), x)
-
-
- def test_workingUtf8_3(self):
- """
- L{safe_str} for C{bytes} with utf-8 encoded data should return
- the value decoded into C{str}.
- """
- x = b't\xc3\xbcst'
- self.assertEqual(reflect.safe_str(x), x.decode('utf-8'))
-
- if _PY3:
- # TODO: after something like python.compat.nativeUtf8String is
- # introduced, use that one for assertEqual. Then we can combine
- # test_workingUtf8_* tests into one without needing _PY3.
- # nativeUtf8String is needed for Python 3 anyway.
- test_workingUtf8_2.skip = ("Skip Python 2 specific test for utf-8 str")
- else:
- test_workingUtf8_3.skip = (
- "Skip Python 3 specific test for utf-8 bytes")
-
-
- def test_brokenUtf8(self):
- """
- Use str() for non-utf8 bytes: "b'non-utf8'"
- """
- x = b'\xff'
- xStr = reflect.safe_str(x)
- self.assertEqual(xStr, str(x))
-
-
- def test_brokenRepr(self):
- b = Breakable()
- b.breakRepr = True
- reflect.safe_str(b)
-
-
- def test_brokenClassStr(self):
- class X(BTBase):
- breakStr = True
- reflect.safe_str(X)
- reflect.safe_str(X())
-
-
- def test_brokenClassRepr(self):
- class X(BTBase):
- breakRepr = True
- reflect.safe_str(X)
- reflect.safe_str(X())
-
-
- def test_brokenClassAttribute(self):
- """
- If an object raises an exception when accessing its C{__class__}
- attribute, L{reflect.safe_str} uses C{type} to retrieve the class
- object.
- """
- b = NoClassAttr()
- b.breakStr = True
- bStr = reflect.safe_str(b)
- self.assertIn("NoClassAttr instance at 0x", bStr)
- self.assertIn(os.path.splitext(__file__)[0], bStr)
- self.assertIn("RuntimeError: str!", bStr)
-
-
- def test_brokenClassNameAttribute(self):
- """
- If a class raises an exception when accessing its C{__name__} attribute
- B{and} when calling its C{__str__} implementation, L{reflect.safe_str}
- returns 'BROKEN CLASS' instead of the class name.
- """
- class X(BTBase):
- breakName = True
- xStr = reflect.safe_str(X())
- self.assertIn("<BROKEN CLASS AT 0x", xStr)
- self.assertIn(os.path.splitext(__file__)[0], xStr)
- self.assertIn("RuntimeError: str!", xStr)
-
-
-
- class FilenameToModuleTests(TestCase):
- """
- Test L{filenameToModuleName} detection.
- """
-
- def setUp(self):
- self.path = os.path.join(self.mktemp(), "fakepackage", "test")
- os.makedirs(self.path)
- with open(os.path.join(self.path, "__init__.py"), "w") as f:
- f.write("")
- with open(os.path.join(os.path.dirname(self.path), "__init__.py"),
- "w") as f:
- f.write("")
-
-
- def test_directory(self):
- """
- L{filenameToModuleName} returns the correct module (a package) given a
- directory.
- """
- module = reflect.filenameToModuleName(self.path)
- self.assertEqual(module, 'fakepackage.test')
- module = reflect.filenameToModuleName(self.path + os.path.sep)
- self.assertEqual(module, 'fakepackage.test')
-
-
- def test_file(self):
- """
- L{filenameToModuleName} returns the correct module given the path to
- its file.
- """
- module = reflect.filenameToModuleName(
- os.path.join(self.path, 'test_reflect.py'))
- self.assertEqual(module, 'fakepackage.test.test_reflect')
-
-
- def test_bytes(self):
- """
- L{filenameToModuleName} returns the correct module given a C{bytes}
- path to its file.
- """
- module = reflect.filenameToModuleName(
- os.path.join(self.path.encode("utf-8"), b'test_reflect.py'))
- # Module names are always native string:
- self.assertEqual(module, 'fakepackage.test.test_reflect')
-
-
-
- class FullyQualifiedNameTests(TestCase):
- """
- Test for L{fullyQualifiedName}.
- """
-
- def _checkFullyQualifiedName(self, obj, expected):
- """
- Helper to check that fully qualified name of C{obj} results to
- C{expected}.
- """
- self.assertEqual(fullyQualifiedName(obj), expected)
-
-
- def test_package(self):
- """
- L{fullyQualifiedName} returns the full name of a package and a
- subpackage.
- """
- import twisted
- self._checkFullyQualifiedName(twisted, 'twisted')
- import twisted.python
- self._checkFullyQualifiedName(twisted.python, 'twisted.python')
-
-
- def test_module(self):
- """
- L{fullyQualifiedName} returns the name of a module inside a package.
- """
- import twisted.python.compat
- self._checkFullyQualifiedName(
- twisted.python.compat, 'twisted.python.compat')
-
-
- def test_class(self):
- """
- L{fullyQualifiedName} returns the name of a class and its module.
- """
- self._checkFullyQualifiedName(
- FullyQualifiedNameTests,
- '%s.FullyQualifiedNameTests' % (__name__,))
-
-
- def test_function(self):
- """
- L{fullyQualifiedName} returns the name of a function inside its module.
- """
- self._checkFullyQualifiedName(
- fullyQualifiedName, "twisted.python.reflect.fullyQualifiedName")
-
-
- def test_boundMethod(self):
- """
- L{fullyQualifiedName} returns the name of a bound method inside its
- class and its module.
- """
- self._checkFullyQualifiedName(
- self.test_boundMethod,
- "%s.%s.test_boundMethod" % (__name__, self.__class__.__name__))
-
-
- def test_unboundMethod(self):
- """
- L{fullyQualifiedName} returns the name of an unbound method inside its
- class and its module.
- """
- self._checkFullyQualifiedName(
- self.__class__.test_unboundMethod,
- "%s.%s.test_unboundMethod" % (__name__, self.__class__.__name__))
-
-
- class ObjectGrepTests(unittest.TestCase):
- if _PY3:
- # This is to be removed when fixing #6986
- skip = "twisted.python.reflect.objgrep hasn't been ported to Python 3"
-
-
- def test_dictionary(self):
- """
- Test references search through a dictionary, as a key or as a value.
- """
- o = object()
- d1 = {None: o}
- d2 = {o: None}
-
- self.assertIn("[None]", reflect.objgrep(d1, o, reflect.isSame))
- self.assertIn("{None}", reflect.objgrep(d2, o, reflect.isSame))
-
- def test_list(self):
- """
- Test references search through a list.
- """
- o = object()
- L = [None, o]
-
- self.assertIn("[1]", reflect.objgrep(L, o, reflect.isSame))
-
- def test_tuple(self):
- """
- Test references search through a tuple.
- """
- o = object()
- T = (o, None)
-
- self.assertIn("[0]", reflect.objgrep(T, o, reflect.isSame))
-
- def test_instance(self):
- """
- Test references search through an object attribute.
- """
- class Dummy:
- pass
- o = object()
- d = Dummy()
- d.o = o
-
- self.assertIn(".o", reflect.objgrep(d, o, reflect.isSame))
-
- def test_weakref(self):
- """
- Test references search through a weakref object.
- """
- class Dummy:
- pass
- o = Dummy()
- w1 = weakref.ref(o)
-
- self.assertIn("()", reflect.objgrep(w1, o, reflect.isSame))
-
- def test_boundMethod(self):
- """
- Test references search through method special attributes.
- """
- class Dummy:
- def dummy(self):
- pass
- o = Dummy()
- m = o.dummy
-
- self.assertIn(".__self__",
- reflect.objgrep(m, m.__self__, reflect.isSame))
- self.assertIn(".__self__.__class__",
- reflect.objgrep(m, m.__self__.__class__, reflect.isSame))
- self.assertIn(".__func__",
- reflect.objgrep(m, m.__func__, reflect.isSame))
-
- def test_everything(self):
- """
- Test references search using complex set of objects.
- """
- class Dummy:
- def method(self):
- pass
-
- o = Dummy()
- D1 = {(): "baz", None: "Quux", o: "Foosh"}
- L = [None, (), D1, 3]
- T = (L, {}, Dummy())
- D2 = {0: "foo", 1: "bar", 2: T}
- i = Dummy()
- i.attr = D2
- m = i.method
- w = weakref.ref(m)
-
- self.assertIn("().__self__.attr[2][0][2]{'Foosh'}",
- reflect.objgrep(w, o, reflect.isSame))
-
- def test_depthLimit(self):
- """
- Test the depth of references search.
- """
- a = []
- b = [a]
- c = [a, b]
- d = [a, c]
-
- self.assertEqual(['[0]'], reflect.objgrep(d, a, reflect.isSame, maxDepth=1))
- self.assertEqual(['[0]', '[1][0]'], reflect.objgrep(d, a, reflect.isSame, maxDepth=2))
- self.assertEqual(['[0]', '[1][0]', '[1][1][0]'], reflect.objgrep(d, a, reflect.isSame, maxDepth=3))
-
-
- def test_deque(self):
- """
- Test references search through a deque object.
- """
- o = object()
- D = deque()
- D.append(None)
- D.append(o)
-
- self.assertIn("[1]", reflect.objgrep(D, o, reflect.isSame))
-
-
- class GetClassTests(unittest.TestCase):
- if _PY3:
- oldClassNames = ['type']
- else:
- oldClassNames = ['class', 'classobj']
-
- def test_old(self):
- class OldClass:
- pass
- old = OldClass()
- self.assertIn(reflect.getClass(OldClass).__name__, self.oldClassNames)
- self.assertEqual(reflect.getClass(old).__name__, 'OldClass')
-
- def test_new(self):
- class NewClass(object):
- pass
- new = NewClass()
- self.assertEqual(reflect.getClass(NewClass).__name__, 'type')
- self.assertEqual(reflect.getClass(new).__name__, 'NewClass')
|