pathlib: Path('.').exists() returns True when current working directory (cwd) was deleted
还没有人认领这个 Issue。
- 主要语言
- Python
- 星标
- 77.2k
- 派生
- 36k
- PR 合并指标
- PR 指标待抓取
描述
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:
Path('.').exists()andPath('').exists()should not tell you a path exists that doesn't.Path('foo').resolve()should not raise aFileNotFoundErrorif the cwd doesn't exist, unlessstrict=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
贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
调研方向
从 pathlib/_local.py 中的 Path.exists() 和 Path.resolve() 开始,然后跟踪当前工作目录已被删除时它们对相对路径使用 os.path.realpath 的情况。比较 '.', '' 和 'foo' 的报告行为;当 exists() 不再报告已删除的当前工作目录,并且 resolve() 仅在 strict=True 时引发 FileNotFoundError 时,即表示完成,gh-135531 表明相关工作已经在进行中。
由索引模型根据 Issue 内容生成。
评估
- 技术栈
- python
- 领域
- operating-systems
- Issue 类型
- 缺陷
- 难度
- 3/5
- 预计耗时
- 1-2 天
- 活跃度
- 停滞
- 描述清晰度
- 基本清楚
- 新手友好度
- 25/100