pytest: `python_files=*.py` breaks with Python 3.10

Consider this simple setup (no other files in the directory):

# setup.cfg
[tool:pytest]
python_files=*.py
# broken.py
from requests import certs

def test_foo():
    print(certs.where())

This has worked fine for previous versions of Python. Since 3.10, I’m getting this:

> py.test .
======================================= test session starts =======================================
platform linux -- Python 3.10.0, pytest-6.2.5, py-1.10.0, pluggy-1.0.0
rootdir: /home/trehn/git/aur/python310/venv/frob, configfile: setup.cfg
collected 0 items / 1 error                                                                       

============================================= ERRORS ==============================================
_____________________________________ ERROR collecting broken.py __________________________________
broken.py:1: in <module>
    from requests import certs
<frozen importlib._bootstrap>:1027: in _find_and_load
    ???
<frozen importlib._bootstrap>:1006: in _find_and_load_unlocked
    ???
<frozen importlib._bootstrap>:688: in _load_unlocked
    ???
../lib/python3.10/site-packages/_pytest/assertion/rewrite.py:170: in exec_module
    exec(co, module.__dict__)
../lib/python3.10/site-packages/requests/__init__.py:133: in <module>
    from . import utils
<frozen importlib._bootstrap>:1027: in _find_and_load
    ???
<frozen importlib._bootstrap>:1006: in _find_and_load_unlocked
    ???
<frozen importlib._bootstrap>:688: in _load_unlocked
    ???
../lib/python3.10/site-packages/_pytest/assertion/rewrite.py:170: in exec_module
    exec(co, module.__dict__)
../lib/python3.10/site-packages/requests/utils.py:41: in <module>
    DEFAULT_CA_BUNDLE_PATH = certs.where()
../lib/python3.10/site-packages/certifi/core.py:37: in where
    _CACERT_PATH = str(_CACERT_CTX.__enter__())
/usr/lib/python3.10/contextlib.py:135: in __enter__
    return next(self.gen)
/usr/lib/python3.10/importlib/_common.py:88: in _tempfile
    fd, raw_path = tempfile.mkstemp(suffix=suffix)
/usr/lib/python3.10/tempfile.py:337: in mkstemp
    return _mkstemp_inner(dir, prefix, suffix, flags, output_type)
/usr/lib/python3.10/tempfile.py:249: in _mkstemp_inner
    file = _os.path.join(dir, pre + name + suf)
E   TypeError: can only concatenate str (not "method") to str
----------------------------------------- Captured stdout -----------------------------------------
<class 'method'> <bound method DegenerateFiles.Path.name of <importlib._adapters.DegenerateFiles.Path object at 0x7f1860f59420>>
===================================== short test summary info =====================================
ERROR broken.py - TypeError: can only concatenate str (not "method") to str
!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 1 error during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
======================================== 1 error in 0.29s =========================================

When changing python_files in setup.cfg to anything other than *.py (e.g. b*.py), things work as expected again.

I tried digging into why this happens, but it seems rather involved. The method mentioned in the TypeError is this one:

https://github.com/python/cpython/blob/67148254146948041a77d8a2989f41b88cdb2f99/Lib/importlib/_adapters.py#L49

I’m not sure what DegenerateFiles is and under which circumstances it is used. Also note that it has been removed from Python’s main branch in this commit:

https://github.com/python/cpython/commit/aaa83cdfab6817446285e631232f64b394ac6791

If python_files=*.py is problematic in general, pytest should throw a better error message. But of course I’d prefer it to be fixed since it lets me use shorter filenames when all my tests live in a dedicated directory.

Thanks!

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 16 (12 by maintainers)

Commits related to this issue

Most upvoted comments

I can confirm that this is still happening, but my error is yet another one: a PermissionError for accessing a temporary file that is already being used. Although GH Actions produces the ValueError.

I’m on Windows 10. Taking either requests or *.py out of the equation fixes the error. To (hopefully) reproduce:

# tests/test_requests
import requests
conda create -c conda-forge -n py10 python=3.10.1
conda activate py10
pip install pytest requests
pytest tests (with python_files = "*.py")

Thanks for all the effort so far! But should this issue be reopened?

@jaraco i believe its a bug in the degraded files in import-lib, at first glance name is a method instead of a property,