python / python/cpython

pathlib: Path('.').exists() returns True when current working directory (cwd) was deleted

Offen
#127,264 8 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

stdlib topic-pathlib type-bug
Vorherrschende Sprache
Python
Sterne
77.2k
Forks
35.9k
PR-Merge-Kennzahlen
PR-Kennzahlen ausstehend

Beschreibung

Bug report

Bug description:

Path.exists() and Path.resolve() do not work consistently with each other if the current working directory is deleted after Python is launched.

For example, if I open a Python 3.13.0 interpreter (although I have verified this occurs in older versions as well) in a directory, and then delete that directory I experience the following behavior:

>>> from pathlib import Path
>>> Path('.').exists()
True
>>> Path('.').resolve()
Traceback (most recent call last):
  File "<python-input-2>", line 1, in <module>
    Path('.').resolve()
    ~~~~~~~~~~~~~~~~~^^
  File "/opt/homebrew/Caskroom/mambaforge/base/envs/py313minimal/lib/python3.13/pathlib/_local.py", line 670, in resolve
    return self.with_segments(os.path.realpath(self, strict=strict))
                              ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^
  File "<frozen posixpath>", line 413, in realpath
FileNotFoundError: [Errno 2] No such file or directory

Note how Path('.').exists() is True, even though the cwd does not exist, and then when I try to resolve the path, I get a FileNotFoundError.

You also get a FileNotFoundError when the cwd doesn't exist for all relative paths, even though in the non-dot cases Path.exists() works as one would expect.

>>> Path('asdf').exists()
False
>>> Path('asdf').resolve().exists()
Traceback (most recent call last):
  File "<python-input-4>", line 1, in <module>
    Path('asdf').resolve().exists()
    ~~~~~~~~~~~~~~~~~~~~^^
  File "/opt/homebrew/Caskroom/mambaforge/base/envs/py313minimal/lib/python3.13/pathlib/_local.py", line 670, in resolve
    return self.with_segments(os.path.realpath(self, strict=strict))
                              ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^
  File "<frozen posixpath>", line 413, in realpath
FileNotFoundError: [Errno 2] No such file or directory

If the cwd does exist, you can see that Path.resolve() does not raise a FileNotFoundError when the path does not exist.

>>> from pathlib import Path
>>> Path('asdf').exists()
False
>>> Path('asdf').resolve()
PosixPath('/Users/danielblanchard/asdf')

I believe resolve is doing the right thing here, but two things are not working as expected when the cwd is deleted:

  1. Path('.').exists() and Path('').exists() should not tell you a path exists that doesn't.
  2. Path('foo').resolve() should not raise a FileNotFoundError if the cwd doesn't exist, unless strict=True. Instead it should just return the initial path.
CPython versions tested on:

3.9, 3.12, 3.13

Operating systems tested on:

Linux, macOS

Linked PRs
  • gh-135531

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Beginne in pathlib/_local.py bei Path.exists() und Path.resolve(), und verfolge anschließend ihre Verwendung von os.path.realpath für relative Pfade, wenn das aktuelle Arbeitsverzeichnis gelöscht wurde. Vergleiche das berichtete Verhalten für '.', '' und 'foo'; abgeschlossen ist die Arbeit, wenn exists() das gelöschte aktuelle Arbeitsverzeichnis nicht mehr meldet und resolve() nur unter strict=True FileNotFoundError auslöst, wobei gh-135531 darauf hinweist, dass verwandte Arbeiten bereits im Gange sind.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
python
Bereich
operating-systems
Issue-Typ
Bug
Schwierigkeit
3/5
Geschätzter Aufwand
1-2 Tage
Aktivitätsstatus
Veraltet
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
25/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.