Как стать автором
Обновить

Комментарии 13

Видимо, я буду копипастить этот комментарий под каждый пост про FastAPI)


У Pydantic очень долгое время висел такой пример в документации самым первым:


class User(BaseModel):
    # ...
    signup_ts: datetime = None

Естественно такой код не проходит проверку в mypy --strict, и аннотации типов теряют всякий смысл. Причём это не баг, а фича, и разработчики Pydantic предлагают просто отказаться от --strict. Но тогда какой вообще смысл в типизации?


Сейчас этот пример уже поправили, но не потому что разработчики изменили своё отношение к mypy --strict, а потому что кто-то пулл-реквест прислал. Но для Pydantic это по-прежнему валидный код, имеющий особую логику.


И это для меня основная причина НЕ использовать FastAPI. Одумайтесь, в питоне и так с системой типов всё очень плохо, не надо её окончательно доламывать. Я вместо FastAPI лучше напишу свой велосипед, лишь бы не связываться с Pydantic. (Или попробовать форкнуть FastAPI с заменой Pydantic на что-то другое, что ли...)

НЛО прилетело и опубликовало эту надпись здесь

В том-то и проблема, что с точки зрения разработчиков Pydantic — не нужно, и подобные примеры ещё встречаются повсюду в документации.

Не всё так просто, т.к. в настоящее время тайпинг Питона плохо отражает то, что происходит в рантайме. Особенно это касается интерпретации "значений по умолчанию", объявленных в теле класса. К примеру, "dataclasses" и "attr" имеют особые объявления полей с использованием семантики "значения по умолчанию" и функции field. Есть ещё descriptor protocol, хитрые инициализации аттрибутов экземпляра итд.


Есть по данной теме обсуждение на гитхабе, где Гвидо посоветовал использовать плагины для mypy для разрешения подобных ситуаций.

Что конкретно «плохо отражает» аннотация вида signup_ts: Optional[datetime] = None и откуда появилась необходимость использования именно signup_ts: datetime = None, кроме как от тараканов в головах разработчиков Pydantic, которые зачем-то решили завязать на такую аннотацию специальное поведение?

Определение вида signup_ts: datetime = None вполне используемо, если при отсутствии явного значения при создании модели требуется вытащить его из соседних полей.


Но есть маленькое "но" с которым я полностью согласен: в документации ничего такого не происходит, что не есть правильно. Особенно не правильно поведение из коробки, при котором значение по умолчанию будет взято без валидации. К счастью, это можно изменить через конфигурацию модели.


Своим предыдущем комментарием я хотел напомнить, что такие разногласия — результат столкновения идеологии типов и банальной утилитарности, а также о том, что в мире Питона есть ещё много нерешённых вопросов на данную тему. Так что говорить о "тараканах в головах разработчиков Pydantic" — лишнее. В конце концов никто не мешает законтрибутить в этот хороший проект.

если при отсутствии явного значения при создании модели требуется вытащить его из соседних полей.

Это конечно хорошо и правильно, только вот Pydantic плевать хотел на это всё, и какое-нибудь print(User(signup_ts=None)) всё равно великолепно работает и печатает signup_ts=None. Так что заявление про тараканов остаётся в силе.


это можно изменить через конфигурацию модели.

А можно забыть её изменить, или же не уследить за каким-нибудь джуниором, и в итоге получаем баг в проекте, который мог бы быть отловлен через mypy, но не будет отловлен, потому что у разработчиков Pydantic тараканы.


В конце концов никто не мешает законтрибутить в этот хороший проект.

Очень мешают заявления разработчиков, что это не баг, а фича. Висел бы issue с лейблом «help wanted» — тогда да, но вместо этого issue на эту тему просто закрывают. Значит и пулл-реквест тоже завернут.

А можно забыть её изменить, или же не уследить за каким-нибудь джуниором, и в итоге получаем баг в проекте, который мог бы быть отловлен через mypy, но не будет отловлен, потому что у разработчиков Pydantic тараканы.

+1


Очень мешают заявления разработчиков, что это не баг, а фича. Висел бы issue с лейблом ...

Дайте, пожалуста, ссылку, может получится поучаствовать.

Вот тут я ныл на ломаном английском, и мне там ответили в общем-то примерно то же самое что и вы рассказываете:


Yes, there are some patterns that work with pydantic that are not valid with mypy. There is also an enormous amount of non-pydantic python code that is valid python and not valid with mypy.

Но меня такие попытки усидеть на двух стульях не устраивают.


Потом, конечно, докинули пулл-реквест, исправляющий первый пример из документации, только вот сам Pydantic исправлять, похоже, не очень спешат.


Там хоть и написано, что «we should absolutely strive toward better supporting --strict mode», но дальше слов, похоже, дело не идёт.

Извините не сдержался :)

Вы вот смеетесь, а человек за полтора года наклепал уже 96 релизов.
Это же хорошо, да?
Или по крайней мере не смешно.

отдавать 500 ошибку на неверные входные данные — не есть хорошо. скорее всего, фреймворк так не делает, а если и делает, то в случае неправильного использования

Он и не отдает. Он в дефолте кидает 422 и в ответном json — инфу, что именно пошло не так. Насчет 500 автор что-то путает. Вообще удобная штука, чтобы быстро накидать апишечку на json'ах, и, может даже restful, если чуть заморочиться. Из приятного — делать валидацию за счет тайп-хинтов без лишнего кода прям греет душу. :)

Зарегистрируйтесь на Хабре, чтобы оставить комментарий