Skip to content

Commit 7cadf94

Browse files
committed
Make the test self-contained and stop it re-running __main__
The positive-control arg crafted a "module '__main__' has no attribute" message, which the cross-interpreter path matched and re-executed __main__ (the test runner) in-process. Drop that case and build the module in memory instead of writing a file, so test_interpreters.test_queues runs in isolation again.
1 parent 48ad5c4 commit 7cadf94

1 file changed

Lines changed: 25 additions & 27 deletions

File tree

Lib/test/test_interpreters/test_queues.py

Lines changed: 25 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import importlib
22
import pickle
3+
import sys
34
import threading
5+
import types
46
from textwrap import dedent
57
import unittest
68

@@ -382,28 +384,25 @@ def test_put_get_full_fallback(self):
382384
self.assertIsNot(obj, obj2)
383385

384386
def _check_unpickle_attributeerror_arg(self, arg):
385-
# Cross an object through a queue where get() must re-import its
386-
# class via a module __getattr__ that raises AttributeError(arg).
387-
source = dedent("""
388-
_attrerr_arg = None
389-
390-
class Thing:
391-
pass
392-
393-
def break_module(mod, arg):
394-
del mod.Thing
395-
mod._attrerr_arg = arg
396-
def __getattr__(name):
397-
raise AttributeError(mod._attrerr_arg)
398-
mod.__getattr__ = __getattr__
399-
""")
400-
with import_helper.ready_to_import('_xi_attrerr', source) as (name, _):
401-
mod = importlib.import_module(name)
402-
queue = queues.create()
403-
queue.put(mod.Thing())
404-
mod.break_module(mod, arg)
405-
with self.assertRaises(interpreters.NotShareableError):
406-
queue.get()
387+
# Put an object through a queue where get() must re-import its class
388+
# via a module __getattr__ that raises AttributeError(arg).
389+
modname = '_test_xi_attrerr'
390+
mod = types.ModuleType(modname)
391+
class Thing:
392+
pass
393+
Thing.__module__ = modname
394+
Thing.__qualname__ = 'Thing'
395+
mod.Thing = Thing
396+
sys.modules[modname] = mod
397+
self.addCleanup(sys.modules.pop, modname, None)
398+
queue = queues.create()
399+
queue.put(Thing())
400+
del mod.Thing
401+
def raise_attributeerror(name):
402+
raise AttributeError(arg)
403+
mod.__getattr__ = raise_attributeerror
404+
with self.assertRaises(interpreters.NotShareableError):
405+
queue.get()
407406

408407
def test_get_unpickle_fails_with_bad_attributeerror_arg(self):
409408
# gh-151862: an AttributeError arg that can't be UTF-8 encoded used
@@ -413,11 +412,10 @@ def test_get_unpickle_fails_with_bad_attributeerror_arg(self):
413412
self._check_unpickle_attributeerror_arg(arg)
414413

415414
def test_get_unpickle_fails_with_str_attributeerror_arg(self):
416-
# Positive control: a normal str arg (incl. the real missing-__main__
417-
# message) must not crash, locking in the non-NULL strncmp() path.
418-
for arg in ['boom', "module '__main__' has no attribute 'Thing'"]:
419-
with self.subTest(arg=arg):
420-
self._check_unpickle_attributeerror_arg(arg)
415+
# Positive control: a normal str arg must not crash, locking in the
416+
# non-NULL strncmp() path.
417+
with self.subTest(arg='boom'):
418+
self._check_unpickle_attributeerror_arg('boom')
421419

422420
def test_put_get_same_interpreter(self):
423421
interp = interpreters.create()

0 commit comments

Comments
 (0)