diff --git a/src/python/pants/backend/python/__init__.py b/src/python/pants/backend/python/__init__.py index de40ea7ca05..e69de29bb2d 100644 --- a/src/python/pants/backend/python/__init__.py +++ b/src/python/pants/backend/python/__init__.py @@ -1 +0,0 @@ -__import__('pkg_resources').declare_namespace(__name__) diff --git a/src/python/pants/backend/python/tasks/__init__.py b/src/python/pants/backend/python/tasks/__init__.py index de40ea7ca05..e69de29bb2d 100644 --- a/src/python/pants/backend/python/tasks/__init__.py +++ b/src/python/pants/backend/python/tasks/__init__.py @@ -1 +0,0 @@ -__import__('pkg_resources').declare_namespace(__name__) diff --git a/src/python/pants/backend/python/tasks/coverage/plugin.py b/src/python/pants/backend/python/tasks/coverage/plugin.py index 483145fe472..0473e8064d5 100644 --- a/src/python/pants/backend/python/tasks/coverage/plugin.py +++ b/src/python/pants/backend/python/tasks/coverage/plugin.py @@ -15,20 +15,18 @@ from coverage.python import PythonFileReporter -class MyFileTracer(FileTracer): +class SimpleFileTracer(FileTracer): def __init__(self, filename): - super(MyFileTracer, self).__init__() + super(SimpleFileTracer, self).__init__() self._filename = filename def source_filename(self): return self._filename -class MyFileReporter(PythonFileReporter): - """A python file reporter that knows how to map Pants PEX chroots back to repo source code.""" - +class SimpleFileReporter(PythonFileReporter): def __init__(self, morf, relpath): - super(MyFileReporter, self).__init__(morf, coverage=None) + super(SimpleFileReporter, self).__init__(morf, coverage=None) self._relpath = relpath def relative_filename(self): @@ -50,11 +48,11 @@ def no_branch_lines(self): join_regex(DEFAULT_PARTIAL_ALWAYS[:])) -class MyPlugin(CoveragePlugin): +class ChrootRemappingPlugin(CoveragePlugin): """A plugin that knows how to map Pants PEX chroots back to repo source code when reporting.""" def __init__(self, buildroot, src_chroot_path, src_to_target_base): - super(MyPlugin, self).__init__() + super(ChrootRemappingPlugin, self).__init__() self._buildroot = buildroot self._src_chroot_path = src_chroot_path self._src_to_target_base = src_to_target_base @@ -68,14 +66,15 @@ def find_executable_files(self, top): yield os.path.join(root, f) def file_tracer(self, filename): + # Don't trace third party libraries or the standard lib, just user code in the src chroot. if filename.startswith(self._src_chroot_path): src = os.path.relpath(filename, self._src_chroot_path) if src in self._src_to_target_base: - return MyFileTracer(filename) + return SimpleFileTracer(filename) def file_reporter(self, filename): mapped_relpath = self._map_relpath(filename) - return MyFileReporter(filename, mapped_relpath or filename) + return SimpleFileReporter(filename, mapped_relpath) def _map_relpath(self, filename): src = os.path.relpath(filename, self._src_chroot_path) @@ -92,4 +91,4 @@ def coverage_init(reg, options): buildroot = options['buildroot'] src_chroot_path = options['src_chroot_path'] src_to_target_base = json.loads(options['src_to_target_base']) - reg.add_file_tracer(MyPlugin(buildroot, src_chroot_path, src_to_target_base)) + reg.add_file_tracer(ChrootRemappingPlugin(buildroot, src_chroot_path, src_to_target_base)) diff --git a/src/python/pants/backend/python/tasks/pytest_prep.py b/src/python/pants/backend/python/tasks/pytest_prep.py index 890b724d0fa..2450359abd8 100644 --- a/src/python/pants/backend/python/tasks/pytest_prep.py +++ b/src/python/pants/backend/python/tasks/pytest_prep.py @@ -20,6 +20,8 @@ class PytestPrep(PythonExecutionTaskBase): class PytestBinary(object): """A `py.test` PEX binary with an embedded default (empty) `pytest.ini` config file.""" + _COVERAGE_PLUGIN_MODULE_NAME = '__{}__'.format(__name__.replace('.', '_')) + def __init__(self, pex): self._pex = pex @@ -39,9 +41,17 @@ def config_path(self): """ return os.path.join(self._pex.path(), 'pytest.ini') + @classmethod + def coverage_plugin_module(cls): + """Return the name of the coverage plugin module embedded in this py.test binary. + + :rtype: str + """ + return cls._COVERAGE_PLUGIN_MODULE_NAME + @classmethod def implementation_version(cls): - return super(PytestPrep, cls).implementation_version() + [('PytestPrep', 1)] + return super(PytestPrep, cls).implementation_version() + [('PytestPrep', 2)] @classmethod def product_types(cls): @@ -56,10 +66,7 @@ def extra_requirements(self): def extra_files(self): yield self.ExtraFile.empty('pytest.ini') - - enclosing_dir = os.path.dirname(__name__.replace('.', os.sep)) - plugin_path = os.path.join(enclosing_dir, 'coverage/plugin.py') - yield self.ExtraFile(path=plugin_path, + yield self.ExtraFile(path='{}.py'.format(self.PytestBinary.coverage_plugin_module()), content=pkg_resources.resource_string(__name__, 'coverage/plugin.py')) def execute(self): diff --git a/src/python/pants/backend/python/tasks/pytest_run.py b/src/python/pants/backend/python/tasks/pytest_run.py index a1d87b2ac0c..f6b2e99b554 100644 --- a/src/python/pants/backend/python/tasks/pytest_run.py +++ b/src/python/pants/backend/python/tasks/pytest_run.py @@ -186,7 +186,7 @@ def _ensure_section(cp, section): def _add_plugin_config(cls, cp, src_chroot_path, src_to_target_base): # We use a coverage plugin to map PEX chroot source paths back to their original repo paths for # report output. - plugin_module = 'pants.backend.python.tasks.coverage.plugin' + plugin_module = PytestPrep.PytestBinary.coverage_plugin_module() cls._ensure_section(cp, 'run') cp.set('run', 'plugins', plugin_module)