python / python/cpython

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

Aperta
#127,264 8 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

stdlib topic-pathlib type-bug
Lingua principale
Python
Stelle
77.2k
Fork
36k
Metriche di merge delle PR
Metriche PR in attesa

Descrizione

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

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Direzione di ricerca

Inizia in pathlib/_local.py da Path.exists() e Path.resolve(), quindi segui il loro utilizzo di os.path.realpath per i percorsi relativi quando la directory di lavoro corrente è stata eliminata. Confronta il comportamento osservato per '.', '' e 'foo'; il lavoro è completato quando exists() non segnala più la directory di lavoro corrente eliminata e resolve() solleva FileNotFoundError solo con strict=True, mentre gh-135531 indica che il lavoro correlato è già in corso.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
python
Ambito
operating-systems
Tipo di issue
Bug
Difficoltà
3/5
Tempo stimato
1-2 giorni
Stato di attività
Ferma
Chiarezza
Abbastanza chiara
Idoneità per principianti
25/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.