Skip to content

ClassVar implementation #2771

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

Closed
miedzinski opened this issue Jan 29, 2017 · 2 comments
Closed

ClassVar implementation #2771

miedzinski opened this issue Jan 29, 2017 · 2 comments

Comments

@miedzinski
Copy link
Contributor

Currently ClassVar isn't implemented. I have opened python/typeshed#888 and submitted python/typeshed#889 (I hope it's enough). Once it's get merged mypy should implement this.

I would like to tackle this. I have started implementing this with ClassVar definition from PR I had submitted to typeshed and so far mypy is able to treat ClassVar[T] as T, which is expected. Of course assignment semantics are main purpose of ClassVar and I plan to implement them.

By the way, should mypy treat objects of this type as immutable, that is report errors on operations like calling append on List? AFAIK mypy doesn't have any concept of mutability.

@miedzinski
Copy link
Contributor Author

I have some questions about class inheritance. Consider this:

from typing import ClassVar


class A:
    x: ClassVar[str] = 'A'


class B(A):
    pass


A().x = 'A'  # clearly an error
B().x = 'b'  # what about this?
B.x = 'B'    # or this?


class C(A):
    x: str = 'C'


C().x = 'c'

I feel that assigning to instance of subclass should be an error, but I have no clue about subclass itself. I am not sure about redefining attribute to bare type in subclass - technically it is OK in terms of types, but what about semantics? If we want to check against any kind of shadowing class attribute then all these statements should be errors.

@ilevkivskyi
Copy link
Member

I think it should be like this:

A().x = 'A'  # clearly an error
B().x = 'b'  # also error
B.x = 'B'    # this is OK, also reading from B.x is OK

class C(A):
    x: str = 'C' # error

C().x = 'c' # error

The last two errors are because we should not allow to override classmethods with instance methods, see #1867. I think, for consistency the same should apply to variables.

miedzinski added a commit to miedzinski/mypy that referenced this issue Feb 15, 2017
JukkaL pushed a commit that referenced this issue Mar 9, 2017
Implements ClassVar introduced in PEP 526. Resolves #2771, #2879.

* Support annotating class attributes with ClassVar[...].
* Prohibit ClassVar annotations outside class bodies (regular variable
  annotations, function and method signatures).
* Prohibit assignments to class variables accessed from instances (including
  assignments on self).
* Add checks for overriding class variables with instance variables and vice
  versa when subclassing.
* Prohibit ClassVars nested inside other types.
* Add is_classvar flag to Var.
* Add nesting_level attribute to TypeAnalyser and use it inside helper methods
  anal_type and anal_array. Move analyzing implicit TupleTypes from
  SemanticAnalyzer to TypeAnalyser.
* Analyze ClassVar[T] as T and bare ClassVar as Any.
* Prohibit generic ClassVars and accessing generic instance variables via class
  (see #2878 comments).
* Add types.get_type_vars helper, which returns all type variables present in
  analyzed type, similar to TypeAnalyser.get_type_var_names.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants