How to annotate a write-only property using type hints

Viewed 58

I would like to have a write-only property that notifies me when somebody changes it. Also I had to re-assign the name(here var) in order not to have an extra name in class's namespace. This goes against Mypy rules.

Here is the simplified version:

class A:
    def var(self, value):
        print("value changed:", value)

    var = property(fset=var)


obj = A()
obj.var = 10
obj.var = "hi"

Mypy error messages:

main.py:5: error: Incompatible types in assignment (expression has type "property", variable has type "Callable[[A, Any], Any]")
main.py:9: error: Cannot assign to a method
main.py:9: error: Incompatible types in assignment (expression has type "int", variable has type "Callable[[Any], Any]")
main.py:10: error: Cannot assign to a method
main.py:10: error: Incompatible types in assignment (expression has type "str", variable has type "Callable[[Any], Any]")
Found 5 errors in 1 file (checked 1 source file)

How can I make Mypy happy without suppressing the error with # type: ignore?

My current attempt to solve it is:

class A:
    def temp(self, value):
        print("value changed:", value)

    var = property(fset=temp)
    del temp


obj = A()
obj.var = 10
obj.var = "hi"

Is there any better way?

1 Answers

Seems like there is no other way, Mypy doesn't let me re-define names in the class body. It's OK with class variables but not with methods.

Although I could use that temporary method that I showed in the question, I prefer defining a property using @property decorator with both getter and setter and manually raising AttributeError:

class A:
    @property
    def var(self):
        raise AttributeError("unreadable attribute 'var'")

    @var.setter
    def var(self, value):
        print("value changed:", value)
Related