Skip to content

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

Closed

Description

@Carreau

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

Activity

  1. bluetech commented on Mar 14, 2022

    @bluetech
    Member

    Thanks for the report, I will take a look when I get a chance. 7.1 had some internal conftest refactorings. If you manage to provide a reproduction that'd be great.

  2. The-Compiler commented on Mar 14, 2022

    @The-Compiler
    Member

    One thing that seems somewhat suspicious is how IPython's pytest_ipdoctest.py seems to have some custom code around importing conftest files:

    https://github.com/ipython/ipython/blob/d7cc335a36cdfe4159c9b88c94311866c923a547/IPython/testing/plugin/pytest_ipdoctest.py#L635-L646

  3. Carreau commented on Mar 14, 2022

    @Carreau
    ContributorAuthor

    Yeah, it might be something on our end, we have to do some pretty weird things seeing we also an interpreter. So I would not be surprised if the problem is from our plugins.

  4. Carreau commented on Mar 14, 2022

    @Carreau
    ContributorAuthor

    It does seem like removing the plugin fixes the issue,
    I'm not quite sure why it's windows only, and I haven't written it, so I'm not sure how I can fix it.

    Feel free to close, worse case I'll run the plugin only on linux CI.

  5. added a commit that references this issue on Mar 14, 2022
  6. gonzalocasas commented on Mar 14, 2022

    @gonzalocasas

    Not sure if it helps, I know it's not a slim repro setup, but this repo was just pinned to <7.1 because it was consistently reproducible in there: https://github.com/compas-dev/compas

  7. added
    type: regressionindicates a problem that was introduced in a release which was working previously
    topic: configrelated to config handling, argument parsing and config file
    on Mar 15, 2022
  8. added a commit that references this issue on Mar 16, 2022
  9. Carreau commented on Mar 18, 2022

    @Carreau
    ContributorAuthor

    @gonzalocasas and @bashtage I see both your CI install IPython in them, could you try pinning IPython to <8 to see if it's a problem with the IPython doctest plugin itself (that should not be present in 7.x)

  10. bashtage commented on Mar 20, 2022

    @bashtage

    @Carreau I get the same error when I pip install ipython<8. I also get the same error when I pip uninstall ipython. Works find with 7.0.x, broken in 7.1.x.

  11. bashtage commented on Mar 20, 2022

    @bashtage

    I can also get this error when I reun specific tests:

     ValueError: Plugin already registered: c:\git\statsmodels\statsmodels\conftest.py=<module 'statsmodels.conftest' from 'c:\\git\\statsmodels\\statsmodels\\conftest.py'>
    
    
  12. jgb commented on Apr 8, 2022

    @jgb

    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
    
  13. bnavigator commented on Apr 26, 2022

    @bnavigator

    FYI: I also get this in an rpmbuild of asdf for openSUSE Linux. I attribute it to some import mismatch for the conftest.py installed into the sitelib.

    Fails:

    Have asdf installed in sitelib but collect from asdf in source directory. This worked with pytest < 7

    [    3s] Executing(%check): /usr/bin/bash -e /var/tmp/rpm-tmp.cC3tTE
    [    3s] + umask 022
    [    3s] + cd /home/abuild/rpmbuild/BUILD
    [    3s] + cd asdf-2.11.1
    [    3s] + export LANG=en_US.UTF-8
    [    3s] + LANG=en_US.UTF-8
    [    3s] + export PY_IGNORE_IMPORTMISMATCH=1
    [    3s] + PY_IGNORE_IMPORTMISMATCH=1
    [    3s] ++ '[' -f _current_flavor ']'
    [    3s] ++ cat _current_flavor
    [    3s] + last_flavor=python38
    [    3s] + '[' -z python38 ']'
    [    3s] + '[' python38 '!=' python39 ']'
    [    3s] + '[' -d build ']'
    [    3s] + mv build _build.python38
    [    3s] + '[' -d _build.python39 ']'
    [    3s] + mv _build.python39 build
    [    3s] + echo python39
    [    3s] + python_flavor=python39
    [    3s] + PYTHONDONTWRITEBYTECODE=1
    [    3s] + pytest-3.9 --ignore=_build.python39 --ignore=_build.python310 --ignore=_build.python38 -v --remote-data=none
    [    3s] Internet access disabled
    [    3s] ============================= test session starts ==============================
    [    3s] platform linux -- Python 3.9.12, pytest-7.1.1, pluggy-1.0.0 -- /usr/bin/python3.9
    [    3s] cachedir: .pytest_cache
    [    3s] rootdir: /home/abuild/rpmbuild/BUILD/asdf-2.11.1, configfile: setup.cfg, testpaths: asdf, docs
    [    3s] plugins: asdf-2.11.1, sugar-0.9.4, openfiles-0.5.0, doctestplus-0.12.0, remotedata-0.3.2
    [    4s] collecting ... collected 0 items / 1 error
    [    4s] 
    [    4s] ==================================== ERRORS ====================================
    [    4s] ________________________ ERROR collecting test session _________________________
    [    4s] /usr/lib/python3.9/site-packages/_pytest/runner.py:338: in from_call
    [    4s]     result: Optional[TResult] = func()
    [    4s] /usr/lib/python3.9/site-packages/_pytest/runner.py:369: in <lambda>
    [    4s]     call = CallInfo.from_call(lambda: list(collector.collect()), "collect")
    [    4s] /usr/lib/python3.9/site-packages/_pytest/main.py:723: in collect
    [    4s]     for x in self._collectfile(pkginit):
    [    4s] /usr/lib/python3.9/site-packages/_pytest/main.py:575: in _collectfile
    [    4s]     ihook = self.gethookproxy(fspath)
    [    4s] /usr/lib/python3.9/site-packages/_pytest/main.py:539: in gethookproxy
    [    4s]     my_conftestmodules = pm._getconftestmodules(
    [    4s] /usr/lib/python3.9/site-packages/_pytest/config/__init__.py:575: in _getconftestmodules
    [    4s]     mod = self._importconftest(conftestpath, importmode, rootpath)
    [    4s] /usr/lib/python3.9/site-packages/_pytest/config/__init__.py:620: in _importconftest
    [    4s]     assert mod not in mods
    [    4s] E   AssertionError
    [    4s] =========================== short test summary info ============================
    [    4s] ERROR  - AssertionError
    [    4s] !!!!!!!!!!!!!!!!!!!! Interrupted: 1 error during collection !!!!!!!!!!!!!!!!!!!!
    [    4s] =============================== 1 error in 0.29s ===============================
    [    4s] error: Bad exit status from /var/tmp/rpm-tmp.cC3tTE (%check)
    

    Works:

    move the asdf source directory away and directly test with --pyargs asdf

    [    3s] Executing(%check): /usr/bin/bash -e /var/tmp/rpm-tmp.wVMB1t
    [    3s] + umask 022
    [    3s] + cd /home/abuild/rpmbuild/BUILD
    [    3s] + cd asdf-2.11.1
    [    3s] + export LANG=en_US.UTF-8
    [    3s] + LANG=en_US.UTF-8
    [    3s] + mv asdf asdf.moved
    [    3s] ++ '[' -f _current_flavor ']'
    [    3s] ++ cat _current_flavor
    [    3s] + last_flavor=python38
    [    3s] + '[' -z python38 ']'
    [    3s] + '[' python38 '!=' python39 ']'
    [    3s] + '[' -d build ']'
    [    3s] + mv build _build.python38
    [    3s] + '[' -d _build.python39 ']'
    [    3s] + mv _build.python39 build
    [    3s] + echo python39
    [    3s] + python_flavor=python39
    [    3s] + PYTHONDONTWRITEBYTECODE=1
    [    3s] + pytest-3.9 --ignore=_build.python39 --ignore=_build.python310 --ignore=_build.python38 -v --pyargs asdf --remote-data=none
    [    3s] Internet access disabled
    [    3s] ============================= test session starts ==============================
    [    3s] platform linux -- Python 3.9.12, pytest-7.1.1, pluggy-1.0.0 -- /usr/bin/python3.9
    [    3s] cachedir: .pytest_cache
    [    3s] rootdir: /home/abuild/rpmbuild/BUILD/asdf-2.11.1, configfile: setup.cfg
    [    3s] plugins: asdf-2.11.1, sugar-0.9.4, openfiles-0.5.0, doctestplus-0.12.0, remotedata-0.3.2
    [    5s] collecting ... collected 721 items
    [    5s] 
    [    5s] asdf.py::asdf.asdf.AsdfFile.make_reference PASSED                        [  0%]
    ...
    [  200s] ============ 691 passed, 8 skipped, 22 xfailed in 196.36s (0:03:16) ==========
    
  14. 60 remaining items

  15. lesteve commented on Jan 8, 2024

    @lesteve
    Contributor

    @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 #11708. Hopefully we manage to push the PR forward tomorrow.

  16. pllim commented on Jan 8, 2024

    @pllim
    Contributor

    Thanks, @lesteve ! I will be happy to test that PR when it is ready.

  17. lesteve commented on Jan 9, 2024

    @lesteve
    Contributor

    @pllim and maybe @h-vetinari or @tylerjereddy, can you try installing the code from #11708 and see whether that fixes your issue 🤞?

    pip install git+https://github.com/fcharras/pytest@FIX/crash_during_conftest_collection
    
  18. pllim commented on Jan 9, 2024

    @pllim
  19. pllim commented on Jan 9, 2024

    @pllim
    Contributor

    @lesteve , I applied the patch from fcharras to 8.0rc1 directly at https://github.com/pllim/pytest/tree/debug-8.0rc1 (pllim@22949f2). It went further this time but errored out because it cannot find test fixtures. We have a root level root/conftest.py and a root/package/conftest.py. The first one is so that tox picks up the pytest header stuff. The second one is where all the fixtures are and we need it at the package level so we can run package.test() command for any installed package (this uses the astropy test runner machinery).

    Log: https://github.com/spacetelescope/jdaviz/actions/runs/7465954413/job/20316247352?pr=2654

    For completeness, I can confirm that this problem only still happens on Windows. OSX passed and Linux failed with some transient remote data access problem that is unrelated to pytest itself.

  20. lesteve commented on Jan 9, 2024

    @lesteve
    Contributor

    OK, so at least you avoid the assert mod not in mods and it goes a bit further, so I would count that as a win for the PR 😉 !

    Your debug branch looks fine to me. Right now, I don't really understand how such a change could cause some fixtures to not be registered.

    It could potentially be another pytest 8.0rc1 regression, hard to tell since I am by no means a pytest expert ...

  21. pllim commented on Jan 9, 2024

    @pllim
    Contributor

    Yes, I agree that the "assert mod not in mods" problem is solved in #11708

  22. pllim commented on Jan 9, 2024

    @pllim
    Contributor

    I also just found out that this "mod not in mods" problem on Windows is not a problem at all if I switch from Python 3.10 to Python 3.11 🤪 🤷‍♀️

  23. added a commit that references this issue on Jan 13, 2024
  24. woutdenolf commented on Jan 14, 2024

    @woutdenolf
    Contributor

    For reference, in case this needs to be reproduced (Windows 11, python 3.8.10):

    python -m pip install "ewokscore[test]==0.7.1" "pytest==8.0.0rc1"
    python -m pytest -v --pyargs ewokscore.tests
    

    This works fine (well there is an issue with the papermill dependency but that's not related to pytest)

    python -m pip install "ewokscore[test]==0.7.1" "pytest==7.4.4"
    python -m pytest -v --pyargs ewokscore.tests
    
  25. lesteve commented on Jan 15, 2024

    @lesteve
    Contributor

    @woutdenolf this is similar to scipy and jdaviz see #9765 (comment), lib (small l) vs Lib (capital L).

    I think this is fixed in main (since Saturday January 13 ~9PM Grenoble time) and in has been back-ported in the 8.0.x branch.

    I double-checked and I don't get the assert mod not in mods on Windows and Python 3.8, when doing this:

    python -m pip install "ewokscore[test]==0.7.1" git+https://github.com/pytest-dev/pytest.git@main
    python -m pytest -v --pyargs ewokscore.tests
    
  26. bluetech commented on Jan 15, 2024

    @bluetech
    Member

    For reference, the simple "Solution 3" normalize-as-early-as-possible approach (implemented here) does not work -- the problem is that, while Foo/Mod.py and foo/mod.py are equivalent paths in a case-insensitive filesystem, Foo.Mod and foo.mod are not equivalent Python module names.

  27. woutdenolf commented on Jan 15, 2024

    @woutdenolf
    Contributor

    For reference, the simple "Solution 3" normalize-as-early-as-possible approach (implemented here) does not work -- the problem is that, while Foo/Mod.py and foo/mod.py are equivalent paths in a case-insensitive filesystem, Foo.Mod and foo.mod are not equivalent Python module names.

    The link is broken. What do you mean by "normalize"? Normalize what and how?

    I don't see the problem. You cannot import Foo/Mod.py by doing import foo.mod. Could you create an example?

    I'm asking because I made a proposal that normalizes anymodule.__file__ but preserves symlinks: #11821. The tests pass so if there is a problem with this, it is not covered by the tests.

  28. lesteve commented on Jan 16, 2024

    @lesteve
    Contributor

    The correct link for the commit is 203889b

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    topic: configrelated to config handling, argument parsing and config filetype: regressionindicates a problem that was introduced in a release which was working previously

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions