Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace importlib_metadata with importlib.metadata on Python 3.8+ #5539

Merged
merged 2 commits into from
Jul 5, 2019

Conversation

hroncok
Copy link
Member

@hroncok hroncok commented Jul 2, 2019

Fixes #5537

  • Target the features branch

Unless your change is trivial or a small documentation fix (e.g., a typo or reword of a small section) please:

  • Create a new changelog file in the changelog folder, with a name like <ISSUE NUMBER>.<TYPE>.rst. See changelog/README.rst for details.
  • Add yourself to AUTHORS in alphabetical order;

I'm still running tox locally, there are some 3.8 failures, not yet sure if related.

@hroncok
Copy link
Member Author

hroncok commented Jul 2, 2019

OK, the failures indeed seem related, yet I'll let the CI show them here, so we can figure out what's the actual problem.

=================================================== FAILURES ====================================================
____________________________ TestGeneralUsage.test_early_load_setuptools_name[True] _____________________________

self = <acceptance_test.TestGeneralUsage object at 0x7f4036a209d0>
testdir = <Testdir local('/tmp/pytest-of-churchyard/pytest-4/test_early_load_setuptools_name0')>
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7f4036a14820>, load_cov_early = True

    @pytest.mark.parametrize("load_cov_early", [True, False])
    def test_early_load_setuptools_name(self, testdir, monkeypatch, load_cov_early):
        testdir.makepyfile(mytestplugin1_module="")
        testdir.makepyfile(mytestplugin2_module="")
        testdir.makepyfile(mycov_module="")
        testdir.syspathinsert()
    
        loaded = []
    
        @attr.s
        class DummyEntryPoint:
            name = attr.ib()
            module = attr.ib()
            group = "pytest11"
    
            def load(self):
                __import__(self.module)
                loaded.append(self.name)
                return sys.modules[self.module]
    
        entry_points = [
            DummyEntryPoint("myplugin1", "mytestplugin1_module"),
            DummyEntryPoint("myplugin2", "mytestplugin2_module"),
            DummyEntryPoint("mycov", "mycov_module"),
        ]
    
        @attr.s
        class DummyDist:
            entry_points = attr.ib()
            files = ()
    
        def my_dists():
            return (DummyDist(entry_points),)
    
        monkeypatch.setattr(metadata, "distributions", my_dists)
        params = ("-p", "mycov") if load_cov_early else ()
        testdir.runpytest_inprocess(*params)
        if load_cov_early:
>           assert loaded == ["mycov", "myplugin1", "myplugin2"]
E           AssertionError: assert [] == ['mycov', 'myplugin1', 'myplugin2']
E             Right contains 3 more items, first extra item: 'mycov'
E             Use -v to get the full diff

.../pytest/testing/acceptance_test.py:148: AssertionError
--------------------------------------------- Captured stderr call ----------------------------------------------
Traceback (most recent call last):
  File ".../pytest/.tox/py38/lib/python3.8/site-packages/_pytest/config/__init__.py", line 544, in import_plugin
    __import__(importspec)
ModuleNotFoundError: No module named 'mycov'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File ".../pytest/.tox/py38/lib/python3.8/site-packages/_pytest/pytester.py", line 858, in runpytest_inprocess
    reprec = self.inline_run(*args, **kwargs)
  File ".../pytest/.tox/py38/lib/python3.8/site-packages/_pytest/pytester.py", line 824, in inline_run
    ret = pytest.main(list(args), plugins=plugins)
  File ".../pytest/.tox/py38/lib/python3.8/site-packages/_pytest/config/__init__.py", line 59, in main
    config = _prepareconfig(args, plugins)
  File ".../pytest/.tox/py38/lib/python3.8/site-packages/_pytest/config/__init__.py", line 190, in _prepareconfig
    config = get_config(args)
  File ".../pytest/.tox/py38/lib/python3.8/site-packages/_pytest/config/__init__.py", line 161, in get_config
    pluginmanager.consider_preparse(args)
  File ".../pytest/.tox/py38/lib/python3.8/site-packages/_pytest/config/__init__.py", line 478, in consider_preparse
    self.consider_pluginarg(parg)
  File ".../pytest/.tox/py38/lib/python3.8/site-packages/_pytest/config/__init__.py", line 503, in consider_pluginarg
    self.import_plugin(arg, consider_entry_points=True)
  File ".../pytest/.tox/py38/lib/python3.8/site-packages/_pytest/config/__init__.py", line 552, in import_plugin
    raise new_exc.with_traceback(tb)
  File ".../pytest/.tox/py38/lib/python3.8/site-packages/_pytest/config/__init__.py", line 544, in import_plugin
    __import__(importspec)
