summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNed Batchelder <ned@nedbatchelder.com>2022-12-30 18:07:36 -0500
committerNed Batchelder <ned@nedbatchelder.com>2022-12-30 18:35:09 -0500
commit45787e29dea3a41f2e9570b66a571a7ebcda4592 (patch)
tree7eeadde7d7a033e27abd1df7411bb525bd711148
parent85c7a4ac4161c4eb2efeaf07e6f833d3a073b018 (diff)
downloadpython-coveragepy-git-45787e29dea3a41f2e9570b66a571a7ebcda4592.tar.gz
refactor: removed mentions of Jython and IronPython
-rw-r--r--CHANGES.rst10
-rw-r--r--coverage/control.py11
-rw-r--r--coverage/env.py2
-rw-r--r--coverage/exceptions.py10
-rw-r--r--coverage/inorout.py8
-rw-r--r--coverage/parser.py11
-rw-r--r--coverage/python.py8
-rw-r--r--metacov.ini10
-rw-r--r--setup.py4
-rw-r--r--tests/conftest.py9
-rw-r--r--tests/coveragetest.py20
-rw-r--r--tests/test_arcs.py6
-rw-r--r--tests/test_cmdline.py2
-rw-r--r--tests/test_concurrency.py16
-rw-r--r--tests/test_execfile.py4
-rw-r--r--tests/test_oddball.py9
-rw-r--r--tests/test_process.py22
-rw-r--r--tests/test_python.py4
-rw-r--r--tests/test_summary.py8
-rw-r--r--tox.ini2
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
diff --git a/setup.py b/setup.py
index fe01b7d0..c30907f9 100644
--- a/setup.py
+++ b/setup.py
@@ -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()
diff --git a/tox.ini b/tox.ini
index b306a6d2..fb423748 100644
--- a/tox.ini
+++ b/tox.ini
@@ -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=