Skip to content

support NewType #115

@TimSimpsonR

Description

@TimSimpsonR

Pydantic does not seem to support NewType.

Given this code:

import typing as t
import pydantic

BossId = t.NewType('BossId', str)
EmployeeId = t.NewType('EmployeeId', str)
CustomerId = t.NewType('CustomerId', str)

class DirectReport(pydantic.BaseModel):
    boss: BossId
    employee: EmployeeId

The code will hit an error as it's being parsed:

my_code.py:8: in <module>
    class DirectReport(pydantic.BaseModel):
.tox/py36/lib/python3.6/site-packages/pydantic/main.py:82: in __new__
    config=config,
.tox/py36/lib/python3.6/site-packages/pydantic/fields.py:86: in infer
    description=field_config and field_config.get('description'),
.tox/py36/lib/python3.6/site-packages/pydantic/fields.py:72: in __init__
    self._prepare(class_validators)
.tox/py36/lib/python3.6/site-packages/pydantic/fields.py:111: in _prepare
    self._populate_validators(class_validators)
.tox/py36/lib/python3.6/site-packages/pydantic/fields.py:190: in _populate_validators
    *(get_validators() if get_validators else find_validators(self.type_)),
.tox/py36/lib/python3.6/site-packages/pydantic/validators.py:156: in find_validators
    raise TypeError(f'error checking inheritance of {type_!r} (type: {display_as_type(type_)})') from e
E   TypeError: error checking inheritance of <function NewType.<locals>.new_type at 0x407b26388> (type: function)

I currently am using Pydantic with this work around which involves monkey-patching:

import types
import pydantic

def find_validators(type_):
    if type_ is t.Any:
        return []
    for val_type, validators in pydantic.validators._VALIDATORS:
        try:
            if issubclass(type_, val_type):
                return validators
        except TypeError as e:
            if isinstance(type_, types.FunctionType):
                super_type = getattr(type_, '__supertype__')
                if super_type:
                    # Assume this is a NewType
                    if super_type != type_:
                        return find_validators(super_type)
            raise TypeError('error checking inheritance of '
                            f'{type_!r} (type: '
                            f'{pydantic.validators.display_as_type(type_)})'
                            ) from e
    raise pydantic.validators.ConfigError(f'no validator found for {type_}')


# Alters behavior of Pydantic so NewType will work (!!)
pydantic.validators.find_validators = find_validators
pydantic.fields.find_validators = find_validators

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