-
Notifications
You must be signed in to change notification settings - Fork 152
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
pytest-asyncio-0.23.2 loads packages more eagerly #729
Comments
We're seeing something similar (i suspect) - though due to an even odder case. Our tests work fine up to pytest-asyncio-0.23.x ... at which point, ONLY the mac runs are failing (they do fail with Now We do have an auto-use fixture to completely mock the torch module on macos to work around this problem - but (i suspect) due to the eager loading of pytest-asyncio, it's loading torch BEFORE actually running the auto-use fixture, therefore importing torch - which causes the random segfaults. I could also confirm this by messing with the installed torch file (simply placing a It's unclear to me why pytest-asyncio does need to mess with the importing logic and would import packages that
Now torch is imported in some files within the project - which are only referenced through a custom resolver responsible to load the package (similar to the original author of this issue) - but these files are not touched or imported directly anywyere. In my eyes/understanding (correct me if i'm wrong), pytest-asyncio is a plugin to provide async support for tests, not to modify the test sequence, or help find additional tests - so what's the exact reason to have to modify the importing logic? Exception details of "importing torch" error
added
|
We also see this on a minimal Pandas installation. Pandas has lots of optional dependencies but imports fine with the minimal requirements. With older pytest-asyncio the test suite would collect fine and skip tests not applicable. But with the new version, the optional Pandas submodules cause an early pytest internalerror. [ 4s] + python3.11 -c 'import pandas; print(pandas.__path__); print(pandas.show_versions())'
[ 8s] /usr/lib/python3.11/site-packages/_distutils_hack/__init__.py:33: UserWarning: Setuptools is replacing distutils.
[ 8s] warnings.warn("Setuptools is replacing distutils.")
[ 8s] ['/home/abuild/rpmbuild/BUILD/pandas-2.1.4/pandas']
[ 8s]
[ 8s] INSTALLED VERSIONS
[ 8s] ------------------
[ 8s] commit : a671b5a8bf5dd13fb19f0e88edc679bc9e15c673
[ 8s] python : 3.11.6.final.0
[ 8s] python-bits : 64
[ 8s] OS : Linux
[ 8s] OS-release : 6.6.6-1-default
[ 8s] Version : #1 SMP PREEMPT_DYNAMIC Mon Dec 11 09:46:39 UTC 2023 (a946a9f)
[ 8s] machine : x86_64
[ 8s] processor : x86_64
[ 8s] byteorder : little
[ 8s] LC_ALL : en_US.UTF-8
[ 8s] LANG : en_US.UTF-8
[ 8s] LOCALE : en_US.UTF-8
[ 8s]
[ 8s] pandas : 2.1.4
[ 8s] numpy : 1.26.2
[ 8s] pytz : 2023.3.post1
[ 8s] dateutil : 2.8.2
[ 8s] setuptools : 69.0.3
[ 8s] pip : 23.3.2
[ 8s] Cython : 0.29.36
[ 8s] pytest : 7.4.4
[ 8s] hypothesis : 6.92.1
[ 8s] sphinx : None
[ 8s] blosc : None
[ 8s] feather : None
[ 8s] xlsxwriter : None
[ 8s] lxml.etree : None
[ 8s] html5lib : None
[ 8s] pymysql : None
[ 8s] psycopg2 : None
[ 8s] jinja2 : None
[ 8s] IPython : None
[ 8s] pandas_datareader : None
[ 8s] bs4 : None
[ 8s] bottleneck : None
[ 8s] dataframe-api-compat: None
[ 8s] fastparquet : None
[ 8s] fsspec : None
[ 8s] gcsfs : None
[ 8s] matplotlib : None
[ 8s] numba : None
[ 8s] numexpr : None
[ 8s] odfpy : None
[ 8s] openpyxl : None
[ 8s] pandas_gbq : None
[ 8s] pyarrow : None
[ 8s] pyreadstat : None
[ 8s] pyxlsb : None
[ 8s] s3fs : None
[ 8s] scipy : None
[ 8s] sqlalchemy : None
[ 8s] tables : None
[ 8s] tabulate : None
[ 8s] xarray : None
[ 8s] xlrd : None
[ 8s] zstandard : None
[ 8s] tzdata : None
[ 8s] qtpy : None
[ 8s] pyqt5 : None
[ 8s] None
[ 8s] + xvfb-run pytest-3.11 -vvv -rsfE -n0 -m 'not (network or clipboard or single_cpu)' -k 'not (test_pivot_number_of_levels_larger_than_int32 or psycopg2_engine or psycopg2_conn or pymysql_engine or pymysql_conn or test_git_version)' pandas
[ 12s] ============================= test session starts ==============================
[ 12s] platform linux -- Python 3.11.6, pytest-7.4.4, pluggy-1.3.0 -- /usr/bin/python3.11
[ 12s] cachedir: .pytest_cache
[ 12s] hypothesis profile 'ci' -> deadline=None, suppress_health_check=[HealthCheck.too_slow, HealthCheck.differing_executors], database=DirectoryBasedExampleDatabase(PosixPath('/home/abuild/rpmbuild/BUILD/pandas-2.1.4/.hypothesis/examples'))
[ 12s] rootdir: /home/abuild/rpmbuild/BUILD/pandas-2.1.4/pandas
[ 12s] configfile: pyproject.toml
[ 12s] plugins: asyncio-0.23.3, xdist-3.5.0, hypothesis-6.92.1
[ 12s] asyncio: mode=Mode.STRICT
[ 12s] collecting ... collected 0 items
[ 12s] INTERNALERROR> Traceback (most recent call last):
[ 12s] INTERNALERROR> File "/usr/lib/python3.11/site-packages/_pytest/python.py", line 617, in _importtestmodule
[ 12s] INTERNALERROR> mod = import_path(self.path, mode=importmode, root=self.config.rootpath)
[ 12s] INTERNALERROR> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[ 12s] INTERNALERROR> File "/usr/lib/python3.11/site-packages/_pytest/pathlib.py", line 567, in import_path
[ 12s] INTERNALERROR> importlib.import_module(module_name)
[ 12s] INTERNALERROR> File "/usr/lib64/python3.11/importlib/__init__.py", line 126, in import_module
[ 12s] INTERNALERROR> return _bootstrap._gcd_import(name[level:], package, level)
[ 12s] INTERNALERROR> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[ 12s] INTERNALERROR> File "<frozen importlib._bootstrap>", line 1204, in _gcd_import
[ 12s] INTERNALERROR> File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
[ 12s] INTERNALERROR> File "<frozen importlib._bootstrap>", line 1147, in _find_and_load_unlocked
[ 12s] INTERNALERROR> File "<frozen importlib._bootstrap>", line 690, in _load_unlocked
[ 12s] INTERNALERROR> File "<frozen importlib._bootstrap_external>", line 940, in exec_module
[ 12s] INTERNALERROR> File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
[ 12s] INTERNALERROR> File "/home/abuild/rpmbuild/BUILD/pandas-2.1.4/pandas/core/_numba/kernels/__init__.py", line 1, in <module>
[ 12s] INTERNALERROR> from pandas.core._numba.kernels.mean_ import (
[ 12s] INTERNALERROR> File "/home/abuild/rpmbuild/BUILD/pandas-2.1.4/pandas/core/_numba/kernels/mean_.py", line 13, in <module>
[ 12s] INTERNALERROR> import numba
[ 12s] INTERNALERROR> ModuleNotFoundError: No module named 'numba'
[ 12s] INTERNALERROR>
[ 12s] INTERNALERROR> The above exception was the direct cause of the following exception:
[ 12s] INTERNALERROR>
[ 12s] INTERNALERROR> Traceback (most recent call last):
[ 12s] INTERNALERROR> File "/usr/lib/python3.11/site-packages/_pytest/main.py", line 271, in wrap_session
[ 12s] INTERNALERROR> session.exitstatus = doit(config, session) or 0
[ 12s] INTERNALERROR> ^^^^^^^^^^^^^^^^^^^^^
[ 12s] INTERNALERROR> File "/usr/lib/python3.11/site-packages/_pytest/main.py", line 324, in _main
[ 12s] INTERNALERROR> config.hook.pytest_collection(session=session)
[ 12s] INTERNALERROR> File "/usr/lib/python3.11/site-packages/pluggy/_hooks.py", line 493, in __call__
[ 12s] INTERNALERROR> return self._hookexec(self.name, self._hookimpls, kwargs, firstresult)
[ 12s] INTERNALERROR> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[ 12s] INTERNALERROR> File "/usr/lib/python3.11/site-packages/pluggy/_manager.py", line 115, in _hookexec
[ 12s] INTERNALERROR> return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
[ 12s] INTERNALERROR> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[ 12s] INTERNALERROR> File "/usr/lib/python3.11/site-packages/pluggy/_callers.py", line 152, in _multicall
[ 12s] INTERNALERROR> return outcome.get_result()
[ 12s] INTERNALERROR> ^^^^^^^^^^^^^^^^^^^^
[ 12s] INTERNALERROR> File "/usr/lib/python3.11/site-packages/pluggy/_result.py", line 114, in get_result
[ 12s] INTERNALERROR> raise exc.with_traceback(exc.__traceback__)
[ 12s] INTERNALERROR> File "/usr/lib/python3.11/site-packages/pluggy/_callers.py", line 77, in _multicall
[ 12s] INTERNALERROR> res = hook_impl.function(*args)
[ 12s] INTERNALERROR> ^^^^^^^^^^^^^^^^^^^^^^^^^
[ 12s] INTERNALERROR> File "/usr/lib/python3.11/site-packages/_pytest/main.py", line 335, in pytest_collection
[ 12s] INTERNALERROR> session.perform_collect()
[ 12s] INTERNALERROR> File "/usr/lib/python3.11/site-packages/_pytest/main.py", line 675, in perform_collect
[ 12s] INTERNALERROR> self.items.extend(self.genitems(node))
[ 12s] INTERNALERROR> File "/usr/lib/python3.11/site-packages/_pytest/main.py", line 842, in genitems
[ 12s] INTERNALERROR> rep = collect_one_node(node)
[ 12s] INTERNALERROR> ^^^^^^^^^^^^^^^^^^^^^^
[ 12s] INTERNALERROR> File "/usr/lib/python3.11/site-packages/_pytest/runner.py", line 546, in collect_one_node
[ 12s] INTERNALERROR> ihook.pytest_collectstart(collector=collector)
[ 12s] INTERNALERROR> File "/usr/lib/python3.11/site-packages/pluggy/_hooks.py", line 493, in __call__
[ 12s] INTERNALERROR> return self._hookexec(self.name, self._hookimpls, kwargs, firstresult)
[ 12s] INTERNALERROR> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[ 12s] INTERNALERROR> File "/usr/lib/python3.11/site-packages/pluggy/_manager.py", line 115, in _hookexec
[ 12s] INTERNALERROR> return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
[ 12s] INTERNALERROR> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[ 12s] INTERNALERROR> File "/usr/lib/python3.11/site-packages/pluggy/_callers.py", line 113, in _multicall
[ 12s] INTERNALERROR> raise exception.with_traceback(exception.__traceback__)
[ 12s] INTERNALERROR> File "/usr/lib/python3.11/site-packages/pluggy/_callers.py", line 77, in _multicall
[ 12s] INTERNALERROR> res = hook_impl.function(*args)
[ 12s] INTERNALERROR> ^^^^^^^^^^^^^^^^^^^^^^^^^
[ 12s] INTERNALERROR> File "/usr/lib/python3.11/site-packages/pytest_asyncio/plugin.py", line 626, in pytest_collectstart
[ 12s] INTERNALERROR> pyobject = collector.obj
[ 12s] INTERNALERROR> ^^^^^^^^^^^^^
[ 12s] INTERNALERROR> File "/usr/lib/python3.11/site-packages/_pytest/python.py", line 310, in obj
[ 12s] INTERNALERROR> self._obj = obj = self._getobj()
[ 12s] INTERNALERROR> ^^^^^^^^^^^^^^
[ 12s] INTERNALERROR> File "/usr/lib/python3.11/site-packages/_pytest/python.py", line 528, in _getobj
[ 12s] INTERNALERROR> return self._importtestmodule()
[ 12s] INTERNALERROR> ^^^^^^^^^^^^^^^^^^^^^^^^
[ 12s] INTERNALERROR> File "/usr/lib/python3.11/site-packages/_pytest/python.py", line 642, in _importtestmodule
[ 12s] INTERNALERROR> raise self.CollectError(
[ 12s] INTERNALERROR> _pytest.nodes.Collector.CollectError: ImportError while importing test module '/home/abuild/rpmbuild/BUILD/pandas-2.1.4/pandas/core/_numba/kernels/__init__.py'.
[ 12s] INTERNALERROR> Hint: make sure your test modules/packages have valid Python names.
[ 12s] INTERNALERROR> Traceback:
[ 12s] INTERNALERROR> /usr/lib/python3.11/site-packages/_pytest/python.py:617: in _importtestmodule
[ 12s] INTERNALERROR> mod = import_path(self.path, mode=importmode, root=self.config.rootpath)
[ 12s] INTERNALERROR> /usr/lib/python3.11/site-packages/_pytest/pathlib.py:567: in import_path
[ 12s] INTERNALERROR> importlib.import_module(module_name)
[ 12s] INTERNALERROR> /usr/lib64/python3.11/importlib/__init__.py:126: in import_module
[ 12s] INTERNALERROR> return _bootstrap._gcd_import(name[level:], package, level)
[ 12s] INTERNALERROR> <frozen importlib._bootstrap>:1204: in _gcd_import
[ 12s] INTERNALERROR> ???
[ 12s] INTERNALERROR> <frozen importlib._bootstrap>:1176: in _find_and_load
[ 12s] INTERNALERROR> ???
[ 12s] INTERNALERROR> <frozen importlib._bootstrap>:1147: in _find_and_load_unlocked
[ 12s] INTERNALERROR> ???
[ 12s] INTERNALERROR> <frozen importlib._bootstrap>:690: in _load_unlocked
[ 12s] INTERNALERROR> ???
[ 12s] INTERNALERROR> <frozen importlib._bootstrap_external>:940: in exec_module
[ 12s] INTERNALERROR> ???
[ 12s] INTERNALERROR> <frozen importlib._bootstrap>:241: in _call_with_frames_removed
[ 12s] INTERNALERROR> ???
[ 12s] INTERNALERROR> pandas/core/_numba/kernels/__init__.py:1: in <module>
[ 12s] INTERNALERROR> from pandas.core._numba.kernels.mean_ import (
[ 12s] INTERNALERROR> pandas/core/_numba/kernels/mean_.py:13: in <module>
[ 12s] INTERNALERROR> import numba
[ 12s] INTERNALERROR> E ModuleNotFoundError: No module named 'numba'
[ 12s]
[ 12s] ============================ no tests ran in 0.58s ============================= |
@seifertm Thanks for your efforts in triaging this. I see you added this ticket to the v0.23 milestone. Does that mean you aim to address it sometime soon? I'm just trying to determine whether we should give it some more time, or start looking for a longer term workaround. |
@sanderr i'm not entirely sure what a longer-term workaround would look like (?) I've had a look around, but it doesn't seem that there's alternative plugins that provide the same functionality. |
I have to confess that I haven't given it a lot of thought yet, but at least for my scenario I guess it would be possible (albeit through a bit of a hack) to not use I agree there's no urgent need to upgrade for now, but I also don't want to lag behind indefinitely. Therefore, if this turns out to be considered a low-priority issue, I might consider trying to work around it from our side, rather than to keep the pinned version. This would allow us to keep moving forward now, rather than if/when a need to upgrade does pop up. Don't get me wrong, I'd much prefer it if it the old behavior would be restored, but that doesn't necessarily mean that the maintainer(s?) feel the same, or that it fits their agenda, hence the question. |
@xmatthias The concept of scoped event loops essentially requires generating pytest fixtures dynamically, depending on the structure of the test suite. This is a feature that's currently not supported in pytest. The current workaround, which is also used by pytest internally for calling things such as Accessing a the Starting from pytest v8, @sanderr In my opinion, a pytest plugin should not change the way tests are collected and the old behaviour should be restored. I'm planning to do this in a patch release for v0.23. I don't think you should have to look into changes of your test suite, because of this issue. I set aside some time for pytest-asyncio this weekend, but I cannot promise I will resolve this issue then. I'm sorry the 0.23 releases are causing so many problems, but currently my support of pytest-asyncio happens on a best-effort basis in my free time. As for alternative testing packages, there's anyio, which comes with a pytest-plugin. I have no experience how much effort it is to migrate to anyio, though. |
Thanks for the update. I understand that you can not provide any guarantees with respect to the timeline but it's good to have rough idea of how and when this will move forward. That's all I was after at this point. Thank you for looking into this, and for the clear communication. |
@sanderr @xmatthias @bnavigator For example, I tested the bcrypt test suite based on the instructions that @mgorny provided in #738 and the tests pass with v0.23.4a0, whereas the crashed with a different 0.23 version. |
I can confirm that the pandas test suite now sucessfully collects the tests in the minimal environment: Pandas environment and pytest header
|
Here's what I'm seeing with 0.23.4a0: https://github.com/blink1073/ipykernel/actions/runs/7469345207/job/20326312710?pr=1 |
Hi @seifertm, Thanks for this - the test that was failing (in my case, the MacOS version of our CI) is working fine now (previous errors: https://github.com/freqtrade/freqtrade/actions/runs/7442875401). With the new alpha version - i'm now getting a (new) failure on Windows which i don't quite understand - but is most likely windows specific, and based on your idea posted above, most likely caused by the new virtual module that's being added. Link to the Actions run: https://github.com/xmatthias/freqtrade/actions/runs/7471096789/job/20330820415 Error on Windows
edit seems to be a similar error / identical than the one posted by @blink1073 above ... |
Thanks. I can confirm that the issue I observed on our test suite is fixed with version |
Thank you for your feedback! There are still problems when running on Windows due to platform specific behavior of @xmatthias @blink1073 I tagged the pre-release v0.23.4.a1 which you can use for testing. If you can verify that it also works for you, I'll tag v0.23.4 |
@seifertm thanks a lot for your efforts! the v0.23.4.a1 release seems to work fine now! 👍 https://github.com/xmatthias/freqtrade/actions/runs/7479730385/job/20357544175 |
v23.4.a1 is failing for a different reason: https://github.com/blink1073/ipykernel/actions/runs/7480301750/job/20359431173?pr=1 |
After upgrading from 0.23.3 to 0.23.4a1, I'm seeing random packages failing with pytest-xdist with errors like:
Example log (from setuptools): dev-python:setuptools-69.0.3:20240111-191012.log |
…c package-scoped fixtures. The temporary files used for this mechanism appearing as disappear after they have been collected. This seems to create issues in some projects, such as setuptools. see pytest-dev#729 (comment) Signed-off-by: Michael Seifert <[email protected]>
…c package-scoped fixtures. The temporary files used for this mechanism appearing as disappear after they have been collected. This seems to create issues in some projects, such as setuptools. see #729 (comment) Signed-off-by: Michael Seifert <[email protected]>
…c package-scoped fixtures. The temporary files used for this mechanism appearing as disappear after they have been collected. This seems to create issues in some projects, such as setuptools. see #729 (comment) Signed-off-by: Michael Seifert <[email protected]>
I created another pre-release (v0.23.4a2) which no longer creates temporary files during test runs. The dynamic package-scoped fixtures are now attached to the first test module in each package. This should eliminate any issues with test suites that rely on a specific set of collected items (I assume this is the issue for setuptools). I tested the pre-release against ipythonkernel and bcrypt successfully. One other user also confirmed that the code fixes their INTERNALERROR. I'll tag a proper patch release by the end of the week, unless I receive any further reports regarding this issue. |
Thanks a lot. I've just tested it with known suspects, and I'll be running it doing version bumps for the next days. I'll let you know if I hit something else. |
The 2nd pre-release appears to work fine on all OS's, from python 3.9 to python 3.12. 👍 |
I'm very sorry but I've found another regression.
|
Good catch! I made yet another change to the test collection that seems to fix the issue. Rather than another pre-release, I did a proper release of v0.23.4, because pytest 8 has been released and older pytest-asyncio version don't have proper upper bounds on the pytest version. |
Hello, I think there's still a problem as of
then this raises an ImportError during test collection. When I downgrade to (Sorry if this is not entirely relevant, I didn't read the entire thread) |
In our case it is actually causing issues. In short, we have Python files in our tests dir that should only be loaded in a specific context. I'll elaborate in more detail below. We could probably work around it if we need to, but for now we have pinned pytest-asyncio to the previous version until this discussion reaches a conclusion.
Our specifix use case: we are developing a Python project with a plugin system. Put simply, these plugins are Python packages that register themselves at load time. They are expected to be loaded by a custom importlib finder/loader and they do not work as standalone package.
Since this plugin system is an integral part of the application we're developing, we test their behavior thoroughly. Therefore we have a bunch of these plugin "packages" as resources underneath our
tests
directory. They are meant as nothing more than data: our application will find and load them when appropriate. They will raise an error when loaded as a standalone package, which pytest v0.23 now does.Originally posted by @sanderr in #713 (comment)
The text was updated successfully, but these errors were encountered: