Closed
Description
Bug report
On Python 3.11.0a7, calling Path.rglob("*.*")
returns an iterator over no files, whereas on previous versions (including alpha 6) it would correctly return an iterator over all files in the directory and all of its children.
The following code illustrates this problem:
import pathlib, tempfile, pprint
with tempfile.TemporaryDirectory() as tmpdir:
tmp_path = pathlib.Path(tmpdir)
(tmp_path / "a.txt").touch()
(tmp_path / "b.txt").touch()
(tmp_path / "c").mkdir()
(tmp_path / "c" / "d.txt").touch()
pprint.pprint(list(tmp_path.rglob("*.*")))
pprint.pprint(list(tmp_path.rglob("*.txt")))
Save this as pathlib_rglob.py
.
Output:
$ python3.11 pathlib_rglob.py
[]
[PosixPath('/tmp/tmpngjo2cyn/a.txt'),
PosixPath('/tmp/tmpngjo2cyn/b.txt'),
PosixPath('/tmp/tmpngjo2cyn/c/d.txt')]
$ python3.10 pathlib_rglob.py
[PosixPath('/tmp/tmpodfbqyhx/a.txt'),
PosixPath('/tmp/tmpodfbqyhx/b.txt'),
PosixPath('/tmp/tmpodfbqyhx/c/d.txt')]
[PosixPath('/tmp/tmpodfbqyhx/a.txt'),
PosixPath('/tmp/tmpodfbqyhx/b.txt'),
PosixPath('/tmp/tmpodfbqyhx/c/d.txt')]
$ # This is Python 3.11.0a6 built from source
$ ~/python311a6/bin/python3.11 pathlib_rglob.py
[PosixPath('/tmp/tmpobellcrw/a.txt'),
PosixPath('/tmp/tmpobellcrw/b.txt'),
PosixPath('/tmp/tmpobellcrw/c/d.txt')]
[PosixPath('/tmp/tmpobellcrw/a.txt'),
PosixPath('/tmp/tmpobellcrw/b.txt'),
PosixPath('/tmp/tmpobellcrw/c/d.txt')]
After much debugging I have tracked the issue to #32029
With that change, fnmatch.translate("*.*")
gives (?s:(?>.*?\.).*)\Z
.
With the change reverted (or on 3.11.0a6) its (?s:(?=(?P<g0>.*?\.))(?P=g0).*)\Z
.
I don't know what the difference between those amounts to, but the former doesn't work while the latter does:
>>> import re
>>> re.fullmatch('(?s:(?>.*?\\.).*)\\Z', "a.txt")
>>> re.fullmatch('(?s:(?=(?P<g0>.*?\\.))(?P=g0).*)\\Z', "a.txt")
<re.Match object; span=(0, 5), match='a.txt'>
Your environment
- CPython versions tested on: 3.10.4, 3.11.0a6, 3.11.0a7, built from git checkouts of the relevant tag.
- Operating system and architecture: Ubuntu 20.04 amd64