Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Announcing typed-linter
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Sobolev Nikita
June 13, 2021
Programming
330
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Announcing typed-linter
Sobolev Nikita
June 13, 2021
More Decks by Sobolev Nikita
See All by Sobolev Nikita
Чего вы не знали о строках в Python – Василий Рябов, PythoNN
sobolevn
0
260
ИИ-Агенты в каждый дом – Алексей Порядин, PythoNN
sobolevn
0
220
Внутреннее устройство сборки мусора в CPython 3.14+ – Сергей Мирянов, PythoNN
sobolevn
0
150
Генератор байткода и байткод генератора, Михаил Ефимов, PythoNN
sobolevn
0
150
Дотянуться до кремния. HighLoad Python: SIMD, GPU – Пётр Андреев, PythoNN
sobolevn
0
130
Проектирование — это когда чувствуешь, а не какие-то там циферки, Николай Хитров, PythoNN
sobolevn
0
150
Continuous profiling, Давид Джалаев, PythoNN
sobolevn
0
180
Михаил Гурбанов – Are you NATS? @ PythoNN
sobolevn
0
340
Дмитрий Бровкин – Почему исправление опечаток сложнее, чем кажется, и как мы с этим српавляемся @ PythoNN
sobolevn
0
80
Other Decks in Programming
See All in Programming
残高管理から台帳サービスへの進化
artoy
0
140
FreeBSDでZabbixを動かす
kenkino
0
360
仕様駆動開発による爆速プロダクト開発 / Bakusoku Spec Driven Development
kobakei
0
180
手動確認はもう限界 〜XCUITestでCustom URL Schemeの遷移を起動種別ごとに自動テストする〜 / Testing Custom URL Schemes with XCUITest
otouto
0
390
ジョジョの世界をXRで再現する
mofurune
0
110
難しいけど、読めた。- OSSの入口に立った話。
sts11142
0
140
phperだってパンチカードでコーディングしたい
o0h
PRO
0
200
MVNOの申込からeSIM開通までをiOSアプリでつなぐ- 本人確認・MNP・通信事業者基盤をまたぐ実装
satotakeshi
0
540
App Storeの外へ──日本のiOSサイドローディング入門 for iOSDC Japan 2026
yuukiw00w
0
310
大喜利で理解するLLM as a Judge / Understanding LLM-as-a-Judge through Ogiri
rockname
0
190
Everything will be SERVERLESS — 信じて運用した10年の経験値 / Everything Will be Serverless — Lessons Learned from 10 Years of Operational Experience
seike460
PRO
1
740
The Rails Doctrine Decade
koic
2
490
Featured
See All Featured
Build your cross-platform service in a week with App Engine
jlugia
234
19k
Prompt Engineering for Job Search
mfonobong
0
480
The SEO Collaboration Effect
kristinabergwall1
1
590
StorybookのUI Testing Handbookを読んだ
zakiyama
31
7k
Navigating the moral maze — ethical principles for Al-driven product design
skipperchong
2
600
エンジニアに許された特別な時間の終わり
watany
109
250k
Fireside Chat
paigeccino
43
4k
Being A Developer After 40
akosma
91
590k
Building a A Zero-Code AI SEO Workflow
portentint
PRO
0
760
The Director’s Chair: Orchestrating AI for Truly Effective Learning
tmiket
1
310
Side Projects
sachag
456
43k
Building a Scalable Design System with Sketch
lauravandoore
464
34k
Transcript
Никита Соболев github.com/sobolevn 1
>_ X Новые и старые проблемы статического анализа в Python
2
Мы живем в уникальное время 3
Проблемы накопились! 4
Важно! Пользоваться текущими инструментами все равно полезно 5
>_ X Карта текущих решений 6
Flake8 Плагины 7
Flake8 Плагины pylint Плагины 8
Flake8 Плагины pylint Плагины mypy Плагины 9
Flake8 Плагины pylint Плагины mypy Плагины pylance 10
Flake8 Плагины pylint Плагины mypy Плагины pylance pytype 11
Flake8 Плагины pylint Плагины mypy Плагины pylance pytype pyre-check 12
Flake8 Плагины pylint Плагины mypy Плагины pylance pytype pyre-check black
13
Flake8 Плагины pylint Плагины mypy Плагины pylance pytype pyre-check black
autopep8 14
Flake8 Плагины pylint Плагины mypy Плагины pylance pytype pyre-check black
autopep8 fixit 15
Flake8 Плагины pylint Плагины mypy Плагины pylance pytype pyre-check black
autopep8 fixit yapf 16
Flake8 Плагины pylint Плагины mypy Плагины pylance pytype pyre-check black
autopep8 fixit yapf pyupgrade 17
Flake8 Плагины pylint Плагины mypy Плагины pylance pytype pyre-check black
autopep8 fixit yapf pyupgrade Линтеры 18
Flake8 Плагины pylint Плагины mypy Плагины pylance pytype pyre-check black
autopep8 fixit yapf pyupgrade Тайпчекеры Линтеры 19
Flake8 Плагины pylint Плагины mypy Плагины pylance pytype pyre-check black
autopep8 fixit yapf pyupgrade Тайпчекеры Линтеры Авто-форматеры 20
>_ X Что лежит в основе? 21
ast = abstract syntax tree 22
print(name_with_meaning, second_name_with_meaning, third) 23
<_ast.Module> ┗━ body ┣━ [0] <_ast.Expr> ┃ ┗━ value: <_ast.Call>
┃ ┣━ args ┃ ┃ ┣━ [0] <_ast.Name> ┃ ┃ ┃ ┗━ id: first_long_name_with_meaning ┃ ┃ ┣━ [1] <_ast.Name> ┃ ┃ ┃ ┗━ id: second_very_long_name_with_meaning ┃ ┃ ┗━ [2] <_ast.Name> ┃ ┃ ┗━ id: third ┃ ┗━ func: <_ast.Name> ┃ ┗━ id: print 24
Используется > Почти во всех линтерах для анализа кода 25
Проблемы 26
Проблемы > Неконсистентность между версиями Python 26
Проблемы > Неконсистентность между версиями Python > Нет информации о
типах 26
Проблемы > Неконсистентность между версиями Python > Нет информации о
типах > Нет нюансов синтаксиса 26
Проблемы > Неконсистентность между версиями Python > Нет информации о
типах > Нет нюансов синтаксиса > Нет комментариев 26
tokenize 27
28 print("test", a, b)
29
Используется 30
Используется > Для проверки нюансов синтаксиса 30
Используется > Для проверки нюансов синтаксиса > Для авто-форматирования в
некоторых инструментах 30
Проблемы 31
Проблемы > Представляет собой не "структуру", а простой список 31
Проблемы > Представляет собой не "структуру", а простой список >
Вообще ничего не знает / не умеет 31
Проблемы > Представляет собой не "структуру", а простой список >
Вообще ничего не знает / не умеет > Очень сложен в работе для правил с хоть какой-то логикой 31
libcst = Concrete Syntax Tree 32
Используется 33
Используется > В инфраструктуре Инстаграма 33
Используется > В инфраструктуре Инстаграма > Во многих новых библиотеках
для авто-форматирования 33
Используется > В инфраструктуре Инстаграма > Во многих новых библиотеках
для авто-форматирования > Для проверки нюансов синтаксиса 33
Используется > В инфраструктуре Инстаграма > Во многих новых библиотеках
для авто-форматирования > Для проверки нюансов синтаксиса > Для анализа кода 33
Проблемы 34
Проблемы > Сбоит на некоторых синтаксических конструкциях Python3.9 https:// github.com/Instagram/LibCST/
issues/490 34
Проблемы > Сбоит на некоторых синтаксических конструкциях Python3.9 https:// github.com/Instagram/LibCST/
issues/490 > Не работает с Python3.10+ https:// github.com/Instagram/LibCST/ issues/285 34
typed-tree* *(такого нет) 35
Используется 36
Используется > В любом тайпчекере для представления нашего кода с
типами 36
Используется > В любом тайпчекере для представления нашего кода с
типами > Для каждого тайпчекера - оно свое 36
Проблемы 37
Проблемы > У каждой реализации они свои! 37
Проблемы > У каждой реализации они свои! > Нет единого
стандарта 37
Проблемы > У каждой реализации они свои! > Нет единого
стандарта > В каждом тайпчекере поддерживается далеко не все возможности 37
Проблемы > У каждой реализации они свои! > Нет единого
стандарта > В каждом тайпчекере поддерживается далеко не все возможности > Нигде (кроме mypy) нет возможности подключать плагины 37
>_ X Пару слов про устаревшие инструменты 38
Flake8 39
Flake8 > Примитивная конфигурация 39
Flake8 > Примитивная конфигурация > Нет типов 39
Flake8 > Примитивная конфигурация > Нет типов > Невозможно нормально
внедрить 39
Pylint 40
Pylint > Примитивная конфигурация 40
Pylint > Примитивная конфигурация > Нет типов 40
Pylint > Примитивная конфигурация > Нет типов > Но лучше
бы их совсем не было 40
Pylint > Примитивная конфигурация > Нет типов > Но лучше
бы их совсем не было > Невозможно нормально внедрить 40
Black 41
Black > Супер примитивный 41
Black > Супер примитивный > Использует lib2to3 41
>_ X Новые проблемы 42
Новый парсер / новая грамматика 43
44
Аннотации github.com/samuelcolvin/pydantic/issues/2678 45
PEP 563 mail.python.org/archives/list/
[email protected]
/thread/ CLVXXPQ2T2LQ5MP2Y53VVQFCXYWQJHKZ 46
Pattern Matching 47
>_ X Так что делать? 48
typed-linter 49
typed-linter > Нормальная конфигурация в духе eslint 49
typed-linter > Нормальная конфигурация в духе eslint > Провайдеры типов
49
typed-linter > Нормальная конфигурация в духе eslint > Провайдеры типов
> Гибкая система плагинов 49
typed-linter > Нормальная конфигурация в духе eslint > Провайдеры типов
> Гибкая система плагинов > Авто-форматирование 49
typed-linter > Нормальная конфигурация в духе eslint > Провайдеры типов
> Гибкая система плагинов > Авто-форматирование > Нормальное внедрение 49
Конфигурация 50
Как сейчас? 51
[flake8] format = wemake show-source = True statistics = False
doctests = True # darglint configuration: # https://github.com/terrencepreilly/darglint strictness = long docstring-style = numpy # Plugins: max-complexity = 6 max-line-length = 80 # wemake-python-styleguide settings: i-control-code = False 52
[tool.nitpick] style = "https://raw.githubusercontent.com/wemake-services/ wemake-python-styleguide/master/styles/nitpick-style- wemake.toml" [tool.poetry.dev-dependencies] nitpick = "^0.23"
53
54
Как надо? 55
extends: - typed-linter/recommended - 'url:https://path-to-my-config/file.yml' - 'file:local/path/file.yml' checks: - name:
typed-linter/new-style-generics level: error extras: allow-old-style: [typing.List] settings: type-engine: name: typed-linter/mypy reporter: name: typed-linter/rich 56
extends: - typed-linter/recommended - 'url:https://path-to-my-config/file.yml' - 'file:local/path/file.yml' checks: - name:
typed-linter/new-style-generics level: error extras: allow-old-style: [typing.List] settings: type-engine: name: typed-linter/mypy reporter: name: typed-linter/rich 57
extends: - typed-linter/recommended - 'url:https://path-to-my-config/file.yml' - 'file:local/path/file.yml' checks: - name:
typed-linter/new-style-generics level: error extras: allow-old-style: [typing.List] settings: type-engine: name: typed-linter/mypy reporter: name: typed-linter/rich 58
Игнорирование ошибок 59
checks: - name: typed-linter/eqeq-is-mixup level: none overrides: - glob: some/**/*.py
checks: - name: typed-linter/new-style-generics level: none type-overrides: - astpath: | \\ClassDef[type=django.url.URLConf]\method[name=locate] checks: - name: typed-linter/hidden-any level: none 60
checks: - name: typed-linter/eqeq-is-mixup level: none overrides: - glob: some/**/*.py
checks: - name: typed-linter/new-style-generics level: none type-overrides: - astpath: | \\ClassDef[type=django.url.URLConf]\method[name=locate] checks: - name: typed-linter/hidden-any level: none 61
Не все библиотеки одинаково полезны! github.com/wemake-services/wemake-python-styleguide/issues/1737 62
my_num = 5 my_num >> 2 # useless! 63
unload_task = _unload_to_file(export_config) if not export_config.is_incremental: _latest_only(export_config.athena_table_name) >> unload_task unload_task
\ >> _upload_to_s3(export_config.athena_table_name) \ >> [ _clear_export_dir_and_logs(export_config.athena_table_name), *_repair_tables(export_config), ] 64
checks: - name: typed-linter/eqeq-is-mixup level: none overrides: - glob: some/**/*.py
checks: - name: typed-linter/new-style-generics level: none type-overrides: - astpath: | \\ClassDef[type=django.url.URLConf]\method[name=locate] checks: - name: typed-linter/hidden-any level: none 65
Система плагинов 66
API 67
class BasePlugin(object): def __init__(self, name: str, checks: CheckTypeSpec): ... @classmethod
def load_checks( cls, configuration: Configuration, loader: ConventionalLoader, ) -> Sequence[CheckTypeSpec]: ... def run_project_checks( self, type_engine: BaseTypeEngine, project_modules: ProjectModules, configuration: Configuration, ) -> Iterable[BaseViolation]: ... def run_module_checks( self, type_checker: BaseTypeChecker, configuration: Configuration, module_spec: ModuleSpec, ) -> Iterable[BaseViolation]: ...
Система конвенций 69
70
71
extends: - typed-linter/recommended - flake8/recommended overrides: - glob: some/**/*.py checks:
- name: flake8/F001 level: none settings: type-engine: name: your-project/pytype reporter: name: circle-ci/json 72
Поменять провайдер типов? 73
74
extends: - typed-linter/recommended - flake8/recommended overrides: - glob: some/**/*.py checks:
- name: flake8/F001 level: none settings: type-engine: name: your-project/pytype reporter: name: circle-ci/json 75
Включить flake8? 76
extends: - typed-linter/recommended - flake8/recommended overrides: - glob: some/**/*.py checks:
- name: flake8/F001 level: none settings: type-engine: name: your-project/pytype reporter: name: circle-ci/json 77
Внедрение 78
--baseline > FlakeHell: https:// flakehell.readthedocs.io/commands/ baseline.html > wemake-python-styleguide: https:// github.com/wemake-services/wemake-
python-styleguide/pull/1276 79
Как оно будет? 80
Как оно будет? > typed-linter --baseline myproject 80
Как оно будет? > typed-linter --baseline myproject > Все ошибки
запомнились 80
Как оно будет? > typed-linter --baseline myproject > Все ошибки
запомнились > typed-linter --baseline myproject 80
Как оно будет? > typed-linter --baseline myproject > Все ошибки
запомнились > typed-linter --baseline myproject > Старых ошибок нет 80
Как оно будет? > typed-linter --baseline myproject > Все ошибки
запомнились > typed-linter --baseline myproject > Старых ошибок нет > Новые делать нельзяы 80
Проблемы 81
Проблемы > В текущей реализации очень сложно идентифицировать ошибку и
привязать её к определенному месту 81
Проблемы > В текущей реализации очень сложно идентифицировать ошибку и
привязать её к определенному месту > Раньше мы оперировали только: строками, позицией, кодом ошибки 81
Авто-форматирование 82
😭 😭 😭 83
Есть одно "но" github.com/wemake-services/typed-linter 84
85
>_ X 💰 86
Планы релиза > SponsorsWare > Dual License > Contributor-based 87
А пока 88
Самый строгий линтер в мире github.com/wemake-services/wemake-python-styleguide 89
sobolevn.me/2019/10/complexity-waterfall 90
sobolevn.me Вопросы? github.com/sobolevn 91