Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: nedbat/coveragepy
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 6.0
Choose a base ref
...
head repository: nedbat/coveragepy
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 6.0.1
Choose a head ref
  • 9 commits
  • 14 files changed
  • 2 contributors

Commits on Oct 3, 2021

  1. build: bump version

    nedbat committed Oct 3, 2021
    Copy the full SHA
    a5da277 View commit details

Commits on Oct 4, 2021

  1. Copy the full SHA
    fb21f8e View commit details

Commits on Oct 5, 2021

  1. build: 3.10.0 is out

    nedbat committed Oct 5, 2021
    Copy the full SHA
    6211680 View commit details

Commits on Oct 6, 2021

  1. fix: pretend we didn't import third-party packages we use. #1228

    tomli couldn't use coverage themselves because we imported it early.
    Cleaning sys.modules means their own imports will actually execute after
    coverage has started, so their files will be properly measured.
    nedbat committed Oct 6, 2021
    Copy the full SHA
    613446c View commit details
  2. Fix an incompatibility with pyarmor

    glacials authored and nedbat committed Oct 6, 2021
    Copy the full SHA
    19545b7 View commit details
  3. docs: note #1210 in the changelog

    nedbat committed Oct 6, 2021
    Copy the full SHA
    f33b733 View commit details

Commits on Oct 7, 2021

  1. Copy the full SHA
    a309f08 View commit details
  2. Copy the full SHA
    72200e2 View commit details
  3. build: prep for 6.0.1

    nedbat committed Oct 7, 2021
    Copy the full SHA
    78a9c68 View commit details
Showing with 99 additions and 17 deletions.
  1. +1 −1 .github/workflows/coverage.yml
  2. +1 −0 .github/workflows/kit.yml
  3. +1 −1 .github/workflows/testsuite.yml
  4. +27 −3 CHANGES.rst
  5. +1 −0 CONTRIBUTORS.txt
  6. +1 −1 coverage/context.py
  7. +32 −0 coverage/misc.py
  8. +2 −5 coverage/tomlconfig.py
  9. +1 −1 coverage/version.py
  10. +2 −2 doc/conf.py
  11. +1 −2 doc/index.rst
  12. +2 −0 doc/whatsnew5x.rst
  13. +8 −0 tests/test_context.py
  14. +19 −1 tests/test_misc.py
2 changes: 1 addition & 1 deletion .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
@@ -37,7 +37,7 @@ jobs:
- "3.7"
- "3.8"
- "3.9"
- "3.10.0-rc.2"
- "3.10"
- "pypy3"
exclude:
# Windows PyPy doesn't seem to work?
1 change: 1 addition & 0 deletions .github/workflows/kit.yml
Original file line number Diff line number Diff line change
@@ -122,6 +122,7 @@ jobs:

prerel:
name: "Build ${{ matrix.python-version }} wheels on ${{ matrix.os }}"
if: ${{ false }} # disable for now, since there are no pre-rel Python versions.
runs-on: ${{ matrix.os }}
strategy:
matrix:
2 changes: 1 addition & 1 deletion .github/workflows/testsuite.yml
Original file line number Diff line number Diff line change
@@ -35,7 +35,7 @@ jobs:
- "3.7"
- "3.8"
- "3.9"
- "3.10.0-rc.2"
- "3.10"
- "pypy3"
exclude:
# Windows PyPy doesn't seem to work?
30 changes: 27 additions & 3 deletions CHANGES.rst
Original file line number Diff line number Diff line change
@@ -9,9 +9,7 @@ These changes are listed in decreasing version number order. Note this can be
different from a strict chronological order when there are two branches in
development at the same time, such as 4.5.x and 5.0.

This list is detailed and covers changes in each pre-release version. If you
want to know what's different in 5.0 since 4.5.x, see :ref:`whatsnew5x`.

This list is detailed and covers changes in each pre-release version.

.. When updating the "Unreleased" header to a specific version, use this
.. format. Don't forget the jump target:
@@ -21,6 +19,29 @@ want to know what's different in 5.0 since 4.5.x, see :ref:`whatsnew5x`.
.. Version 9.8.1 --- 2027-07-27
.. ----------------------------
.. _changes_601:

Version 6.0.1 --- 2021-10-06
----------------------------

- In 6.0, the coverage.py exceptions moved from coverage.misc to
coverage.exceptions. These exceptions are not part of the public supported
API, CoverageException is. But a number of other third-party packages were
importing the exceptions from coverage.misc, so they are now available from
there again (`issue 1226`_).

- Changed an internal detail of how tomli is imported, so that tomli can use
coverage.py for their own test suite (`issue 1228`_).

- Defend against an obscure possibility under code obfuscation, where a
function can have an argument called "self", but no local named "self"
(`pull request 1210`_). Thanks, Ben Carlsson.

.. _pull request 1210: https://github.com/nedbat/coveragepy/pull/1210
.. _issue 1226: https://github.com/nedbat/coveragepy/issues/1226
.. _issue 1228: https://github.com/nedbat/coveragepy/issues/1228


.. _changes_60:

Version 6.0 --- 2021-10-03
@@ -462,6 +483,9 @@ Version 5.0 --- 2019-12-14

Nothing new beyond 5.0b2.

A summary of major changes in 5.0 since 4.5.x is in see :ref:`whatsnew5x`.



.. _changes_50b2:

1 change: 1 addition & 0 deletions CONTRIBUTORS.txt
Original file line number Diff line number Diff line change
@@ -20,6 +20,7 @@ Arcadiy Ivanov
Aron Griffis
Artem Dayneko
Arthur Deygin
Ben Carlsson
Ben Finney
Bernát Gábor
Bill Hart
2 changes: 1 addition & 1 deletion coverage/context.py
Original file line number Diff line number Diff line change
@@ -48,7 +48,7 @@ def qualname_from_frame(frame):
fname = co.co_name
method = None
if co.co_argcount and co.co_varnames[0] == "self":
self = frame.f_locals["self"]
self = frame.f_locals.get("self", None)
method = getattr(self, fname, None)

