diff options
author | Ned Batchelder <ned@nedbatchelder.com> | 2022-12-30 18:07:36 -0500 |
---|---|---|
committer | Ned Batchelder <ned@nedbatchelder.com> | 2022-12-30 18:35:09 -0500 |
commit | 45787e29dea3a41f2e9570b66a571a7ebcda4592 (patch) | |
tree | 7eeadde7d7a033e27abd1df7411bb525bd711148 | |
parent | 85c7a4ac4161c4eb2efeaf07e6f833d3a073b018 (diff) | |
download | python-coveragepy-git-45787e29dea3a41f2e9570b66a571a7ebcda4592.tar.gz |
refactor: removed mentions of Jython and IronPython
-rw-r--r-- | CHANGES.rst | 10 | ||||
-rw-r--r-- | coverage/control.py | 11 | ||||
-rw-r--r-- | coverage/env.py | 2 | ||||
-rw-r--r-- | coverage/exceptions.py | 10 | ||||
-rw-r--r-- | coverage/inorout.py | 8 | ||||
-rw-r--r-- | coverage/parser.py | 11 | ||||
-rw-r--r-- | coverage/python.py | 8 | ||||
-rw-r--r-- | metacov.ini | 10 | ||||
-rw-r--r-- | setup.py | 4 | ||||
-rw-r--r-- | tests/conftest.py | 9 | ||||
-rw-r--r-- | tests/coveragetest.py | 20 | ||||
-rw-r--r-- | tests/test_arcs.py | 6 | ||||
-rw-r--r-- | tests/test_cmdline.py | 2 | ||||
-rw-r--r-- | tests/test_concurrency.py | 16 | ||||
-rw-r--r-- | tests/test_execfile.py | 4 | ||||
-rw-r--r-- | tests/test_oddball.py | 9 | ||||
-rw-r--r-- | tests/test_process.py | 22 | ||||
-rw-r--r-- | tests/test_python.py | 4 | ||||
-rw-r--r-- | tests/test_summary.py | 8 | ||||
-rw-r--r-- | tox.ini | 2 |
20 files changed, 21 insertions, 155 deletions
diff --git a/CHANGES.rst b/CHANGES.rst index 9cebd7cb..d8d36442 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -20,10 +20,6 @@ development at the same time, such as 4.5.x and 5.0. Unreleased ---------- -- Refactor: a number of refactorings internally due to adding type annotations. - This should not affect outward behavior, but they were a bit invasive in some - places. - - Fix: if Python doesn't provide tomllib, then TOML configuration files can only be read if coverage.py is installed with the ``[toml]`` extra. Coverage.py will raise an error if toml support is not installed when it sees @@ -34,6 +30,12 @@ Unreleased - Fix: adjusted how decorators are traced on PyPy 7.3.10, fixing `issue 1515`_. +- Refactor: a number of refactorings internally due to adding type annotations. + This should not affect outward behavior, but they were a bit invasive in some + places. + +- Remove vestigial and long-untested support for Jython and IronPython. + .. _issue 1515: https://github.com/nedbat/coveragepy/issues/1515 .. _issue 1516: https://github.com/nedbat/coveragepy/issues/1516 diff --git a/coverage/control.py b/coverage/control.py index 71b56a44..6bbc17c7 100644 --- a/coverage/control.py +++ b/coverage/control.py @@ -37,6 +37,7 @@ from coverage.jsonreport import JsonReporter from coverage.lcovreport import LcovReporter from coverage.misc import bool_or_none, join_regex, human_sorted from coverage.misc import DefaultValue, ensure_dir_for_file, isolate_module +from coverage.multiproc import patch_multiprocessing from coverage.plugin import FileReporter from coverage.plugin_support import Plugins from coverage.python import PythonFileReporter @@ -46,12 +47,6 @@ from coverage.summary import SummaryReporter from coverage.types import TConfigurable, TConfigSection, TConfigValue, TSysInfo from coverage.xmlreport import XmlReporter -try: - from coverage.multiproc import patch_multiprocessing - has_patch_multiprocessing = True -except ImportError: # pragma: only jython - # Jython has no multiprocessing module. - has_patch_multiprocessing = False os = isolate_module(os) @@ -493,10 +488,6 @@ class Coverage(TConfigurable): # Construct the collector. concurrency: List[str] = self.config.concurrency or [] if "multiprocessing" in concurrency: - if not has_patch_multiprocessing: - raise ConfigError( # pragma: only jython - "multiprocessing is not supported on this Python" - ) if self.config.config_file is None: raise ConfigError("multiprocessing requires a configuration file") patch_multiprocessing(rcfile=self.config.config_file) diff --git a/coverage/env.py b/coverage/env.py index 3d0114c8..fcd5ff04 100644 --- a/coverage/env.py +++ b/coverage/env.py @@ -15,8 +15,6 @@ OSX = sys.platform == "darwin" # Python implementations. CPYTHON = (platform.python_implementation() == "CPython") PYPY = (platform.python_implementation() == "PyPy") -JYTHON = (platform.python_implementation() == "Jython") -IRONPYTHON = (platform.python_implementation() == "IronPython") # Python versions. We amend version_info with one more value, a zero if an # official version, or 1 if built from source beyond an official version. diff --git a/coverage/exceptions.py b/coverage/exceptions.py index c6a7f3da..43dc0047 100644 --- a/coverage/exceptions.py +++ b/coverage/exceptions.py @@ -57,16 +57,6 @@ class _ExceptionDuringRun(CoverageException): pass -class _StopEverything(_BaseCoverageException): - """An exception that means everything should stop. - - The CoverageTest class converts these to SkipTest, so that when running - tests, raising this exception will automatically skip the test. - - """ - pass - - class CoverageWarning(Warning): """A warning from Coverage.py.""" pass diff --git a/coverage/inorout.py b/coverage/inorout.py index 65aec83c..4be4a85d 100644 --- a/coverage/inorout.py +++ b/coverage/inorout.py @@ -81,10 +81,6 @@ def name_for_module(filename: str, frame: Optional[FrameType]) -> str: """ module_globals = frame.f_globals if frame is not None else {} - if module_globals is None: # pragma: only ironpython - # IronPython doesn't provide globals: https://github.com/IronLanguages/main/issues/1296 - module_globals = {} # type: ignore[unreachable] - dunder_name: str = module_globals.get('__name__', None) if isinstance(dunder_name, str) and dunder_name != '__main__': @@ -349,10 +345,6 @@ class InOrOut: # can't do anything with the data later anyway. return nope(disp, "not a real file name") - # Jython reports the .class file to the tracer, use the source file. - if filename.endswith("$py.class"): - filename = filename[:-9] + ".py" - canonical = canonical_filename(filename) disp.canonical_filename = canonical diff --git a/coverage/parser.py b/coverage/parser.py index 9c71e2d3..3512fdc3 100644 --- a/coverage/parser.py +++ b/coverage/parser.py @@ -21,7 +21,7 @@ from typing import ( from coverage import env from coverage.bytecode import code_objects from coverage.debug import short_stack -from coverage.exceptions import NoSource, NotPython, _StopEverything +from coverage.exceptions import NoSource, NotPython from coverage.misc import join_regex, nice_pair from coverage.phystokens import generate_tokens from coverage.types import Protocol, TArc, TLineNo @@ -393,15 +393,6 @@ class ByteParser: ) ) from synerr - # Alternative Python implementations don't always provide all the - # attributes on code objects that we need to do the analysis. - for attr in ['co_lnotab', 'co_firstlineno']: - if not hasattr(self.code, attr): - raise _StopEverything( # pragma: only jython - "This implementation of Python doesn't support code analysis.\n" + - "Run coverage.py under another Python for this command." - ) - def child_parsers(self) -> Iterable[ByteParser]: """Iterate over all the code objects nested within this one. diff --git a/coverage/python.py b/coverage/python.py index 70d38fe3..2d2faa14 100644 --- a/coverage/python.py +++ b/coverage/python.py @@ -35,10 +35,6 @@ def read_python_source(filename: str) -> bytes: with open(filename, "rb") as f: source = f.read() - if env.IRONPYTHON: - # IronPython reads Unicode strings even for "rb" files. - source = bytes(source) - return source.replace(b"\r\n", b"\n").replace(b"\r", b"\n") @@ -126,10 +122,6 @@ def source_for_file(filename: str) -> str: # Didn't find source, but it's probably the .py file we want. return py_filename - elif filename.endswith("$py.class"): - # Jython is easy to guess. - return filename[:-9] + ".py" - # No idea, just use the file name as-is. return filename diff --git a/metacov.ini b/metacov.ini index 368a205f..787553f9 100644 --- a/metacov.ini +++ b/metacov.ini @@ -70,14 +70,6 @@ exclude_lines = # longer tested. pragma: obscure - # Jython needs special care. - pragma: only jython - if env.JYTHON - - # IronPython isn't included in metacoverage. - pragma: only ironpython - if env.IRONPYTHON - partial_branches = pragma: part covered # A for-loop that always hits its break statement @@ -87,8 +79,6 @@ partial_branches = assert any\( if env.TESTING: if env.METACOV: - if .* env.JYTHON - if .* env.IRONPYTHON precision = 3 @@ -196,10 +196,6 @@ class ve_build_ext(build_ext): compile_extension = True -if sys.platform.startswith('java'): - # Jython can't compile C extensions - compile_extension = False - if '__pypy__' in sys.builtin_module_names: # Pypy can't compile C extensions compile_extension = False diff --git a/tests/conftest.py b/tests/conftest.py index 600ada44..d45cae1d 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -16,7 +16,6 @@ from pathlib import Path import pytest from coverage import env -from coverage.exceptions import _StopEverything from coverage.files import set_relative_directory # Pytest will rewrite assertions in test modules, but not elsewhere. @@ -106,14 +105,6 @@ def pytest_sessionfinish(): if pth_file.exists(): pth_file.unlink() -@pytest.hookimpl(hookwrapper=True) -def pytest_runtest_call(item): - """Run once for each test.""" - # Convert _StopEverything into skipped tests. - outcome = yield - if outcome.excinfo and issubclass(outcome.excinfo[0], _StopEverything): # pragma: only jython - pytest.skip(f"Skipping {item.nodeid} for _StopEverything: {outcome.excinfo[1]}") - def possible_pth_dirs(): """Produce a sequence of directories for trying to write .pth files.""" diff --git a/tests/coveragetest.py b/tests/coveragetest.py index 56e78853..e718dd31 100644 --- a/tests/coveragetest.py +++ b/tests/coveragetest.py @@ -15,10 +15,7 @@ import re import shlex import sys -import pytest - import coverage -from coverage import env from coverage.cmdline import CoverageScript from coverage.misc import import_local_file @@ -386,18 +383,9 @@ class CoverageTest( command_words = [os.path.basename(sys.executable)] elif command_name == "coverage": - if env.JYTHON: # pragma: only jython - # Jython can't do reporting, so let's skip the test now. - if command_args and command_args[0] in ('report', 'html', 'xml', 'annotate'): - pytest.skip("Can't run reporting commands in Jython") - # Jython can't run "coverage" as a command because the shebang - # refers to another shebang'd Python script. So run them as - # modules. - command_words = "jython -m coverage".split() - else: - # The invocation requests the coverage.py program. Substitute the - # actual coverage.py main command name. - command_words = [self.coverage_command] + # The invocation requests the coverage.py program. Substitute the + # actual coverage.py main command name. + command_words = [self.coverage_command] else: command_words = [command_name] @@ -407,8 +395,6 @@ class CoverageTest( # Add our test modules directory to PYTHONPATH. I'm sure there's too # much path munging here, but... pythonpath_name = "PYTHONPATH" - if env.JYTHON: - pythonpath_name = "JYTHONPATH" # pragma: only jython testmods = nice_file(self.working_root(), "tests/modules") zipfile = nice_file(self.working_root(), "tests/zipmods.zip") diff --git a/tests/test_arcs.py b/tests/test_arcs.py index 1d20470f..4c68abba 100644 --- a/tests/test_arcs.py +++ b/tests/test_arcs.py @@ -157,13 +157,9 @@ class SimpleArcTest(CoverageTest): ) def test_what_is_the_sound_of_no_lines_clapping(self): - if env.JYTHON: - # Jython reports no lines for an empty file. - arcz_missing=".1 1." # pragma: only jython - elif env.PYBEHAVIOR.empty_is_empty: + if env.PYBEHAVIOR.empty_is_empty: arcz_missing=".1 1." else: - # Other Pythons report one line. arcz_missing="" self.check_coverage("""\ # __init__.py diff --git a/tests/test_cmdline.py b/tests/test_cmdline.py index 96e7ffb9..67899b75 100644 --- a/tests/test_cmdline.py +++ b/tests/test_cmdline.py @@ -977,7 +977,6 @@ class CmdLineStdoutTest(BaseCmdLineTest): assert "without C extension" in out assert out.count("\n") < 4 - @pytest.mark.skipif(env.JYTHON, reason="Jython gets mad if you patch sys.argv") def test_help_contains_command_name(self): # Command name should be present in help output. fake_command_path = os_sep("lorem/ipsum/dolor") @@ -988,7 +987,6 @@ class CmdLineStdoutTest(BaseCmdLineTest): out = self.stdout() assert expected_command_name in out - @pytest.mark.skipif(env.JYTHON, reason="Jython gets mad if you patch sys.argv") def test_help_contains_command_name_from_package(self): # Command package name should be present in help output. # diff --git a/tests/test_concurrency.py b/tests/test_concurrency.py index 2c827760..8dea0a44 100644 --- a/tests/test_concurrency.py +++ b/tests/test_concurrency.py @@ -4,6 +4,7 @@ """Tests for concurrency libraries.""" import glob +import multiprocessing import os import random import re @@ -12,6 +13,7 @@ import threading import time from flaky import flaky +import greenlet import pytest import coverage @@ -27,11 +29,6 @@ from tests.coveragetest import CoverageTest # These libraries aren't always available, we'll skip tests if they aren't. try: - import multiprocessing -except ImportError: # pragma: only jython - multiprocessing = None - -try: import eventlet except ImportError: eventlet = None @@ -41,11 +38,6 @@ try: except ImportError: gevent = None -try: - import greenlet -except ImportError: # pragma: only jython - greenlet = None - def measurable_line(l): """Is this a line of code coverage will measure? @@ -59,9 +51,6 @@ def measurable_line(l): return False if l.startswith('else:'): return False - if env.JYTHON and l.startswith(('try:', 'except:', 'except ', 'break', 'with ')): - # Jython doesn't measure these statements. - return False # pragma: only jython return True @@ -443,7 +432,6 @@ def start_method_fixture(request): return start_method -@pytest.mark.skipif(not multiprocessing, reason="No multiprocessing in this Python") @flaky(max_runs=30) # Sometimes a test fails due to inherent randomness. Try more times. class MultiprocessingTest(CoverageTest): """Test support of the multiprocessing module.""" diff --git a/tests/test_execfile.py b/tests/test_execfile.py index 329ec528..e1db7bb5 100644 --- a/tests/test_execfile.py +++ b/tests/test_execfile.py @@ -14,7 +14,6 @@ import sys import pytest -from coverage import env from coverage.exceptions import NoCode, NoSource, _ExceptionDuringRun from coverage.execfile import run_python_file, run_python_module from coverage.files import python_reported_file @@ -196,9 +195,6 @@ class RunPycFileTest(CoverageTest): def make_pyc(self, **kwargs): """Create a .pyc file, and return the path to it.""" - if env.JYTHON: - pytest.skip("Can't make .pyc files on Jython") - self.make_file("compiled.py", """\ def doit(): print("I am here!") diff --git a/tests/test_oddball.py b/tests/test_oddball.py index 15dae128..37216b39 100644 --- a/tests/test_oddball.py +++ b/tests/test_oddball.py @@ -155,7 +155,6 @@ class MemoryLeakTest(CoverageTest): """ @flaky - @pytest.mark.skipif(env.JYTHON, reason="Don't bother on Jython") @pytest.mark.skipif(not env.C_TRACER, reason="Only the C tracer has refcounting issues") def test_for_leaks(self): # Our original bad memory leak only happened on line numbers > 255, so @@ -235,7 +234,6 @@ class MemoryFumblingTest(CoverageTest): assert "Fatal" not in out -@pytest.mark.skipif(env.JYTHON, reason="Pyexpat isn't a problem on Jython") class PyexpatTest(CoverageTest): """Pyexpat screws up tracing. Make sure we've counter-defended properly.""" @@ -388,13 +386,6 @@ class ExceptionTest(CoverageTest): lines = data.lines(abs_file(filename)) clean_lines[filename] = sorted(lines) - if env.JYTHON: # pragma: only jython - # Jython doesn't report on try or except lines, so take those - # out of the expected lines. - invisible = [202, 206, 302, 304] - for lines in lines_expected.values(): - lines[:] = [l for l in lines if l not in invisible] - assert clean_lines == lines_expected diff --git a/tests/test_process.py b/tests/test_process.py index 3324497d..33d52923 100644 --- a/tests/test_process.py +++ b/tests/test_process.py @@ -578,8 +578,6 @@ class ProcessTest(CoverageTest): # Pypy passes locally, but fails in CI? Perhaps the version of macOS is # significant? https://foss.heptapod.net/pypy/pypy/-/issues/3074 @pytest.mark.skipif(env.PYPY, reason="PyPy is unreliable with this test") - # Jython as of 2.7.1rc3 won't compile a filename that isn't utf-8. - @pytest.mark.skipif(env.JYTHON, reason="Jython can't handle this test") def test_lang_c(self): # LANG=C forces getfilesystemencoding on Linux to 'ascii', which causes # failures with non-ascii file names. We don't want to make a real file @@ -669,12 +667,6 @@ class EnvironmentTest(CoverageTest): """ # First, is this even credible try_execfile.py output? assert '"DATA": "xyzzy"' in actual - - if env.JYTHON: # pragma: only jython - # Argv0 is different for Jython, remove that from the comparison. - expected = re_lines_text(r'\s+"argv0":', expected, match=False) - actual = re_lines_text(r'\s+"argv0":', actual, match=False) - assert actual == expected def test_coverage_run_is_like_python(self): @@ -906,10 +898,8 @@ class ExcepthookTest(CoverageTest): """) cov_st, cov_out = self.run_command_status("coverage run excepthook.py") py_st, py_out = self.run_command_status("python excepthook.py") - if not env.JYTHON: - assert cov_st == py_st - assert cov_st == 1 - + assert cov_st == py_st + assert cov_st == 1 assert "in excepthook" in py_out assert cov_out == py_out @@ -960,15 +950,12 @@ class ExcepthookTest(CoverageTest): """) cov_st, cov_out = self.run_command_status("coverage run excepthook_throw.py") py_st, py_out = self.run_command_status("python excepthook_throw.py") - if not env.JYTHON: - assert cov_st == py_st - assert cov_st == 1 - + assert cov_st == py_st + assert cov_st == 1 assert "in excepthook" in py_out assert cov_out == py_out -@pytest.mark.skipif(env.JYTHON, reason="Coverage command names don't work on Jython") class AliasedCommandTest(CoverageTest): """Tests of the version-specific command aliases.""" @@ -1261,7 +1248,6 @@ class ProcessStartupWithSourceTest(CoverageTest): self.make_file(path("__init__.py"), "") # sub.py will write a few lines. self.make_file(path("sub.py"), """\ - # Avoid 'with' so Jython can play along. f = open("out.txt", "w") f.write("Hello, world!") f.close() diff --git a/tests/test_python.py b/tests/test_python.py index a8288613..fd8e7b52 100644 --- a/tests/test_python.py +++ b/tests/test_python.py @@ -59,7 +59,3 @@ def test_source_for_file_windows(tmpdir): # If both pyw and py exist, py is preferred path.ensure(file=True) assert source_for_file(src + 'c') == src - - -def test_source_for_file_jython(): - assert source_for_file("a$py.class") == "a.py" diff --git a/tests/test_summary.py b/tests/test_summary.py index f0f16aa2..45427079 100644 --- a/tests/test_summary.py +++ b/tests/test_summary.py @@ -614,7 +614,6 @@ class SummaryTest(UsingModulesMixin, CoverageTest): output = self.get_report(cov, squeeze=False) assert output == report_expected - @pytest.mark.skipif(env.JYTHON, reason="Jython doesn't like accented file names") def test_accenteddotpy_not_python(self): # We run a .py file with a non-ascii name, and when reporting, we can't # parse it as Python. We should get an error message in the report. @@ -779,10 +778,9 @@ class SummaryTest(UsingModulesMixin, CoverageTest): # Python 3 puts the .pyc files in a __pycache__ directory, and will # not import from there without source. It will import a .pyc from # the source location though. - if not env.JYTHON: - pycs = glob.glob("__pycache__/mod.*.pyc") - assert len(pycs) == 1 - os.rename(pycs[0], "mod.pyc") + pycs = glob.glob("__pycache__/mod.*.pyc") + assert len(pycs) == 1 + os.rename(pycs[0], "mod.pyc") # Run the program. cov = coverage.Coverage() @@ -26,8 +26,6 @@ install_command = python -m pip install -U {opts} {packages} passenv = * setenv = pypy{3,37,38,39}: COVERAGE_NO_CTRACER=no C extension under PyPy - jython: COVERAGE_NO_CTRACER=no C extension under Jython - jython: PYTEST_ADDOPTS=-n 0 # For some tests, we need .pyc files written in the current directory, # so override any local setting. PYTHONPYCACHEPREFIX= |