Ruff
Rust로 작성된 고성능 Python 린터이자 코드 포매터.
- 정적 분석을 통해 코드의 스타일 및 오류를 검토하고 잠재적 문제를 조기에 발견할 수 있도록 돕는다.
- 코드 스타일과 오류 탐지를 위한 기본 규칙 세트를 포함하고 있다. 기본적으로 PEP8 스타일 가이드를 기반으로 하며, 불필요한 공백, 잘못된 들여쓰기, 코드 복잡도 등 다양한 문제를 다룬다.
- 다양한 플러그인을 지원하며, 특정 코드 스타일이나 검사 규칙에 맞춘 프리셋을 불러올 수 있다.
특징
- 속도: 기존 린터들보다 10~100배 빠르다.
- 다기능성: Flake8, isort, pyupgrade, Black 등 여러 도구를 대체할 수 있다. 800개 이상의 린트 규칙을 지원.
- 자동 수정: 많은 린트 문제를 자동으로 수정할 수 있다.
- 설정 용이성: pyproject.toml 파일을 통해 쉽게 설정할 수 있다.
- 에디터 통합: VS code, Neovim, PyCharm 등 다양한 에디터와 통합
- CI/CD 통합: Github Actions와 같은 CI/CD 환경에서 Ruff를 사용하여 코드 품질을 자동으로 검사할 수 있다.
- 모노레포 친화적: 프로젝트 내 여러 수준에서 설정 파일을 가질 수 있다.
- Jupyter 노트북 지원: Jupyter Notebook도 린트 및 포맷할 수 있다.
- 커스터마이징: 규칙 선택, 무시, 수정 가능 여부 등을 세밀하게 제어할 수 있다.
- 캐싱: 변경되지 않은 파일은 다시 분석하지 않아 실행시 더욱 빠르다
- 지속적인 개발: 활발한 개발과 커뮤니티 지원으로 계속 발전중
설치 방법
PyPI를 통한 설치
PyPI에서 ruff
라는 이름으로 제공
|
|
설치 후 command에서 다음과 같이 실행 가능.
독립 실행형 설치 프로그램
버전 0.5.0부터 독립 실행형 설치 프로그램을 사용 가능
macOS 및 Linux
|
|
Windows
|
|
기타 설치 방법
Homebrew (macOS 및 Linux)
|
|
Conda
|
|
Docker에서 사용
이미지로 제공됨
|
|
Linter
기본 사용법
ruff check
명령어를 사용하여 린팅을 수행
린팅 규칙 설정
Ruff는 PEP8을 기반으로 하며, 추가 설정을 통해 원하는 스타일 가이드를 적용할 수 있다.pyproject.toml
파일에서 설정을 변경하여 규칙을 커스터마이징할 수 있다.
lint.select
,lint.extend-select
,lint.ignore
,lint.extend-ignore
설정으로 규칙 제어lint.select
: 활성화할 규칙 리스트lint.ignore
: 무시할 규칙 리스트lint.extend-select
/lint.extend-ignore
: 선택된 규칙에 더할 규칙을 지정하거나, 기존에 무시된 규칙에 추가할 수 있다.
- 규칙 코드는 접두사(1-3글자)와 3자리 숫자로 구성 (예:
F401
) ALL
코드로 모든 규칙 활성화 가능
오류 수정
--fix
플래그로 자동 수정 활성화- 안전한 수정과 불안전한 수정으로 구분
--unsafe-fixes
플래그로 불안전한 수정 활성화 가능
Fix Safety
Disabling Fixes
오류 억제
- 인라인 억제:
# noqa: {code}
|
|
- 파일 전체 억제: 파일 최상단에
# ruff: noqa
- 특정 규칙 파일 전체 억제: 파일 최상단에
# ruff: noqa: {code}
lint.per-file-ignores
설정 사용
사용하지 않는 억제 주석 감지
RUF100
규칙을 사용하여 불필요한 noqa
주석 감지 및 제거 가능
필요한 억제 주석 자동 추가
--add-noqa
플래그로 필요한 noqa
주석 자동 추가
액션 주석
isort의 액션 주석 지원 (예: # isort: skip_file
, # isort: on
등)
종료 코드
0
: 위반 없음 또는 모든 위반 자동 수정1
: 위반 발견2
: 비정상 종료
--exit-zero
와 --exit-non-zero-on-fix
플래그로 종료 코드 동작 변경 가능
Formatter
성능 향상과 Ruff의 린터, 포맷터 등을 통합하는데 중점을 둠.
Black과의 호환성을 목표로 하여 대부분의 프로젝트에서 최소한의 변경으로 도입 가능.
기본 사용법
--check
옵션을 사용하면 파일을 수정하지 않고 포맷 필요 여부만 확인
설정
따옴표 스타일, 들여쓰기 스타일, 줄 끝 문자 등을 설정할 수 있다.
Docstring 포맷팅
Ruff는 독스트링 내의 Python 코드 예제를 자동으로 포맷팅하는 기능을 제공.
이는 doctest, Markdown, reStructuredText 등 다양한 형식을 지원
포맷 억제
# fmt: on
, # fmt: off
, # fmt: skip
주석을 사용하여 특정 코드 블록의 포맷팅을 비활성화
충돌하는 린트 규칙
Ruff 포맷터와 충돌할 수 있는 린트 규칙들이 있으며, 이들을 비활성화하는 것이 권장
- tab-indentation (W191)
- indentation-with-invalid-multiple (E111)
- indentation-with-invalid-multiple-comment (E114)
- over-indented (E117)
- indent-with-spaces (D206)
- triple-single-quotes (D300)
- bad-quotes-inline-string (Q000)
- bad-quotes-multiline-string (Q001)
- bad-quotes-docstring (Q002)
- avoidable-escaped-quote (Q003)
- missing-trailing-comma (COM812)
- prohibited-trailing-comma (COM819)
- single-line-implicit-string-concatenation (ISC001)
- multi-line-implicit-string-concatenation (ISC002)
종료 코드
ruff format
은 성공 시 0, 비정상 종료 시 2를 반환.--check
옵션 사용 시에는 포맷 필요 여부에 따라 0 또는 1을 반환
Black 호환성
Black과 거의 동일한 출력을 생성하도록 설계
임포트 정렬
현재 Ruff 포맷터는 임포트를 정렬하지 않는다.
임포트 정렬과 포맷팅을 모두 수행하려면 다음과 같이 실행한다.
편집기 통합
다양한 코드 편집기와 통합되어 실시간으로 코드 품질을 점검하고 포매팅할 수 있다.
- Ruff 언어 서버는 언어 서버 프로토콜 (Language Server Protocol)을 구현하여 에디터 통합의 핵심 역할을 한다.
- Rust로 작성되었으며
ruff
CLI의 일부로ruff server
명령을 통해 사용 가능. - 이전의
ruff-lsp
를 대체하는 단일 공통 백엔드
언어 서버 기능
- 진단 하이라이팅: Python 코드에 대한 실시간 진단 제공
- 동적 설정: 작업 공간의 설정 파일(
pyproject.toml
,ruff.toml
,.ruff.toml
) 변경 시 진단 자동 갱신 - 포맷팅: Python 코드 전체 또는 특정 범위 포맷팅을 지원한다. VS Code에서
Ruff: Format Document
명령 제공 - 코드 액션: 특정 코드 문제에 대한 빠른 수정 제안을 제공한다. 예를 들어,
# noqa
주석으로 특정 진단을 무시할 수 있으며 문서 내 모든 빠른 수정 적용하거나 import를 정리하는 기능도 지원한다. - 수정 안전성: 자동 수정은 “안전"과 “비안전"으로 구분된다. 기본적으로 “모두 수정” 기능은 안전한 수정만 적용하며, 비안전한 수정은 수동으로 적용할 수 있다. 구성 파일에서
unsafe-fixes = true
로 설정하면 “모두 수정” 시 비안전한 수정도 적용할 수 있다. - 호버:
# noqa
주석 위에 마우스를 올리면 해당 규칙에 대한 문서를 표시하여 이해를 돕는다 - Jupyter Notebook 지원: Ruff는 Jupyter Notebook 파일에 대해서도 Python 파일과 동일한 기능을 제공.
에디터 설정
각 에디터별로 특정 설정 지침이 제공된다.ruff-lsp
에서 설정을 이전하는 경우 변경된 설정이 있으므로 마이그레이션 가이드를 참조
VS Code
VS Code 마켓 플레이스에서 Ruff 확장 프로그램을 설치
버전 2024.32.0 이상을 권장.
설정
settings.json
파일을 열어 다음과 같이 설정하여 Ruff를 기본 린터로 지정
Neovim
nvim-lspconfig
플러그인을 사용하여 Ruff 언어 서버를 설정.
Pyright와 함께 사용할 경우 특정 기능을 비활성화하는 방법이 제공.
설정
init.lua
내 설정
Vim
vim-lsp
플러그인을 사용하여 Ruff 언어 서버를 설정
설정
.vimrc
내 설정
PyCharm
외부 도구로 Ruff를 설정하거나 서드파티 플러그인을 사용
설정
- 파일 감시기를 설정하려면 PyCharm의
Settings
>Tools
>File Watchers
로 이동하여 새 파일 감시기를 추가 Name
필드에Ruff
라고 입력하고,File Type
을 Python으로 선택.Scope
와Output Paths
는 기본값으로 두고,Program
필드에는 Ruff의 설치 경로를 지정.Arguments
에는$FilePathRelativeToProjectRoot$
를 입력하여 현재 파일 경로를 기준으로 린팅이 수행되도록 한다.
Ruff 언어 서버의 설정
일반 설정
configuration
: Ruff 설정 파일 경로 지정configurationPreference
: 설정 우선순위 전략 설정- 옵션:
"editorFirst"
: 편집기 설정이 워크스페이스의 구성 파일보다 우선."filesystemFirst"
: 워크스페이스의 구성 파일이 편집기 설정보다 우선."editorOnly"
: 구성 파일을 완전히 무시하고 편집기 설정만 사용.
- 옵션:
exclude
: 린팅 및 포맷팅에서 제외할 파일 패턴lineLength
: 라인 길이 설정fixAll
:source.fixAll
코드 액션 활성화 여부organizeImports
:source.organizeImports
코드 액션 활성화 여부showSyntaxErrors
: 구문 오류 진단 표시 여부logLevel
: 서버 로그 레벨 설정logFile
: 로그 파일 경로 설정
코드 액션 설정
codeAction.disableRuleComment.enable
:noqa
주석을 통한 규칙 비활성화 액션 표시 여부codeAction.fixViolation.enable
: 자동 수정 액션 표시 여부
린터 설정
lint.enable
: 린팅 활성화 여부lint.preview
: 린터 프리뷰 모드 활성화 여부lint.select
,lint.extendSelect
: 활성화할 규칙 설정lint.ignore
,lint.extendIgnore
: 비활성화할 규칙 설정
포맷터 설정
format.preview
: 포맷터 프리뷰 모드 활성화 여부
## VS Code 전용 설정
enable
: Ruff 확장 활성화 여부format.args
: 포맷터에 전달할 추가 인수ignoreStandardLibrary
: 표준 라이브러리 파일 무시 여부importStrategy
: Ruff 실행 파일 로딩 전략interpreter
: Python 인터프리터 경로lint.args
: 린터에 전달할 추가 인수lint.run
: 린팅 실행 시점 설정nativeServer
: 네이티브 언어 서버 사용 여부path
: Ruff 실행 파일 경로showNotifications
: 알림 표시 설정trace.server
: 언어 서버 추적 레벨 설정
Ruff 설정
pyproject.toml
, ruff.toml
, 또는 .ruff.toml
파일을 통해 구성이 가능하다.
|
|
주요 설정 옵션
exclude
: 린팅 및 포맷팅에서 제외할 디렉토리 및 파일line-length
: 최대 줄 길이 (기본값 88)indent-width
: 들여쓰기 너비 (기본값 4)target-version
: 대상 Python 버전
린터 설정
select
: 활성화할 규칙 선택ignore
: 무시할 규칙 선택fixable
: 자동 수정 가능한 규칙 설정unfixable
: 자동 수정 불가능한 규칙 설정
포맷터 설정
quote-style
: 문자열 따옴표 스타일indent-style
: 들여쓰기 스타일line-ending
: 줄 끝 문자 설정docstring-code-format
: 독스트링 내 코드 예제 자동 포맷팅 여부
설정 파일 우선순위
.ruff.toml
>ruff.toml
>pyproject.toml
- 가장 가까운 설정 파일이 사용됨
명령줄 인터페이스
- 일부 설정은 명령줄 플래그로 제공 가능
--config
플래그를 통해 설정 파일 지정 또는 개별 설정 오버라이드 가능
Python 파일 탐색
- 기본적으로
*.py
,*.pyi
,*.ipynb
,pyproject.toml
파일 포함 extend-include
설정으로 추가 파일 확장자 포함 가능
Extend
현재 구성에 다른 pyproject.toml
파일을 병합할 수 있도록 한다.
이 설정을 통해 사용자 홈 디렉터리와 환경 변수를 확장할 수 있다.
현재의 pyproject.toml
파일을 해석할 때, 먼저 이 기본 구성 파일을 로드한 후, 현재 구성 파일에 정의된 속성을 병합
Jupyter 노트북 지원
- 버전 0.6.0 이상에서 기본적으로 린팅 및 포맷팅 지원
per-file-ignores
설정으로 노트북 파일에 대한 특정 규칙 무시 가능
Ruff 특정 규칙 (RUF)
Ruff에서 특별히 제공하는 것으로, 다음과 같은 내용을 포함한다.
- 모호한 유니코드 문자 사용 감지 (RUF001, RUF002, RUF003)
- 컬렉션 리터럴 연결 관련 문제 (RUF004, RUF005)
- asyncio 관련 문제 (RUF006)
- 함수 데코레이터 사용 개선 (RUF007)
- f-string 사용 개선 (RUF008, RUF009, RUF010)
- zip 대신 dict 생성자 사용 권장 (RUF011)
- 클래스 속성 관련 문제 (RUF012)
- 타입 힌트 개선 (RUF013)
- 사용되지 않는 noqa 지시문 감지 (RUF100)
- sys.path 조작 감지 (RUF200)
코드 | 이름 | 메시지 | 상태 |
---|---|---|---|
RUF001 | ambiguous-unicode-character-string | String contains ambiguous unicode character ‘{char}’ (character ‘{name}’). Consider using the ‘{type}’ literal \u{code} instead | ✔️ 🛠️ |
RUF002 | ambiguous-unicode-character-docstring | Docstring contains ambiguous unicode character ‘{char}’ (character ‘{name}’). Consider using the ‘{type}’ literal \u{code} instead | ✔️ 🛠️ |
RUF003 | ambiguous-unicode-character-comment | Comment contains ambiguous unicode character ‘{char}’ (character ‘{name}’). Consider using the ‘{type}’ literal \u{code} instead | ✔️ 🛠️ |
RUF004 | collection-literal-concatenation | Collection literal concatenated with literal | ✔️ 🛠️ |
RUF005 | collection-literal-concatenation-multiple | Collection literal concatenated with multiple literals | ✔️ 🛠️ |
RUF006 | asyncio-dangling-task | Dangling asyncio.create_task call | ✔️ |
RUF007 | preferred-lru-cache | Prefer functools.lru_cache() over functools.lru_cache without parentheses | ✔️ 🛠️ |
RUF008 | explicit-f-string-type-conversion | Use f"{var!r}" instead of f"{repr(var)}" | ✔️ 🛠️ |
RUF009 | explicit-multiple-concatenated-f-strings | Use a single f-string instead of multiple concatenated f-strings | ✔️ 🛠️ |
RUF010 | explicit-f-string-formatting | Convert f"{var:0>3}" to f"{var:>03}" | ✔️ 🛠️ |
RUF011 | replace-zip-with-dict | Replace zip with dict constructor | ✔️ 🛠️ |
RUF012 | mutable-class-default | Mutable class attribute {name} should be annotated with ClassVar | ✔️ |
RUF013 | implicit-optional | {type} doesn’t accept None ; consider using Optional[{type}] instead | ✔️ 🛠️ |
RUF100 | unused-noqa | Unused noqa directive | ✔️ 🛠️ |
RUF200 | sys-path-manipulation | sys.path manipulation detected | ✔️ |
Integrations
Github Actions
GitHub Actions에서 Ruff를 바로 사용 가능.
repository내에 .github/workflows
폴더에 파일을 생성하고 아래의 예시처럼 작성한다.
|
|
또한, astral-sh/ruff-action을 사용하여 Ruff를 GitHub Actions에서 직접 실행할 수 있다. 기본적으로 ruff-action
은 린팅을 수행하며, 필요에 따라 args
를 통해 추가 명령어를 지정할 수 있다.
GitLab CI/CD
GitLab CI/CD에서 Ruff를 사용하려면 .gitlab-ci.yml
파일에 다음과 같이 설정한다.
|
|
이 설정은 ruff check
와 ruff format
을 병렬로 실행하며, GitLab의 코드 품질 보고서와 연동된다.
Pre-commit
Ruff는 pre-commit과 통합되어 커밋 전에 자동으로 린팅과 포매팅을 수행할 수 있다. 설정 예시는 다음과 같다:
--fix
옵션을 추가하면 자동으로 수정 가능한 린팅 오류를 해결한다. 또한, Jupyter Notebook 파일에도 적용하려면 types_or
에 jupyter
를 추가할 수 있다.
Mdformat
Ruff는 mdformat과의 플러그인을 통해 Markdown 파일 내의 Python 코드 블록을 포매팅할 수 있다. 설치 방법은 다음과 같습니다:
|
|
설치 후, mdformat
을 실행하면 Markdown 파일 내의 Python 코드 블록이 Ruff를 통해 포매팅된다.
참고 및 출처
Ruff
Tutorial | Ruff
Installing Ruff | Ruff
The Ruff Linter | Ruff
The Ruff Formatter | Ruff
Editor Integration | Ruff
Settings | Ruff
Configuring Ruff | Ruff
Rules | Ruff
Settings | Ruff
Integrations | Ruff