Pattern matching and Paths

I was writing a tutorial on pattern matching, and I thought matching against paths would be useful. My first thought was str(x), then I thought about PathLike’s, so I tried:

case str(x) | os.PathLike(x): ...

But this doesn’t work - PathLike doesn’t have a __match_args__ or even a property that a match args could point at. Since it’s a Protocol, the string it returns is applied to the class it’s wrapping, and since __fspath__ is a method, I can’t make it match any closer than getting a bound method. This seems to be a deficiency of the design for Protocols using a list of strings for property names - if the argument is only available by a method call, then you can’t use pattern matching with the protocol to get that value.

If __match_args__ = ("__fspath__()",) was supported, this would work…

Okay, less general, but what about Path? That certainly seems like it should work:

case str(x) | pathlib.Path(x): ...

Nope, also missing __match_args__. At least this one is easy to fix, though it’s not easy to subclass it, but I can at least test it out by adding the following:

    __match_args__ = ("__match_self_prop__",)
    
    @property
    def __match_self_prop__(self):
        return self.__fspath__()

This causes case Path(x) to work. It seems like this should probably be added?

I am running into this exact same issue two years later :frowning:

edit: submitted __match_args__ should work with pathlib.Path · Issue #108128 · python/cpython · GitHub