diff options
author | Ned Batchelder <ned@nedbatchelder.com> | 2021-05-01 17:53:27 -0400 |
---|---|---|
committer | Ned Batchelder <ned@nedbatchelder.com> | 2021-05-01 17:53:27 -0400 |
commit | bfd2b7585e64f4766e4eec315f94d187e2d4f976 (patch) | |
tree | 67e94be7cad9f3a147d96f2e8066ed6864135f32 | |
parent | 3d43c74cd2dd8c66c29572bc04a4b0de3e206364 (diff) | |
download | python-coveragepy-git-bfd2b7585e64f4766e4eec315f94d187e2d4f976.tar.gz |
refactor: move the remaining backward.py code, no more backward.py
-rw-r--r-- | coverage/backward.py | 64 | ||||
-rw-r--r-- | coverage/execfile.py | 90 | ||||
-rw-r--r-- | coverage/html.py | 2 | ||||
-rw-r--r-- | coverage/inorout.py | 40 | ||||
-rw-r--r-- | coverage/misc.py | 25 | ||||
-rw-r--r-- | perf/perf_measure.py | 2 | ||||
-rw-r--r-- | tests/coveragetest.py | 2 | ||||
-rw-r--r-- | tests/mixins.py | 6 | ||||
-rw-r--r-- | tests/test_api.py | 3 | ||||
-rw-r--r-- | tests/test_concurrency.py | 2 | ||||
-rw-r--r-- | tests/test_mixins.py | 2 | ||||
-rw-r--r-- | tests/test_oddball.py | 2 | ||||
-rw-r--r-- | tests/test_plugins.py | 3 | ||||
-rw-r--r-- | tests/test_xml.py | 2 |
14 files changed, 68 insertions, 177 deletions
diff --git a/coverage/backward.py b/coverage/backward.py deleted file mode 100644 index 1169ff46..00000000 --- a/coverage/backward.py +++ /dev/null @@ -1,64 +0,0 @@ -# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0 -# For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt - -"""Add things to old Pythons so I can pretend they are newer.""" - -import sys - -# imp was deprecated in Python 3.3 -try: - import importlib - import importlib.util - imp = None -except ImportError: - importlib = None - -# We only want to use importlib if it has everything we need. -try: - importlib_util_find_spec = importlib.util.find_spec -except Exception: - import imp - importlib_util_find_spec = None - - -def format_local_datetime(dt): - """Return a string with local timezone representing the date. - If python version is lower than 3.6, the time zone is not included. - """ - try: - return dt.astimezone().strftime('%Y-%m-%d %H:%M %z') - except (TypeError, ValueError): - # Datetime.astimezone in Python 3.5 can not handle naive datetime - return dt.strftime('%Y-%m-%d %H:%M') - - -def import_local_file(modname, modfile=None): - """Import a local file as a module. - - Opens a file in the current directory named `modname`.py, imports it - as `modname`, and returns the module object. `modfile` is the file to - import if it isn't in the current directory. - - """ - try: - import importlib.util as importlib_util - except ImportError: - importlib_util = None - - if modfile is None: - modfile = modname + '.py' - if importlib_util: - spec = importlib_util.spec_from_file_location(modname, modfile) - mod = importlib_util.module_from_spec(spec) - sys.modules[modname] = mod - spec.loader.exec_module(mod) - else: - for suff in imp.get_suffixes(): # pragma: part covered - if suff[0] == '.py': - break - - with open(modfile, 'r') as f: - # pylint: disable=undefined-loop-variable - mod = imp.load_module(modname, f, modfile, suff) - - return mod diff --git a/coverage/execfile.py b/coverage/execfile.py index 338fb477..e96a5265 100644 --- a/coverage/execfile.py +++ b/coverage/execfile.py @@ -13,7 +13,6 @@ import sys import types from coverage import env -from coverage.backward import imp, importlib_util_find_spec from coverage.files import canonical_filename, python_reported_file from coverage.misc import CoverageException, ExceptionDuringRun, NoCode, NoSource, isolate_module from coverage.phystokens import compile_unicode @@ -33,76 +32,33 @@ class DummyLoader(object): self.fullname = fullname -if importlib_util_find_spec: - def find_module(modulename): - """Find the module named `modulename`. +def find_module(modulename): + """Find the module named `modulename`. - Returns the file path of the module, the name of the enclosing - package, and the spec. - """ - try: - spec = importlib_util_find_spec(modulename) - except ImportError as err: - raise NoSource(str(err)) + Returns the file path of the module, the name of the enclosing + package, and the spec. + """ + try: + spec = importlib.util.find_spec(modulename) + except ImportError as err: + raise NoSource(str(err)) + if not spec: + raise NoSource("No module named %r" % (modulename,)) + pathname = spec.origin + packagename = spec.name + if spec.submodule_search_locations: + mod_main = modulename + ".__main__" + spec = importlib.util.find_spec(mod_main) if not spec: - raise NoSource("No module named %r" % (modulename,)) + raise NoSource( + "No module named %s; " + "%r is a package and cannot be directly executed" + % (mod_main, modulename) + ) pathname = spec.origin packagename = spec.name - if spec.submodule_search_locations: - mod_main = modulename + ".__main__" - spec = importlib_util_find_spec(mod_main) - if not spec: - raise NoSource( - "No module named %s; " - "%r is a package and cannot be directly executed" - % (mod_main, modulename) - ) - pathname = spec.origin - packagename = spec.name - packagename = packagename.rpartition(".")[0] - return pathname, packagename, spec -else: - def find_module(modulename): - """Find the module named `modulename`. - - Returns the file path of the module, the name of the enclosing - package, and None (where a spec would have been). - """ - openfile = None - glo, loc = globals(), locals() - try: - # Search for the module - inside its parent package, if any - using - # standard import mechanics. - if '.' in modulename: - packagename, name = modulename.rsplit('.', 1) - package = __import__(packagename, glo, loc, ['__path__']) - searchpath = package.__path__ - else: - packagename, name = None, modulename - searchpath = None # "top-level search" in imp.find_module() - openfile, pathname, _ = imp.find_module(name, searchpath) - - # Complain if this is a magic non-file module. - if openfile is None and pathname is None: - raise NoSource( - "module does not live in a file: %r" % modulename - ) - - # If `modulename` is actually a package, not a mere module, then we - # pretend to be Python 2.7 and try running its __main__.py script. - if openfile is None: - packagename = modulename - name = '__main__' - package = __import__(packagename, glo, loc, ['__path__']) - searchpath = package.__path__ - openfile, pathname, _ = imp.find_module(name, searchpath) - except ImportError as err: - raise NoSource(str(err)) - finally: - if openfile: - openfile.close() - - return pathname, packagename, None + packagename = packagename.rpartition(".")[0] + return pathname, packagename, spec class PyRunner(object): diff --git a/coverage/html.py b/coverage/html.py index aea1aa25..f4670caf 100644 --- a/coverage/html.py +++ b/coverage/html.py @@ -11,10 +11,10 @@ import shutil import types import coverage -from coverage.backward import format_local_datetime from coverage.data import add_data_to_hash from coverage.files import flat_rootname from coverage.misc import CoverageException, ensure_dir, file_be_gone, Hasher, isolate_module +from coverage.misc import format_local_datetime from coverage.report import get_analysis_to_report from coverage.results import Numbers from coverage.templite import Templite diff --git a/coverage/inorout.py b/coverage/inorout.py index 554d34c4..f4d99772 100644 --- a/coverage/inorout.py +++ b/coverage/inorout.py @@ -3,6 +3,7 @@ """Determining whether files are being measured/reported or not.""" +import importlib.util import inspect import itertools import os @@ -13,7 +14,6 @@ import sysconfig import traceback from coverage import env -from coverage.backward import importlib_util_find_spec from coverage.disposition import FileDisposition, disposition_init from coverage.files import TreeMatcher, FnmatchMatcher, ModuleMatcher from coverage.files import prep_patterns, find_python_files, canonical_filename @@ -109,37 +109,15 @@ def module_has_file(mod): def file_for_module(modulename): """Find the file for `modulename`, or return None.""" - if importlib_util_find_spec: - filename = None - try: - spec = importlib_util_find_spec(modulename) - except ImportError: - pass - else: - if spec is not None: - filename = spec.origin - return filename + filename = None + try: + spec = importlib.util.find_spec(modulename) + except ImportError: + pass else: - import imp - openfile = None - glo, loc = globals(), locals() - try: - # Search for the module - inside its parent package, if any - using - # standard import mechanics. - if '.' in modulename: - packagename, name = modulename.rsplit('.', 1) - package = __import__(packagename, glo, loc, ['__path__']) - searchpath = package.__path__ - else: - packagename, name = None, modulename - searchpath = None # "top-level search" in imp.find_module() - openfile, pathname, _ = imp.find_module(name, searchpath) - return pathname - except ImportError: - return None - finally: - if openfile: - openfile.close() + if spec is not None: + filename = spec.origin + return filename def add_stdlib_paths(paths): diff --git a/coverage/misc.py b/coverage/misc.py index 7182d385..6f104ac0 100644 --- a/coverage/misc.py +++ b/coverage/misc.py @@ -5,6 +5,7 @@ import errno import hashlib +import importlib.util import inspect import locale import os @@ -315,6 +316,30 @@ def substitute_variables(text, variables): return text +def format_local_datetime(dt): + """Return a string with local timezone representing the date. + """ + return dt.astimezone().strftime('%Y-%m-%d %H:%M %z') + + +def import_local_file(modname, modfile=None): + """Import a local file as a module. + + Opens a file in the current directory named `modname`.py, imports it + as `modname`, and returns the module object. `modfile` is the file to + import if it isn't in the current directory. + + """ + if modfile is None: + modfile = modname + '.py' + spec = importlib.util.spec_from_file_location(modname, modfile) + mod = importlib.util.module_from_spec(spec) + sys.modules[modname] = mod + spec.loader.exec_module(mod) + + return mod + + class BaseCoverageException(Exception): """The base of all Coverage exceptions.""" pass diff --git a/perf/perf_measure.py b/perf/perf_measure.py index b903567c..652f0fa8 100644 --- a/perf/perf_measure.py +++ b/perf/perf_measure.py @@ -14,7 +14,7 @@ import time from unittest_mixins.mixins import make_file import coverage -from coverage.backward import import_local_file +from coverage.misc import import_local_file from tests.helpers import SuperModuleCleaner diff --git a/tests/coveragetest.py b/tests/coveragetest.py index 2a55cf8b..1163e349 100644 --- a/tests/coveragetest.py +++ b/tests/coveragetest.py @@ -19,8 +19,8 @@ import pytest import coverage from coverage import env -from coverage.backward import import_local_file from coverage.cmdline import CoverageScript +from coverage.misc import import_local_file from tests.helpers import arcs_to_arcz_repr, arcz_to_arcs, assert_count_equal from tests.helpers import nice_file, run_command diff --git a/tests/mixins.py b/tests/mixins.py index ff47a4da..44b16f6c 100644 --- a/tests/mixins.py +++ b/tests/mixins.py @@ -7,6 +7,7 @@ Test class mixins Some of these are transitional while working toward pure-pytest style. """ +import importlib import os import os.path import shutil @@ -14,8 +15,6 @@ import sys import pytest -from coverage.backward import importlib - from tests.helpers import change_dir, make_file, remove_files @@ -130,8 +129,7 @@ class SysPathModulesMixin: if os.path.exists("__pycache__"): shutil.rmtree("__pycache__") - if importlib and hasattr(importlib, "invalidate_caches"): - importlib.invalidate_caches() + importlib.invalidate_caches() class StdStreamCapturingMixin: diff --git a/tests/test_api.py b/tests/test_api.py index b17f9ee0..57154d64 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -17,10 +17,9 @@ import pytest import coverage from coverage import env -from coverage.backward import import_local_file from coverage.data import line_counts from coverage.files import abs_file, relative_filename -from coverage.misc import CoverageException +from coverage.misc import CoverageException, import_local_file from tests.coveragetest import CoverageTest, TESTS_DIR, UsingModulesMixin from tests.helpers import assert_count_equal, change_dir, nice_file diff --git a/tests/test_concurrency.py b/tests/test_concurrency.py index fa482f91..9cc1f3b6 100644 --- a/tests/test_concurrency.py +++ b/tests/test_concurrency.py @@ -16,9 +16,9 @@ import pytest import coverage from coverage import env -from coverage.backward import import_local_file from coverage.data import line_counts from coverage.files import abs_file +from coverage.misc import import_local_file from tests.coveragetest import CoverageTest from tests.helpers import remove_files diff --git a/tests/test_mixins.py b/tests/test_mixins.py index 028a19fd..aab1242a 100644 --- a/tests/test_mixins.py +++ b/tests/test_mixins.py @@ -6,7 +6,7 @@ import pytest -from coverage.backward import import_local_file +from coverage.misc import import_local_file from tests.mixins import TempDirMixin, SysPathModulesMixin diff --git a/tests/test_oddball.py b/tests/test_oddball.py index a63719ea..2e438396 100644 --- a/tests/test_oddball.py +++ b/tests/test_oddball.py @@ -11,8 +11,8 @@ import pytest import coverage from coverage import env -from coverage.backward import import_local_file from coverage.files import abs_file +from coverage.misc import import_local_file from tests.coveragetest import CoverageTest from tests import osinfo diff --git a/tests/test_plugins.py b/tests/test_plugins.py index 5a8d92ee..fec92749 100644 --- a/tests/test_plugins.py +++ b/tests/test_plugins.py @@ -12,10 +12,9 @@ import pytest import coverage from coverage import env -from coverage.backward import import_local_file from coverage.data import line_counts from coverage.control import Plugins -from coverage.misc import CoverageException +from coverage.misc import CoverageException, import_local_file import coverage.plugin diff --git a/tests/test_xml.py b/tests/test_xml.py index 94669cdc..334abb4c 100644 --- a/tests/test_xml.py +++ b/tests/test_xml.py @@ -12,8 +12,8 @@ from xml.etree import ElementTree import pytest import coverage -from coverage.backward import import_local_file from coverage.files import abs_file +from coverage.misc import import_local_file from tests.coveragetest import CoverageTest from tests.goldtest import compare, gold_path |