SlideShare a Scribd company logo
Python Linters at Scale
Jimmy Lai, Staff Software Engineer at Carta
April 22, 2023
2
What to Expect?
● ❗Problems
● 🛠 Tools
● ☑ Checklists
3
Tax
Fund Admin.
Compensation
Valuation
Startup Founder
Employee
Stock
Option
Investor
Stock
Money
4
Python Codebases
Monolith: a large codebase
3 million lines of code
Service 1 Library 1
Service 2 Library 2
Service 2 Library 2
… …
Micro Services
Many Developers
Popular Python Linters
6
Black: code formatting
https://github.com/psf/black
🛠
pyproject.toml
[tool.black]
Line-length = 120 # defaults to 88
target-version = ["py39"]
exclude = "some_path"
# include = defaults to “.pyi?$”
7
isort: import sorting
https://github.com/PyCQA/isort
🛠
pyproject.toml
[tool.isort]
profile = 'black'
line_length = 120
8
Flake8: code style, syntax errors and bugs
https://github.com/PyCQA/flake8
🛠
In setup.cfg, tox.ini or .flake8
[flake8]
max-line-length=120
# select=E,W # pycodestyle
# F # pyflakes
ignore=E203,E501 # conflict to Black on py files
E301,E302 # conflict to Black on pyi files
9
mypy: type checking
% mypy example.py
mypy.py:4: error: Argument 1 to
"greeting" has incompatible type
"int"; expected "str" [arg-type]
mypy.py:5: error: Argument 1 to
"greeting" has incompatible type
"bytes"; expected "str" [arg-type]
Found 2 errors in 1 file (checked 1
source file)
https://github.com/python/mypy 🛠
pyproject.toml
[tool.mypy]
# strict type annotation
# explicit over implicit
warn_return_any = true
warn_unused_configs = true
warn_unused_ignores = true
warn_redundant_casts = true
disallow_incomplete_defs = true
disallow_untyped_defs = true
no_implicit_optional = true
Common Linter Practices
Version Control in a codebase:
● Linter versions
● Linter configs
Python package management:
● pip with a requirements.txt
● poetry with a pyproject.toml and a lock file
Install specific versions of linters and use the linter config file in the codebase
Version Control
11
pyproject.toml
[tool.isort]
profile = 'black'
line_length = 120
requirements-dev.txt
isort==5.10.0
Goal: detect linter errors at development time to iterate fast
Setup local environment:
● pip/poetry install
● docker
Run linters at:
● Commit time via git commit hooks
● Edit time via IDE plugin or file watcher on file changes
● Ad-hoc via linter CLI command
Local Runs
12
13
Continuous Integration (CI) Runs
Pre-install and cache dependencies in CI runners:
● Remote cache
● Docker image
Run linters when a commit is pushed
Scaling Challenges
❗Slow Linters: 10-30+ minutes
Large Codebase
15
Monolith: a large codebase
30,000+ Python files
❗Poor Developer Experience:
● Inconsistent linter version
and configuration
● Endless efforts on upgrading
linters and configs
Multiple Codebases
16
Service 1 Library 1
Service 2 Library 2
Service 2 Library 2
… …
Linter A
Linter A
Linter A
Linter B
Linter B
Linter B
Linter B
❗Poor Developer Experience
● Observability is missing
● Linter/test errors may be merged to the
main branch
● Developers are slowed down by linter
suggestions
● Missing best practices on things other
than Python, e.g. Github, Docker, etc.
Many Developers
17
Pull
Request
1
Pull
Request
2
Pull
Request
3
Pull
Request
4
Pull
Request
5
Solutions
19
❗Checklist for Speeding up Linters
Strategy: Avoid unnecessary code analysis on large number of code
Checklist:
❏ Only run on updated code
❏ Run in parallel
❏ Reuse prior results
❏ Faster implementation
20
Only run necessary analysis on updated code
Local:
● get updated files from git:
○ git diff --name-only --diff-filter=d
● Run linters in daemon mode with a file watcher (e.g. watchman)
○ mypy daemon
CI: get updated files from Github Pulls API (application/vnd.github.diff)
● gh api -H "Accept: application/vnd.github.VERSION.diff"
/repos/python/cpython/pulls/100957
✓ Only run on updated code
❏ Run in parallel
❏ Reuse prior results
❏ Faster implementation
21
pre-commit: manage pre-commit hooks
Features:
● Run on committed files
● Run linters in parallel
● Reuse installed linters with a
virtualenv
https://github.com/pre-commit/pre-commit 🛠
.pre-commit-config.yaml
repos:
- repo: 'https://github.com/psf/black'
rev: 22.10.0
hooks:
- id: black
✓ Only run on updated code
✓ Run in parallel
❏ Reuse prior results
❏ Faster implementation
22
Some linters (e.g. mypy) require the knowledge of the dependency graph
Cache the prior results of the entire codebase
Workflow:
● Download most recent cache based on Git revision
● Run linters with cache
● Upload cache to be reused later
Use case: use mypy remote cache improved our mypy CI run from 20+ minutes to
less than 5 minutes
Remote Cache
❏ Only run on updated code
❏ Run in parallel
✓ Reuse prior results
❏ Faster implementation
23
Ruff: fast linter implementation using rust
Implements:
● Flake8
● isort
Parse source code once
across supported linters
Cache results and skip
unchanged files
https://github.com/charliermarsh/ruff 🛠
❏ Only run on updated code
❏ Run in parallel
✓ Reuse prior results
✓ Faster implementation
24
❗Checklist for Improving Developer Experience
Problems:
● Inconsistent linter version and
configuration
● Endless efforts on upgrading linters
and configs
● Observability is missing
● Linter/test errors may be merged to
the main branch
● Developers are slowed down by linter
suggestions
● Missing best practices on things
other than Python, e.g. Github,
Docker, etc.
Strategy: Build linters for best
practices and provide autofixes for
productivity
Checklist:
❏ Telemetry
❏ Custom Linter
❏ Autofix
Collect metrics from CI and Local runs:
● Where: environment, Git codebase and branch
● What: linter suggestions
● How: latency, exception stack trace
Understand Developer Experience
25
✓ Telemetry
❏ Custom Linter
❏ Autofix
26
fixit: Python linters and autofixes using LibCST
ExplicitFrozenDataclassRule
@dataclass
class Data:
name: str
# linter suggestion:
# When using dataclasses, explicitly
specify a frozen keyword argument.
# suggested fix
@dataclass(frozen=True)
class Data:
name: str
UseFstringRule
"%s" % "hi"
# linter suggestion:
# Do not use printf style formatting or
.format().
# Use f-string instead to be more
readable and efficient.
# See
https://www.python.org/dev/peps/pep-0498/
# suggested fix
f"{'hi'}"
https://github.com/Instagram/Fixit 🛠
❏ Telemetry
✓ Custom Linter
✓ Autofix
27
Our Custom Python Linters: Github Check with annotations
Github Check:
● Use required check
for branch protection
● Use annotations to
provide inline
context to speed up
the fix
❏ Telemetry
✓ Custom Linter
❏ Autofix
28
Our Custom non-Python Linters: rebase reminder
Errors may be merged into the main branch
A
| 
B PR1
| 
C PR2
(x)
✓ Telemetry
✓ Custom Linter
❏ Autofix
29
Our Custom Python Linters: deprecation toolkit
Too many pre-existing
linter errors
Need to resolve them
incrementally
Linters for prevent new
usages
Run linters to collect
historical data to drive
progress over time
✓ Telemetry
✓ Custom Linter
❏ Autofix
30
Reusable Workflows
Build reusable workflows to be shared across codebases easily, e.g. Github
reusable workflows
Build a reusable framework:
● Simple APIs for building linters and autofixes
● Collect metrics
● Generate Github Check with annotations easily
✓ Telemetry
✓ Custom Linter
✓ Autofix
31
Automated Refactoring
Auto bump version: Github Dependabot
Auto fix linter errors:
● LibCST: custom codemods
● PyGithub: create pull requests
Build an automated refactoring framework:
● Create pull requests and manage their life cycle until merges
● [talk] Automated Refactoring in Large Python Codebases (EuroPython 2022)
● [blog] Type annotation via automated refactoring (link)
❏ Telemetry
❏ Custom Linter
✓ Autofix
Our Custom Python Autofixes: Flake8
32
❏ Telemetry
❏ Custom Linter
✓ Autofix
Our Custom Python Autofixes: mypy
33
❏ Telemetry
❏ Custom Linter
✓ Autofix
34
Our Custom non-Python Autofixes: notify-reviewer-teams
Sometimes PRs are blocked
on code reviews.
❏ Telemetry
❏ Custom Linter
✓ Autofix
35
Our Custom non-Python Autofixes: release-on-merge
❏ Telemetry
❏ Custom Linter
✓ Autofix
36
Results
Support 200+ developers in 30+ codebases to run common Python linters with
consistent configs and autofixes
Each week, the linters run 10k+ times and provide 25k+ suggestions.
So far, the autofixes have been used 7000+ times and saved lots of developer time.
37
Recap
Slow Linter Checklist:
✓ Only run on updated code
✓ Run in parallel
✓ Reuse prior results
✓ Faster implementation
Developer Experience Checklist:
✓ Telemetry
✓ Linter
✓ Autofix
38
Thank you for your attentions!
Carta Engineering Blog https://medium.com/building-carta
Carta Jobs https://boards.greenhouse.io/carta

More Related Content

PPTX
스마트폰 온라인 게임에서 고려해야 할 것들
PDF
Paralelismo y sincronizacion scratch
PDF
Introduction-to-Git-Github-andWorshop.pdf
PDF
Applied Machine learning for business analytics
PDF
Continuous Delivery: 5 years later (Incontro DevOps 2018)
PDF
Rejekts 24 EU No GitOps Pain, No Platform Gain
PDF
Webinar - Unbox GitLab CI/CD
PPTX
Cinder On-boarding Room - Berlin (11-13-2018)
스마트폰 온라인 게임에서 고려해야 할 것들
Paralelismo y sincronizacion scratch
Introduction-to-Git-Github-andWorshop.pdf
Applied Machine learning for business analytics
Continuous Delivery: 5 years later (Incontro DevOps 2018)
Rejekts 24 EU No GitOps Pain, No Platform Gain
Webinar - Unbox GitLab CI/CD
Cinder On-boarding Room - Berlin (11-13-2018)

Similar to Python Linters at Scale.pdf (20)

PPTX
Understanding the GitOps Workflow and CICD Pipeline - What It Is, Why It Matt...
PPTX
Open source
PDF
Vibe Coding_ Develop a web application using AI (1).pdf
PDF
Goodpractice
PPTX
Symfony Under Control by Maxim Romanovsky
PPTX
Symfony under control. Continuous Integration and Automated Deployments in Sy...
PDF
Software maintenance PyConUK 2016
PPTX
Python for IoT CoE.pptx KDOJWIHJNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
PPTX
OpenStack Cinder On-Boarding Room - Vancouver Summit 2018
PDF
Piyush Mishra(191381030040).pdf
PDF
The State of Logging on Docker
PDF
Gitlab Commit: How Containerized GitLab CI Pipelines Can Help You Streamline ...
PPTX
Jfokus 2016 - A JVMs Journey into Polyglot Runtimes
PDF
Docker and the K computer
PPTX
Headless browser: puppeteer and git client : GitKraken
PPTX
tech winter break workshop on git &git hub.pptx
PDF
Assign, commit, and review - A developer’s guide to OpenStack contribution-20...
PDF
Traefik on Kubernetes at MySocialApp (CNCF Paris Meetup)
PDF
EuroPython 2013 - Python3 TurboGears Training
PDF
Free GitOps Workshop
Understanding the GitOps Workflow and CICD Pipeline - What It Is, Why It Matt...
Open source
Vibe Coding_ Develop a web application using AI (1).pdf
Goodpractice
Symfony Under Control by Maxim Romanovsky
Symfony under control. Continuous Integration and Automated Deployments in Sy...
Software maintenance PyConUK 2016
Python for IoT CoE.pptx KDOJWIHJNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
OpenStack Cinder On-Boarding Room - Vancouver Summit 2018
Piyush Mishra(191381030040).pdf
The State of Logging on Docker
Gitlab Commit: How Containerized GitLab CI Pipelines Can Help You Streamline ...
Jfokus 2016 - A JVMs Journey into Polyglot Runtimes
Docker and the K computer
Headless browser: puppeteer and git client : GitKraken
tech winter break workshop on git &git hub.pptx
Assign, commit, and review - A developer’s guide to OpenStack contribution-20...
Traefik on Kubernetes at MySocialApp (CNCF Paris Meetup)
EuroPython 2013 - Python3 TurboGears Training
Free GitOps Workshop
Ad

