Skip to content

Incomplete type annotations in BaseConfig yield mypy errors when Config is defined from BaseConfig #2719

@mpkocher

Description

@mpkocher

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 is a bug

Bug

  1. The BaseConfig is missing type annotations for a few fields. Inheriting from BaseConfig and setting values yields type errors from mypy.
from pydantic import BaseConfig, BaseModel, Extra


class Record(BaseModel):
    alpha: str
    beta: str

    class Config(BaseConfig):
        title = "Record"
        extra = Extra.ignore
        max_anystr_length = 1234

yields

mypy --version && mypy example.py
mypy 0.812
example.py:9: error: Incompatible types in assignment (expression has type "str", base class "BaseConfig" defined the type as "None")  [assignment]
example.py:11: error: Incompatible types in assignment (expression has type "int", base class "BaseConfig" defined the type as "None")  [assignment]
Found 2 errors in 1 file (checked 1 source file)

I believe the type annotations should be:

from typing import Union, Optional

class BaseConfig:
    title: Optional[str] = None
    min_anystr_length: Optional[int] = None # can this just be int = 0 ?
    max_anystr_length: Optional[int] = None
    extra = Union[str, Extra] = Extra.ignore

Inheriting from BaseConfig is useful for autocomplete and avoids typos like the following.

from pydantic import BaseModel

class Point(BaseModel):
    x: int
    y: int
    
    class Config:
        extras = "forbid"
  1. The Config docs look to be inconsistent with the default values defined in BaseConfig.
  • the default for max_anystr_length is listed as 2 ** 16 in the docs, however, None is defined in BaseConfig (i.e., there is no limit)
  • Setting max_anystr_length = 0 ignores the validation completely and has a different semantic meaning than any other positive integer. In other words, max_anystr_length = 0 is the same as max_anystr_length = None.
  • Similarly, the default for min_anystr_length is listed as 0 in the docs, but the listed default is None in BaseConfig. If these are semantically the same, then perhaps set min_anystr_length:int = 0 as the default?
  • In general, it might be useful to clarify the truthyness of these 0 vs None values

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

             pydantic version: 1.8.1
            pydantic compiled: False
               python version: 3.9.2 | packaged by conda-forge | (default, Feb 21 2021, 05:02:20)  [Clang 11.0.1 ]
                     platform: macOS-11.2.3-x86_64-i386-64bit
     optional deps. installed: ['typing-extensions']

Metadata

Metadata

Assignees

No one assigned

    Labels

    bug V1Bug related to Pydantic V1.X

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions