diff options
author | Ned Batchelder <ned@nedbatchelder.com> | 2019-06-23 07:14:16 -0400 |
---|---|---|
committer | Ned Batchelder <ned@nedbatchelder.com> | 2019-06-25 09:54:41 -0400 |
commit | e9e703c7885840412295a0aaf3c84b5244483881 (patch) | |
tree | ab63e85a914e00207b2e3ae0614c11ea766d7813 | |
parent | e126d4720a4abad33a772734e0a0b40403b974d2 (diff) | |
download | python-coveragepy-git-e9e703c7885840412295a0aaf3c84b5244483881.tar.gz |
New API: Coverage.current() returns the latest started instance.
-rw-r--r-- | CHANGES.rst | 2 | ||||
-rw-r--r-- | coverage/control.py | 15 | ||||
-rw-r--r-- | tests/test_api.py | 31 |
3 files changed, 48 insertions, 0 deletions
diff --git a/CHANGES.rst b/CHANGES.rst index 3e651d2e..3e9de91e 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -32,6 +32,8 @@ Unreleased information to each covered line. Hovering over the "ctx" marker at the end of the line reveals a list of the contexts that covered the line. +- Added :meth:`Coverage.current` to get the latest started `Coverage` instance. + - Error handling during reporting has changed slightly. All reporting methods now behave the same. The ``--ignore-errors`` option keeps errors from stopping the reporting, but files that couldn't parse as Python will always diff --git a/coverage/control.py b/coverage/control.py index c398f2a7..03e36324 100644 --- a/coverage/control.py +++ b/coverage/control.py @@ -55,6 +55,17 @@ class Coverage(object): """ + # The stack of started Coverage instances. + _instances = [] + + @classmethod + def current(cls): + """Get the latest started `Coverage` instance, if any.""" + if cls._instances: + return cls._instances[-1] + else: + return None + def __init__( self, data_file=None, data_suffix=None, cover_pylib=None, auto_data=False, timid=None, branch=None, config_file=True, @@ -453,9 +464,13 @@ class Coverage(object): self._collector.start() self._started = True + self._instances.append(self) def stop(self): """Stop measuring code coverage.""" + if self._instances: + if self._instances[-1] is self: + self._instances.pop() if self._started: self._collector.stop() self._started = False diff --git a/tests/test_api.py b/tests/test_api.py index a034c828..920cd9ad 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -614,6 +614,37 @@ class ApiTest(CoverageTest): cov.switch_context("test3") +class CurrentInstanceTest(CoverageTest): + """Tests of Coverage.current().""" + + def assert_current_is_none(self, current): + """Assert that a current we expect to be None is correct.""" + # During meta-coverage, the None answers will be wrong because the + # overall coverage measurement will still be on the current-stack. + # Since we know they will be wrong, and we have non-meta test runs + # also, don't assert them. + if not env.METACOV: + assert current is None + + def test_current(self): + cur0 = coverage.Coverage.current() + self.assert_current_is_none(cur0) + # Making an instance doesn't make it current. + cov = coverage.Coverage() + cur1 = coverage.Coverage.current() + self.assert_current_is_none(cur1) + assert cur0 is cur1 + # Starting the instance makes it current. + cov.start() + cur2 = coverage.Coverage.current() + assert cur2 is cov + # Stopping the instance makes current None again. + cov.stop() + cur3 = coverage.Coverage.current() + self.assert_current_is_none(cur3) + assert cur0 is cur3 + + class NamespaceModuleTest(UsingModulesMixin, CoverageTest): """Test PEP-420 namespace modules.""" |