Have BaseModel inherit from Representation (#1319)

* Have BaseModel inherit from Representation

This changes the inheritance so that `BaseModel` *actually* inherits from `Representation`, rather than just having the same methods as it. While this doesn't actually affect the runtime, it does make mypy happier.

Fixes https://github.com/samuelcolvin/pydantic/issues/1310

* Add '__dict__' back into slots
This commit is contained in:
Danny Weinberg
2020-04-15 14:07:16 -07:00
committed by GitHub
parent 7bebf2bdc3
commit a015cd01ba
4 changed files with 18 additions and 8 deletions
+1
View File
@@ -0,0 +1 @@
Have `BaseModel` inherit from `Representation` to make mypy happy when overriding `__str__`.
+12 -8
View File
@@ -184,6 +184,12 @@ def validate_custom_root_type(fields: Dict[str, ModelField]) -> None:
UNTOUCHED_TYPES = FunctionType, property, type, classmethod, staticmethod
# Note `ModelMetaclass` refers to `BaseModel`, but is also used to *create* `BaseModel`, so we need to add this extra
# (somewhat hacky) boolean to keep track of whether we've created the `BaseModel` class yet, and therefore whether it's
# safe to refer to it. If it *hasn't* been created, we assume that the `__new__` call we're in the middle of is for
# the `BaseModel` class, since that's defined immediately after the metaclass.
_is_base_model_class_defined = False
class ModelMetaclass(ABCMeta):
@no_type_check # noqa C901
@@ -195,7 +201,7 @@ class ModelMetaclass(ABCMeta):
pre_root_validators, post_root_validators = [], []
for base in reversed(bases):
if issubclass(base, BaseModel) and base != BaseModel:
if _is_base_model_class_defined and issubclass(base, BaseModel) and base != BaseModel:
fields.update(deepcopy(base.__fields__))
config = inherit_config(base.__config__, config)
validators = inherit_validators(base.__validators__, validators)
@@ -297,7 +303,7 @@ class ModelMetaclass(ABCMeta):
return cls
class BaseModel(metaclass=ModelMetaclass):
class BaseModel(Representation, metaclass=ModelMetaclass):
if TYPE_CHECKING:
# populated by the metaclass, defined here to help IDEs only
__fields__: Dict[str, ModelField] = {}
@@ -314,12 +320,7 @@ class BaseModel(metaclass=ModelMetaclass):
Config = BaseConfig
__slots__ = ('__dict__', '__fields_set__')
# equivalent of inheriting from Representation
__repr_name__ = Representation.__repr_name__
__repr_str__ = Representation.__repr_str__
__pretty__ = Representation.__pretty__
__str__ = Representation.__str__
__repr__ = Representation.__repr__
__doc__ = '' # Null out the Representation docstring
def __init__(__pydantic_self__, **data: Any) -> None:
"""
@@ -768,6 +769,9 @@ class BaseModel(metaclass=ModelMetaclass):
return self.__dict__
_is_base_model_class_defined = True
def create_model(
model_name: str,
*,
+2
View File
@@ -220,6 +220,8 @@ class Representation:
of objects.
"""
__slots__: Tuple[str, ...] = tuple()
def __repr_args__(self) -> 'ReprArgs':
"""
Returns the attributes to show in __str__, __repr__, and __pretty__ this is generally overridden.
+3
View File
@@ -16,6 +16,9 @@ from pydantic.generics import GenericModel
class Flags(BaseModel):
strict_bool: StrictBool = False
def __str__(self) -> str:
return f'flag={self.strict_bool}'
class Model(BaseModel):
age: int