myke
myke

Reputation: 541

Instance vs class variables and type hinting

I am confused by how Python is expecting me to do type hinting for instance and class variables.

Both the Python documentation and the mypy cheatsheet (according to my understanding, at least) state that such type hinting should work as in the code below.

from typing import ClassVar


class A:
    x: ClassVar[int] = 1  # class variable
    y: int = 2  # instance variable


# This should and does work:
print(A.x)

# If y was really an instance variable, then the following should
# a) not work and/or b) at least show a type issue -- but it does
# neither:
print(A.y)

# y is clearly a class variable:
a1 = A()
a2 = A()
print(a1.y, a2.y)
A.y = 3
print(a1.y, a2.y)

However, as mentioned in the comments, if Python really treated y as an instance variable, accessing A.y should produce an error in my view. Or what am I missing here?

So maybe this is only about type checking and not about the functionality itself? That would be questionable in my view because it is highly confusing. But even if that was the case I would at least expect mypy to produce some warning where A.y gets accessed but it doesn't, Success: no issues found in 1 source file, so clearly I am missing something.

Upvotes: 1

Views: 1346

Answers (1)

Silvio Mayolo
Silvio Mayolo

Reputation: 70287

You don't initialize instance variables outside the constructor. What you're doing is accidentally making y both a class variable and an instance variable. Consider

class A:
    x: ClassVar[int] = 1  # class variable
    y: int  # instance variable

    def __init__(self) -> None:
        self.y = 2

Upvotes: 4

Related Questions