1- from collections .abc import Iterator
21import contextlib
32import importlib
43import io
@@ -1555,6 +1554,7 @@ def test_parse_error(self):
15551554 with self .subTest (code = code ):
15561555 self .assertEqual (actual , None )
15571556
1557+ @patch .dict (sys .modules )
15581558 def test_suggestions_and_messages (self ) -> None :
15591559 # more unitary tests checking the exact suggestions provided
15601560 # (sorting, de-duplication, import action...)
@@ -1615,27 +1615,27 @@ def test_suggestions_and_messages(self) -> None:
16151615 new_imports = sys .modules .keys () - _imported
16161616 self .assertSetEqual (new_imports , expected_imports )
16171617
1618- class TestModuleCompleterAutomaticImports (TestCase ):
1619- """Out of TestPyReplModuleCompleter case because it blocks module import."""
1620-
1621- @classmethod
1622- def setUpClass (cls ) -> None :
1623- super ().setUpClass ()
1624- cls ._audit_events : set [str ] | None = None
1625- def _hook (name : str , _args : tuple ):
1626- if cls ._audit_events is not None :
1627- cls ._audit_events .add (name )
1628- sys .addaudithook (_hook )
1629-
1630- @classmethod
1631- @contextlib .contextmanager
1632- def _capture_audit_events (cls ) -> Iterator [set [str ]]:
1633- cls ._audit_events = set ()
1634- try :
1635- yield cls ._audit_events
1636- finally :
1637- cls ._audit_events = None
16381618
1619+ # Audit hook used to check for stdlib modules import side-effects
1620+ # Defined globally to avoid adding one hook per test run (refleak)
1621+ _audit_events : set [str ] | None = None
1622+ def _hook (name : str , _args : tuple ):
1623+ if _audit_events is not None : # No-op when not activated
1624+ _audit_events .add (name )
1625+ sys .addaudithook (_hook )
1626+
1627+
1628+ @contextlib .contextmanager
1629+ def _capture_audit_events ():
1630+ global _audit_events
1631+ _audit_events = set ()
1632+ try :
1633+ yield _audit_events
1634+ finally :
1635+ _audit_events = None
1636+
1637+
1638+ class TestModuleCompleterAutomaticImports (TestCase ):
16391639 def test_no_side_effects (self ):
16401640 from test .test___all__ import AllTest # TODO: extract to a helper?
16411641
@@ -1644,11 +1644,10 @@ def test_no_side_effects(self):
16441644 with self .subTest (modname = modname ):
16451645 with (captured_stdout () as out ,
16461646 captured_stderr () as err ,
1647- self . _capture_audit_events () as audit_events ,
1647+ _capture_audit_events () as audit_events ,
16481648 (patch ("tkinter._tkinter.create" ) if tkinter
16491649 else contextlib .nullcontext ()) as tk_mock ,
1650- warnings .catch_warnings (action = "ignore" ),
1651- patch .dict (sys .modules )):
1650+ warnings .catch_warnings (action = "ignore" )):
16521651 completer ._maybe_import_module (modname )
16531652 # Test no module is imported that
16541653 # 1. prints any text
0 commit comments