[Python] Make type checker understand that class and instance attributes share names but have...

Discussão em 'Python' iniciado por Stack, Julho 14, 2025.

  1. Stack

    Stack Membro Participativo

    I have a piece of code in Python that in essence looks and works the following way:

    class Column:
    def __init__(self, s: str) -> None:
    self.name = s

    class Meta(type):
    def __new__(cls, name: str, bases: tuple[type, ...], namespace: dict[str, Any]) -> type:
    annotations = namespace.get('__annotations__', {})
    namespace.update({k: Column(k) for k in annotations})

    return super().__new__(cls, name, bases, namespace)

    class Base(metaclass=Meta):
    def __init__(self, data: dict[str, Any]) -> None:
    if self.__class__ == Base:
    raise RuntimeError

    self.__dict__ = data


    Now let's make an example. The Base class should be inherited and then we create an object for testing (and we assume the data passed is correct):

    class Human(Base):
    name: str
    height: int

    tom = Human({'name': "Tom", 'height': 180})

    Human.height # Column(name="height")
    tom.height # 180



    Now when we access a field from the class, we get back a Column with the field's name. When we access the field from an instance like tom we get back the actual value for that field of that instance, in our case 180. We also kind of tricked the type checker that these are both valid fields, because it just thinks we are working with class fields. (At least this is the case for Pylance, which is what I use)

    Now comes the question: Is there a trick or workaround for the type checker to understand that Human.height is of type Column, without specifying the same field twice like the following I would have to do here:

    class Human(Base):
    name: str
    name: ClassVar[Column]
    height: int
    height: ClassVar[Column]


    So the goal is to have my type checker think the class has the annotated instance attributes, while all class attributes have the same name but are all of type Column.

    Continue reading...

Compartilhe esta Página