diff options
-rw-r--r-- | coverage/backward.py | 76 | ||||
-rw-r--r-- | coverage/collector.py | 2 | ||||
-rw-r--r-- | coverage/config.py | 5 | ||||
-rw-r--r-- | coverage/control.py | 6 | ||||
-rw-r--r-- | coverage/debug.py | 5 | ||||
-rw-r--r-- | coverage/misc.py | 6 | ||||
-rw-r--r-- | coverage/numbits.py | 4 | ||||
-rw-r--r-- | coverage/parser.py | 5 | ||||
-rw-r--r-- | coverage/sqldata.py | 17 | ||||
-rw-r--r-- | coverage/tomlconfig.py | 4 | ||||
-rw-r--r-- | tests/coveragetest.py | 9 | ||||
-rw-r--r-- | tests/test_api.py | 7 | ||||
-rw-r--r-- | tests/test_debug.py | 4 | ||||
-rw-r--r-- | tests/test_html.py | 7 | ||||
-rw-r--r-- | tests/test_plugins.py | 11 | ||||
-rw-r--r-- | tests/test_summary.py | 8 |
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() |