summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNed Batchelder <ned@nedbatchelder.com>2021-05-01 13:46:29 -0400
committerNed Batchelder <ned@nedbatchelder.com>2021-05-01 16:24:37 -0400
commite96ef93d18831630687b6c026bed89a1f9149c90 (patch)
tree9f1e71e96cf9124fbc21b46c86840369d10fa9f7
parent9df434550a499c16e9fd26cfb9627837bfdc02a5 (diff)
downloadpython-coveragepy-git-e96ef93d18831630687b6c026bed89a1f9149c90.tar.gz
refactor: remove unneeded backward.py shims
Removed were: - StringIO - configparser - string_class - unicode_class - range - zip_longest - get_thread_id - path_types - shlex_quote - reprlib
-rw-r--r--coverage/backward.py76
-rw-r--r--coverage/collector.py2
-rw-r--r--coverage/config.py5
-rw-r--r--coverage/control.py6
-rw-r--r--coverage/debug.py5
-rw-r--r--coverage/misc.py6
-rw-r--r--coverage/numbits.py4
-rw-r--r--coverage/parser.py5
-rw-r--r--coverage/sqldata.py17
-rw-r--r--coverage/tomlconfig.py4
-rw-r--r--tests/coveragetest.py9
-rw-r--r--tests/test_api.py7
-rw-r--r--tests/test_debug.py4
-rw-r--r--tests/test_html.py7
-rw-r--r--tests/test_plugins.py11
-rw-r--r--tests/test_summary.py8
16 files changed, 53 insertions, 123 deletions
diff --git a/coverage/backward.py b/coverage/backward.py
index da839d71..15f4e88a 100644
--- a/coverage/backward.py
+++ b/coverage/backward.py
@@ -3,84 +3,8 @@
"""Add things to old Pythons so I can pretend they are newer."""
-# This file's purpose is to provide modules to be imported from here.
-# pylint: disable=unused-import
-
-import os
import sys
-from datetime import datetime
-
-
-# Pythons 2 and 3 differ on where to get StringIO.
-try:
- from cStringIO import StringIO
-except ImportError:
- from io import StringIO
-
-# In py3, ConfigParser was renamed to the more-standard configparser.
-# But there's a py3 backport that installs "configparser" in py2, and I don't
-# want it because it has annoying deprecation warnings. So try the real py2
-# import first.
-try:
- import ConfigParser as configparser
-except ImportError:
- import configparser
-
-# What's a string called?
-try:
- string_class = basestring
-except NameError:
- string_class = str
-
-# What's a Unicode string called?
-try:
- unicode_class = unicode
-except NameError:
- unicode_class = str
-
-# range or xrange?
-try:
- range = xrange # pylint: disable=redefined-builtin
-except NameError:
- range = range
-
-try:
- from itertools import zip_longest
-except ImportError:
- from itertools import izip_longest as zip_longest
-
-# Where do we get the thread id from?
-try:
- from thread import get_ident as get_thread_id
-except ImportError:
- from threading import get_ident as get_thread_id
-
-try:
- os.PathLike
-except AttributeError:
- # This is Python 2 and 3
- path_types = (bytes, string_class, unicode_class)
-else:
- # 3.6+
- path_types = (bytes, str, os.PathLike)
-
-# shlex.quote is new, but there's an undocumented implementation in "pipes",
-# who knew!?
-try:
- from shlex import quote as shlex_quote
-except ImportError:
- # Useful function, available under a different (undocumented) name
- # in Python versions earlier than 3.3.
- from pipes import quote as shlex_quote
-
-try:
- import reprlib
-except ImportError: # pragma: not covered
- # We need this on Python 2, but in testing environments, a backport is
- # installed, so this import isn't used.
- import repr as reprlib
-
# A function to iterate listlessly over a dict's items, and one to get the
# items as a list.
try:
diff --git a/coverage/collector.py b/coverage/collector.py
index a4f1790d..17dcac1c 100644
--- a/coverage/collector.py
+++ b/coverage/collector.py
@@ -7,7 +7,7 @@ import os
import sys
from coverage import env
-from coverage.backward import litems, range # pylint: disable=redefined-builtin
+from coverage.backward import litems
from coverage.debug import short_stack
from coverage.disposition import FileDisposition
from coverage.misc import CoverageException, isolate_module
diff --git a/coverage/config.py b/coverage/config.py
index a48251fb..7bfc74db 100644
--- a/coverage/config.py
+++ b/coverage/config.py
@@ -4,13 +4,14 @@
"""Config file for coverage.py"""
import collections
+import configparser
import copy
import os
import os.path
import re
from coverage import env
-from coverage.backward import configparser, iitems, string_class
+from coverage.backward import iitems
from coverage.misc import contract, CoverageException, isolate_module
from coverage.misc import substitute_variables
@@ -247,7 +248,7 @@ class CoverageConfig(object):
"""Read config values from `kwargs`."""
for k, v in iitems(kwargs):
if v is not None:
- if k in self.MUST_BE_LIST and isinstance(v, string_class):
+ if k in self.MUST_BE_LIST and isinstance(v, str):
v = [v]
setattr(self, k, v)
diff --git a/coverage/control.py b/coverage/control.py
index 1623b093..5c5d13aa 100644
--- a/coverage/control.py
+++ b/coverage/control.py
@@ -14,7 +14,7 @@ import time
from coverage import env
from coverage.annotate import AnnotateReporter
-from coverage.backward import string_class, iitems
+from coverage.backward import iitems
from coverage.collector import Collector, CTracer
from coverage.config import read_coverage_config
from coverage.context import should_start_context_test_function, combine_context_switchers
@@ -465,7 +465,7 @@ class Coverage(object):
suffix = self._data_suffix_specified
if suffix or self.config.parallel:
- if not isinstance(suffix, string_class):
+ if not isinstance(suffix, str):
# if data_suffix=True, use .machinename.pid.random
suffix = True
else:
@@ -812,7 +812,7 @@ class Coverage(object):
plugin = None
file_reporter = "python"
- if isinstance(morf, string_class):
+ if isinstance(morf, str):
mapped_morf = self._file_mapper(morf)
plugin_name = self._data.file_tracer(mapped_morf)
if plugin_name:
diff --git a/coverage/debug.py b/coverage/debug.py
index 194f16f5..efcaca2a 100644
--- a/coverage/debug.py
+++ b/coverage/debug.py
@@ -6,16 +6,17 @@
import contextlib
import functools
import inspect
+import io
import itertools
import os
import pprint
+import reprlib
import sys
try:
import _thread
except ImportError:
import thread as _thread
-from coverage.backward import reprlib, StringIO
from coverage.misc import isolate_module
os = isolate_module(os)
@@ -86,7 +87,7 @@ class DebugControl(object):
class DebugControlString(DebugControl):
"""A `DebugControl` that writes to a StringIO, for testing."""
def __init__(self, options):
- super(DebugControlString, self).__init__(options, StringIO())
+ super(DebugControlString, self).__init__(options, io.StringIO())
def get_output(self):
"""Get the output text from the `DebugControl`."""
diff --git a/coverage/misc.py b/coverage/misc.py
index 44d1cdf8..148f42e1 100644
--- a/coverage/misc.py
+++ b/coverage/misc.py
@@ -16,7 +16,7 @@ import sys
import types
from coverage import env
-from coverage.backward import to_bytes, unicode_class
+from coverage.backward import to_bytes
ISOLATED_MODULES = {}
@@ -71,7 +71,7 @@ if USE_CONTRACTS:
# Define contract words that PyContract doesn't have.
new_contract('bytes', lambda v: isinstance(v, bytes))
- new_contract('unicode', lambda v: isinstance(v, unicode_class))
+ new_contract('unicode', lambda v: isinstance(v, str))
def one_of(argnames):
"""Ensure that only one of the argnames is non-None."""
@@ -204,7 +204,7 @@ class Hasher(object):
def update(self, v):
"""Add `v` to the hash, recursively if needed."""
self.md5.update(to_bytes(str(type(v))))
- if isinstance(v, unicode_class):
+ if isinstance(v, str):
self.md5.update(v.encode('utf8'))
elif isinstance(v, bytes):
self.md5.update(v)
diff --git a/coverage/numbits.py b/coverage/numbits.py
index 7205b9f1..7a17fc56 100644
--- a/coverage/numbits.py
+++ b/coverage/numbits.py
@@ -15,7 +15,9 @@ the future. Use these functions to work with those binary blobs of data.
"""
import json
-from coverage.backward import byte_to_int, bytes_to_ints, binary_bytes, zip_longest
+from itertools import zip_longest
+
+from coverage.backward import byte_to_int, bytes_to_ints, binary_bytes
from coverage.misc import contract, new_contract
def _to_blob(b):
diff --git a/coverage/parser.py b/coverage/parser.py
index 6280129c..abcda5fb 100644
--- a/coverage/parser.py
+++ b/coverage/parser.py
@@ -11,8 +11,7 @@ import token
import tokenize
from coverage import env
-from coverage.backward import range # pylint: disable=redefined-builtin
-from coverage.backward import bytes_to_ints, string_class
+from coverage.backward import bytes_to_ints
from coverage.bytecode import code_objects
from coverage.debug import short_stack
from coverage.misc import contract, join_regex, new_contract, nice_pair, one_of
@@ -1206,7 +1205,7 @@ if AST_DUMP: # pragma: debugging
"""Is `value` simple enough to be displayed on a single line?"""
return (
value in [None, [], (), {}, set()] or
- isinstance(value, (string_class, int, float))
+ isinstance(value, (str, int, float))
)
def ast_dump(node, depth=0):
diff --git a/coverage/sqldata.py b/coverage/sqldata.py
index 62df6508..9af08030 100644
--- a/coverage/sqldata.py
+++ b/coverage/sqldata.py
@@ -14,9 +14,10 @@ import os
import re
import sqlite3
import sys
+import threading
import zlib
-from coverage.backward import get_thread_id, iitems, to_bytes, to_string
+from coverage.backward import iitems, to_bytes, to_string
from coverage.debug import NoDebugging, SimpleReprMixin, clipped_repr
from coverage.files import PathAliases
from coverage.misc import CoverageException, contract, file_be_gone, filename_suffix, isolate_module
@@ -244,7 +245,7 @@ class CoverageData(SimpleReprMixin):
"""
if self._debug.should('dataio'):
self._debug.write("Creating data file {!r}".format(self._filename))
- self._dbs[get_thread_id()] = db = SqliteDb(self._filename, self._debug)
+ self._dbs[threading.get_ident()] = db = SqliteDb(self._filename, self._debug)
with db:
db.executescript(SCHEMA)
db.execute("insert into coverage_schema (version) values (?)", (SCHEMA_VERSION,))
@@ -261,12 +262,12 @@ class CoverageData(SimpleReprMixin):
"""Open an existing db file, and read its metadata."""
if self._debug.should('dataio'):
self._debug.write("Opening data file {!r}".format(self._filename))
- self._dbs[get_thread_id()] = SqliteDb(self._filename, self._debug)
+ self._dbs[threading.get_ident()] = SqliteDb(self._filename, self._debug)
self._read_db()
def _read_db(self):
"""Read the metadata from a database so that we are ready to use it."""
- with self._dbs[get_thread_id()] as db:
+ with self._dbs[threading.get_ident()] as db:
try:
schema_version, = db.execute_one("select version from coverage_schema")
except Exception as exc:
@@ -292,15 +293,15 @@ class CoverageData(SimpleReprMixin):
def _connect(self):
"""Get the SqliteDb object to use."""
- if get_thread_id() not in self._dbs:
+ if threading.get_ident() not in self._dbs:
if os.path.exists(self._filename):
self._open_db()
else:
self._create_db()
- return self._dbs[get_thread_id()]
+ return self._dbs[threading.get_ident()]
def __nonzero__(self):
- if (get_thread_id() not in self._dbs and not os.path.exists(self._filename)):
+ if (threading.get_ident() not in self._dbs and not os.path.exists(self._filename)):
return False
try:
with self._connect() as con:
@@ -357,7 +358,7 @@ class CoverageData(SimpleReprMixin):
"Unrecognized serialization: {!r} (head of {} bytes)".format(data[:40], len(data))
)
script = to_string(zlib.decompress(data[1:]))
- self._dbs[get_thread_id()] = db = SqliteDb(self._filename, self._debug)
+ self._dbs[threading.get_ident()] = db = SqliteDb(self._filename, self._debug)
with db:
db.executescript(script)
self._read_db()
diff --git a/coverage/tomlconfig.py b/coverage/tomlconfig.py
index 3ad58157..5f8c154d 100644
--- a/coverage/tomlconfig.py
+++ b/coverage/tomlconfig.py
@@ -3,12 +3,12 @@
"""TOML configuration support for coverage.py"""
+import configparser
import io
import os
import re
from coverage import env
-from coverage.backward import configparser, path_types
from coverage.misc import CoverageException, substitute_variables
# TOML support is an install-time extra option.
@@ -37,7 +37,7 @@ class TomlConfigParser:
def read(self, filenames):
# RawConfigParser takes a filename or list of filenames, but we only
# ever call this with a single filename.
- assert isinstance(filenames, path_types)
+ assert isinstance(filenames, (bytes, str, os.PathLike))
filename = filenames
if env.PYVERSION >= (3, 6):
filename = os.fspath(filename)
diff --git a/tests/coveragetest.py b/tests/coveragetest.py
index 415dd4ab..2a55cf8b 100644
--- a/tests/coveragetest.py
+++ b/tests/coveragetest.py
@@ -7,6 +7,7 @@ import contextlib
import datetime
import difflib
import glob
+import io
import os
import os.path
import random
@@ -18,7 +19,7 @@ import pytest
import coverage
from coverage import env
-from coverage.backward import StringIO, import_local_file, string_class, shlex_quote
+from coverage.backward import import_local_file
from coverage.cmdline import CoverageScript
from tests.helpers import arcs_to_arcz_repr, arcz_to_arcs, assert_count_equal
@@ -176,7 +177,7 @@ class CoverageTest(
assert False, "None of the lines choices matched %r" % (statements,)
missing_formatted = analysis.missing_formatted()
- if isinstance(missing, string_class):
+ if isinstance(missing, str):
msg = "{!r} != {!r}".format(missing_formatted, missing)
assert missing_formatted == missing, msg
else:
@@ -202,7 +203,7 @@ class CoverageTest(
assert False, msg
if report:
- frep = StringIO()
+ frep = io.StringIO()
cov.report(mod, file=frep, show_missing=True)
rep = " ".join(frep.getvalue().split("\n")[2].split()[1:])
assert report == rep, "{!r} != {!r}".format(report, rep)
@@ -380,7 +381,7 @@ class CoverageTest(
else:
command_words = [command_name]
- cmd = " ".join([shlex_quote(w) for w in command_words] + command_args)
+ cmd = " ".join([shlex.quote(w) for w in command_words] + command_args)
# Add our test modules directory to PYTHONPATH. I'm sure there's too
# much path munging here, but...
diff --git a/tests/test_api.py b/tests/test_api.py
index f24beaf4..6eff06fe 100644
--- a/tests/test_api.py
+++ b/tests/test_api.py
@@ -5,6 +5,7 @@
import fnmatch
import glob
+import io
import os
import os.path
import re
@@ -16,7 +17,7 @@ import pytest
import coverage
from coverage import env
-from coverage.backward import code_object, import_local_file, StringIO
+from coverage.backward import code_object, import_local_file
from coverage.data import line_counts
from coverage.files import abs_file, relative_filename
from coverage.misc import CoverageException
@@ -945,7 +946,7 @@ class ReportIncludeOmitTest(IncludeOmitTestsMixin, CoverageTest):
cov.start()
import usepkgs # pragma: nested # pylint: disable=import-error, unused-import
cov.stop() # pragma: nested
- report = StringIO()
+ report = io.StringIO()
cov.report(file=report, **kwargs)
return report.getvalue()
@@ -1070,7 +1071,7 @@ class TestRunnerPluginTest(CoverageTest):
self.start_import_stop(cov, "prog")
cov.combine()
cov.save()
- report = StringIO()
+ report = io.StringIO()
cov.report(show_missing=None, ignore_errors=True, file=report, skip_covered=None,
skip_empty=None)
assert report.getvalue() == textwrap.dedent("""\
diff --git a/tests/test_debug.py b/tests/test_debug.py
index cb83e519..50f191c6 100644
--- a/tests/test_debug.py
+++ b/tests/test_debug.py
@@ -3,6 +3,7 @@
"""Tests of coverage/debug.py"""
+import io
import os
import re
@@ -10,7 +11,6 @@ import pytest
import coverage
from coverage import env
-from coverage.backward import StringIO
from coverage.debug import filter_text, info_formatter, info_header, short_id, short_stack
from coverage.debug import clipped_repr
@@ -106,7 +106,7 @@ class DebugTraceTest(CoverageTest):
f1(i)
""")
- debug_out = StringIO()
+ debug_out = io.StringIO()
cov = coverage.Coverage(debug=debug)
cov._debug_file = debug_out
self.start_import_stop(cov, "f1")
diff --git a/tests/test_html.py b/tests/test_html.py
index c0413c5a..c561a5d2 100644
--- a/tests/test_html.py
+++ b/tests/test_html.py
@@ -16,7 +16,6 @@ import mock
import pytest
import coverage
-from coverage.backward import unicode_class
from coverage import env
from coverage.files import abs_file, flat_rootname
import coverage.html
@@ -629,12 +628,12 @@ def compare_html(expected, actual):
(r'<span class="(nam|key)">(print|True|False)</span>', r'<span class="nam">\2</span>'),
# Occasionally an absolute path is in the HTML report.
(filepath_to_regex(TESTS_DIR), 'TESTS_DIR'),
- (filepath_to_regex(flat_rootname(unicode_class(TESTS_DIR))), '_TESTS_DIR'),
+ (filepath_to_regex(flat_rootname(str(TESTS_DIR))), '_TESTS_DIR'),
# The temp dir the tests make.
(filepath_to_regex(os.getcwd()), 'TEST_TMPDIR'),
- (filepath_to_regex(flat_rootname(unicode_class(os.getcwd()))), '_TEST_TMPDIR'),
+ (filepath_to_regex(flat_rootname(str(os.getcwd()))), '_TEST_TMPDIR'),
(filepath_to_regex(abs_file(os.getcwd())), 'TEST_TMPDIR'),
- (filepath_to_regex(flat_rootname(unicode_class(abs_file(os.getcwd())))), '_TEST_TMPDIR'),
+ (filepath_to_regex(flat_rootname(str(abs_file(os.getcwd())))), '_TEST_TMPDIR'),
(r'/private/var/folders/[\w/]{35}/coverage_test/tests_test_html_\w+_\d{8}', 'TEST_TMPDIR'),
(r'_private_var_folders_\w{35}_coverage_test_tests_test_html_\w+_\d{8}', '_TEST_TMPDIR'),
]
diff --git a/tests/test_plugins.py b/tests/test_plugins.py
index 59be645c..5a8d92ee 100644
--- a/tests/test_plugins.py
+++ b/tests/test_plugins.py
@@ -4,6 +4,7 @@
"""Tests for plugins."""
import inspect
+import io
import os.path
from xml.etree import ElementTree
@@ -11,7 +12,7 @@ import pytest
import coverage
from coverage import env
-from coverage.backward import StringIO, import_local_file
+from coverage.backward import import_local_file
from coverage.data import line_counts
from coverage.control import Plugins
from coverage.misc import CoverageException
@@ -188,7 +189,7 @@ class PluginTest(CoverageTest):
def coverage_init(reg, options):
reg.add_file_tracer(Plugin())
""")
- debug_out = StringIO()
+ debug_out = io.StringIO()
cov = coverage.Coverage(debug=["sys"])
cov._debug_file = debug_out
cov.set_option("run:plugins", ["plugin_sys_info"])
@@ -218,7 +219,7 @@ class PluginTest(CoverageTest):
def coverage_init(reg, options):
reg.add_configurer(Plugin())
""")
- debug_out = StringIO()
+ debug_out = io.StringIO()
cov = coverage.Coverage(debug=["sys"])
cov._debug_file = debug_out
cov.set_option("run:plugins", ["plugin_no_sys_info"])
@@ -411,7 +412,7 @@ class GoodFileTracerTest(FileTracerTest):
self.start_import_stop(cov, "caller")
- repout = StringIO()
+ repout = io.StringIO()
total = cov.report(file=repout, include=["*.html"], omit=["uni*.html"], show_missing=True)
report = repout.getvalue().splitlines()
expected = [
@@ -511,7 +512,7 @@ class GoodFileTracerTest(FileTracerTest):
cov.set_option("run:plugins", ["fairly_odd_plugin"])
self.start_import_stop(cov, "unsuspecting")
- repout = StringIO()
+ repout = io.StringIO()
total = cov.report(file=repout, show_missing=True)
report = repout.getvalue().splitlines()
expected = [
diff --git a/tests/test_summary.py b/tests/test_summary.py
index b6405bff..b00ee96b 100644
--- a/tests/test_summary.py
+++ b/tests/test_summary.py
@@ -5,6 +5,7 @@
"""Test text-based summary reporting for coverage.py"""
import glob
+import io
import os
import os.path
import py_compile
@@ -13,7 +14,6 @@ import re
import pytest
import coverage
-from coverage.backward import StringIO
from coverage import env
from coverage.control import Coverage
from coverage.data import CoverageData
@@ -655,7 +655,7 @@ class SummaryTest(UsingModulesMixin, CoverageTest):
def get_report(self, cov):
"""Get the report from `cov`, and canonicalize it."""
- repout = StringIO()
+ repout = io.StringIO()
cov.report(file=repout, show_missing=False)
report = repout.getvalue().replace('\\', '/')
report = re.sub(r" +", " ", report)
@@ -779,7 +779,7 @@ class SummaryTest(UsingModulesMixin, CoverageTest):
import usepkgs # pragma: nested # pylint: disable=import-error, unused-import
cov.stop() # pragma: nested
- repout = StringIO()
+ repout = io.StringIO()
cov.report(file=repout, show_missing=False)
report = repout.getvalue().replace('\\', '/')
@@ -857,7 +857,7 @@ class SummaryReporterConfigurationTest(CoverageTest):
for name, value in options:
cov.set_option(name, value)
printer = SummaryReporter(cov)
- destination = StringIO()
+ destination = io.StringIO()
printer.report([], destination)
return destination.getvalue()