|
3 | 3 | Nick Mathewson
|
4 | 4 | '''
|
5 | 5 |
|
| 6 | +import importlib.machinery |
6 | 7 | import sys
|
| 8 | +from contextlib import contextmanager |
7 | 9 | from textwrap import dedent
|
8 | 10 | from types import FunctionType, MethodType, BuiltinFunctionType
|
9 | 11 | import pyclbr
|
|
22 | 24 | # is imperfect (as designed), testModule is called with a set of
|
23 | 25 | # members to ignore.
|
24 | 26 |
|
| 27 | + |
| 28 | +@contextmanager |
| 29 | +def temporary_main_spec(): |
| 30 | + """ |
| 31 | + A context manager that temporarily sets the `__spec__` attribute |
| 32 | + of the `__main__` module if it's missing. |
| 33 | + """ |
| 34 | + main_mod = sys.modules.get("__main__") |
| 35 | + if main_mod is None: |
| 36 | + yield # Do nothing if __main__ is not present |
| 37 | + return |
| 38 | + |
| 39 | + original_spec = getattr(main_mod, "__spec__", None) |
| 40 | + if original_spec is None: |
| 41 | + main_mod.__spec__ = importlib.machinery.ModuleSpec( |
| 42 | + name="__main__", loader=None, origin="built-in" |
| 43 | + ) |
| 44 | + try: |
| 45 | + yield |
| 46 | + finally: |
| 47 | + main_mod.__spec__ = original_spec |
| 48 | + |
| 49 | + |
25 | 50 | class PyclbrTest(TestCase):
|
26 | 51 |
|
27 | 52 | def assertListEq(self, l1, l2, ignore):
|
@@ -145,8 +170,9 @@ def test_easy(self):
|
145 | 170 | self.checkModule('pyclbr')
|
146 | 171 | # XXX: Metaclasses are not supported
|
147 | 172 | # self.checkModule('ast')
|
148 |
| - self.checkModule('doctest', ignore=("TestResults", "_SpoofOut", |
149 |
| - "DocTestCase", '_DocTestSuite')) |
| 173 | + with temporary_main_spec(): |
| 174 | + self.checkModule('doctest', ignore=("TestResults", "_SpoofOut", |
| 175 | + "DocTestCase", '_DocTestSuite')) |
150 | 176 | self.checkModule('difflib', ignore=("Match",))
|
151 | 177 |
|
152 | 178 | def test_cases(self):
|
@@ -223,12 +249,13 @@ def test_others(self):
|
223 | 249 | with warnings.catch_warnings():
|
224 | 250 | warnings.simplefilter('ignore', DeprecationWarning)
|
225 | 251 | cm('sre_parse', ignore=('dump', 'groups', 'pos')) # from sre_constants import *; property
|
226 |
| - cm( |
227 |
| - 'pdb', |
228 |
| - # pyclbr does not handle elegantly `typing` or properties |
229 |
| - ignore=('Union', '_ModuleTarget', '_ScriptTarget', '_ZipTarget', 'curframe_locals'), |
230 |
| - ) |
231 |
| - cm('pydoc', ignore=('input', 'output',)) # properties |
| 252 | + with temporary_main_spec(): |
| 253 | + cm( |
| 254 | + 'pdb', |
| 255 | + # pyclbr does not handle elegantly `typing` or properties |
| 256 | + ignore=('Union', '_ModuleTarget', '_ScriptTarget', '_ZipTarget', 'curframe_locals'), |
| 257 | + ) |
| 258 | + cm('pydoc', ignore=('input', 'output',)) # properties |
232 | 259 |
|
233 | 260 | # Tests for modules inside packages
|
234 | 261 | cm('email.parser')
|
|
0 commit comments