Skip to content

ClassVar inheritance #2061

@layday

Description

@layday

Checks

  • I added a descriptive title to this issue
  • I have searched (google, github) for similar issues and couldn't find anything
  • I have read and followed the docs and still think this feature/change is needed
  • After submitting this, I commit to one of:
    • Look through open issues and helped at least one other person
    • Hit the "watch" button on this repo to receive notifications and I commit to help at least 2 people that ask questions in the future
    • Implement a Pull Request for a confirmed bug

Feature Request

Output of python -c "import pydantic.utils; print(pydantic.utils.version_info())":

             pydantic version: 1.7
            pydantic compiled: False
                 install path: [...]/pydantic
               python version: 3.9.0 (default, Oct  8 2020, 06:18:59)  [Clang 7.1.0 (tags/RELEASE_710/final)]
                     platform: macOS-10.14.6-x86_64-i386-64bit
     optional deps. installed: ['typing-extensions']

Currently, it is possible to annotate an attribute as being a class variable and it will be excluded from the model:

from typing import ClassVar

from pydantic import BaseModel


class Foo(BaseModel):
    class_var_to_be_redefined_on_children: ClassVar[str] = "value"


class Bar(Foo):
    class_var_to_be_redefined_on_children = "some other value"

However, when inheriitng from a model with a ClassVar, overwriting the class variable produces an error:

Traceback (most recent call last):
  File "test.py", line 10, in <module>
    class Bar(Foo):
  File "pydantic/main.py", line 284, in __new__
    validate_field_name(bases, var_name)
  File "utils.py", line 144, in validate_field_name
    raise NameError(
NameError: Field name "class_var_to_be_redefined_on_children" shadows a BaseModel attribute; use a different field name with "alias='class_var_to_be_redefined_on_children'".

What appears to be happening here is that Pydantic assumes that class_var_to_be_redefined_on_children is a Pydantic field but errors out because there is a class attribute with the same name. I would prefer not to re-annotate subclass class variables with ClassVar[T]. I believe the following should also be interpret as a ClassVar, especially in conjunction with generic models (an uninitialised ClassVar):

from typing import ClassVar

from pydantic import BaseModel


class Foo(BaseModel):
    class_var_to_be_defined_on_children: ClassVar[str]


class Bar(Foo):
    class_var_to_be_defined_on_children = "some other value"

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions