Skip to content

Support for detecting the flavour of pathlib subclasses #100502

Closed

Description

@barneygale

Feature or enhancement

Provide a way of checking whether a user subclass of pathlib.PurePath and Path uses POSIX or Windows semantics

The Problem

Now that #68320 is resolved, users can subclass pathlib.PurePath and Path directly:

import pathlib

class MyPath(pathlib.Path):
    pass

path = MyPath('foo')

However, there's no (public) procedure to detect whether an instance of MyPath uses POSIX or Windows semantics.

A non-public way of doing it:

path._flavour is posixpath  # Check whether the path object uses POSIX semantics
path._flavour is ntpath  # Check whether the path uses Windows semantics
path._flavour is os.path  # Check whether the path uses the current OS's semantics

Note that checking isinstance(path, PurePosixPath) (etc) won't work, as user subclasses of PurePath and Path do not have the POSIX- and Windows-specific subclasses in their class hierarchy.

The Proposal

Make the _flavour attribute public; document it. Possible names:

  • flavour (simply remove the underscore)
  • pathmod (used internally in older pathlib versions)
  • module (used in the longstanding thirdparty path package)

Alternatives

We could make the PurePosixPath and PureWindowsPath classes 'protocols', which support isinstance() checks even when the passed object isn't a conventional subclass. But:

  1. The implementation will be more complex
  2. It could open a can of worms about whether PurePosixPath and PureWindowsPath should be proper protocols, and not directly instantiable.

A further alternative would be to add an is_posix() method, which gels pretty nicely with the existing is_*() and as_posix() methods.

Linked PRs

Activity

  1. added 3 commits that reference this issue on Jul 7, 2023
  2. merwok commented on Jul 8, 2023

    @merwok
    Member

    pathmod is not a bad name! It makes it clear that the value is (normally) one of the path modules, and Python being Python it doesn’t prevent someone using another kind of object for custom needs.

    flavour is a bit more vague but okay; accessor is also available!

  3. merwok commented on Jul 8, 2023

    @merwok
    Member

    About is_posix: I don’t think the name is clear enough. Without reading docs, it could be interpreted as a question about the current platform, or the path module, or a check for some posix spec conformity, or even a question about the form of the paths?!
    But maybe my worry is unfounded and it would be fine, we have os.name == 'posix' and os.path is posixpath.

  4. barneygale commented on Jul 8, 2023

    @barneygale
    ContributorAuthor

    Thanks for the feedback! pathmod sounds good to me. It occurs to me that the pathlib documentation already refers to PureWindowsPath, PurePosixPath etc as "flavours", and so re-using that term could be confusing.

    Agree also on is_posix()

  5. added a commit that references this issue on Jul 19, 2023
  6. barneygale commented on Jul 19, 2023

    @barneygale
    ContributorAuthor

    Implemented in c6c5665 / #106533

  7. barneygale commented on Dec 19, 2023

    @barneygale
    ContributorAuthor

    @merwok I'm beginning to have doubts about the solution I implemented. I think the new, internal PurePathBase class ought to support syntax customization beyond a fat "NT or POSIX" switch, and that perhaps the path module should be an internal implementation detail of PurePath, rather than an attribute of PurePathBase. Would you mind if I revert #106533? It's only been available in 3.13 alphas so far, so it's safe to do so.

  8. merwok commented on Dec 19, 2023

    @merwok
    Member

    Would you revert to _flavour or keep the new name we came to and mark it private with _pathmod?

  9. barneygale commented on Dec 19, 2023

    @barneygale
    ContributorAuthor

    I think I'd keep the new name and mark it as private with _pathmod

  10. merwok commented on Dec 19, 2023

    @merwok
    Member

    This is related to the ongoing discussions about preserving final slash and follow_symlinks (and co) as implicit parameters, yes?
    You’re thinking that the addition of parameters to track choices for these properties removes or weakens the usefulness of checking that a Path class or subclass uses posix or nt base rules?

    Generally I trust you to shepherd the changes needed to support important features.
    In this case I would suggest that maybe it’s not required to revert right now, as the discussions haven’t reached their conclusions and it’s not clear how the pathlib design should change to move in a good direction.
    The first beta is in May, so pathmod could be hidden, removed or changed between now and then 🙂

    If you still think the attribute should hidden now, then go ahead!

  11. added a commit that references this issue on Dec 19, 2023
  12. barneygale commented on Dec 19, 2023

    @barneygale
    ContributorAuthor

    This is related to the ongoing discussions about preserving final slash and follow_symlinks (and co) as implicit parameters, yes?

    It's related to those discussions, but more directly to the work on pathlib ABCs which has been going on at the same time. There's now a private pathlib._abc module, and though I'm pretty satisfied with the I/O aspects of the PathBase class, I'm much less convinced that the pure aspects of the PurePathBase class are correct, and I expect I'll need to iterate on them over the coming months.

    You’re thinking that the addition of parameters to track choices for these properties removes or weakens the usefulness of checking that a Path class or subclass uses posix or nt base rules?

    Yes that's right.

    Thanks for the advice - I'll follow your suggestion to not revert yet. I appreciate your take on this :)

  13. barneygale commented on Jan 12, 2024

    @barneygale
    ContributorAuthor

    I've played with two approaches:

    1. Moving pathmod from PurePathBase to PurePath, and making some PurePathBase methods directly raise UnsupportedOperation
    2. Keeping PurePathBase.pathmod and changing its value to a new PathModuleBase ABC.

    Both of these have the effect of making PurePathBase methods raise UnsupportedOperation, but the first option is really nasty, as it means PathBase has two sets abstract methods that are largely independent. The second option is uses composition rather than inheritance and works out much nicer. I've put it up as a PR: #113893

    Re-resolving this issue.

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

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions