Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Lib/test/libregrtest/findtests.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"test_asyncio",
"test_concurrent_futures",
"test_future_stmt",
"test_inspect",
"test_multiprocessing_fork",
"test_multiprocessing_forkserver",
"test_multiprocessing_spawn",
Expand Down
26 changes: 25 additions & 1 deletion Lib/test/support/import_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import unittest
import warnings

from .os_helper import unlink
from .os_helper import unlink, temp_dir


@contextlib.contextmanager
Expand Down Expand Up @@ -274,3 +274,27 @@ def mock_register_at_fork(func):
# memory.
from unittest import mock
return mock.patch('os.register_at_fork', create=True)(func)


@contextlib.contextmanager
def ready_to_import(name=None, source=""):
# To fix import cycles:
from test.support import script_helper

# sets up a temporary directory and removes it
# creates the module file
# temporarily clears the module from sys.modules (if any)
# reverts or removes the module when cleaning up
name = name or "spam"
with temp_dir() as tempdir:
path = script_helper.make_script(tempdir, name, source)
old_module = sys.modules.pop(name, None)
try:
sys.path.insert(0, tempdir)
yield name, path
sys.path.remove(tempdir)
finally:
if old_module is not None:
sys.modules[name] = old_module
elif name in sys.modules:
del sys.modules[name]
39 changes: 9 additions & 30 deletions Lib/test/test_import/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import builtins
import contextlib
import errno
import glob
import json
Expand Down Expand Up @@ -30,9 +29,10 @@
STDLIB_DIR, swap_attr, swap_item, cpython_only, is_emscripten,
is_wasi, run_in_subinterp, run_in_subinterp_with_config, Py_TRACE_REFS)
from test.support.import_helper import (
forget, make_legacy_pyc, unlink, unload, DirsOnSysPath, CleanImport)
forget, make_legacy_pyc, unlink, unload, ready_to_import,
DirsOnSysPath, CleanImport)
from test.support.os_helper import (
TESTFN, rmtree, temp_umask, TESTFN_UNENCODABLE, temp_dir)
TESTFN, rmtree, temp_umask, TESTFN_UNENCODABLE)
from test.support import script_helper
from test.support import threading_helper
from test.test_importlib.util import uncache
Expand Down Expand Up @@ -125,27 +125,6 @@ def wrapper(self):
return deco


@contextlib.contextmanager
def _ready_to_import(name=None, source=""):
# sets up a temporary directory and removes it
# creates the module file
# temporarily clears the module from sys.modules (if any)
# reverts or removes the module when cleaning up
name = name or "spam"
with temp_dir() as tempdir:
path = script_helper.make_script(tempdir, name, source)
old_module = sys.modules.pop(name, None)
try:
sys.path.insert(0, tempdir)
yield name, path
sys.path.remove(tempdir)
finally:
if old_module is not None:
sys.modules[name] = old_module
elif name in sys.modules:
del sys.modules[name]


if _testsinglephase is not None:
def restore__testsinglephase(*, _orig=_testsinglephase):
# We started with the module imported and want to restore
Expand Down Expand Up @@ -401,7 +380,7 @@ def test_from_import_missing_attr_path_is_canonical(self):

def test_from_import_star_invalid_type(self):
import re
with _ready_to_import() as (name, path):
with ready_to_import() as (name, path):
with open(path, 'w', encoding='utf-8') as f:
f.write("__all__ = [b'invalid_type']")
globals = {}
Expand All @@ -410,7 +389,7 @@ def test_from_import_star_invalid_type(self):
):
exec(f"from {name} import *", globals)
self.assertNotIn(b"invalid_type", globals)
with _ready_to_import() as (name, path):
with ready_to_import() as (name, path):
with open(path, 'w', encoding='utf-8') as f:
f.write("globals()[b'invalid_type'] = object()")
globals = {}
Expand Down Expand Up @@ -818,7 +797,7 @@ class FilePermissionTests(unittest.TestCase):
)
def test_creation_mode(self):
mask = 0o022
with temp_umask(mask), _ready_to_import() as (name, path):
with temp_umask(mask), ready_to_import() as (name, path):
cached_path = importlib.util.cache_from_source(path)
module = __import__(name)
if not os.path.exists(cached_path):
Expand All @@ -837,7 +816,7 @@ def test_creation_mode(self):
def test_cached_mode_issue_2051(self):
# permissions of .pyc should match those of .py, regardless of mask
mode = 0o600
with temp_umask(0o022), _ready_to_import() as (name, path):
with temp_umask(0o022), ready_to_import() as (name, path):
cached_path = importlib.util.cache_from_source(path)
os.chmod(path, mode)
__import__(name)
Expand All @@ -853,7 +832,7 @@ def test_cached_mode_issue_2051(self):
@os_helper.skip_unless_working_chmod
def test_cached_readonly(self):
mode = 0o400
with temp_umask(0o022), _ready_to_import() as (name, path):
with temp_umask(0o022), ready_to_import() as (name, path):
cached_path = importlib.util.cache_from_source(path)
os.chmod(path, mode)
__import__(name)
Expand All @@ -868,7 +847,7 @@ def test_cached_readonly(self):
def test_pyc_always_writable(self):
# Initially read-only .pyc files on Windows used to cause problems
# with later updates, see issue #6074 for details
with _ready_to_import() as (name, path):
with ready_to_import() as (name, path):
# Write a Python file, make it read-only and import it
with open(path, 'w', encoding='utf-8') as f:
f.write("x = 'original'\n")
Expand Down
6 changes: 6 additions & 0 deletions Lib/test/test_inspect/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import os
from test import support


def load_tests(*args):
return support.load_package_tests(os.path.dirname(__file__), *args)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@serhiy-storchaka: It would be nice if we could magically generate such function, instead of having to duplicate the same 4 lines in each test_xxx/ test package. Do you think that it would be possible?

File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,16 @@

from test.support import cpython_only
from test.support import MISSING_C_DOCSTRINGS, ALWAYS_EQ
from test.support.import_helper import DirsOnSysPath
from test.support.import_helper import DirsOnSysPath, ready_to_import
from test.support.os_helper import TESTFN
from test.support.script_helper import assert_python_ok, assert_python_failure
from test import inspect_fodder as mod
from test import inspect_fodder2 as mod2
from test import support
from test import inspect_stock_annotations
from test import inspect_stringized_annotations
from test import inspect_stringized_annotations_2

from test.test_import import _ready_to_import
from test.test_inspect import inspect_fodder as mod
from test.test_inspect import inspect_fodder2 as mod2
from test.test_inspect import inspect_stock_annotations
from test.test_inspect import inspect_stringized_annotations
from test.test_inspect import inspect_stringized_annotations_2


# Functions tested in this suite:
Expand Down Expand Up @@ -4954,7 +4953,7 @@ def assertInspectEqual(self, path, source):

def test_getsource_reload(self):
# see issue 1218234
with _ready_to_import('reload_bug', self.src_before) as (name, path):
with ready_to_import('reload_bug', self.src_before) as (name, path):
module = importlib.import_module(name)
self.assertInspectEqual(path, module)
with open(path, 'w', encoding='utf-8') as src:
Expand Down
2 changes: 1 addition & 1 deletion Lib/test/test_tokenize.py
Original file line number Diff line number Diff line change
Expand Up @@ -1862,7 +1862,7 @@ def test_random_files(self):
# TODO: Remove this once we can untokenize PEP 701 syntax
testfiles.remove(os.path.join(tempdir, "test_fstring.py"))

for f in ('buffer', 'builtin', 'fileio', 'inspect', 'os', 'platform', 'sys'):
for f in ('buffer', 'builtin', 'fileio', 'os', 'platform', 'sys'):
testfiles.remove(os.path.join(tempdir, "test_%s.py") % f)

if not support.is_resource_enabled("cpu"):
Expand Down
1 change: 1 addition & 0 deletions Makefile.pre.in
Original file line number Diff line number Diff line change
Expand Up @@ -2168,6 +2168,7 @@ TESTSUBDIRS= idlelib/idle_test \
test/test_email \
test/test_email/data \
test/test_future_stmt \
test/test_inspect \
test/test_import \
test/test_import/data \
test/test_import/data/circular_imports \
Expand Down