pytest: Regression in 7.1 ? Windows CI started to fail with "assert mod not in mods" since 7.1

Now sorry I know this is not a minimal reproducer, but I just want to log this here, and will investigate later:

You can see one Failure here

ERROR collecting test session 
C:\hostedtoolcache\windows\Python\3.9.10\x64\lib\site-packages\_pytest\runner.py:338: in from_call
    result: Optional[TResult] = func()
C:\hostedtoolcache\windows\Python\3.9.10\x64\lib\site-packages\_pytest\runner.py:369: in <lambda>
    call = CallInfo.from_call(lambda: list(collector.collect()), "collect")
C:\hostedtoolcache\windows\Python\3.9.10\x64\lib\site-packages\_pytest\main.py:7[23](https://github.com/ipython/ipython/runs/5535021197?check_suite_focus=true#step:8:23): in collect
    for x in self._collectfile(pkginit):
C:\hostedtoolcache\windows\Python\3.9.10\x64\lib\site-packages\_pytest\main.py:575: in _collectfile
    ihook = self.gethookproxy(fspath)
C:\hostedtoolcache\windows\Python\3.9.10\x64\lib\site-packages\_pytest\main.py:539: in gethookproxy
    my_conftestmodules = pm._getconftestmodules(
C:\hostedtoolcache\windows\Python\3.9.10\x64\lib\site-packages\_pytest\config\__init__.py:579: in _getconftestmodules
    mod = self._importconftest(conftestpath, importmode, rootpath)
C:\hostedtoolcache\windows\Python\3.9.10\x64\lib\site-packages\_pytest\config\__init__.py:6[24](https://github.com/ipython/ipython/runs/5535021197?check_suite_focus=true#step:8:24): in _importconftest
    assert mod not in mods
E   AssertionError

Now I’m not sure what this does, but my quick understanding is that it checks whether conftest.py itself is not in the list of collected modules ? We might definitely do something wrong on IPython side, but it’s strange as other non-windows CI are passing and regardless of whether this is something I did wrong, can the assert get an explanation messages as second argument ?

Downgrading to <7.1 fixes the issue.

Again I’ll try to get a MVP/small example, but it may take me some time, and I guessed maybe one of you will immediately know why this is happening.

  • a detailed description of the bug or problem you are having
  • output of pip list from the virtual environment you are using
  • pytest and operating system versions
  • minimal example if possible

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Reactions: 3
  • Comments: 81 (47 by maintainers)

Commits related to this issue

Most upvoted comments

@bluetech any news on this? Anything newer than pytest 7.0.1 is still broken for me on linux, including the latest 7.2.1. I’ve got one conftest.py in my root, and several smaller conftest.py in subfolders for different django apps. This works fine in 7.0.1 and before, but fails to run at all in any newer version, with the following output:

Traceback (most recent call last):
  File "/usr/local/bin/pytest", line 8, in <module>
    sys.exit(console_main())
  File "/usr/local/lib/python3.10/dist-packages/_pytest/config/__init__.py", line 190, in console_main
    code = main()
  File "/usr/local/lib/python3.10/dist-packages/_pytest/config/__init__.py", line 148, in main
    config = _prepareconfig(args, plugins)
  File "/usr/local/lib/python3.10/dist-packages/_pytest/config/__init__.py", line 329, in _prepareconfig
    config = pluginmanager.hook.pytest_cmdline_parse(
  File "/usr/local/lib/python3.10/dist-packages/pluggy/_hooks.py", line 265, in __call__
    return self._hookexec(self.name, self.get_hookimpls(), kwargs, firstresult)
  File "/usr/local/lib/python3.10/dist-packages/pluggy/_manager.py", line 80, in _hookexec
    return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
  File "/usr/local/lib/python3.10/dist-packages/pluggy/_callers.py", line 55, in _multicall
    gen.send(outcome)
  File "/usr/local/lib/python3.10/dist-packages/_pytest/helpconfig.py", line 103, in pytest_cmdline_parse
    config: Config = outcome.get_result()
  File "/usr/local/lib/python3.10/dist-packages/pluggy/_result.py", line 60, in get_result
    raise ex[1].with_traceback(ex[2])
  File "/usr/local/lib/python3.10/dist-packages/pluggy/_callers.py", line 39, in _multicall
    res = hook_impl.function(*args)
  File "/usr/local/lib/python3.10/dist-packages/_pytest/config/__init__.py", line 1058, in pytest_cmdline_parse
    self.parse(args)
  File "/usr/local/lib/python3.10/dist-packages/_pytest/config/__init__.py", line 1346, in parse
    self._preparse(args, addopts=addopts)
  File "/usr/local/lib/python3.10/dist-packages/_pytest/config/__init__.py", line 1248, in _preparse
    self.hook.pytest_load_initial_conftests(
  File "/usr/local/lib/python3.10/dist-packages/pluggy/_hooks.py", line 265, in __call__
    return self._hookexec(self.name, self.get_hookimpls(), kwargs, firstresult)
  File "/usr/local/lib/python3.10/dist-packages/pluggy/_manager.py", line 80, in _hookexec
    return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
  File "/usr/local/lib/python3.10/dist-packages/pluggy/_callers.py", line 60, in _multicall
    return outcome.get_result()
  File "/usr/local/lib/python3.10/dist-packages/pluggy/_result.py", line 60, in get_result
    raise ex[1].with_traceback(ex[2])
  File "/usr/local/lib/python3.10/dist-packages/pluggy/_callers.py", line 39, in _multicall
    res = hook_impl.function(*args)
  File "/usr/local/lib/python3.10/dist-packages/_pytest/config/__init__.py", line 1125, in pytest_load_initial_conftests
    self.pluginmanager._set_initial_conftests(
  File "/usr/local/lib/python3.10/dist-packages/_pytest/config/__init__.py", line 560, in _set_initial_conftests
    self._try_load_conftest(current, namespace.importmode, rootpath)
  File "/usr/local/lib/python3.10/dist-packages/_pytest/config/__init__.py", line 579, in _try_load_conftest
    self._getconftestmodules(x, importmode, rootpath)
  File "/usr/local/lib/python3.10/dist-packages/_pytest/config/__init__.py", line 603, in _getconftestmodules
    mod = self._importconftest(conftestpath, importmode, rootpath)
  File "/usr/local/lib/python3.10/dist-packages/_pytest/config/__init__.py", line 648, in _importconftest
    assert mod not in mods
AssertionError

@pllim this seems very similar to the Scipy one, os.path.normcase issue, capital L Lib (in mod.__file__) vs small l lib (in conftestpath):

E   RuntimeError: mod=<module 'jdaviz.conftest' from 'D:\\a\\jdaviz\\jdaviz\\.tox\\py310-test-predeps\\lib\\site-packages\\jdaviz\\conftest.py'> has already been loaded
E   
E   str(conftestpath)='D:\\a\\jdaviz\\jdaviz\\.tox\\py310-test-predeps\\Lib\\site-packages\\jdaviz\\conftest.py'

I think this could be fixed by https://github.com/pytest-dev/pytest/pull/11708. Hopefully we manage to push the PR forward tomorrow.

@pllim not sure what is going on, ideally you would cherry-pick my simple debug commit on top of whichever version you were seeing the assert mod not in mods error before.

@pllim can you try with (cherry-picked the commit but using the 0.8.x branch):

pip install git+https://github.com/lesteve/pytest@debug-pytest-8.0-issue-9765

and post the output?

I guess @tylerjereddy you can do this as well?

While we still don’t have a proper reproduction for all cases, I believe we have a pretty good grasp of the issue and how to fix it (see https://github.com/pytest-dev/pytest/issues/9765#issuecomment-1869103766). Since @fcharras presumably hasn’t had time to update PR #11708, I’ll try to update it myself in the next few days so that we can backport it to pytest 8.0 release.

@pllim is it easily doable in your CI to install pytest from my branch:

pip install git+https://github.com/lesteve/pytest@debug-pytest-issue-9765

and post the output?

I added a quick and dirty commit that should add a bit more information to troubleshoot.

@fcharras I’m using a regular ext4 case-sensitive FS on linux. These are the variables you asked for:

conftestpath=PosixPath('/srv/vidicenter/conftest.py') mod.__file__='/srv/vidicenter/../vidicenter/conftest.py'

@fcharras @bluetech I can confirm that this solves the problem for me on Linux!

After thorough investigation with @lesteve slowly comparing the loading steps from both two environments on windows, one of those showcasing the issue, the other being sane, we found that for some reason the paths of the conftest files are sometimes small cased when used as keys in the name2plugin dictionary, but then the same small-casing is not applied at inspection time. This leads to the double loading of plugins, and the subsequent crash.

https://github.com/pytest-dev/pytest/pull/11708 fixes that.

Could other users confirm that the fix work for them too ?

I’ve got the same error, but on linux! Can’t run any test on 7.1.x, reverting back to 7.0.x fixes the issue:

root@f786a0bfb51b:/srv/vidicenter# pytest -n4
WARNING No rollbar access token provided
Traceback (most recent call last):
  File "/usr/local/bin/pytest", line 8, in <module>
    sys.exit(console_main())
  File "/usr/local/lib/python3.8/dist-packages/_pytest/config/__init__.py", line 187, in console_main
    code = main()
  File "/usr/local/lib/python3.8/dist-packages/_pytest/config/__init__.py", line 145, in main
    config = _prepareconfig(args, plugins)
  File "/usr/local/lib/python3.8/dist-packages/_pytest/config/__init__.py", line 324, in _prepareconfig
    config = pluginmanager.hook.pytest_cmdline_parse(
  File "/usr/local/lib/python3.8/dist-packages/pluggy/_hooks.py", line 265, in __call__
    return self._hookexec(self.name, self.get_hookimpls(), kwargs, firstresult)
  File "/usr/local/lib/python3.8/dist-packages/pluggy/_manager.py", line 80, in _hookexec
    return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
  File "/usr/local/lib/python3.8/dist-packages/pluggy/_callers.py", line 55, in _multicall
    gen.send(outcome)
  File "/usr/local/lib/python3.8/dist-packages/_pytest/helpconfig.py", line 102, in pytest_cmdline_parse
    config: Config = outcome.get_result()
  File "/usr/local/lib/python3.8/dist-packages/pluggy/_result.py", line 60, in get_result
    raise ex[1].with_traceback(ex[2])
  File "/usr/local/lib/python3.8/dist-packages/pluggy/_callers.py", line 39, in _multicall
    res = hook_impl.function(*args)
  File "/usr/local/lib/python3.8/dist-packages/_pytest/config/__init__.py", line 1016, in pytest_cmdline_parse
    self.parse(args)
  File "/usr/local/lib/python3.8/dist-packages/_pytest/config/__init__.py", line 1304, in parse
    self._preparse(args, addopts=addopts)
  File "/usr/local/lib/python3.8/dist-packages/_pytest/config/__init__.py", line 1206, in _preparse
    self.hook.pytest_load_initial_conftests(
  File "/usr/local/lib/python3.8/dist-packages/pluggy/_hooks.py", line 265, in __call__
    return self._hookexec(self.name, self.get_hookimpls(), kwargs, firstresult)
  File "/usr/local/lib/python3.8/dist-packages/pluggy/_manager.py", line 80, in _hookexec
    return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
  File "/usr/local/lib/python3.8/dist-packages/pluggy/_callers.py", line 60, in _multicall
    return outcome.get_result()
  File "/usr/local/lib/python3.8/dist-packages/pluggy/_result.py", line 60, in get_result
    raise ex[1].with_traceback(ex[2])
  File "/usr/local/lib/python3.8/dist-packages/pluggy/_callers.py", line 39, in _multicall
    res = hook_impl.function(*args)
  File "/usr/local/lib/python3.8/dist-packages/_pytest/config/__init__.py", line 1083, in pytest_load_initial_conftests
    self.pluginmanager._set_initial_conftests(
  File "/usr/local/lib/python3.8/dist-packages/_pytest/config/__init__.py", line 532, in _set_initial_conftests
    self._try_load_conftest(current, namespace.importmode, rootpath)
  File "/usr/local/lib/python3.8/dist-packages/_pytest/config/__init__.py", line 551, in _try_load_conftest
    self._getconftestmodules(x, importmode, rootpath)
  File "/usr/local/lib/python3.8/dist-packages/_pytest/config/__init__.py", line 575, in _getconftestmodules
    mod = self._importconftest(conftestpath, importmode, rootpath)
  File "/usr/local/lib/python3.8/dist-packages/_pytest/config/__init__.py", line 620, in _importconftest
    assert mod not in mods
AssertionError