summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNed Batchelder <ned@nedbatchelder.com>2023-01-09 17:42:53 -0500
committerNed Batchelder <ned@nedbatchelder.com>2023-01-09 19:00:40 -0500
commit880a64afd24aae34eff2781f568d8ac9807d2ecc (patch)
tree802cf3368d4d7a1b27ee6b5d614c367ac691e320
parent8fef6f057c377879720c4c9d994e9651362a49b9 (diff)
downloadpython-coveragepy-git-880a64afd24aae34eff2781f568d8ac9807d2ecc.tar.gz
fix: isolate user code from coverage.py internal code flags. #1524
-rw-r--r--CHANGES.rst6
-rw-r--r--coverage/execfile.py2
-rw-r--r--coverage/parser.py2
-rw-r--r--lab/genpy.py2
-rw-r--r--lab/parser.py2
-rw-r--r--lab/show_pyc.py2
-rw-r--r--setup.py2
-rw-r--r--tests/test_cmdline.py2
-rw-r--r--tests/test_summary.py16
9 files changed, 28 insertions, 8 deletions
diff --git a/CHANGES.rst b/CHANGES.rst
index 91937952..765695f8 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -20,7 +20,11 @@ development at the same time, such as 4.5.x and 5.0.
Unreleased
----------
-Nothing yet.
+- Fix: On Python 3.7, a file with type annotations but no ``from __future__
+ import annotations`` would be missing statements in the coverage report. This
+ is now fixed, closing `issue 1524`_.
+
+.. _issue 1524: https://github.com/nedbat/coveragepy/issues/1524
.. _changes_7-0-4:
diff --git a/coverage/execfile.py b/coverage/execfile.py
index f0f4f171..d26da65b 100644
--- a/coverage/execfile.py
+++ b/coverage/execfile.py
@@ -275,7 +275,7 @@ def make_code_from_py(filename):
except (OSError, NoSource) as exc:
raise NoSource(f"No file to run: '{filename}'") from exc
- return compile(source, filename, "exec")
+ return compile(source, filename, "exec", dont_inherit=True)
def make_code_from_pyc(filename):
diff --git a/coverage/parser.py b/coverage/parser.py
index 37d74767..b8ddb501 100644
--- a/coverage/parser.py
+++ b/coverage/parser.py
@@ -385,7 +385,7 @@ class ByteParser:
else:
assert filename is not None
try:
- self.code = compile(text, filename, "exec")
+ self.code = compile(text, filename, "exec", dont_inherit=True)
except SyntaxError as synerr:
raise NotPython(
"Couldn't parse '%s' as Python source: '%s' at line %d" % (
diff --git a/lab/genpy.py b/lab/genpy.py
index f968c916..f88e70ca 100644
--- a/lab/genpy.py
+++ b/lab/genpy.py
@@ -231,7 +231,7 @@ def show_a_bunch():
source = PythonSpinner.generate_python(maker.make_body("def"))
try:
print("-"*80, "\n", source, sep="")
- compile(source, "<string>", "exec")
+ compile(source, "<string>", "exec", dont_inherit=True)
except Exception as ex:
print(f"Oops: {ex}\n{source}")
if len(source) > len(longest):
diff --git a/lab/parser.py b/lab/parser.py
index ebd4e7f3..c7687bda 100644
--- a/lab/parser.py
+++ b/lab/parser.py
@@ -177,7 +177,7 @@ def all_code_objects(code):
def disassemble(pyparser):
"""Disassemble code, for ad-hoc experimenting."""
- code = compile(pyparser.text, "", "exec")
+ code = compile(pyparser.text, "", "exec", dont_inherit=True)
for code_obj in all_code_objects(code):
if pyparser.text:
srclines = pyparser.text.splitlines()
diff --git a/lab/show_pyc.py b/lab/show_pyc.py
index e346930a..1bd98ec6 100644
--- a/lab/show_pyc.py
+++ b/lab/show_pyc.py
@@ -48,7 +48,7 @@ def show_py_file(fname):
show_py_text(text, fname=fname)
def show_py_text(text, fname="<string>"):
- code = compile(text, fname, "exec")
+ code = compile(text, fname, "exec", dont_inherit=True)
show_code(code)
CO_FLAGS = [
diff --git a/setup.py b/setup.py
index c30907f9..dd767601 100644
--- a/setup.py
+++ b/setup.py
@@ -59,7 +59,7 @@ with open(cov_ver_py) as version_file:
# Keep pylint happy.
__version__ = __url__ = version_info = ""
# Execute the code in version.py.
- exec(compile(version_file.read(), cov_ver_py, 'exec'))
+ exec(compile(version_file.read(), cov_ver_py, 'exec', dont_inherit=True))
with open("README.rst") as readme:
readme_text = readme.read()
diff --git a/tests/test_cmdline.py b/tests/test_cmdline.py
index 6caac307..c517d39d 100644
--- a/tests/test_cmdline.py
+++ b/tests/test_cmdline.py
@@ -142,7 +142,7 @@ class BaseCmdLineTest(CoverageTest):
code = textwrap.dedent(code)
expected = self.model_object()
globs = {n: getattr(expected, n) for n in self.MOCK_GLOBALS}
- code_obj = compile(code, "<code>", "exec")
+ code_obj = compile(code, "<code>", "exec", dont_inherit=True)
eval(code_obj, globs, {}) # pylint: disable=eval-used
# Many of our functions take a lot of arguments, and cmdline.py
diff --git a/tests/test_summary.py b/tests/test_summary.py
index 3109e90f..f532a7b1 100644
--- a/tests/test_summary.py
+++ b/tests/test_summary.py
@@ -849,6 +849,22 @@ class SummaryTest(UsingModulesMixin, CoverageTest):
assert self.get_report(cov, output_format="total", precision=2) == "78.57\n"
assert self.get_report(cov, output_format="total", precision=4) == "78.5714\n"
+ def test_bug_1524(self) -> None:
+ self.make_file("bug1524.py", """\
+ class Mine:
+ @property
+ def thing(self) -> int:
+ return 17
+
+ print(Mine().thing)
+ """)
+ cov = coverage.Coverage()
+ self.start_import_stop(cov, "bug1524")
+ assert self.stdout() == "17\n"
+ report = self.get_report(cov)
+ report_lines = report.splitlines()
+ assert report_lines[2] == "bug1524.py 5 0 100%"
+
class ReportingReturnValueTest(CoverageTest):
"""Tests of reporting functions returning values."""