GeezerVison is showing github.com — Make `Path` subscriptable · Issue #139270 · python/cpython
Make Path subscriptable #139270DescriptionFeature or enhancement
Proposal:
Path should be subscriptable so I can select components, e.g.
# Add a code block here, if required
In [5]: x = Path("hello/there/general/kenobi")
In [6]: x[0:1] == Path("hello/there")
# Returns true
(This is a more convenient alternative to .parts, which returns a tuple of strings I have to reassemble into a path.)
Has this already been discussed elsewhere?
This is a minor feature, which does not need previous discussion elsewhere
Links to previous discussion of this feature:
No response Activitympkocher commented on Sep 24, 2025 To be explicit, the workarounds are:
In [1]: x = Path("hello/there/general/kenobi")
In [2]: x.parents[1]
Out[2]: PosixPath('hello/there')
In [3]: Path(*x.parts[0:2])
Out[3]: PosixPath('hello/there')
Adding subscripting might be useful, but it also could be adding entropy.
Several of the current methods/accessors (e.g,. name, root) return a string instead of Path.
Not sure if encouraging different access patterns, such as x[-1] instead of x.name based on the expected return of a str or Path is a good idea.
For example, with x = Path("/a/b/c.txt" using x.root (returns str) instead of x[0] (returns Path). Similarly, x.name instead of x[-1] -> Path("c.txt") with __getitem__ mechanics.
For example:
In [1]: from pathlib import Path
In [2]: p = Path("/a/b/c.txt")
In [3]: p.root
Out[3]: '/'
In [4]: p.name
Out[4]: 'c.txt'
In [5]: # p[0] -> PosixPath("/")
In [6]: # p[-1] -> PosixPath("c.txt")
In [8]: p.parents[-1]
Out[8]: PosixPath('/')
Interesting feature request idea, but the workaround Path(*x.parts[0:3])) is pretty straightforward. Reacted by Barney Gale and sobolevn sobolevn commented on Sep 24, 2025 For me this looks a bit too magical. I would not want to associtate numbers with path components. For example: x = Path('/a') and x = Path('C:\\a'). What would x[0] be in these cases?
Further more, it is also not really clear from the code that Path('a/b')[0] returns Path('a') because it is also kinda expected to return 'a', because of 'a/b'[0] expectations.
I don't see a big problem in using Path(*Path('a/b').parts[0:1]), it is clear, short and fast. Reacted by Sergey Miryanov, yihong, W. H. Wang, Bénédikt Tran and Barney Gale picnixz commented on Sep 24, 2025 barneygale commented on Sep 24, 2025
Several of the current methods/accessors (e.g,. name, root) return a string instead of Path.
To expand on this a bit:
pathlib usually treats relative paths as relative to the current directory, not just free-floating partial paths. If my working directory is /home/barney and I have p = Path('.local/share'), any operations I perform on p should only generate Path objects that also make sense relative to the same working directory. So p.parent generates a Path object because Path('.local') still makes sense, but p.name generates a str because Path('share') wouldn't. There are exceptions, e.g. p.relative_to().
Allowing arbitrary slices that generate Paths would break this rule. It would be fine if we insisted that slices start at 0, but at that point you may as well use path.parents.
There's maybe an argument for a path.lineage attribute that works like path.parents but in reverse and including self at the end. So in my previous example, p.lineage == (Path(), Path('.local'), Path('.local/share')). But that's for the forum if someone wants to pursue it :)
MetadataMetadataDevelopmentNo branches or pull requestsIssue actions
|