ยปCore Development>Code coverage>Lib/test/test_pyclbr.py

Python code coverage for Lib/test/test_pyclbr.py

#countcontent
1n/a'''
2n/a Test cases for pyclbr.py
3n/a Nick Mathewson
4n/a'''
5n/aimport sys
6n/afrom types import FunctionType, MethodType, BuiltinFunctionType
7n/aimport pyclbr
8n/afrom unittest import TestCase, main as unittest_main
9n/a
10n/aStaticMethodType = type(staticmethod(lambda: None))
11n/aClassMethodType = type(classmethod(lambda c: None))
12n/a
13n/a# Here we test the python class browser code.
14n/a#
15n/a# The main function in this suite, 'testModule', compares the output
16n/a# of pyclbr with the introspected members of a module. Because pyclbr
17n/a# is imperfect (as designed), testModule is called with a set of
18n/a# members to ignore.
19n/a
20n/aclass PyclbrTest(TestCase):
21n/a
22n/a def assertListEq(self, l1, l2, ignore):
23n/a ''' succeed iff {l1} - {ignore} == {l2} - {ignore} '''
24n/a missing = (set(l1) ^ set(l2)) - set(ignore)
25n/a if missing:
26n/a print("l1=%r\nl2=%r\nignore=%r" % (l1, l2, ignore), file=sys.stderr)
27n/a self.fail("%r missing" % missing.pop())
28n/a
29n/a def assertHasattr(self, obj, attr, ignore):
30n/a ''' succeed iff hasattr(obj,attr) or attr in ignore. '''
31n/a if attr in ignore: return
32n/a if not hasattr(obj, attr): print("???", attr)
33n/a self.assertTrue(hasattr(obj, attr),
34n/a 'expected hasattr(%r, %r)' % (obj, attr))
35n/a
36n/a
37n/a def assertHaskey(self, obj, key, ignore):
38n/a ''' succeed iff key in obj or key in ignore. '''
39n/a if key in ignore: return
40n/a if key not in obj:
41n/a print("***",key, file=sys.stderr)
42n/a self.assertIn(key, obj)
43n/a
44n/a def assertEqualsOrIgnored(self, a, b, ignore):
45n/a ''' succeed iff a == b or a in ignore or b in ignore '''
46n/a if a not in ignore and b not in ignore:
47n/a self.assertEqual(a, b)
48n/a
49n/a def checkModule(self, moduleName, module=None, ignore=()):
50n/a ''' succeed iff pyclbr.readmodule_ex(modulename) corresponds
51n/a to the actual module object, module. Any identifiers in
52n/a ignore are ignored. If no module is provided, the appropriate
53n/a module is loaded with __import__.'''
54n/a
55n/a ignore = set(ignore) | set(['object'])
56n/a
57n/a if module is None:
58n/a # Import it.
59n/a # ('<silly>' is to work around an API silliness in __import__)
60n/a module = __import__(moduleName, globals(), {}, ['<silly>'])
61n/a
62n/a dict = pyclbr.readmodule_ex(moduleName)
63n/a
64n/a def ismethod(oclass, obj, name):
65n/a classdict = oclass.__dict__
66n/a if isinstance(obj, MethodType):
67n/a # could be a classmethod
68n/a if (not isinstance(classdict[name], ClassMethodType) or
69n/a obj.__self__ is not oclass):
70n/a return False
71n/a elif not isinstance(obj, FunctionType):
72n/a return False
73n/a
74n/a objname = obj.__name__
75n/a if objname.startswith("__") and not objname.endswith("__"):
76n/a objname = "_%s%s" % (oclass.__name__, objname)
77n/a return objname == name
78n/a
79n/a # Make sure the toplevel functions and classes are the same.
80n/a for name, value in dict.items():
81n/a if name in ignore:
82n/a continue
83n/a self.assertHasattr(module, name, ignore)
84n/a py_item = getattr(module, name)
85n/a if isinstance(value, pyclbr.Function):
86n/a self.assertIsInstance(py_item, (FunctionType, BuiltinFunctionType))
87n/a if py_item.__module__ != moduleName:
88n/a continue # skip functions that came from somewhere else
89n/a self.assertEqual(py_item.__module__, value.module)
90n/a else:
91n/a self.assertIsInstance(py_item, type)
92n/a if py_item.__module__ != moduleName:
93n/a continue # skip classes that came from somewhere else
94n/a
95n/a real_bases = [base.__name__ for base in py_item.__bases__]
96n/a pyclbr_bases = [ getattr(base, 'name', base)
97n/a for base in value.super ]
98n/a
99n/a try:
100n/a self.assertListEq(real_bases, pyclbr_bases, ignore)
101n/a except:
102n/a print("class=%s" % py_item, file=sys.stderr)
103n/a raise
104n/a
105n/a actualMethods = []
106n/a for m in py_item.__dict__.keys():
107n/a if ismethod(py_item, getattr(py_item, m), m):
108n/a actualMethods.append(m)
109n/a foundMethods = []
110n/a for m in value.methods.keys():
111n/a if m[:2] == '__' and m[-2:] != '__':
112n/a foundMethods.append('_'+name+m)
113n/a else:
114n/a foundMethods.append(m)
115n/a
116n/a try:
117n/a self.assertListEq(foundMethods, actualMethods, ignore)
118n/a self.assertEqual(py_item.__module__, value.module)
119n/a
120n/a self.assertEqualsOrIgnored(py_item.__name__, value.name,
121n/a ignore)
122n/a # can't check file or lineno
123n/a except:
124n/a print("class=%s" % py_item, file=sys.stderr)
125n/a raise
126n/a
127n/a # Now check for missing stuff.
128n/a def defined_in(item, module):
129n/a if isinstance(item, type):
130n/a return item.__module__ == module.__name__
131n/a if isinstance(item, FunctionType):
132n/a return item.__globals__ is module.__dict__
133n/a return False
134n/a for name in dir(module):
135n/a item = getattr(module, name)
136n/a if isinstance(item, (type, FunctionType)):
137n/a if defined_in(item, module):
138n/a self.assertHaskey(dict, name, ignore)
139n/a
140n/a def test_easy(self):
141n/a self.checkModule('pyclbr')
142n/a self.checkModule('ast')
143n/a self.checkModule('doctest', ignore=("TestResults", "_SpoofOut",
144n/a "DocTestCase", '_DocTestSuite'))
145n/a self.checkModule('difflib', ignore=("Match",))
146n/a
147n/a def test_decorators(self):
148n/a # XXX: See comment in pyclbr_input.py for a test that would fail
149n/a # if it were not commented out.
150n/a #
151n/a self.checkModule('test.pyclbr_input', ignore=['om'])
152n/a
153n/a def test_others(self):
154n/a cm = self.checkModule
155n/a
156n/a # These were once about the 10 longest modules
157n/a cm('random', ignore=('Random',)) # from _random import Random as CoreGenerator
158n/a cm('cgi', ignore=('log',)) # set with = in module
159n/a cm('pickle', ignore=('partial',))
160n/a cm('aifc', ignore=('openfp', '_aifc_params')) # set with = in module
161n/a cm('sre_parse', ignore=('dump', 'groups', 'pos')) # from sre_constants import *; property
162n/a cm('pdb')
163n/a cm('pydoc')
164n/a
165n/a # Tests for modules inside packages
166n/a cm('email.parser')
167n/a cm('test.test_pyclbr')
168n/a
169n/a def test_issue_14798(self):
170n/a # test ImportError is raised when the first part of a dotted name is
171n/a # not a package
172n/a self.assertRaises(ImportError, pyclbr.readmodule_ex, 'asyncore.foo')
173n/a
174n/a
175n/aif __name__ == "__main__":
176n/a unittest_main()