Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't tell apart untyped from typed class variable assignment #4387

Closed
euresti opened this issue Dec 19, 2017 · 2 comments
Closed

Can't tell apart untyped from typed class variable assignment #4387

euresti opened this issue Dec 19, 2017 · 2 comments
Labels

Comments

@euresti
Copy link
Contributor

euresti commented Dec 19, 2017

While working on #2088 I came across an interesting problem. Take this code

class A:
   x: int
   y: ClassVar[int] = 67
   z = 67

It's clear that x is an instance variable and y is a class variable. However z is a bit vague. Technically, as far as python is concerned it's a class variable. Both dataclasses and attr.s(auto_attribs=True) will ignore z when creating the __init__. (Because they only look in cls.__annotations__) (Full disclosure, I haven't run dataclasses yet but looking at the code it looks that way) However I can't figure out a way to tell the difference in mypy code.

Basically I'm walking the class body looking for AssignmentStmts. And I thought "Oh hey. node.is_classvar" should help me here. It return False for x, True for y, but sadly it also returns False for z. To make it harder, if you look at visit_assignment_stmt it does analyze_simple_literal_type to infer the type of z and then store_declared_types sets is_inferred_def = False so I can't tell apart z = 67 from z: int = 67

@euresti euresti changed the title classvar ambiguities Can't tell apart untyped from typed class variable assignment Dec 19, 2017
@ilevkivskyi
Copy link
Member

ilevkivskyi commented Dec 19, 2017

I think PEP 526 is clear on this, everything that is not typed with ClassVar is an instance variable. In particular:

class C:
    z = 42

introduces an instance variable with a default value. As for how to check this in mypy, there are several options and the simplest one is probably to re-use stmt.new_syntax, see semanal.check_namedtuple_classdef.

@euresti
Copy link
Contributor Author

euresti commented Dec 19, 2017

Ooh. new_syntax is exactly what I need. Thanks!

@euresti euresti closed this as completed Dec 19, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants