I'm attempting to create a subclass of pathlib.Path that will do some manipulation to the passed string path value before passing it along to the base class.
class MyPath(Path):
def __init__(self, str_path):
str_path = str_path.upper() # just representative, not what I'm actually doing
super().__init__(str_path)
However, when I try to use this:
foo = MyPath("/path/to/my/file.txt")
bar = foo / "bar"
I get the following error: TypeError: unsupported operand type(s) for /: 'MyPath' and 'str'
I am using Python 3.12 which I understand to have better support for subclassing Path
MyPath("foo") / "bar' goes through several steps:
MyPath("foo").__truediv__("bar"), whichMyPath("foo").with_segments("bar"), whichMyPath(MyPath("foo"), "bar"), whichTypeError because you overrode MyPath.__init__ to only accept a single additional positional argument, whichMyPath.__truediv__ to catch a TypeError and subsequently return NotImplementedYour __init__ method must be careful to accept multiple path components, not just a single string, and it must not assume that each argument is an actual string, but rather objects that implement the os.PathLike interface. (In particular, don't assume that a path component has an upper method. Call os.fspath on the component first to retrieve a str representation that does have an upper method.)
Something like
import os
class MyPath(Path):
def __init__(self, *paths):
super().__init__(*(os.fspath(x).upper() for x in paths))
and thus
% py312/bin/python -i tmp.py
>>> bar
MyPath('/PATH/TO/MY/FILE.TXT/BAR')
Alternately, as others have alluded to, you can override with_segments to, for example, combine the segments yourself and pass the single result to MyPath, but I see no reason to restrict MyPath.__init__'s signature as you currently do.