LINUX.ORG.RU

История изменений

Исправление byko3y, (текущая версия) :

а в питоне динамическая типизация, надеяться в нём на то что что-то там проверяется нельзя

Как же pydantic проводит проверку — задался я вопросом.

fields.py:_apply_validators
    v = validator(cls, v, values, self, self.model_config)
    ...
    return v, None

Кстати, передача ошибки через возвращаемое значение.
Смотрим на какой-нибудь «валидатор»:

def int_validator(v: Any) -> int:
    if isinstance(v, int) and not (v is True or v is False):
        return v

    try:
        return int(v)
    except (TypeError, ValueError):
        raise errors.IntegerError()

И, внезапно, выясняется, что эти валидаторы, на самом деле, просто пересоздают все входные данные. если они еще не являются экземплярами целевого типа. И это, на мой взгляд, есть самый адекватный способ проверки типов в питоне.

Напоминаю, что изменяемые (mutable) типы данных были не более чем оптимизацией ранних компьютеров с малым объемом памяти. Сами базовые типы построены на неизменяемых контейнерах, пересоздаваемых при изменении значения. Однако при этом Гвиде почему-то захотелось императивным с кучей изменяемых по месту типов данных, вроде того же массива — сравните с массивами PHP, которые имеют copy-on-write семантику, нивелирующую кучу граблей, на которые регулярно наступают питонисты.

К слову о массивах, fields.py:_validate_sequence_like

result = []
errors: List[ErrorList] = []
for i, v_ in enumerate(v):
    v_loc = *loc, i
    r, ee = self._validate_singleton(v_, values, v_loc, cls)
    if ee:
        errors.append(ee)
    else:
        result.append(r)
    converted: Union[List[Any], Set[Any], FrozenSet[Any], Tuple[Any, ...], Iterator[Any], Deque[Any]] = result
    ...
    return converted, None

Оно пересоздает заново весь массив, даже если входное значение уже является массивом. Конечно, это менее эффективно, чем copy-on-write и более эффективные варианты персистентных структур данных, но лучше чем питон ничего.

Исходная версия byko3y, :

а в питоне динамическая типизация, надеяться в нём на то что что-то там проверяется нельзя

Как же pydantic проводит проверку — задался я вопросом.

fields.py:_apply_validators
    v = validator(cls, v, values, self, self.model_config)
    ...
    return v, None

Кстати, передача ошибки через возвращаемое значение.
Смотрим на какой-нибудь «валидатор»:

def int_validator(v: Any) -> int:
    if isinstance(v, int) and not (v is True or v is False):
        return v

    try:
        return int(v)
    except (TypeError, ValueError):
        raise errors.IntegerError()

И, внезапно, выясняется, что эти валидаторы, на самом деле, просто пересоздают все входные данные. если они еще не являются экземплярами целевого типа. И это, на мой взгляд, есть самый адекватный способ проверки типов в питоне.

Напоминаю, что изменяемые (mutable) типы данных были не более чем оптимизацией ранних компьютеров с малым объемом памяти. Сами базовые типы построены на неизменяемых контейнерах, пересоздаваемых при изменении значения. Однако при этом Гвиде почему-то захотелось императивным с кучей изменяемых по месту типов данных, вроде того же массива — сравните с массивами PHP, которые имеют copy-on-write семантику, нивелирующую кучу граблей, на которые регулярно наступают питонисты.

К слову о массивах, fields.py:_validate_sequence_like

result = []
errors: List[ErrorList] = []
for i, v_ in enumerate(v):
    v_loc = *loc, i
    r, ee = self._validate_singleton(v_, values, v_loc, cls)
    if ee:
        errors.append(ee)
    else:
        result.append(r)
    ...
    return converted, None

Оно пересоздает заново весь массив, даже если входное значение уже является массивом. Конечно, это менее эффективно, чем copy-on-write и более эффективные варианты персистентных структур данных, но лучше чем питон ничего.