Why I have no warnings for mistyped class attribute?

Viewed 54

I have the following class:

class MyClass:
    my_attribute1: str
    my_attribute2: int

    def __init__(self):
        self.my_attribute1 = "value"
        self.my_attribute2 = "10" # got warning Expected type 'int', got 'str'... so it works as expected
        self.my_non_hinted_attribute = 100 # no warnings at all.

The non type hinted attribute could be a simple typo, so it seems I have no guarding warning for my typos... Using PyCharm with default settings.

Question

How can I achieve, that I get warning in case I make a typo in self.attribute_name?

2 Answers

Here is an equivalent implementation with data classes:

import attrs
@attrs.define(kw_only=True)
class MyClass:
    my_attribute1: str
    my_attribute2: int
    right_attribute: float

c = MyClass(
    my_attribute1="50",
    my_attribute2=700,
    wrong_name=55.55
)

When checked with mypy:

$ mypy example.py
example.py:8: error: Unexpected keyword argument "wrong_name" for "MyClass"

sometimes the best way to write a proper constructor is let somebody else (attrs here) do it for you.

I'm not sure you can give a warning for that, but you can restrict the class to having predefined attributes using the __slots__ class attribute. If you assign an attribute that is not prespecified, it will throw an error.

In this case:

class MyClass:
    __slots__ = ["my_attribute1", "my_attribute2"]
    my_attribute1: str
    my_attribute2: int
    
    def __init__(self):
        self.my_attribute1 = "value"
        self.my_attribute2 = "10"
        self.my_non_hinted_attribute = 100

my_class = MyClass()

python will raise an error because my_non_hinted_attribute is not in __slots__.

In this case:

class MyClass:
    __slots__ = ["my_attribute1", "my_attribute2", "my_non_hinted_attribute"]
    my_attribute1: str
    my_attribute2: int

    def __init__(self):
        self.my_attribute1 = "value"
        self.my_attribute2 = "10"
        self.my_non_hinted_attribute = 100

you won't get an error. This is not a way to warn you about wrong data types of non-hinted attributes (because how would you do that). But you will know when you assign an unexpected attribute. So you can type hint all of them and put them in __slots__ to get something close to the behavior you're expecting.

Related