More from Jimmy Lai (20)

PDF
[PyCon US 2025] Scaling the Mountain_ A Framework for Tackling Large-Scale Te...
PDF
PyCon JP 2024 Streamlining Testing in a Large Python Codebase .pdf
PDF
EuroPython 2024 - Streamlining Testing in a Large Python Codebase
PDF
EuroPython 2022 - Automated Refactoring Large Python Codebases
PDF
Annotate types in large codebase with automated refactoring
PDF
The journey of asyncio adoption in instagram
PDF
Data Analyst Nanodegree
PDF
Distributed system coordination by zookeeper and introduction to kazoo python...
PDF
Continuous Delivery: automated testing, continuous integration and continuous...
PDF
Build a Searchable Knowledge Base
PDF
[LDSP] Solr Usage
PDF
[LDSP] Search Engine Back End API Solution for Fast Prototyping
PDF
Text classification in scikit-learn
PDF
Big data analysis in python @ PyCon.tw 2013
PDF
Text Classification in Python – using Pandas, scikit-learn, IPython Notebook ...
PDF
Software development practices in python
PDF
Fast data mining flow prototyping using IPython Notebook
PDF
Documentation with sphinx @ PyHug
PDF
Apache thrift-RPC service cross languages
PDF
NetworkX - python graph analysis and visualization @ PyHug
[PyCon US 2025] Scaling the Mountain_ A Framework for Tackling Large-Scale Te...
PyCon JP 2024 Streamlining Testing in a Large Python Codebase .pdf
EuroPython 2024 - Streamlining Testing in a Large Python Codebase
EuroPython 2022 - Automated Refactoring Large Python Codebases
Annotate types in large codebase with automated refactoring
The journey of asyncio adoption in instagram
Data Analyst Nanodegree
Distributed system coordination by zookeeper and introduction to kazoo python...
Continuous Delivery: automated testing, continuous integration and continuous...
Build a Searchable Knowledge Base
[LDSP] Solr Usage
[LDSP] Search Engine Back End API Solution for Fast Prototyping
Text classification in scikit-learn
Big data analysis in python @ PyCon.tw 2013
Text Classification in Python – using Pandas, scikit-learn, IPython Notebook ...
Software development practices in python
Fast data mining flow prototyping using IPython Notebook
Documentation with sphinx @ PyHug
Apache thrift-RPC service cross languages
NetworkX - python graph analysis and visualization @ PyHug
Ad

