Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Typing Django

Typing Django

Sobolev Nikita

March 27, 2020
Tweet

More Decks by Sobolev Nikita

Other Decks in Programming

Transcript

  1. А их много: > Гигантская (и плохая) кодовая база без

    типов > Нет прав на её редактирование (!)
  2. А их много: > Гигантская (и плохая) кодовая база без

    типов > Нет прав на её редактирование (!) > Куча магии
  3. А их много: > Гигантская (и плохая) кодовая база без

    типов > Нет прав на её редактирование (!) > Куча магии > Нет поддержки нового API типизации
  4. 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]
  5. 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
  6. 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
  7. 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
  8. # 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)
  9. if DJANGO_3_0: ... # type specific for 3.0 else: ...

    # type specific for other versions
  10. from django.models import QuerySet from myapp.models import User def filter_active_users()

    -> QuerySet[User]: return User.objects.filter(is_active=True)
  11. from django.models import QuerySet from myapp.models import User def filter_active_users()

    -> 'QuerySet[User]': return User.objects.filter(is_active=True)
  12. Но что? > Типизация – тяжело налазит на магию >

    Есть инструменты, которые помогут портировать нетипизированный проект в новый мир
  13. Но что? > Типизация – тяжело налазит на магию >

    Есть инструменты, которые помогут портировать нетипизированный проект в новый мир > Плагины справятся со всем остальным!
  14. Еще (полезные!) ссылки > 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