16

Since Python 3.5 you can use Generics and other interesting stuff described in PEP-0484. I tried that and here's a code I have:

from typing import TypeVar, Generic, Optional
...

_T = TypeVar('T')
_S = TypeVar('S')


class Pool(Generic[_S, _T]):
    def __init__(self) -> None:
        self.pool = dict()

    ... getters and setters here...

This code works perfectly and does what is expected. Then I decided to extend this class to make some additional work. That's how I did that:

class PoolEx(Pool[_S, _T]):

    ARGUMENTS = []

    def __init__(self) -> None:
        print("self=", self, self.__class__.__bases__)
        super(PoolEx, self).__init__()
        self.arguments_pool = dict()

    ... other code here ...

To test Pool class I created MyPool which looked like this:

class MyPool(Pool[str, Hello]):
    pass

Then I put something like mypool = MyPool() and it worked fine. Once I implemented PoolEx, I've updated MyPool to this:

class MyPool(PoolEx[str, Hello]):
    ARGUMENTS = ['name', 'surname']

And tried to do the same thing: mypool = MyPool(). Unfortunately I got:

self= <__main__.MyPool object at 0x1068644e0> (__main__.PoolEx[str, __main__.Hello],)
Traceback (most recent call last):
  File "/usr/local/Cellar/python3/3.5.0/Frameworks/Python.framework/Versions/3.5/lib/python3.5/runpy.py", line 170, in _run_module_as_main
    "__main__", mod_spec)
  File "/usr/local/Cellar/python3/3.5.0/Frameworks/Python.framework/Versions/3.5/lib/python3.5/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/Users/8bitjoey/.../utils/pool.py", line 141, in <module>
    mypool = MyPool()
  File "/Users/8bitjoey/.../utils/pool.py", line 52, in __init__
    super(PoolEx, self).__init__()
TypeError: super(type, obj): obj must be an instance or subtype of type

As you can see, I also put self.__class__.__bases to the log. When I tried to test isinstance(self, PoolEx) and similar with issubclass, I got False. Same as super() verifications.

Is it something with my code or such classes can't have descendants? And if I still want to have PoolEx I have to use composition rather than inheritance.

3
  • 1
    Since this is Python3 you can use the shorter form: super().__init__(). Does that work? Commented Sep 18, 2015 at 11:37
  • Nope. It was how I implemented that first. Then I was playing with different calls to super and in the code above is one of variants. Commented Sep 18, 2015 at 12:13
  • @DanielRoseman Using super() worked for me when retyping the class itself did not. Why is this? Commented Jun 7, 2019 at 3:46

1 Answer 1

6

Well, just for the record, I have just run your code on Python 3.8.10, and I've got no errors. It runned perfectly. Then I've pulled the docker image python:3.5.0 from Docker Hub and run it again, and then I've got your exact same error:

TypeError: super(type, obj): obj must be an instance or subtype of type

So it seems to have been and issue with the first implementations of such features, which have already been fixed in latest versions.

Here follows the file I used for testing, in case anyone will ever be interested in reproduce any similar errors:

from typing import TypeVar, Generic, Optional

_T = TypeVar('T')
_S = TypeVar('S')

class Pool(Generic[_S, _T]):
    def __init__(self) -> None:
        self.pool = dict()

class PoolEx(Pool[_S, _T]):
    ARGUMENTS = []

    def __init__(self) -> None:
        print("self=", self, self.__class__.__bases__)
        super(PoolEx, self).__init__()
        self.arguments_pool = dict()

class MyPool(Pool[str, int]):
    pass

mypool = MyPool()

class MyPool(PoolEx[str, int]):
    ARGUMENTS = ['name', 'surname']

mypool2 = MyPool()
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.