Recently uploaded (20)

PDF
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
PDF
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
PDF
Review of recent advances in non-invasive hemoglobin estimation
PPTX
20250228 LYD VKU AI Blended-Learning.pptx
PPTX
Cloud computing and distributed systems.
PDF
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
PDF
The Rise and Fall of 3GPP – Time for a Sabbatical?
DOCX
The AUB Centre for AI in Media Proposal.docx
PDF
Reach Out and Touch Someone: Haptics and Empathic Computing
PPTX
Digital-Transformation-Roadmap-for-Companies.pptx
PDF
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
PDF
Advanced methodologies resolving dimensionality complications for autism neur...
PDF
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
PPTX
Spectroscopy.pptx food analysis technology
PDF
gpt5_lecture_notes_comprehensive_20250812015547.pdf
PPTX
A Presentation on Artificial Intelligence
PDF
Empathic Computing: Creating Shared Understanding
PDF
Approach and Philosophy of On baking technology
PDF
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
PPTX
ACSFv1EN-58255 AWS Academy Cloud Security Foundations.pptx
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
Review of recent advances in non-invasive hemoglobin estimation
20250228 LYD VKU AI Blended-Learning.pptx
Cloud computing and distributed systems.
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
The Rise and Fall of 3GPP – Time for a Sabbatical?
The AUB Centre for AI in Media Proposal.docx
Reach Out and Touch Someone: Haptics and Empathic Computing
Digital-Transformation-Roadmap-for-Companies.pptx
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
Advanced methodologies resolving dimensionality complications for autism neur...
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
Spectroscopy.pptx food analysis technology
gpt5_lecture_notes_comprehensive_20250812015547.pdf
A Presentation on Artificial Intelligence
Empathic Computing: Creating Shared Understanding
Approach and Philosophy of On baking technology
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
ACSFv1EN-58255 AWS Academy Cloud Security Foundations.pptx

Python Linters at Scale.pdf

  • 1. Python Linters at Scale Jimmy Lai, Staff Software Engineer at Carta April 22, 2023
  • 2. 2 What to Expect? ● ❗Problems ● 🛠 Tools ● ☑ Checklists
  • 4. 4 Python Codebases Monolith: a large codebase 3 million lines of code Service 1 Library 1 Service 2 Library 2 Service 2 Library 2 … … Micro Services Many Developers
  • 6. 6 Black: code formatting https://github.com/psf/black 🛠 pyproject.toml [tool.black] Line-length = 120 # defaults to 88 target-version = ["py39"] exclude = "some_path" # include = defaults to “.pyi?$”
  • 8. 8 Flake8: code style, syntax errors and bugs https://github.com/PyCQA/flake8 🛠 In setup.cfg, tox.ini or .flake8 [flake8] max-line-length=120 # select=E,W # pycodestyle # F # pyflakes ignore=E203,E501 # conflict to Black on py files E301,E302 # conflict to Black on pyi files
  • 9. 9 mypy: type checking % mypy example.py mypy.py:4: error: Argument 1 to "greeting" has incompatible type "int"; expected "str" [arg-type] mypy.py:5: error: Argument 1 to "greeting" has incompatible type "bytes"; expected "str" [arg-type] Found 2 errors in 1 file (checked 1 source file) https://github.com/python/mypy 🛠 pyproject.toml [tool.mypy] # strict type annotation # explicit over implicit warn_return_any = true warn_unused_configs = true warn_unused_ignores = true warn_redundant_casts = true disallow_incomplete_defs = true disallow_untyped_defs = true no_implicit_optional = true
  • 11. Version Control in a codebase: ● Linter versions ● Linter configs Python package management: ● pip with a requirements.txt ● poetry with a pyproject.toml and a lock file Install specific versions of linters and use the linter config file in the codebase Version Control 11 pyproject.toml [tool.isort] profile = 'black' line_length = 120 requirements-dev.txt isort==5.10.0
  • 12. Goal: detect linter errors at development time to iterate fast Setup local environment: ● pip/poetry install ● docker Run linters at: ● Commit time via git commit hooks ● Edit time via IDE plugin or file watcher on file changes ● Ad-hoc via linter CLI command Local Runs 12
  • 13. 13 Continuous Integration (CI) Runs Pre-install and cache dependencies in CI runners: ● Remote cache ● Docker image Run linters when a commit is pushed
  • 15. ❗Slow Linters: 10-30+ minutes Large Codebase 15 Monolith: a large codebase 30,000+ Python files
  • 16. ❗Poor Developer Experience: ● Inconsistent linter version and configuration ● Endless efforts on upgrading linters and configs Multiple Codebases 16 Service 1 Library 1 Service 2 Library 2 Service 2 Library 2 … … Linter A Linter A Linter A Linter B Linter B Linter B Linter B
  • 17. ❗Poor Developer Experience ● Observability is missing ● Linter/test errors may be merged to the main branch ● Developers are slowed down by linter suggestions ● Missing best practices on things other than Python, e.g. Github, Docker, etc. Many Developers 17 Pull Request 1 Pull Request 2 Pull Request 3 Pull Request 4 Pull Request 5
  • 19. 19 ❗Checklist for Speeding up Linters Strategy: Avoid unnecessary code analysis on large number of code Checklist: ❏ Only run on updated code ❏ Run in parallel ❏ Reuse prior results ❏ Faster implementation
  • 20. 20 Only run necessary analysis on updated code Local: ● get updated files from git: ○ git diff --name-only --diff-filter=d ● Run linters in daemon mode with a file watcher (e.g. watchman) ○ mypy daemon CI: get updated files from Github Pulls API (application/vnd.github.diff) ● gh api -H "Accept: application/vnd.github.VERSION.diff" /repos/python/cpython/pulls/100957 ✓ Only run on updated code ❏ Run in parallel ❏ Reuse prior results ❏ Faster implementation
  • 21. 21 pre-commit: manage pre-commit hooks Features: ● Run on committed files ● Run linters in parallel ● Reuse installed linters with a virtualenv https://github.com/pre-commit/pre-commit 🛠 .pre-commit-config.yaml repos: - repo: 'https://github.com/psf/black' rev: 22.10.0 hooks: - id: black ✓ Only run on updated code ✓ Run in parallel ❏ Reuse prior results ❏ Faster implementation
  • 22. 22 Some linters (e.g. mypy) require the knowledge of the dependency graph Cache the prior results of the entire codebase Workflow: ● Download most recent cache based on Git revision ● Run linters with cache ● Upload cache to be reused later Use case: use mypy remote cache improved our mypy CI run from 20+ minutes to less than 5 minutes Remote Cache ❏ Only run on updated code ❏ Run in parallel ✓ Reuse prior results ❏ Faster implementation
  • 23. 23 Ruff: fast linter implementation using rust Implements: ● Flake8 ● isort Parse source code once across supported linters Cache results and skip unchanged files https://github.com/charliermarsh/ruff 🛠 ❏ Only run on updated code ❏ Run in parallel ✓ Reuse prior results ✓ Faster implementation
  • 24. 24 ❗Checklist for Improving Developer Experience Problems: ● Inconsistent linter version and configuration ● Endless efforts on upgrading linters and configs ● Observability is missing ● Linter/test errors may be merged to the main branch ● Developers are slowed down by linter suggestions ● Missing best practices on things other than Python, e.g. Github, Docker, etc. Strategy: Build linters for best practices and provide autofixes for productivity Checklist: ❏ Telemetry ❏ Custom Linter ❏ Autofix
  • 25. Collect metrics from CI and Local runs: ● Where: environment, Git codebase and branch ● What: linter suggestions ● How: latency, exception stack trace Understand Developer Experience 25 ✓ Telemetry ❏ Custom Linter ❏ Autofix
  • 26. 26 fixit: Python linters and autofixes using LibCST ExplicitFrozenDataclassRule @dataclass class Data: name: str # linter suggestion: # When using dataclasses, explicitly specify a frozen keyword argument. # suggested fix @dataclass(frozen=True) class Data: name: str UseFstringRule "%s" % "hi" # linter suggestion: # Do not use printf style formatting or .format(). # Use f-string instead to be more readable and efficient. # See https://www.python.org/dev/peps/pep-0498/ # suggested fix f"{'hi'}" https://github.com/Instagram/Fixit 🛠 ❏ Telemetry ✓ Custom Linter ✓ Autofix
  • 27. 27 Our Custom Python Linters: Github Check with annotations Github Check: ● Use required check for branch protection ● Use annotations to provide inline context to speed up the fix ❏ Telemetry ✓ Custom Linter ❏ Autofix
  • 28. 28 Our Custom non-Python Linters: rebase reminder Errors may be merged into the main branch A | B PR1 | C PR2 (x) ✓ Telemetry ✓ Custom Linter ❏ Autofix
  • 29. 29 Our Custom Python Linters: deprecation toolkit Too many pre-existing linter errors Need to resolve them incrementally Linters for prevent new usages Run linters to collect historical data to drive progress over time ✓ Telemetry ✓ Custom Linter ❏ Autofix
  • 30. 30 Reusable Workflows Build reusable workflows to be shared across codebases easily, e.g. Github reusable workflows Build a reusable framework: ● Simple APIs for building linters and autofixes ● Collect metrics ● Generate Github Check with annotations easily ✓ Telemetry ✓ Custom Linter ✓ Autofix
  • 31. 31 Automated Refactoring Auto bump version: Github Dependabot Auto fix linter errors: ● LibCST: custom codemods ● PyGithub: create pull requests Build an automated refactoring framework: ● Create pull requests and manage their life cycle until merges ● [talk] Automated Refactoring in Large Python Codebases (EuroPython 2022) ● [blog] Type annotation via automated refactoring (link) ❏ Telemetry ❏ Custom Linter ✓ Autofix
  • 32. Our Custom Python Autofixes: Flake8 32 ❏ Telemetry ❏ Custom Linter ✓ Autofix
  • 33. Our Custom Python Autofixes: mypy 33 ❏ Telemetry ❏ Custom Linter ✓ Autofix
  • 34. 34 Our Custom non-Python Autofixes: notify-reviewer-teams Sometimes PRs are blocked on code reviews. ❏ Telemetry ❏ Custom Linter ✓ Autofix
  • 35. 35 Our Custom non-Python Autofixes: release-on-merge ❏ Telemetry ❏ Custom Linter ✓ Autofix
  • 36. 36 Results Support 200+ developers in 30+ codebases to run common Python linters with consistent configs and autofixes Each week, the linters run 10k+ times and provide 25k+ suggestions. So far, the autofixes have been used 7000+ times and saved lots of developer time.
  • 37. 37 Recap Slow Linter Checklist: ✓ Only run on updated code ✓ Run in parallel ✓ Reuse prior results ✓ Faster implementation Developer Experience Checklist: ✓ Telemetry ✓ Linter ✓ Autofix
  • 38. 38 Thank you for your attentions! Carta Engineering Blog https://medium.com/building-carta Carta Jobs https://boards.greenhouse.io/carta