1. Anuncie Aqui ! Entre em contato fdantas@4each.com.br

[Python] Type hinting a python descriptor implementing read-only instance attributes after...

Discussão em 'Python' iniciado por Stack, Setembro 12, 2024.

  1. Stack

    Stack Membro Participativo

    I have a couple of data structure classes that are intended to have public read-only attributes. I cannot use dataclasses or namedtuples as I need the ability to define args, kwargs in the child classes inheriting these classes.

    One way I can set this up is simply having read-only properties but at some point, my data structure can have more than 20 attributes and writing a property for each one of them feels cumbersome.

    I think the best solution for me would be to implement a descriptor and I have an implementation which works but mypy seems to be struggling with it:

    from typing import Type, TypeVar, Generic

    _Object = TypeVar("_Object")
    _Value = TypeVar("_Value")


    class ReadOnlyAttribute(Generic[_Value]):
    def __set_name__(self, owner: Type[_Object], name: str) -> None:
    self.public_name = name
    self.private_name = f"_{name}"

    def __get__(self, instance: _Object, owner: Type[_Object]) -> _Value:
    return getattr(instance, self.private_name)

    def __set__(self, instance: _Object, value: _Value) -> None:
    if hasattr(instance, self.private_name):
    raise AttributeError(
    f"Cannot set read-only attribute '{self.public_name}' of '{instance}'"
    )

    setattr(instance, self.private_name, value)


    class Test:
    # error: Incompatible types in assignment (expression has type "ReadOnlyAttribute[Never]", variable has type "str") [assignment]
    foo: str = ReadOnlyAttribute()

    def __init__(self):
    self.foo = "foooooo"

    # Revealed type is "builtins.str"
    reveal_type(Test().foo)


    It is able to infer the type correctly but is giving an error about incompatible types in assignment. I think it's because I am type-hinting self.foo as a str but assigning an instance of ReadOnlyAttribute?

    However, without doing this and using Generic, reveal_type does not perform as expected and returns Never.

    Continue reading...

Compartilhe esta Página