pytest-mypy
pytest-mypy copied to clipboard
v1.0.0: `FileNotFoundError: [Errno 2] No such file or directory` on Windows, Python 3.9
This doesn't affect Python 3.13 or other OSes. Other Python versions on Windows (3.10, 3.11, 3.12) untested.
_____________________________ [mypy] conftest.py ______________________________
[gw0] win32 -- Python 3.9.13 D:\a\setuptools\setuptools\.tox\py\Scripts\python.EXE
cls = <class 'pytest_mypy.MypyResults'>
session = <Session exitstatus=<ExitCode.OK: 0> testsfailed=0 testscollected=1725>
@classmethod
def from_session(cls, session: pytest.Session) -> MypyResults:
"""Load (or generate) cached mypy results for a pytest session."""
mypy_results_path = session.config.stash[stash_key["config"]].mypy_results_path
with FileLock(str(mypy_results_path) + ".lock"):
try:
> with open(mypy_results_path, mode="rb") as results_f:
E FileNotFoundError: [Errno 2] No such file or directory: 'C:\\Users\\RUNNER~1\\AppData\\Local\\Temp\\tmpz7dkhc13'
.tox\py\lib\site-packages\pytest_mypy\__init__.py:385: FileNotFoundError
Full logs:
- https://github.com/pypa/setuptools/actions/runs/14180052613/job/39786912967?pr=4931#step:11:63
- https://github.com/pypa/distutils/actions/runs/14137799549/job/39613515503?pr=338#step:6:139
🤔 Looks like this is actual the error:
cls = <class 'pytest_mypy.MypyResults'>
session = <Session exitstatus=<ExitCode.OK: 0> testsfailed=0 testscollected=1725>
@classmethod
def from_session(cls, session: pytest.Session) -> MypyResults:
"""Load (or generate) cached mypy results for a pytest session."""
mypy_results_path = session.config.stash[stash_key["config"]].mypy_results_path
with FileLock(str(mypy_results_path) + ".lock"):
try:
with open(mypy_results_path, mode="rb") as results_f:
results = cls.load(results_f)
except FileNotFoundError:
cwd = Path.cwd()
> results = cls.from_mypy(
[
item.path.relative_to(cwd)
for item in session.items
if isinstance(item, MypyFileItem)
],
)
.tox\py\lib\site-packages\pytest_mypy\__init__.py:389:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cls = <class 'pytest_mypy.MypyResults'>
paths = [WindowsPath('conftest.py'), WindowsPath('docs/conf.py'), WindowsPath('exercises.py'), WindowsPath('pkg_resources/__in...'), WindowsPath('pkg_resources/tests/__init__.py'), WindowsPath('pkg_resources/tests/test_find_distributions.py'), ...]
@classmethod
def from_mypy(
cls,
paths: List[Path],
*,
opts: Optional[List[str]] = None,
) -> MypyResults:
"""Generate results from mypy."""
if opts is None:
opts = mypy_argv[:]
args = [str(path) for path in paths]
stdout, stderr, status = mypy.api.run(opts + args)
path_lines: Dict[Optional[Path], List[str]] = {
path.resolve(): [] for path in paths
}
path_lines[None] = []
for line in stdout.split("\n"):
if not line:
continue
> path = Path(line.partition(":")[0]).resolve()
.tox\py\lib\site-packages\pytest_mypy\__init__.py:363:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = WindowsPath('\x1b[1m\x1b[92mSuccess'), strict = False
def resolve(self, strict=False):
"""
Make the path absolute, resolving all symlinks on the way and also
normalizing it (for example turning slashes into backslashes under
Windows).
"""
> s = self._flavour.resolve(self, strict=strict)
C:\hostedtoolcache\windows\Python\3.9.13\x64\lib\pathlib.py:1215:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <pathlib._WindowsFlavour object at 0x00000181FCDADC10>
path = WindowsPath('\x1b[1m\x1b[92mSuccess'), strict = False
def resolve(self, path, strict=False):
s = str(path)
if not s:
return os.getcwd()
previous_s = None
if _getfinalpathname is not None:
if strict:
return self._ext_to_normal(_getfinalpathname(s))
else:
tail_parts = [] # End of the path after the first one not found
while True:
try:
> s = self._ext_to_normal(_getfinalpathname(s))
E OSError: [WinError 123] The filename, directory name, or volume label syntax is incorrect: '\x1b[1m\x1b[92mSuccess'
C:\hostedtoolcache\windows\Python\3.9.13\x64\lib\pathlib.py:215: OSError
Ah...
for line in stdout.split("\n"):
if not line:
continue
> path = Path(line.partition(":")[0]).resolve()
.tox\py\lib\site-packages\pytest_mypy\__init__.py:363:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = WindowsPath('\x1b[1m\x1b[92mSuccess'), strict = False
Looks like we're taking the success line e.g.
$ mypy demo/good.py
Success: no issues found in 1 source file
(which is green)
$ MYPY_FORCE_COLOR=1 venv/bin/mypy demo/good.py | cat -v
^[[1m^[[32mSuccess: no issues found in 1 source file^[(B^[[m
and trying to .resolve() it as a Path (fine, but should be try-ed).
Thanks for the report! I'll have a fix tomorrow.
Fixed in v1.0.1