chila
chila

Reputation: 2442

Why a Python subclass does not inherit its parent class's annotations?

A Python subclass does not inherit its parent class's annotations apparently:

#!/usr/bin/env python3

class A:
    valA: int
    
class B(A):
    valB: str

print(B.__annotations__)

Output:

{'valB': <class 'str'>}

Why is that? How can I make it so?

Upvotes: 2

Views: 419

Answers (1)

chila
chila

Reputation: 2442

Idea:

#!/usr/bin/env python3

def updateAnnotations(annotations, bases):
    for base in bases:
        annotations.update(getattr(base, '__annotations__', dict()))

class A:
    valA: int
    
class B:
    valB: int
    
class C(A, B):
    valC: int
    
    updateAnnotations(__annotations__, [A, B])

print(sorted(C.__annotations__.items()))

Output:

[('valA', <class 'int'>), ('valB', <class 'int'>), ('valC', <class 'int'>)]

Using a decorator:

def update_annotations(cls: typing.Type) -> typing.Type:
    annotations = getattr(cls, '__annotations__', None)
    if annotations == None:
        cls.__annotations__ = dict()
        annotations = cls.__annotations__

    for clsType in [cls] + list(cls.__bases__):
        annotations.update(getattr(clsType, '__annotations__', dict()))

    return cls

class A:
    valA: int

class B:
    valA: str
    valB: int

@update_annotations    
class C(A, B):
    valC: int
    
    def __init__(self):
        self.valA = 'asd'
        self.valB = 30
        self.valC = 40

print(C.__annotations__)

Output:

{'valC': <class 'int'>, 'valA': <class 'str'>, 'valB': <class 'int'>}

Upvotes: 0

Related Questions