Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Function annotation for subclasses of abstract class

I'm trying to use function annotations in the hope that my editor will be better at refactoring. I however am stumbling over the following problem:

I have an abstract base class Algorithm.

class Algorithm(metaclass=ABCMeta):
     def __init__(self):   
          self.foo = 'bar'

I also have a function that uses instances of subclasses of Algorithm

def get_foo(foo_algorithm):
    return foo_algoritm.foo

the input foo_algorithm can be an instance of any of the subclasses of Algorithm. How do I sensibly annotate this input? I'm looking for something along the lines off:

def get_foo(foo_algorithm: subclassof(Algorithm)):
    return foo_algoritm.foo

But I couldn't find the right way to do this.

like image 230
PdevG Avatar asked Aug 05 '16 14:08

PdevG


1 Answers

Just use Algorithm directly:

def get_foo(foo_algorithm: Algorithm):
    return foo_algoritm.foo

and automatically any instance of a subclass will be acceptable (isinstance(foo_algorithm, Algorithm) must be true, which applies to all subclasses of a baseclass).

If you can only accept classes, then use Type[Algorithm] as the type hint:

def get_foo(foo_algorithm: Type[Algorithm]):
    return foo_algoritm().foo

See the The type of class objects section of PEP 484 -- Type Hints:

Sometimes you want to talk about class objects, in particular class objects that inherit from a given class. This can be spelled as Type[C] where C is a class. To clarify: while C (when used as an annotation) refers to instances of class C, Type[C] refers to subclasses of C.

Here I called the class object, since .foo is an instance attribute according to your code example; a class derived from Algorithm would not have such an attribute itself.

like image 129
Martijn Pieters Avatar answered Oct 06 '22 00:10

Martijn Pieters