ImportError: Error importing plugin "mycov": No module named 'mycov'
____________________________ TestGeneralUsage.test_early_load_setuptools_name[False] ____________________________

self = <acceptance_test.TestGeneralUsage object at 0x7f4037119a00>
testdir = <Testdir local('/tmp/pytest-of-churchyard/pytest-4/test_early_load_setuptools_name1')>
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7f4037090850>, load_cov_early = False

    @pytest.mark.parametrize("load_cov_early", [True, False])
    def test_early_load_setuptools_name(self, testdir, monkeypatch, load_cov_early):
        testdir.makepyfile(mytestplugin1_module="")
        testdir.makepyfile(mytestplugin2_module="")
        testdir.makepyfile(mycov_module="")
        testdir.syspathinsert()
    
        loaded = []
    
        @attr.s
        class DummyEntryPoint:
            name = attr.ib()
            module = attr.ib()
            group = "pytest11"
    
            def load(self):
                __import__(self.module)
                loaded.append(self.name)
                return sys.modules[self.module]
    
        entry_points = [
            DummyEntryPoint("myplugin1", "mytestplugin1_module"),
            DummyEntryPoint("myplugin2", "mytestplugin2_module"),
            DummyEntryPoint("mycov", "mycov_module"),
        ]
    
        @attr.s
        class DummyDist:
            entry_points = attr.ib()
            files = ()
    
        def my_dists():
            return (DummyDist(entry_points),)
    
        monkeypatch.setattr(metadata, "distributions", my_dists)
        params = ("-p", "mycov") if load_cov_early else ()
        testdir.runpytest_inprocess(*params)
        if load_cov_early:
            assert loaded == ["mycov", "myplugin1", "myplugin2"]
        else:
>           assert loaded == ["myplugin1", "myplugin2", "mycov"]
E           AssertionError: assert [] == ['myplugin1', 'myplugin2', 'mycov']
E             Right contains 3 more items, first extra item: 'myplugin1'
E             Use -v to get the full diff

.../pytest/testing/acceptance_test.py:150: AssertionError
--------------------------------------------- Captured stdout call ----------------------------------------------
============================= test session starts ==============================
platform linux -- Python 3.8.0b1, pytest-5.0.1.dev17+g50b846e9d.d20190703, py-1.8.0, pluggy-0.12.0
hypothesis profile 'default' -> database=DirectoryBasedExampleDatabase('.../pytest/.hypothesis/examples')
rootdir: /tmp/pytest-of-churchyard/pytest-4/test_early_load_setuptools_name1
plugins: hypothesis-4.24.6
collected 0 items

========================= no tests ran in 0.00 seconds =========================
________________________ TestImportHookInstallation.test_installed_plugin_rewrite[plain] ________________________

self = <test_assertion.TestImportHookInstallation object at 0x7f4036e11310>
testdir = <Testdir local('/tmp/pytest-of-churchyard/pytest-4/test_installed_plugin_rewrite0')>, mode = 'plain'
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7f403715ef10>

    @pytest.mark.parametrize("mode", ["plain", "rewrite"])
    def test_installed_plugin_rewrite(self, testdir, mode, monkeypatch):
        monkeypatch.delenv("PYTEST_DISABLE_PLUGIN_AUTOLOAD", raising=False)
        # Make sure the hook is installed early enough so that plugins
        # installed via setuptools are rewritten.
        testdir.tmpdir.join("hampkg").ensure(dir=1)
        contents = {
            "hampkg/__init__.py": """\
                import pytest
    
                @pytest.fixture
                def check_first2():
                    def check(values, value):
                        assert values.pop(0) == value
                    return check
            """,
            "spamplugin.py": """\
            import pytest
            from hampkg import check_first2
    
            @pytest.fixture
            def check_first():
                def check(values, value):
                    assert values.pop(0) == value
                return check
            """,
            "mainwrapper.py": """\
            import pytest, sys
            if sys.version_info >= (3, 8):
                from importlib import metadata
            else:
                import importlib_metadata as metadata
    
            class DummyEntryPoint(object):
                name = 'spam'
                module_name = 'spam.py'
                group = 'pytest11'
    
                def load(self):
                    import spamplugin
                    return spamplugin
    
            class DummyDistInfo(object):
                version = '1.0'
                files = ('spamplugin.py', 'hampkg/__init__.py')
                entry_points = (DummyEntryPoint(),)
                metadata = {'name': 'foo'}
    
            def distributions():
                return (DummyDistInfo(),)
    
            metadata.distributions = distributions
            pytest.main()
            """,
            "test_foo.py": """\
            def test(check_first):
                check_first([10, 30], 30)
    
            def test2(check_first2):
                check_first([10, 30], 30)
            """,
        }
        testdir.makepyfile(**contents)
        result = testdir.run(
            sys.executable, "mainwrapper.py", "-s", "--assert=%s" % mode
        )
        if mode == "plain":
            expected = "E       AssertionError"
        elif mode == "rewrite":
            expected = "*assert 10 == 30*"
        else:
            assert 0
>       result.stdout.fnmatch_lines([expected])
E       Failed: nomatch: 'E       AssertionError'
E           and: '============================= test session starts =============================='
E           and: 'platform linux -- Python 3.8.0b1, pytest-5.0.1.dev17+g50b846e9d.d20190703, py-1.8.0, pluggy-0.12.0'
E           and: "hypothesis profile 'default' -> database=DirectoryBasedExampleDatabase('/tmp/pytest-of-churchyard/pytest-4/test_installed_plugin_rewrite0/.hypothesis/examples')"
E           and: 'rootdir: /tmp/pytest-of-churchyard/pytest-4/test_installed_plugin_rewrite0'
E           and: 'plugins: hypothesis-4.24.6'
E           and: 'collected 2 items'
E           and: ''
E           and: 'test_foo.py EE'
E           and: ''
E           and: '==================================== ERRORS ===================================='
E           and: '____________________________ ERROR at setup of test ____________________________'
E           and: 'file /tmp/pytest-of-churchyard/pytest-4/test_installed_plugin_rewrite0/test_foo.py, line 1'
E           and: '  def test(check_first):'
E           and: "E       fixture 'check_first' not found"
E           and: '>       available fixtures: cache, capfd, capfdbinary, caplog, capsys, capsysbinary, doctest_namespace, monkeypatch, pytestconfig, record_property, record_testsuite_property, record_xml_attribute, recwarn, tmp_path, tmp_path_factory, tmpdir, tmpdir_factory'
E           and: ">       use 'pytest --fixtures [testpath]' for help on them."
E           and: ''
E           and: '/tmp/pytest-of-churchyard/pytest-4/test_installed_plugin_rewrite0/test_foo.py:1'
E           and: '___________________________ ERROR at setup of test2 ____________________________'
E           and: 'file /tmp/pytest-of-churchyard/pytest-4/test_installed_plugin_rewrite0/test_foo.py, line 4'
E           and: '  def test2(check_first2):'
E           and: "E       fixture 'check_first2' not found"
E           and: '>       available fixtures: cache, capfd, capfdbinary, caplog, capsys, capsysbinary, doctest_namespace, monkeypatch, pytestconfig, record_property, record_testsuite_property, record_xml_attribute, recwarn, tmp_path, tmp_path_factory, tmpdir, tmpdir_factory'
E           and: ">       use 'pytest --fixtures [testpath]' for help on them."
E           and: ''
E           and: '/tmp/pytest-of-churchyard/pytest-4/test_installed_plugin_rewrite0/test_foo.py:4'
E           and: '=========================== 2 error in 0.02 seconds ============================'
E       remains unmatched: 'E       AssertionError'

.../pytest/testing/test_assertion.py:220: Failed
--------------------------------------------- Captured stdout call ----------------------------------------------
running: .../pytest/.tox/py38/bin/python mainwrapper.py -s --assert=plain
     in: /tmp/pytest-of-churchyard/pytest-4/test_installed_plugin_rewrite0
============================= test session starts ==============================
platform linux -- Python 3.8.0b1, pytest-5.0.1.dev17+g50b846e9d.d20190703, py-1.8.0, pluggy-0.12.0
hypothesis profile 'default' -> database=DirectoryBasedExampleDatabase('/tmp/pytest-of-churchyard/pytest-4/test_installed_plugin_rewrite0/.hypothesis/examples')
rootdir: /tmp/pytest-of-churchyard/pytest-4/test_installed_plugin_rewrite0
plugins: hypothesis-4.24.6
collected 2 items

test_foo.py EE

==================================== ERRORS ====================================
____________________________ ERROR at setup of test ____________________________
file /tmp/pytest-of-churchyard/pytest-4/test_installed_plugin_rewrite0/test_foo.py, line 1
  def test(check_first):
E       fixture 'check_first' not found
>       available fixtures: cache, capfd, capfdbinary, caplog, capsys, capsysbinary, doctest_namespace, monkeypatch, pytestconfig, record_property, record_testsuite_property, record_xml_attribute, recwarn, tmp_path, tmp_path_factory, tmpdir, tmpdir_factory
>       use 'pytest --fixtures [testpath]' for help on them.

/tmp/pytest-of-churchyard/pytest-4/test_installed_plugin_rewrite0/test_foo.py:1
___________________________ ERROR at setup of test2 ____________________________
file /tmp/pytest-of-churchyard/pytest-4/test_installed_plugin_rewrite0/test_foo.py, line 4
  def test2(check_first2):
E       fixture 'check_first2' not found
>       available fixtures: cache, capfd, capfdbinary, caplog, capsys, capsysbinary, doctest_namespace, monkeypatch, pytestconfig, record_property, record_testsuite_property, record_xml_attribute, recwarn, tmp_path, tmp_path_factory, tmpdir, tmpdir_factory
>       use 'pytest --fixtures [testpath]' for help on them.

/tmp/pytest-of-churchyard/pytest-4/test_installed_plugin_rewrite0/test_foo.py:4
=========================== 2 error in 0.02 seconds ============================
_______________________ TestImportHookInstallation.test_installed_plugin_rewrite[rewrite] _______________________

self = <test_assertion.TestImportHookInstallation object at 0x7f4036e4e040>
testdir = <Testdir local('/tmp/pytest-of-churchyard/pytest-4/test_installed_plugin_rewrite1')>, mode = 'rewrite'
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7f4036bc9fd0>

    @pytest.mark.parametrize("mode", ["plain", "rewrite"])
    def test_installed_plugin_rewrite(self, testdir, mode, monkeypatch):
        monkeypatch.delenv("PYTEST_DISABLE_PLUGIN_AUTOLOAD", raising=False)
        # Make sure the hook is installed early enough so that plugins
        # installed via setuptools are rewritten.
        testdir.tmpdir.join("hampkg").ensure(dir=1)
        contents = {
            "hampkg/__init__.py": """\
                import pytest
    
                @pytest.fixture
                def check_first2():
                    def check(values, value):
                        assert values.pop(0) == value
                    return check
            """,
            "spamplugin.py": """\
            import pytest
            from hampkg import check_first2
    
            @pytest.fixture
            def check_first():
                def check(values, value):
                    assert values.pop(0) == value
                return check
            """,
            "mainwrapper.py": """\
            import pytest, sys
            if sys.version_info >= (3, 8):
                from importlib import metadata
            else:
                import importlib_metadata as metadata
    
            class DummyEntryPoint(object):
                name = 'spam'
                module_name = 'spam.py'
                group = 'pytest11'
    
                def load(self):
                    import spamplugin
                    return spamplugin
    
            class DummyDistInfo(object):
                version = '1.0'
                files = ('spamplugin.py', 'hampkg/__init__.py')
                entry_points = (DummyEntryPoint(),)
                metadata = {'name': 'foo'}
    
            def distributions():
                return (DummyDistInfo(),)
    
            metadata.distributions = distributions
            pytest.main()
            """,
            "test_foo.py": """\
            def test(check_first):
                check_first([10, 30], 30)
    
            def test2(check_first2):
                check_first([10, 30], 30)
            """,
        }
        testdir.makepyfile(**contents)
        result = testdir.run(
            sys.executable, "mainwrapper.py", "-s", "--assert=%s" % mode
        )
        if mode == "plain":
            expected = "E       AssertionError"
        elif mode == "rewrite":
            expected = "*assert 10 == 30*"
        else:
            assert 0
>       result.stdout.fnmatch_lines([expected])
E       Failed: nomatch: '*assert 10 == 30*'
E           and: '============================= test session starts =============================='
E           and: 'platform linux -- Python 3.8.0b1, pytest-5.0.1.dev17+g50b846e9d.d20190703, py-1.8.0, pluggy-0.12.0'
E           and: "hypothesis profile 'default' -> database=DirectoryBasedExampleDatabase('/tmp/pytest-of-churchyard/pytest-4/test_installed_plugin_rewrite1/.hypothesis/examples')"
E           and: 'rootdir: /tmp/pytest-of-churchyard/pytest-4/test_installed_plugin_rewrite1'
E           and: 'plugins: hypothesis-4.24.6'
E           and: 'collected 2 items'
E           and: ''
E           and: 'test_foo.py EE'
E           and: ''
E           and: '==================================== ERRORS ===================================='
E           and: '____________________________ ERROR at setup of test ____________________________'
E           and: 'file /tmp/pytest-of-churchyard/pytest-4/test_installed_plugin_rewrite1/test_foo.py, line 1'
E           and: '  def test(check_first):'
E           and: "E       fixture 'check_first' not found"
E           and: '>       available fixtures: cache, capfd, capfdbinary, caplog, capsys, capsysbinary, doctest_namespace, monkeypatch, pytestconfig, record_property, record_testsuite_property, record_xml_attribute, recwarn, tmp_path, tmp_path_factory, tmpdir, tmpdir_factory'
E           and: ">       use 'pytest --fixtures [testpath]' for help on them."
E           and: ''
E           and: '/tmp/pytest-of-churchyard/pytest-4/test_installed_plugin_rewrite1/test_foo.py:1'
E           and: '___________________________ ERROR at setup of test2 ____________________________'
E           and: 'file /tmp/pytest-of-churchyard/pytest-4/test_installed_plugin_rewrite1/test_foo.py, line 4'
E           and: '  def test2(check_first2):'
E           and: "E       fixture 'check_first2' not found"
E           and: '>       available fixtures: cache, capfd, capfdbinary, caplog, capsys, capsysbinary, doctest_namespace, monkeypatch, pytestconfig, record_property, record_testsuite_property, record_xml_attribute, recwarn, tmp_path, tmp_path_factory, tmpdir, tmpdir_factory'
E           and: ">       use 'pytest --fixtures [testpath]' for help on them."
E           and: ''
E           and: '/tmp/pytest-of-churchyard/pytest-4/test_installed_plugin_rewrite1/test_foo.py:4'
E           and: '=========================== 2 error in 0.02 seconds ============================'
E       remains unmatched: '*assert 10 == 30*'

