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
Announcing typed-linter
Search
Sobolev Nikita
June 13, 2021
Programming
310
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
240
ИИ-Агенты в каждый дом – Алексей Порядин, PythoNN
sobolevn
0
220
Внутреннее устройство сборки мусора в CPython 3.14+ – Сергей Мирянов, PythoNN
sobolevn
0
130
Генератор байткода и байткод генератора, Михаил Ефимов, PythoNN
sobolevn
0
130
Дотянуться до кремния. HighLoad Python: SIMD, GPU – Пётр Андреев, PythoNN
sobolevn
0
120
Проектирование — это когда чувствуешь, а не какие-то там циферки, Николай Хитров, PythoNN
sobolevn
0
140
Continuous profiling, Давид Джалаев, PythoNN
sobolevn
0
160
Михаил Гурбанов – Are you NATS? @ PythoNN
sobolevn
0
320
Дмитрий Бровкин – Почему исправление опечаток сложнее, чем кажется, и как мы с этим српавляемся @ PythoNN
sobolevn
0
69
Other Decks in Programming
See All in Programming
為什麼你並不需要ViewModel / No, you don't need a ViewModel
lovee
1
480
生成AIで帳票OCRが「簡単に」作れる時代になった?
kon_shou
0
420
Lean は証明の正しさを確認するためだけのツールって思ってませんか?
inoueasei
1
140
型も通る、synthも通る、それでも危ない 〜AIのCDKの権限とコストを機械で検証する〜 / It Passes Type Checks, It Passes Synth Checks, but It’s Still Risky — Automatically Verifying Permissions and Costs in AI’s CDK —
seike460
PRO
1
530
Japan Community Day at Kubecon + CloudNativeCon Japan 2026: Learning Container Privilege Control by Building My Own Low-Level Container Runtime
ternbusty
1
130
属人化した知識を、 AIが辿れる地図にする
pkshadeck
PRO
1
140
2年かけて Deno に DOMMatrix を実装した話 / How I implemented DOMMatrix in Deno over two years
petamoriken
0
200
yield再入門 #phpcon
o0h
PRO
0
930
これって Effect でできたのでは? / TSKaigi Mashup Kansai #2
susisu
0
140
Apache Hive: Toward a Cloud Native Lakehouse
okumin
0
180
AI Engineeringは、AIプロダクトだけのものか? 〜AIがソフトウェアを作る時代の新しい当たり前〜 / No AI in your product. AI Engineering in your development.
rkaga
4
360
テーブルをDELETEした
yuzneri
0
130
Featured
See All Featured
Become a Pro
speakerdeck
PRO
31
6.1k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
28
3.6k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
21
1.6k
What's in a price? How to price your products and services
michaelherold
247
13k
Joys of Absence: A Defence of Solitary Play
codingconduct
1
420
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
34
2.8k
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
Marketing Yourself as an Engineer | Alaka | Gurzu
gurzu
0
270
Building an army of robots
kneath
306
46k
A Soul's Torment
seathinner
6
3.3k
BBQ
matthewcrist
89
10k
Making the Leap to Tech Lead
cromwellryan
135
10k
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