if method is None:
32 changes: 32 additions & 0 deletions coverage/misc.py
Original file line number Diff line number Diff line change
@@ -5,6 +5,7 @@

import errno
import hashlib
import importlib
import importlib.util
import inspect
import locale
@@ -19,6 +20,11 @@
from coverage import env
from coverage.exceptions import CoverageException

# In 6.0, the exceptions moved from misc.py to exceptions.py. But a number of
# other packages were importing the exceptions from misc, so import them here.
# pylint: disable=unused-wildcard-import
from coverage.exceptions import * # pylint: disable=wildcard-import

ISOLATED_MODULES = {}


@@ -43,6 +49,32 @@ def isolate_module(mod):
os = isolate_module(os)


def import_third_party(modname):
"""Import a third-party module we need, but might not be installed.
This also cleans out the module after the import, so that coverage won't
appear to have imported it. This lets the third party use coverage for
their own tests.
Arguments:
modname (str): the name of the module to import.
Returns:
The imported module, or None if the module couldn't be imported.
"""
try:
mod = importlib.import_module(modname)
except ImportError:
mod = None

imported = [m for m in sys.modules if m.startswith(modname)]
for name in imported:
del sys.modules[name]

return mod


def dummy_decorator_with_args(*args_unused, **kwargs_unused):
"""Dummy no-op implementation of a decorator with arguments."""
def _decorator(func):
7 changes: 2 additions & 5 deletions coverage/tomlconfig.py
Original file line number Diff line number Diff line change
@@ -8,13 +8,10 @@
import re

from coverage.exceptions import CoverageException
from coverage.misc import substitute_variables
from coverage.misc import import_third_party, substitute_variables

# TOML support is an install-time extra option.
try:
import tomli
except ImportError: # pragma: not covered
tomli = None
tomli = import_third_party("tomli")


class TomlDecodeError(Exception):
2 changes: 1 addition & 1 deletion coverage/version.py
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@
# This file is exec'ed in setup.py, don't import anything!

# Same semantics as sys.version_info.
version_info = (6, 0, 0, "final", 0)
version_info = (6, 0, 1, "final", 0)


def _make_version(major, minor, micro, releaselevel, serial):
4 changes: 2 additions & 2 deletions doc/conf.py
Original file line number Diff line number Diff line change
@@ -67,9 +67,9 @@
# The short X.Y version.
version = "6.0" # CHANGEME
# The full version, including alpha/beta/rc tags.
release = "6.0" # CHANGEME
release = "6.0.1" # CHANGEME
# The date of release, in "monthname day, year" format.
release_date = "October 3, 2021" # CHANGEME
release_date = "October 6, 2021" # CHANGEME

rst_epilog = """
.. |release_date| replace:: {release_date}
3 changes: 1 addition & 2 deletions doc/index.rst
Original file line number Diff line number Diff line change
@@ -23,7 +23,7 @@ supported on:
.. ifconfig:: prerelease

**This is a pre-release build. The usual warnings about possible bugs
apply.** The latest stable version is coverage.py 6.0, `described here`_.
apply.** The latest stable version is coverage.py 6.0.1, `described here`_.

.. _described here: http://coverage.readthedocs.io/

@@ -222,6 +222,5 @@ More information
contributing
trouble
faq
whatsnew5x
changes
sleepy
2 changes: 2 additions & 0 deletions doc/whatsnew5x.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
.. Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0
.. For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt
:orphan:

.. _whatsnew5x:

====================
8 changes: 8 additions & 0 deletions tests/test_context.py
Original file line number Diff line number Diff line change
@@ -5,6 +5,7 @@

import inspect
import os.path
from unittest import mock

import coverage
from coverage.context import qualname_from_frame
@@ -275,3 +276,10 @@ def test_bug_829(self):
# A class with a name like a function shouldn't confuse qualname_from_frame.
class test_something: # pylint: disable=unused-variable
assert get_qualname() is None

def test_bug_1210(self):
# Under pyarmor (an obfuscator), a function can have a "self" argument,
# but then not have a "self" local.
co = mock.Mock(co_name="a_co_name", co_argcount=1, co_varnames=["self"])
frame = mock.Mock(f_code=co, f_locals={})
assert qualname_from_frame(frame) == "unittest.mock.a_co_name"
20 changes: 19 additions & 1 deletion tests/test_misc.py
Original file line number Diff line number Diff line change
@@ -3,11 +3,13 @@

"""Tests of miscellaneous stuff."""

import sys

import pytest

from coverage.exceptions import CoverageException
from coverage.misc import contract, dummy_decorator_with_args, file_be_gone
from coverage.misc import Hasher, one_of, substitute_variables
from coverage.misc import Hasher, one_of, substitute_variables, import_third_party
from coverage.misc import USE_CONTRACTS

from tests.coveragetest import CoverageTest
@@ -155,3 +157,19 @@ def test_substitute_variables_errors(text):
substitute_variables(text, VARS)
assert text in str(exc_info.value)
assert "Variable NOTHING is undefined" in str(exc_info.value)


class ImportThirdPartyTest(CoverageTest):
"""Test import_third_party."""

run_in_temp_dir = False

def test_success(self):
mod = import_third_party("pytest")
assert mod.__name__ == "pytest"
assert "pytest" not in sys.modules

def test_failure(self):
mod = import_third_party("xyzzy")
assert mod is None
assert "xyzzy" not in sys.modules