Subclass PurePosixPath: TypeError: object.__init__() takes exactly one argument (the instance to initialize)

About as simple as it gets:

from pathlib import PurePosixPath


class Foo(PurePosixPath):
    def __init__(self, *parts, **kwargs):
        # do some other stuff

        super(Foo, self).__init__(*parts, **kwargs)


if __name__ == '__main__':
    Foo('test', 'path')

But it throws:

Traceback (most recent call last):
  File "/workspaces/ng/ppp.py", line 12, in <module>
    Foo('test', 'path')
  File "/workspaces/ng/ppp.py", line 8, in __init__
    super(Foo, self).__init__(*parts, **kwargs)
TypeError: object.__init__() takes exactly one argument (the instance to initialize)

Any ideas?

I’d hoped I could use PurePosixPath to get around system dependency weirdness, but maybe not?

The code above works fine for me:

In [9]: from pathlib import PurePosixPath
   ...:
   ...: class Foo(PurePosixPath):
   ...:     def __init__(self, *parts, **kwargs):
   ...:         super(Foo, self).__init__(*parts, **kwargs)
   ...:

In [10]: Foo('test', 'path')
Out[10]: Foo('test/path')

The error above is the error I’d expect to see if the base class was somehow missing, and sure enough:

In [11]: class Foo:  # no base class
    ...:     def __init__(self, *parts, **kwargs):
    ...:         super(Foo, self).__init__(*parts, **kwargs)
    ...:

In [12]: Foo('test', 'path')
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[12], line 1
----> 1 Foo('test', 'path')

Cell In[11], line 3, in Foo.__init__(self, *parts, **kwargs)
      2 def __init__(self, *parts, **kwargs):
----> 3     super(Foo, self).__init__(*parts, **kwargs)

TypeError: object.__init__() takes exactly one argument (the instance to initialize)

I think the most likely explanation is that your definition of Foo is somehow not what you think it is, or else, that a problem lies in the “do some other stuff” part that you omitted.

In Python versions <= 3.11, *Path classes don’t have a __init__ method, and do all their initialization in __new__/ helper methods. I think your best bet is to override __new__? But these classes haven’t always been designed for subclassing. I think >= 3.12 it should be fine.

2 Likes

@bryevdv what Python are you on?

Per @MegaIng 's reply I just learned that:

➜  ~ pyenv shell 3.11  
➜  ~ python ppp.py   
Traceback (most recent call last):
  File "/Users/dave/ppp.py", line 12, in <module>
    Foo('test', 'path')
  File "/Users/dave/ppp.py", line 8, in __init__
    super(Foo, self).__init__(*parts, **kwargs)
TypeError: object.__init__() takes exactly one argument (the instance to initialize)

But:

➜  ~ pyenv shell 3.12.2  
➜  ~ python ppp.py 

Yep, confirmed! Good excuse to bump to 3.12, let’s see what else breaks :see_no_evil: