Fable, Pylint을 Rust로 변환

발행: (2026년 6월 19일 PM 01:21 GMT+9)
7 분 소요

출처: Hacker News

A Rust 재구현으로 pylint를 만들고, byte‑for‑byte 동일한 출력을 생성하며 15~2300배 빠르다(중간값 약 85배). prylint는 pylint에 “영감을 받았다”는 것이 아니라 버그‑버그 포트이다: 동일한 메시지, 같은 줄과 열, 동일한 텍스트, 동일한 순서, 동일한 종료 코드 및 Your code has been rated 푸터 — 실제 pylint에 대해 52개의 프로덕션 코드베이스(~65,000개 Python 파일)에서 byte‑for‑byte로 검증되었다. 여기에는 django, numpy, pandas, sympy, home-assistant, sqlalchemy, twisted, scikit-learn 및 pylint 자체 기능 테스트 스위트가 포함된다. pylint가 버그를 가지고 있을 때 prylint는 이를 재현하고, pylint가 충돌할 경우 prylint도 동일한 오류 메시지를 보고한다.

설치

pip install prylint
요구 사항: python3(≥3.9)를 PATH에 포함시켜야 합니다 (이것은 pylint의 모듈 해상도 경로를 미러링하고, 파싱할 수 없는 파일에 대해 CPython의 정확한 구문 오류 메시지를 재생산하기 위함). pylint와 astroid 자체는 필요하지 않습니다.

사용법

pylint와 동일하게 사용합니다 — 기본 모드는 전체 검사 모드입니다: prylint . # 전체 확인 (pylint .) prylint -E . # 오류만 (pylint -E .) prylint —disable=C0114,… . # same --disable / --enable / 인라인 Pragmas

Output, message order, exit codes, the score footer, ---rcfile / pyproject.toml discovery, init-hook, and # pylint: pragmas all match pylint 4.0.5.

벤치마크

prylint . vs pylint . (둘 다 전체 확인 모드), pylint 4.0.5, Apple M 시리즈, 단일 스레드:

코드베이스
pylint
prylint
속도 향상
black
26.7 hr
41s
**2328×**
sentry
3.7 hr
24s
546×
home-assistant (17.5k files)
10.3 hr
82s
452×
airflow
1.9 hr
17s
399×
salt
1890s
8.8s
215×
zulip
909s
5.3s
172×
django
1524s
10.1s
150×
ansible
419s
2.9s
143×
nova (OpenStack)
1209s
10.3s
117×
fastapi
116s
1.0s
120×
mypy
367s
3.9s
95×
sqlalchemy
614s
7.1s
87×
pandas
1009s
14.2s
71×
scikit-learn
613s
9.6s
64×
sympy
1238s
26s
48×

*...및 12개 더, 모두 ≥30배*

**전체 (이들 27)**
**45.8 hr**
**4.9 min**
**~560×**

(These 27 are the large repos that are slow enough to time meaningfully; the full accuracy suite is **52 repos** — see below.)
Median per-repo speedup ~85×; the aggregate is higher because pylint's duplicate-code check (`R0801`) is O(n²) and dominates on test-heavy repos like black. **These are single-core numbers** — the inference engine is single-threaded to replicate astroid's order-sensitive global cache exactly (see [LIMITATIONS.md](https://pypi.org/project/prylint/LIMITATIONS.md)), and that byte-identical path is already 15–2300× pylint.

Every row above is also an accuracy test: each repo's full output is byte‑identical to pylint's (see exceptions in [LIMITATIONS.md](https://pypi.org/project/prylint/LIMITATIONS.md)).

## [](#user-content-accuracy)정확도
prylint는 고정된 pylint 4.0.5 / astroid 4.0.4 / CPython 3.12에 대해 차등 테스트를 사용하여 구현되었습니다:

**AST 충실도** — prylint의 파싱 트리(astral‑sh/ruff 파서 기반)는 astroid의 (위치, 스코프, 로컬, 브레인 변환)과 전체 코퍼스 파일에서 노드별로 비교되며, 차이가 없습니다.

**추론 충실도** — astroid의 추론 엔진은 정확히 포트되어 있습니다: lazy‑generator 의미, 100노드 추론 예산, 제한된 LRU 캐시 (`lookup` 128, `_metaclass_lookup_attribute` 1024)와 정확한 폐기, 64건트리 inference-tip FIFO, `Uninferable` 전파. 모든 이름/속성/콜 노드의 추론은 덤프되어 astroid와 비교됩니다.

**출력 충실도** — 전체 실행은 byte‑for‑byte로 비교되며, 메시지 순서, 모듈 헤더, 점수 푸터, `# pylint:` 파그마 처리 (비활성화/활성화 블록, `disable-next`, `skip-file`), 설정 파일 탐색 및 종료 코드 비트마스크 포함.

**블라인드 테스트** — 개발 이후 두 배의 10개 레포씩 추가되어 차가운 상태에서 평가되었으며, 모든 차이는 근본 원인으로 파악돼 수정되었습니다.

알려진, 문서화된 예외(드물게 등장하는 SQLAlchemy 클래스; 의도적으로 제외된 `no-member` 계열; pylint가 자체에 대해 비결정적인인 부분)들은 **[LIMITATIONS.md](https://pypi.org/project/prylint/LIMITATIONS.md)**에 정리되어 있습니다.

## [](#user-content-how-it-works)작동 원리
파일 탐색, 메시지 제어, 설정 파싱 및 보고는 `os.walk` 순서, `************* Module` 헤더 규칙, 점수 보고 푸터까지 pylint 자체 로직을 그대로 포팅한 것입니다. 파싱은 ruff의 Rust 파서를 사용하며, docstring 추출, 데코레이터 위치, 암시적 클래스 로컬, 메타클래스 처리, dataclasses/enums/namedtuples/attrs 등에 대한 브레인 변환을 통해 astroid의 정확한 트리 형태를 재구성합니다. astroid의 전체 추론 엔진은 이름, 호출, 속성, MRO 및 연산 프로토콜을 astroid의 정확한 보수적 접근 방식으로 해석하며, 캐시와 그 특이사항까지 포함한다(왜냐하면 그 특이사항은 출력에 관측 가능하기 때문).

## [](#user-content-reproducing-the-test-suite)테스트 스위트 재현
`scripts/setup_corpora.sh`는 모든 52개 코퍼스를 고정된 커밋으로 복제하고, 고정된 pylint/astroid 기준 진실 가상환경을 구축합니다. 정확도 계약: 모든 변경은 코퍼스가 byte‑identical(`harness/`에 차등 비교기가 포함되어 있음)하도록 해야 합니다.

## [](#user-content-license)라이선스
GPL-2.0-or-later, pylint와 동일한 라이선스 — prylint는 pylint의 메시지 텍스트와 행동을 그대로 재현합니다.
0 조회
Back to Blog

관련 글

더 보기 »

다르파 중생활 도전

What better place to showcase aviation history in the making than at the world's largest military aviation museum! | 0:30 Novel Drone Designs Lift Beyond Limits...