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
320
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
250
ИИ-Агенты в каждый дом – Алексей Порядин, PythoNN
sobolevn
0
220
Внутреннее устройство сборки мусора в CPython 3.14+ – Сергей Мирянов, PythoNN
sobolevn
0
140
Генератор байткода и байткод генератора, Михаил Ефимов, PythoNN
sobolevn
0
140
Дотянуться до кремния. 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
79
Other Decks in Programming
See All in Programming
Go × SIMDで高速化するベクトル検索 ~ルーフラインモデルでSIMDが効く境界を探れ! ~
po3rin
1
800
[DroidKaigi 2026] Bring your own phones to Gradle Managed Devices
f2lk
0
120
技術的負債の返済は、AI時代の複利で効く投資 — 経営としての意思決定とその遂行
curekoshimizu
0
1.2k
モバイル交通系ICへのチャージ実例から考える、クロスプラットフォーム開発におけるiOS実機テスト設計とCI運用
yusuga
1
460
巨大モノリシックアプリ モダン化大作戦
ktcryomm
0
1k
個人開発基盤をまるごとCloudflareに引っ越して爆速で総合的体験を向上させた話
tinykitten
0
180
iOSDC Japan 2026 - Swiftで作って学ぼう!データベース自作入門
kaseken
2
160
Vue Fes Japan 2026 タイムテーブル徹底解説
448jp
0
120
kubernetes コンポーネント開発入門 / 新卒N年目の勉強会&交流会!〜〇〇への誘い〜 #n_study
mazrean
0
240
型解析で実現する Go の言語内 DSL / Conference に Go! タイムテーブルの歩き方 for Gophers
mazrean
0
150
AIは賢い。でも実行環境は? CLIおじさんがAI時代に伝えたいこと ~ CLIおじさんがAI時代に伝えたいこと ~
curekoshimizu
1
240
Family mrubyの進捗
kishima
1
120
Featured
See All Featured
4 Signs Your Business is Dying
shpigford
187
23k
Faster Mobile Websites
deanohume
310
32k
Navigating Weather and Climate Data
rabernat
0
520
How GitHub (no longer) Works
holman
316
150k
The Director’s Chair: Orchestrating AI for Truly Effective Learning
tmiket
1
300
Lightning talk: Run Django tests with GitHub Actions
sabderemane
0
250
So, you think you're a good person
axbom
PRO
2
2.2k
Mobile First: as difficult as doing things right
swwweet
225
10k
Why Mistakes Are the Best Teachers: Turning Failure into a Pathway for Growth
auna
0
280
The Spectacular Lies of Maps
axbom
PRO
1
990
Fashionably flexible responsive web design (full day workshop)
malarkey
409
67k
Winning Ecommerce Organic Search in an AI Era - #searchnstuff2025
aleyda
1
2.1k
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