python / python/cpython

`os.path.realpath` (and possibly others) ignore the special POSIX-meaning of absolute pathnames that start with exactly two `/`?

未关闭
#138,139 7 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

pending stdlib
主要语言
Python
星标
77.2k
派生
36k
PR 合并指标
PR 指标待抓取

描述

Bug report

Bug description:

Hey.

As requested in #134639 moving the issue mentioned there to a separate bug.

POSIX defines that absolute pathnames that start with exactly (and only) two / are special:

If a pathname begins with two successive characters, the first component following the leading characters may be interpreted in an implementation-defined manner, although more than two leading characters shall be treated as a single character.

That is /foo, ///foo, ////foo, etc. are (normalised) all the same as /foo, but //foo is not necessarily (it's implementation-defined whether or not, so it actually may be and e.g. Linux indeed seems to consider it also the same, though I haven't verified whether it really is in all cases).

At least os.path.realpath seems to ignore that however:

>>> os.path.realpath("/foo")
'/foo'

>>> os.path.realpath("///foo")
'/foo'

>>> os.path.realpath("//foo")
'/foo'

while some Python library parts do in fact account for this, e.g.:

>>> pathlib.Path("//foo").parts
('//', 'foo')

>>> pathlib.Path("/foo").parts
('/', 'foo')

>>> pathlib.Path("///foo").parts
('/', 'foo')

I'm kinda tempted to say that os.path.realpath("//foo") should yield //foo.

Now to me, POSIX is not 100% clear (one should perhaps ask for confirmation at the Austin Group before making any incompatible changes):

I, personally, would interpret the above wording of the standard, that //foo/bar/baz merely indicates that foo (and foo alone) is special (e.g. like what we know from Windows with \\hostname\path) but any further components are not.

This could(would) in turn man that normalisation of any later components does happen as usual, and thus e.g. //foo/bar//baz should be normalised to //foo/bar/baz.

The leading // need of course be retained to indicate that foo is still special.

There is of course some "risk" in changing the current behaviour.

One could e.g. simply make it platform dependent, and e.g. on Linux leave things as is, and only change it for platforms (if any exist) that truly handle //foo special. One should do so only, if e.g. the POSIX/C realpath() would do so, too (on that platform).

But even then, other parts of Python do already handle // special... so in order to keep things homogeneous and compatible, one should perhaps anyway adapt os.path.realpath (and possibly others like .normpath().

Cheers,
Chris.

Thanks,
Chris.

CPython versions tested on:

3.13

Operating systems tested on:

Linux

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

调研方向

先从示例中描述的 os.path.realpath 行为开始,然后检查相关的路径规范化,例如 normpath 和 pathlib.Path.parts。确认对于恰好两个前导斜杠的预期 POSIX 处理方式,以及行为是否应取决于平台。行为确定下来、在适当的地方一致实现,并由回归测试覆盖后,即表示完成。

由索引模型根据 Issue 内容生成。

评估

技术栈
python
领域
operating-systems
Issue 类型
缺陷
难度
4/5
预计耗时
3-5 天
活跃度
停滞
描述清晰度
基本清楚
新手友好度
35/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。