Reputation: 12950
I am using mypy
to check my Python code.
I have a class where I set dynamically some attributes and mypy
keep on complaining about it:
error:"Toto" has no attribute "age"
This is my code:
class Toto:
def __init__(self, name:str) -> None:
self.name = name
for attr in ['age', 'height']:
setattr(self, attr, 0)
toto = Toto("Toto")
toto.age = 10 # "Toto" has no attribute "age" :(
Obviously, there could be 3 ways to solve the issue
# type: ignore
: toto.age = 10 # type: ignore #...
setattr
to set the age
of toto
: setattr(toto, "age", 10)
self.age = 0
...)However, I am looking for a more elegant and systematic way at the class level.
Any suggestion?
Upvotes: 14
Views: 5239
Reputation: 30240
I don't follow mypy well enough to know whether this is (still, or ever was) the ideal work around, but this issue and this part of the cheatsheet indicate that something like:
from typing import Any
class Toto:
def __init__(self, name:str) -> None:
self.name = name
for attr in ['age', 'height']:
setattr(self, attr, 0)
def __setattr__(self, name:str, value:Any):
super().__setattr__(name, value)
toto = Toto("Toto")
toto.age = 10
Will allow you to do what you're doing without mypy complaining (which it does, just tested).
Any
could be more restrictive, but the types will be checked on both setattr()
and "traditional" obj.attr = ...
calls, so heads up.
Upvotes: 7