Skip to content

Make Path subscriptable #139270

Description

@ParadaCarleton

Feature 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

Activity

  1. mpkocher commented on Sep 24, 2025

    @mpkocher
    Contributor

    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.

  2. sobolevn commented on Sep 24, 2025

    @sobolevn
    Member

    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.

  3. picnixz commented on Sep 24, 2025

    @picnixz
    Member

    I'm also -1. I'm going to close this as not planned. In the future, please consider opening a thread on https://discuss.python.org/c/ideas/6 first.

  4. barneygale commented on Sep 24, 2025

    @barneygale
    Contributor

    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 :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    stdlibStandard Library Python modules in the Lib/ directorytopic-pathlibtype-featureA feature request or enhancement

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions