Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Typing Django
Search
Sobolev Nikita
March 27, 2020
Programming
0
420
Typing Django
Sobolev Nikita
March 27, 2020
Tweet
Share
More Decks by Sobolev Nikita
See All by Sobolev Nikita
Чего вы не знали о строках в Python – Василий Рябов, PythoNN
sobolevn
0
200
ИИ-Агенты в каждый дом – Алексей Порядин, PythoNN
sobolevn
0
180
Внутреннее устройство сборки мусора в CPython 3.14+ – Сергей Мирянов, PythoNN
sobolevn
0
71
Генератор байткода и байткод генератора, Михаил Ефимов, PythoNN
sobolevn
0
66
Дотянуться до кремния. HighLoad Python: SIMD, GPU – Пётр Андреев, PythoNN
sobolevn
0
73
Проектирование — это когда чувствуешь, а не какие-то там циферки, Николай Хитров, PythoNN
sobolevn
0
100
Continuous profiling, Давид Джалаев, PythoNN
sobolevn
0
110
Михаил Гурбанов – Are you NATS? @ PythoNN
sobolevn
0
140
Дмитрий Бровкин – Почему исправление опечаток сложнее, чем кажется, и как мы с этим српавляемся @ PythoNN
sobolevn
0
55
Other Decks in Programming
See All in Programming
Graviton と Nitro と私
maroon1st
0
170
dchart: charts from deck markup
ajstarks
3
970
Combinatorial Interview Problems with Backtracking Solutions - From Imperative Procedural Programming to Declarative Functional Programming - Part 2
philipschwarz
PRO
0
150
CSC307 Lecture 03
javiergs
PRO
1
480
humanlayerのブログから学ぶ、良いCLAUDE.mdの書き方
tsukamoto1783
0
150
HTTPプロトコル正しく理解していますか? 〜かわいい猫と共に学ぼう。ฅ^•ω•^ฅ ニャ〜
hekuchan
2
660
フルサイクルエンジニアリングをAI Agentで全自動化したい 〜構想と現在地〜
kamina_zzz
0
380
.NET Conf 2025 の興味のあるセッ ションを復習した / dotnet conf 2025 quick recap for backend engineer
tomohisa
0
120
Automatic Grammar Agreementと Markdown Extended Attributes について
kishikawakatsumi
0
140
0→1 フロントエンド開発 Tips🚀 #レバテックMeetup
bengo4com
0
510
AIによるイベントストーミング図からのコード生成 / AI-powered code generation from Event Storming diagrams
nrslib
2
1.6k
AI によるインシデント初動調査の自動化を行う AI インシデントコマンダーを作った話
azukiazusa1
1
550
Featured
See All Featured
The innovator’s Mindset - Leading Through an Era of Exponential Change - McGill University 2025
jdejongh
PRO
1
84
Reality Check: Gamification 10 Years Later
codingconduct
0
2k
Game over? The fight for quality and originality in the time of robots
wayneb77
1
85
Visual Storytelling: How to be a Superhuman Communicator
reverentgeek
2
420
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
31
3.1k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
9
1.1k
16th Malabo Montpellier Forum Presentation
akademiya2063
PRO
0
42
Between Models and Reality
mayunak
1
170
We Analyzed 250 Million AI Search Results: Here's What I Found
joshbly
1
560
brightonSEO & MeasureFest 2025 - Christian Goodrich - Winning strategies for Black Friday CRO & PPC
cargoodrich
3
88
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
34
2.6k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
26
3.3k
Transcript
Никита Соболев github.com/sobolevn
>_ X Типизация Django
Зачем?
Затем!
Затем! > Легче навигация по коду
Затем! > Легче навигация по коду > Быстрее обратная связь
Затем! > Легче навигация по коду > Быстрее обратная связь
> Совпадает с остальным стеком
>_ X Проблемы
А их много:
А их много: > Гигантская (и плохая) кодовая база без
типов
А их много: > Гигантская (и плохая) кодовая база без
типов > Нет прав на её редактирование (!)
А их много: > Гигантская (и плохая) кодовая база без
типов > Нет прав на её редактирование (!) > Куча магии
А их много: > Гигантская (и плохая) кодовая база без
типов > Нет прав на её редактирование (!) > Куча магии > Нет поддержки нового API типизации
>_ X Аннотация кода
MonkeyType github.com/Instagram/MonkeyType
from some.module import add add(1, 2)
monkeytype run myscript.py monkeytype stub some.module
def add(a: int, b: int) -> int: ...
None
И волонтеры!
None
None
Тысячи их! Спасибо.
>_ X Плагин для mypy
class User(models.Model): score = models.IntegerField()
class User(models.Model): score = models.IntegerField(null=True)
User.objects.filter(score=1) # ok! User.objects.filter(score__exact=1) # ok! User.objects.filter(score__exact='1') # Expected: int,
specified: str
django-stubs умеет почти все!
Чего не умеет?
Чего не умеет? > `QuerySet.as_manager()`
Чего не умеет? > `QuerySet.as_manager()` > Известные баги с `Manager.from_queryset()`
Чего не умеет? > `QuerySet.as_manager()` > Известные баги с `Manager.from_queryset()`
> Поддержка нескольких версий Django
Фичи!
class Blog(models.Model): title = models.CharField() num_posts = models.IntegerField(null=True) Blog.objects.values('title').get() #
type: TypedDict({'title': builtins.str}) blog: Blog blog.num_posts # type: Optional[int]
Как оно внутри?
def _callback(ctx: FunctionContext) -> mypy.types.Type: return AnyType() class _ExamplePlugin(Plugin): def
get_function_hook( self, fullname: str, ) -> Optional[Callable]: if fullname == 'django.db.models.fields.CharField': return _callback def plugin(version: str) -> Type[Plugin]: """Plugin's public API and entrypoint.""" return _ExamplePlugin
def _callback(ctx: FunctionContext) -> mypy.types.Type: return AnyType() class _ExamplePlugin(Plugin): def
get_function_hook( self, fullname: str, ) -> Optional[Callable]: if fullname == 'django.db.models.fields.CharField': return _callback def plugin(version: str) -> Type[Plugin]: """Plugin's public API and entrypoint.""" return _ExamplePlugin
def _callback(ctx: FunctionContext) -> mypy.types.Type: return AnyType() class _ExamplePlugin(Plugin): def
get_function_hook( self, fullname: str, ) -> Optional[Callable]: if fullname == 'django.db.models.fields.CharField': return _callback def plugin(version: str) -> Type[Plugin]: """Plugin's public API and entrypoint.""" return _ExamplePlugin
Ответственность плагина > Уточнение типов > Добавление магических атрибутов >
Прочая дичь!
django.setup()
Хотите глубже?
Как глубока кроличья нора?
Как глубока кроличья нора? > https://mypy.readthedocs.io/en/ stable/extending_mypy.html
Как глубока кроличья нора? > https://mypy.readthedocs.io/en/ stable/extending_mypy.html > https://github.com/typeddjango/ django-stubs/blob/master/
mypy_django_plugin/main.py
>_ X Тестирование типизации
None
None
None
# pytest-mypy-plugins # ./typesafety/test_first.yml - case: test_first main: | from
myapp import a reveal_type(a(1)) # N: Revealed type is 'builtins.float*' files: - path: myapp.py content: | def a(num: int) -> float: return float(num)
>_ X Будущее
Есть хорошие новости
None
Есть интересные новости
if DJANGO_3_0: ... # type specific for 3.0 else: ...
# type specific for other versions
Есть плохие новости
from django.models import QuerySet from myapp.models import User def filter_active_users()
-> QuerySet[User]: return User.objects.filter(is_active=True)
from django.models import QuerySet from myapp.models import User def filter_active_users()
-> 'QuerySet[User]': return User.objects.filter(is_active=True)
None
None
>_ X Попробуй!
github.com/wemake- services/wemake- django-template
>_ X Выводы
Сегодня мы многое поняли
Но что?
Но что? > Типизация – тяжело налазит на магию
Но что? > Типизация – тяжело налазит на магию >
Есть инструменты, которые помогут портировать нетипизированный проект в новый мир
Но что? > Типизация – тяжело налазит на магию >
Есть инструменты, которые помогут портировать нетипизированный проект в новый мир > Плагины справятся со всем остальным!
Что осталось за кадром?
Что осталось за кадром? > SemAnal / NewSemAnal
Что осталось за кадром? > SemAnal / NewSemAnal > Incremental
mode
Что осталось за кадром? > SemAnal / NewSemAnal > Incremental
mode > dmypy
Что осталось за кадром? > SemAnal / NewSemAnal > Incremental
mode > dmypy > Боль и страдания
Ссылки
Ссылки > https://github.com/typeddjango/ django-stubs
Ссылки > https://github.com/typeddjango/ django-stubs > https://github.com/typeddjango/ djangorestframework-stubs
Ссылки > https://github.com/typeddjango/ django-stubs > https://github.com/typeddjango/ djangorestframework-stubs > https://github.com/typeddjango/ pytest-mypy-plugins
Еще (полезные!) ссылки
Еще (полезные!) ссылки > https://github.com/typeddjango/ awesome-python-typing
Еще (полезные!) ссылки > https://github.com/typeddjango/ awesome-python-typing > https://sobolevn.me/2019/08/ typechecking-django-and-drf
Еще (полезные!) ссылки > https://github.com/typeddjango/ awesome-python-typing > https://sobolevn.me/2019/08/ typechecking-django-and-drf >
https://sobolevn.me/2019/08/ testing-mypy-types
Еще (полезные!) ссылки > https://github.com/typeddjango/ awesome-python-typing > https://sobolevn.me/2019/08/ typechecking-django-and-drf >
https://sobolevn.me/2019/08/ testing-mypy-types > https://sobolevn.me/2019/10/ testing-django-migrations
t.me/ opensource_findings 56
drylabs.io/py-quarantine
sobolevn.me Вопросы? github.com/sobolevn