.../pytest/testing/test_assertion.py:220: Failed
--------------------------------------------- Captured stdout call ----------------------------------------------
running: .../pytest/.tox/py38/bin/python mainwrapper.py -s --assert=rewrite
     in: /tmp/pytest-of-churchyard/pytest-4/test_installed_plugin_rewrite1
============================= test session starts ==============================
platform linux -- Python 3.8.0b1, pytest-5.0.1.dev17+g50b846e9d.d20190703, py-1.8.0, pluggy-0.12.0
hypothesis profile 'default' -> database=DirectoryBasedExampleDatabase('/tmp/pytest-of-churchyard/pytest-4/test_installed_plugin_rewrite1/.hypothesis/examples')
rootdir: /tmp/pytest-of-churchyard/pytest-4/test_installed_plugin_rewrite1
plugins: hypothesis-4.24.6
collected 2 items

test_foo.py EE

==================================== ERRORS ====================================
____________________________ ERROR at setup of test ____________________________
file /tmp/pytest-of-churchyard/pytest-4/test_installed_plugin_rewrite1/test_foo.py, line 1
  def test(check_first):
E       fixture 'check_first' not found
>       available fixtures: cache, capfd, capfdbinary, caplog, capsys, capsysbinary, doctest_namespace, monkeypatch, pytestconfig, record_property, record_testsuite_property, record_xml_attribute, recwarn, tmp_path, tmp_path_factory, tmpdir, tmpdir_factory
>       use 'pytest --fixtures [testpath]' for help on them.

/tmp/pytest-of-churchyard/pytest-4/test_installed_plugin_rewrite1/test_foo.py:1
___________________________ ERROR at setup of test2 ____________________________
file /tmp/pytest-of-churchyard/pytest-4/test_installed_plugin_rewrite1/test_foo.py, line 4
  def test2(check_first2):
E       fixture 'check_first2' not found
>       available fixtures: cache, capfd, capfdbinary, caplog, capsys, capsysbinary, doctest_namespace, monkeypatch, pytestconfig, record_property, record_testsuite_property, record_xml_attribute, recwarn, tmp_path, tmp_path_factory, tmpdir, tmpdir_factory
>       use 'pytest --fixtures [testpath]' for help on them.

/tmp/pytest-of-churchyard/pytest-4/test_installed_plugin_rewrite1/test_foo.py:4
=========================== 2 error in 0.02 seconds ============================
____________________________________ test_preparse_ordering_with_setuptools _____________________________________

self = <_pytest.config.PytestPluginManager object at 0x7f4037ca31c0>, modname = 'mytestplugin'
consider_entry_points = False

    def import_plugin(self, modname, consider_entry_points=False):
        """
        Imports a plugin with ``modname``. If ``consider_entry_points`` is True, entry point
        names are also considered to find a plugin.
        """
        # most often modname refers to builtin modules, e.g. "pytester",
        # "terminal" or "capture".  Those plugins are registered under their
        # basename for historic purposes but must be imported with the
        # _pytest prefix.
        assert isinstance(modname, str), (
            "module name as text required, got %r" % modname
        )
        modname = str(modname)
        if self.is_blocked(modname) or self.get_plugin(modname) is not None:
            return
    
        importspec = "_pytest." + modname if modname in builtin_plugins else modname
        self.rewrite_hook.mark_rewrite(importspec)
    
        if consider_entry_points:
            loaded = self.load_setuptools_entrypoints("pytest11", name=modname)
            if loaded:
                return
    
        try:
>           __import__(importspec)
E           ModuleNotFoundError: No module named 'mytestplugin'

.../pytest/.tox/py38/lib/python3.8/site-packages/_pytest/config/__init__.py:544: ModuleNotFoundError

During handling of the above exception, another exception occurred:

testdir = <Testdir local('/tmp/pytest-of-churchyard/pytest-4/test_preparse_ordering_with_setuptools0')>
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7f4036337e50>

    def test_preparse_ordering_with_setuptools(testdir, monkeypatch):
        monkeypatch.delenv("PYTEST_DISABLE_PLUGIN_AUTOLOAD", raising=False)
    
        class EntryPoint:
            name = "mytestplugin"
            group = "pytest11"
    
            def load(self):
                class PseudoPlugin:
                    x = 42
    
                return PseudoPlugin()
    
        class Dist:
            files = ()
            entry_points = (EntryPoint(),)
    
        def my_dists():
            return (Dist,)
    
        monkeypatch.setattr(metadata, "distributions", my_dists)
        testdir.makeconftest(
            """
            pytest_plugins = "mytestplugin",
        """
        )
        monkeypatch.setenv("PYTEST_PLUGINS", "mytestplugin")
>       config = testdir.parseconfig()

.../pytest/testing/test_config.py:553: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
.../pytest/.tox/py38/lib/python3.8/site-packages/_pytest/pytester.py:913: in parseconfig
    config = _pytest.config._prepareconfig(args, self.plugins)
.../pytest/.tox/py38/lib/python3.8/site-packages/_pytest/config/__init__.py:203: in _prepareconfig
    return pluginmanager.hook.pytest_cmdline_parse(
.../pytest/.tox/py38/lib/python3.8/site-packages/pluggy/hooks.py:289: in __call__
    return self._hookexec(self, self.get_hookimpls(), kwargs)
.../pytest/.tox/py38/lib/python3.8/site-packages/pluggy/manager.py:87: in _hookexec
    return self._inner_hookexec(hook, methods, kwargs)
.../pytest/.tox/py38/lib/python3.8/site-packages/pluggy/manager.py:78: in <lambda>
    self._inner_hookexec = lambda hook, methods, kwargs: hook.multicall(
.../pytest/.tox/py38/lib/python3.8/site-packages/_pytest/helpconfig.py:89: in pytest_cmdline_parse
    config = outcome.get_result()
.../pytest/.tox/py38/lib/python3.8/site-packages/_pytest/config/__init__.py:665: in pytest_cmdline_parse
    self.parse(args)
.../pytest/.tox/py38/lib/python3.8/site-packages/_pytest/config/__init__.py:873: in parse
    self._preparse(args, addopts=addopts)
.../pytest/.tox/py38/lib/python3.8/site-packages/_pytest/config/__init__.py:820: in _preparse
    self.pluginmanager.consider_env()
.../pytest/.tox/py38/lib/python3.8/site-packages/_pytest/config/__init__.py:509: in consider_env
    self._import_plugin_specs(os.environ.get("PYTEST_PLUGINS"))
.../pytest/.tox/py38/lib/python3.8/site-packages/_pytest/config/__init__.py:517: in _import_plugin_specs
    self.import_plugin(import_spec)
.../pytest/.tox/py38/lib/python3.8/site-packages/_pytest/config/__init__.py:552: in import_plugin
    raise new_exc.with_traceback(tb)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <_pytest.config.PytestPluginManager object at 0x7f4037ca31c0>, modname = 'mytestplugin'
consider_entry_points = False

    def import_plugin(self, modname, consider_entry_points=False):
        """
        Imports a plugin with ``modname``. If ``consider_entry_points`` is True, entry point
        names are also considered to find a plugin.
        """
        # most often modname refers to builtin modules, e.g. "pytester",
        # "terminal" or "capture".  Those plugins are registered under their
        # basename for historic purposes but must be imported with the
        # _pytest prefix.
        assert isinstance(modname, str), (
            "module name as text required, got %r" % modname
        )
        modname = str(modname)
        if self.is_blocked(modname) or self.get_plugin(modname) is not None:
            return
    
        importspec = "_pytest." + modname if modname in builtin_plugins else modname
        self.rewrite_hook.mark_rewrite(importspec)
    
        if consider_entry_points:
            loaded = self.load_setuptools_entrypoints("pytest11", name=modname)
            if loaded:
                return
    
        try:
>           __import__(importspec)
E           ImportError: Error importing plugin "mytestplugin": No module named 'mytestplugin'

.../pytest/.tox/py38/lib/python3.8/site-packages/_pytest/config/__init__.py:544: ImportError
_____________________________________ test_setuptools_importerror_issue1479 _____________________________________

testdir = <Testdir local('/tmp/pytest-of-churchyard/pytest-4/test_setuptools_importerror_issue14790')>
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7f4036301d00>

    def test_setuptools_importerror_issue1479(testdir, monkeypatch):
        monkeypatch.delenv("PYTEST_DISABLE_PLUGIN_AUTOLOAD", raising=False)
    
        class DummyEntryPoint:
            name = "mytestplugin"
            group = "pytest11"
    
            def load(self):
                raise ImportError("Don't hide me!")
    
        class Distribution:
            version = "1.0"
            files = ("foo.txt",)
            entry_points = (DummyEntryPoint(),)
    
        def distributions():
            return (Distribution(),)
    
        monkeypatch.setattr(metadata, "distributions", distributions)
        with pytest.raises(ImportError):
>           testdir.parseconfig()
E           Failed: DID NOT RAISE <class 'ImportError'>

.../pytest/testing/test_config.py:578: Failed
____________________________ test_plugin_preparse_prevents_setuptools_loading[False] ____________________________

self = <_pytest.config.PytestPluginManager object at 0x7f4037d42f70>, modname = 'mytestplugin'
consider_entry_points = False

    def import_plugin(self, modname, consider_entry_points=False):
        """
        Imports a plugin with ``modname``. If ``consider_entry_points`` is True, entry point
        names are also considered to find a plugin.
        """
        # most often modname refers to builtin modules, e.g. "pytester",
        # "terminal" or "capture".  Those plugins are registered under their
        # basename for historic purposes but must be imported with the
        # _pytest prefix.
        assert isinstance(modname, str), (
            "module name as text required, got %r" % modname
        )
        modname = str(modname)
        if self.is_blocked(modname) or self.get_plugin(modname) is not None:
            return
    
        importspec = "_pytest." + modname if modname in builtin_plugins else modname
        self.rewrite_hook.mark_rewrite(importspec)
    
        if consider_entry_points:
            loaded = self.load_setuptools_entrypoints("pytest11", name=modname)
            if loaded:
                return
    
        try:
>           __import__(importspec)
E           ModuleNotFoundError: No module named 'mytestplugin'

.../pytest/.tox/py38/lib/python3.8/site-packages/_pytest/config/__init__.py:544: ModuleNotFoundError

During handling of the above exception, another exception occurred:

testdir = <Testdir local('/tmp/pytest-of-churchyard/pytest-4/test_plugin_preparse_prevents_setuptools_loading1')>
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7f4037d42070>, block_it = False

    @pytest.mark.parametrize("block_it", [True, False])
    def test_plugin_preparse_prevents_setuptools_loading(testdir, monkeypatch, block_it):
        monkeypatch.delenv("PYTEST_DISABLE_PLUGIN_AUTOLOAD", raising=False)
    
        plugin_module_placeholder = object()
    
        class DummyEntryPoint:
            name = "mytestplugin"
            group = "pytest11"
    
            def load(self):
                return plugin_module_placeholder
    
        class Distribution:
            version = "1.0"
            files = ("foo.txt",)
            entry_points = (DummyEntryPoint(),)
    
        def distributions():
            return (Distribution(),)
    
        monkeypatch.setattr(metadata, "distributions", distributions)
        args = ("-p", "no:mytestplugin") if block_it else ()
        config = testdir.parseconfig(*args)
>       config.pluginmanager.import_plugin("mytestplugin")

.../pytest/testing/test_config.py:628: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
.../pytest/.tox/py38/lib/python3.8/site-packages/_pytest/config/__init__.py:552: in import_plugin
    raise new_exc.with_traceback(tb)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <_pytest.config.PytestPluginManager object at 0x7f4037d42f70>, modname = 'mytestplugin'
consider_entry_points = False

    def import_plugin(self, modname, consider_entry_points=False):
        """
        Imports a plugin with ``modname``. If ``consider_entry_points`` is True, entry point
        names are also considered to find a plugin.
        """
        # most often modname refers to builtin modules, e.g. "pytester",
        # "terminal" or "capture".  Those plugins are registered under their
        # basename for historic purposes but must be imported with the
        # _pytest prefix.
        assert isinstance(modname, str), (
            "module name as text required, got %r" % modname
        )
        modname = str(modname)
        if self.is_blocked(modname) or self.get_plugin(modname) is not None:
            return
    
        importspec = "_pytest." + modname if modname in builtin_plugins else modname
        self.rewrite_hook.mark_rewrite(importspec)
    
        if consider_entry_points:
            loaded = self.load_setuptools_entrypoints("pytest11", name=modname)
            if loaded:
                return
    
        try:
>           __import__(importspec)
E           ImportError: Error importing plugin "mytestplugin": No module named 'mytestplugin'

.../pytest/.tox/py38/lib/python3.8/site-packages/_pytest/config/__init__.py:544: ImportError

@codecov
Copy link

codecov bot commented Jul 3, 2019

Codecov Report

Merging #5539 into features will increase coverage by 0.02%.
The diff coverage is 71.42%.

Impacted file tree graph

@@             Coverage Diff              @@
##           features    #5539      +/-   ##
============================================
+ Coverage     96.08%   96.11%   +0.02%     
============================================
  Files           117      117              
  Lines         25695    25698       +3     
  Branches       2493     2494       +1     
============================================
+ Hits          24690    24699       +9     
+ Misses          701      695       -6     
  Partials        304      304
Impacted Files Coverage Δ
src/_pytest/config/argparsing.py 88.2% <ø> (ø) ⬆️
testing/test_assertion.py 97.56% <ø> (ø) ⬆️
src/_pytest/config/__init__.py 94.62% <100%> (ø) ⬆️
testing/acceptance_test.py 98.03% <100%> (ø) ⬆️
testing/test_entry_points.py 100% <100%> (ø) ⬆️
testing/test_config.py 99.83% <100%> (ø) ⬆️
src/_pytest/compat.py 95.68% <33.33%> (-1.38%) ⬇️
src/_pytest/doctest.py 96.62% <0%> (+2.24%) ⬆️
src/_pytest/pastebin.py 91.22% <0%> (+3.5%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 4f9bf02...c54cbd6. Read the comment docs.

@asottile
Copy link
Member

asottile commented Jul 3, 2019

the py38 failures make sense -- until pluggy has the fix it'll be using a hybrid of importlib.metadata and importlib_metadata

@hroncok
Copy link
Member Author

hroncok commented Jul 3, 2019

I've tried with

pluggymaster: git+https://github.com/hroncok/pluggy.git@importlib_metadata

And that didn't work either :(

@nicoddemus
Copy link
Member

Hmmm strange then.

Btw @hroncok this should target features. 👍

I will try to investigate this later too.

@hroncok hroncok changed the base branch from master to features July 3, 2019 11:43
@hroncok hroncok force-pushed the importlib_metadata branch from 14f4bf0 to d68d5eb Compare July 3, 2019 11:44
@hroncok
Copy link
Member Author

hroncok commented Jul 3, 2019

retargeted

Copy link
Member

@nicoddemus nicoddemus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Other than my comment, LGTM! 👍

@hroncok hroncok self-assigned this Jul 4, 2019
@hroncok
Copy link
Member Author

hroncok commented Jul 4, 2019

I'm hitting pytest: error: unrecognized arguments: -ra again. is it not fixed on features branch?

@hroncok hroncok force-pushed the importlib_metadata branch from d68d5eb to 15962e3 Compare July 4, 2019 12:54
@nicoddemus
Copy link
Member

Oh I'm afraid not... please cherry-pick 9021194 into your branch

@nicoddemus
Copy link
Member

Oh you just did it 😅 👍

@hroncok
Copy link
Member Author

hroncok commented Jul 4, 2019

(I have no idea how features vs. master works, so I've just cherrypicked it to be able to test it.)

Hopefully by Python 3.9 this will be fixed upstream, if not we will
need to bump the version again.

Fix pytest-dev#5523
@nicoddemus
Copy link
Member

nicoddemus commented Jul 4, 2019

(I have no idea how features vs. master works, so I've just cherrypicked it to be able to test it.)

That's fine, thanks. master is meant for bug-fixes only, it is the branch used to release patch versions (next will be 5.0.1). features is for the next major/minor versions, so your PR will land in 5.1.0 only. 👍

@hroncok hroncok force-pushed the importlib_metadata branch from 330b71a to c54cbd6 Compare July 4, 2019 13:00
@hroncok
Copy link
Member Author

hroncok commented Jul 4, 2019

How are bugfixes usually forward-ported from master to features? is there a huge merge before release?

@nicoddemus
Copy link
Member

How are bugfixes usually forward-ported from master to features?

We do that periodically and before a release, it just happens that this was not done before the short-option fix landed. 👍

Copy link
Member

@nicoddemus nicoddemus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a ton @hroncok!

@nicoddemus
Copy link
Member

@asottile want't to take a look or can we merge this?

@nicoddemus
Copy link
Member

Thanks again @hroncok!

@nicoddemus nicoddemus merged commit 60a358f into pytest-dev:features Jul 5, 2019
nicoddemus added a commit that referenced this pull request Oct 11, 2019
[4.6] Replace importlib_metadata with importlib.metadata on Python 3.8+ (#5539)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants