Skip to content

Commit

Permalink
Incorporate feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
David Montague committed Nov 11, 2019
1 parent e929333 commit 4e0daa4
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 20 deletions.
4 changes: 2 additions & 2 deletions docs/usage/models.md
Expand Up @@ -324,8 +324,8 @@ extending a base model with extra fields.

## Custom Root Types

Pydantic models which do not represent a `dict` ("object" in JSON parlance) can have a custom
root type defined via the `__root__` field. The root type can be of any type: list, float, int, etc.
Pydantic models can be defined with a custom root type by declaring the `__root__` field.
The root type can be of any type: list, float, int, etc.

The root type is defined via the type hint on the `__root__` field.
The root value can be passed to model `__init__` via the `__root__` keyword argument or as
Expand Down
27 changes: 9 additions & 18 deletions pydantic/main.py
Expand Up @@ -12,7 +12,7 @@
from .class_validators import ROOT_KEY, ValidatorGroup, extract_root_validators, extract_validators, inherit_validators
from .error_wrappers import ErrorWrapper, ValidationError
from .errors import ConfigError, DictError, ExtraError, MissingError
from .fields import SHAPE_MAPPING, ModelField
from .fields import ModelField
from .json import custom_pydantic_encoder, pydantic_encoder
from .parse import Protocol, load_file, load_str_bytes
from .schema import model_schema
Expand Down Expand Up @@ -244,15 +244,7 @@ def __new__(mcs, name, bases, namespace, **kwargs): # noqa C901
'__repr__': Representation.__repr__,
**{n: v for n, v in namespace.items() if n not in fields},
}
cls = super().__new__(mcs, name, bases, new_namespace, **kwargs)
if _custom_root_type and cls.__fields__[ROOT_KEY].shape == SHAPE_MAPPING:
original_parse_obj = cls.parse_obj

def parse_obj(obj: Any) -> 'Model':
return original_parse_obj({ROOT_KEY: obj})

setattr(cls, 'parse_obj', staticmethod(parse_obj))
return cls
return super().__new__(mcs, name, bases, new_namespace, **kwargs)


class BaseModel(metaclass=ModelMetaclass):
Expand Down Expand Up @@ -384,15 +376,14 @@ def json(

@classmethod
def parse_obj(cls: Type['Model'], obj: Any) -> 'Model':
if cls.__custom_root_type__ and not (isinstance(obj, dict) and obj.keys() == {'__root__'}):
obj = {ROOT_KEY: obj}
if not isinstance(obj, dict):
if cls.__custom_root_type__:
obj = {ROOT_KEY: obj}
else:
try:
obj = dict(obj)
except (TypeError, ValueError) as e:
exc = TypeError(f'{cls.__name__} expected dict not {type(obj).__name__}')
raise ValidationError([ErrorWrapper(exc, loc=ROOT_KEY)], cls) from e
try:
obj = dict(obj)
except (TypeError, ValueError) as e:
exc = TypeError(f'{cls.__name__} expected dict not {type(obj).__name__}')
raise ValidationError([ErrorWrapper(exc, loc=ROOT_KEY)], cls) from e
return cls(**obj)

@classmethod
Expand Down

0 comments on commit 4e0daa4

Please sign in to comment.