summaryrefslogtreecommitdiff
path: root/coverage
diff options
context:
space:
mode:
Diffstat (limited to 'coverage')
-rw-r--r--coverage/backward.py7
-rw-r--r--coverage/config.py5
-rw-r--r--coverage/optional.py68
-rw-r--r--coverage/tomlconfig.py3
4 files changed, 74 insertions, 9 deletions
diff --git a/coverage/backward.py b/coverage/backward.py
index e051fa55..17f04219 100644
--- a/coverage/backward.py
+++ b/coverage/backward.py
@@ -3,7 +3,7 @@
"""Add things to old Pythons so I can pretend they are newer."""
-# This file does tricky stuff, so disable a pylint warning.
+# This file's purpose is to provide modules to be imported from here.
# pylint: disable=unused-import
import os
@@ -27,11 +27,6 @@ try:
except ImportError:
import configparser
-try:
- import toml
-except ImportError:
- toml = None
-
# What's a string called?
try:
string_class = basestring
diff --git a/coverage/config.py b/coverage/config.py
index 89a0321e..ca3de3bd 100644
--- a/coverage/config.py
+++ b/coverage/config.py
@@ -9,7 +9,7 @@ import os
import re
from coverage import env
-from coverage.backward import configparser, iitems, string_class, toml
+from coverage.backward import configparser, iitems, string_class
from coverage.misc import contract, CoverageException, isolate_module
from coverage.misc import substitute_variables
@@ -260,6 +260,7 @@ class CoverageConfig(object):
"""
_, ext = os.path.splitext(filename)
if ext == '.toml':
+ from coverage.optional import toml
if toml is None:
return False
cp = TomlConfigParser(our_file)
@@ -482,9 +483,9 @@ def config_files_to_try(config_file):
config_file = ".coveragerc"
files_to_try = [
(config_file, True, specified_file),
- ("pyproject.toml", False, False),
("setup.cfg", False, False),
("tox.ini", False, False),
+ ("pyproject.toml", False, False),
]
return files_to_try
diff --git a/coverage/optional.py b/coverage/optional.py
new file mode 100644
index 00000000..ee617b62
--- /dev/null
+++ b/coverage/optional.py
@@ -0,0 +1,68 @@
+# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0
+# For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt
+
+"""
+Imports that we need at runtime, but might not be present.
+
+When importing one of these modules, always do it in the function where you
+need the module. Some tests will need to remove the module. If you import
+it at the top level of your module, then the test won't be able to simulate
+the module being unimportable.
+
+The import will always succeed, but the value will be None if the module is
+unavailable.
+
+Bad::
+
+ # MyModule.py
+ from coverage.optional import unsure
+
+ def use_unsure():
+ unsure.something()
+
+Good::
+
+ # MyModule.py
+
+ def use_unsure():
+ from coverage.optional import unsure
+ if unsure is None:
+ raise Exception("Module unsure isn't available!")
+
+ unsure.something()
+
+"""
+
+import contextlib
+
+# This file's purpose is to provide modules to be imported from here.
+# pylint: disable=unused-import
+
+# TOML support is an install-time extra option.
+try:
+ import toml
+except ImportError: # pragma: not covered
+ toml = None
+
+
+@contextlib.contextmanager
+def without(modname):
+ """Hide a module for testing.
+
+ Use this in a test function to make an optional module unavailable during
+ the test::
+
+ with coverage.optional.without('toml'):
+ use_toml_somehow()
+
+ Arguments:
+ modname (str): the name of a module importable from
+ `coverage.optional`.
+
+ """
+ real_module = globals()[modname]
+ try:
+ globals()[modname] = None
+ yield
+ finally:
+ globals()[modname] = real_module
diff --git a/coverage/tomlconfig.py b/coverage/tomlconfig.py
index 144b13ca..33647309 100644
--- a/coverage/tomlconfig.py
+++ b/coverage/tomlconfig.py
@@ -8,7 +8,7 @@ import os
import re
from coverage import env
-from coverage.backward import configparser, path_types, toml
+from coverage.backward import configparser, path_types
from coverage.misc import CoverageException, substitute_variables
@@ -32,6 +32,7 @@ class TomlConfigParser:
self._data = []
def read(self, filenames):
+ from coverage.optional import toml
if toml is None:
raise RuntimeError('toml module is not installed.')