diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 7d6f402a6..cc4067fc1 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -7,7 +7,9 @@ * -* +* Assertions are now being rewritten for plugins in development mode + (``pip install -e``) (`#1934`_). + Thanks `@nicoddemus`_ for the PR. * @@ -17,6 +19,7 @@ .. _@philpep: https://github.com/philpep .. _#1905: https://github.com/pytest-dev/pytest/issues/1905 +.. _#1934: https://github.com/pytest-dev/pytest/issues/1934 3.0.2 diff --git a/_pytest/config.py b/_pytest/config.py index 5b4654a24..55ad538d3 100644 --- a/_pytest/config.py +++ b/_pytest/config.py @@ -954,16 +954,21 @@ class Config(object): else: self.pluginmanager.rewrite_hook = hook for entrypoint in pkg_resources.iter_entry_points('pytest11'): - for entry in entrypoint.dist._get_metadata('RECORD'): - fn = entry.split(',')[0] - is_simple_module = os.sep not in fn and fn.endswith('.py') - is_package = fn.count(os.sep) == 1 and fn.endswith('__init__.py') - if is_simple_module: - module_name, ext = os.path.splitext(fn) - hook.mark_rewrite(module_name) - elif is_package: - package_name = os.path.dirname(fn) - hook.mark_rewrite(package_name) + # 'RECORD' available for plugins installed normally (pip install) + # 'SOURCES.txt' available for plugins installed in dev mode (pip install -e) + # for installed plugins 'SOURCES.txt' returns an empty list, and vice-versa + # so it shouldn't be an issue + for metadata in ('RECORD', 'SOURCES.txt'): + for entry in entrypoint.dist._get_metadata(metadata): + fn = entry.split(',')[0] + is_simple_module = os.sep not in fn and fn.endswith('.py') + is_package = fn.count(os.sep) == 1 and fn.endswith('__init__.py') + if is_simple_module: + module_name, ext = os.path.splitext(fn) + hook.mark_rewrite(module_name) + elif is_package: + package_name = os.path.dirname(fn) + hook.mark_rewrite(package_name) self._warn_about_missing_assertion(mode) def _warn_about_missing_assertion(self, mode): diff --git a/testing/test_assertion.py b/testing/test_assertion.py index d49815181..af7e7e0fe 100644 --- a/testing/test_assertion.py +++ b/testing/test_assertion.py @@ -108,7 +108,8 @@ class TestImportHookInstallation: assert result.ret == 0 @pytest.mark.parametrize('mode', ['plain', 'rewrite']) - def test_installed_plugin_rewrite(self, testdir, mode): + @pytest.mark.parametrize('plugin_state', ['development', 'installed']) + def test_installed_plugin_rewrite(self, testdir, mode, plugin_state): # Make sure the hook is installed early enough so that plugins # installed via setuptools are re-written. testdir.tmpdir.join('hampkg').ensure(dir=1) @@ -135,13 +136,22 @@ class TestImportHookInstallation: 'mainwrapper.py': """ import pytest, pkg_resources + plugin_state = "{plugin_state}" + class DummyDistInfo: project_name = 'spam' version = '1.0' def _get_metadata(self, name): - return ['spamplugin.py,sha256=abc,123', - 'hampkg/__init__.py,sha256=abc,123'] + # 'RECORD' meta-data only available in installed plugins + if name == 'RECORD' and plugin_state == "installed": + return ['spamplugin.py,sha256=abc,123', + 'hampkg/__init__.py,sha256=abc,123'] + # 'SOURCES.txt' meta-data only available for plugins in development mode + elif name == 'SOURCES.txt' and plugin_state == "development": + return ['spamplugin.py', + 'hampkg/__init__.py'] + return [] class DummyEntryPoint: name = 'spam' @@ -159,7 +169,7 @@ class TestImportHookInstallation: pkg_resources.iter_entry_points = iter_entry_points pytest.main() - """, + """.format(plugin_state=plugin_state), 'test_foo.py': """ def test(check_first): check_first([10, 30], 30)