UV?
- ํ์ด์ฌ ํ๋ก์ ํธ ๊ด๋ฆฌ all in one ๋๊ตฌ
- rust๊ธฐ๋ฐ์ผ๋ก ๋งค์ฐ ๋น ๋ฆ
- pip, virtualenv, venv, conda, pyenv, pipenv, poetry ๋ฑโฆ ์๋ง์ ๋๊ตฌ๋ค ๋์ uv ์ฌ์ฉํฉ์๋ค
- https://docs.astral.sh/uv/
pyenv ํ๋ก์ ํธ์์ uv ํ๋ก์ ํธ๋ก ๋ฐ๊พธ๊ธฐ
- pyenv ๊ฐ์ํ๊ฒฝ ํ์ฑํ ์ํ์์
pip freeze > requirements.txt.python-version์ด ๊ฐ์ํ๊ฒฝ ์ด๋ฆ์ผ๋ก ๋์ด ์๋ ๊ฒฝ์ฐ ๋ฒ์ ์ผ๋ก ์์ (uv ํธํ ๋ชฉ์ )- ํ๋ก์ ํธ ๋ฃจํธ ๊ฒฝ๋ก์์
uv init --bare๋กpyproject.toml์์ฑuv add -r requirements.txt๋ก.venv/,uv.lock์์ฑ
1. ์ค์น
๋ค์ํ ํ๋ซํผ์์ CLI๋ก ์ค์น๊ฐ ๊ฐ๋ฅํ๋ค
# Mac/Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Window
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
# HomeBrew
brew install uv
# PyPI : pip์ผ๋ก๋ ์ค์น ๊ฐ๋ฅ
pip install uv2. Python ์ค์น
uv๋ฅผ ํตํด ๋ค์ํ python ๋ฒ์ ์ ์ฝ๊ฒ ์ค์นํ๊ณ ๊ด๋ฆฌํ ์ ์๋ค
uv python list
# ์ค์น๋, ์ค์น ๊ฐ๋ฅํ ๋ชจ๋ ํ์ด์ฌ ๋ฒ์ ์ต์ patch ํ์ธ๊ฐ๋ฅ (pyenv๋ฑ์ผ๋ก ์ค์น๋ ๊ฒ๋ ๋์ด)
uv python list
uv python list --only-installed # ์ค์น๋ ๊ฒ๋ง
uv python list --only-downloads # ๋ค์ด๋ก๋ ๊ฐ๋ฅํ ๊ฒ๋ง
uv python list --managed-python # uv๊ฐ ์ค์น/๊ด๋ฆฌํ๋ ๊ฒ๋ง
uv python list --all-versions # ๊ฐ๋ฅํ patch ์ ๋ถ
uv python list --all-platforms # ๊ฐ๋ฅํ patch ์ ๋ถ
uv python list 3.13 # 3.13 ๋ฒ์ ๋ฆฌ์คํธuv python install
# .python-version(s) ํ์ผ์ ์๋ ๋ฒ์ (๋ชจ๋) ์ค์น, ์์ผ๋ฉด ๊ฐ์ฅ ์ต์ ๋ฒ์ ์ค์น
uv python install
uv python install --default # ์์ ๋์ผ, python/python3 executables ์ค์น
uv python install 3.12 --default # 3.12 ๋ฒ์ ์ค์น
uv python install '>=3.8, <3.10' # 3.8 ์ด์ 3.10 ๋ฏธ๋ง ๋ฒ์ ์ค์น
uv python install 3.9 3.10 3.11 # ์ฌ๋ฌ ๋ฒ์ ๋์ ์ค์น
uv python install pypy # ํน์ implementation ์ค์น
uv python install -f 3.12 # ์กด์ฌํ๋ executables ๋์ฒด (reinstall)uv python pin
ํ์ฌ ๊ฒฝ๋ก์์ ์ฌ์ฉํ๊ณ ์ถ์ python ๋ฒ์ ์ ๊ณ ์ ํ ์ ์๋ค (pyenv local, global๊ณผ ๋์ผ)
uv python pin # ํ์ฌ .python-version ๋ฒ์ ์ถ๋ ฅ
uv python pin 3.12.9 # 3.12.9๋ก .python-version ํ์ผ์ด ์์ฑ (์์ผ๋ฉด ์ค์น)
uv python pin --global 3.12.4 # 3.12.4๋ฅผ ์ ์ญ python์ผ๋ก ์ค์ uv python uninstall
uv python uninstall 3.12.9 # 3.12.9 ๋ฒ์ uninstall
uv python uninstall --all # ์ค์น๋ ๋ชจ๋ ๋ฒ์ uninstalluv python upgrade (Experimental)
uv python upgrade 3.12 # 3.12๋ฒ์ ์ ๊ฐ์ฅ ์ต์ path release๋ก ์
๋ฐ์ดํธ
uv python upgrade # ์ค์น๋ ๋ชจ๋ ๋ฒ์ ์
๋ฐ์ดํธuv python find
uv python find # ํ์ฌ ๊ฒฝ๋ก ๊ธฐ์ค ์ค์ ๋ python executable
uv python find '>3.12' # 3.13๋ณด๋ค ํฐ ๋ฒ์ python executable
uv python find 3.13 # 3.13.x์ ๋งค์นญ๋๋ python executable 3. uv ํ๋ก์ ํธ
๊ธฐ์กด์ ์๋ก์ด ํ๋ก์ ํธ๋ฅผ ์์ํ๋ ค๋ฉด ์ํ๋ python ๋ฒ์ ์ ์ค์นํ๊ณ , ๊ฐ์ํ๊ฒฝ์ ๋ง๋ค๊ณ , ํ์ฑํ ์ํค๊ณ , ํจํค์ง๋ฅผ ์ค์นํ๋ ๊ณผ์ ๋ฑ์ ๊ฑฐ์ณ์ผ ํ์ง๋ง, ์ด์ uv๋ฅผ ํตํด ๋ฐ๋ก ํ๊ฒฝ์ ํธํ๊ฒ ์์ฑํ ์ ์๋ค
uv์ ํต์ฌ์ด๋ผ๊ณ ๋ณผ ์ ์๋ 5๊ฐ์ ๋ช ๋ น์ด๋ ๋ค์๊ณผ ๊ฐ๋ค
- uv init
- uv add
- uv lock
- uv sync
- uv run
uv init
python ๋ฒ์ ์ ์ง์ ํ์ง ์์ผ๋ฉด ์ฌ์ฉ ๊ฐ๋ฅํ ๊ฒ์ ์ฐพ์ผ๋ฉฐ, ๊ทธ๊ฒ๋ ์๋ค๋ฉด ์ค์น๊น์ง ์ง์ ์งํํ๋ค
uv init myproj # myproj ํด๋ ๋ง๋ค๊ณ ๊ทธ ์์ ํ์ํ ๊ธฐ๋ณธ ํ์ผ ์์ฑ
uv init # ํ์ฌ ํด๋์์ ๊ธฐ๋ณธ ํ์ผ ์์ฑ
uv init --app myapp # ์ฑ ๋ง๋๋ ํ๋ก์ ํธ (๊ธฐ๋ณธ๊ฐ)
uv init --lib mylib # ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ง๋๋ ํ๋ก์ ํธ, src/mylib/ ํด๋ ์์ฑ
uv init --package pkg # ๋น๋/๋ฐฐํฌ ๊ฐ๋ฅํ ํจํค์ง ๊ตฌ์กฐ๋ก ์ธํ
src/pkg/ ํด๋ ์์ฑ
uv init myapp --python 3.11 # ์ด ํ๋ก์ ํธ๋ ์ต์ 3.11 ์ด์์ผ๋ก ์์ (.python-version๋ ๋ง์ถฐ ์์ฑ)
uv init myapp --no-pin-python # .python-verseion ์์ ์๋ง๋ค๊ณ ์์
uv init --bare # pyproject.toml๋ง ๋ง๋ค๊ธฐ (๊ธฐ์กด repo์ ์ต์ํ์ ๋ณํ๋ง ์ค์ uv ๋์
)์์
uv init์ผ๋ก ์์ฑํ ํ๋ก์ ํธ ๋ด๋ถ๋ ๋ค์๊ณผ ๊ฐ๋ค (--app ์ต์
๊ธฐ์ค)

git ์ด๊ธฐํ, main.py ๋ฐ README.md ๊น์ง ์์ฑํด์ฃผ๋ฉฐ,
python ๋ฒ์ ๋ฐ ์์กด์ฑ๊ด๋ฆฌ๋ฅผ ์ํ .python-version, pyproject.toml ํ์ผ๋ ๋ณด์ธ๋ค
.python-version: ํ์ฌ ํ๋ก์ ํธ์์ ์ฌ์ฉํ python ๋ฒ์ ์ ์ธpyproject.toml: ํ๋ก์ ํธ ํ์ค ๋ฉํ๋ฐ์ดํฐ + ์์กด์ฑ ๋ฒ์ ์ ์ธ (requests>=2, <3๋ฑ)[project] name = "myproj" version = "0.1.0" description = "Add your description here" readme = "README.md" requires-python = ">=3.12" dependencies = []- project์ ์ด๋ฆ, ๋ฒ์ , ์ค๋ช ์ด ํฌํจ
- requires-python : ์ต์ ์๊ตฌ ํ์ด์ฌ ๋ฒ์ ๋ช ์
- dependencies : ์ถํ
uv add๋ก ํ์ํ ํจํค์ง ์ถ๊ฐ
uv add
python ํจํค์ง ์ค์น๋ฅผ ์ํด์๋ pip install ๋์ ๋ค์ ๋ช
๋ น์ด๋ฅผ ์ฌ์ฉํ๋ฉด ๋๋ค
pyproject.toml์ dependency๊ฐ ์ถ๊ฐ๋๋ฉฐ ๋์์ ๊ฐ์ํ๊ฒฝ์ด .venv/ํด๋๋ก ์์ฑ๋๋ค
uv add pandas numpy
uv add 'pandas>=2'
uv add "requests>=2.5; python_version >= '3.10'" # marker ์ถ๊ฐ. ํน์ ์กฐ๊ฑด์์ ํน์ ๋ฒ์ ์ฌ์ฉ ์ง์
uv add --dev pytest # ๊ฐ๋ฐ์ฉ ์์กด์ฑ dev๊ทธ๋ฃน์ผ๋ก ์ถ๊ฐ
# ์์์ ๊ทธ๋ฃน๋ง๋ค์ด์ ์์กด์ฑ ์ถ๊ฐ. uv run, syncํ ๋ ์ง์ ๊ฐ๋ฅ
uv add --group lint ruff
# pyproject.toml๋ง ์์ ํ๊ณ .venv์๋ ์ค์น X. ๋์ค์ uv sync๋ก ํ๋ฒ์ ๋ฐ์
uv add --no-sync pandas ์์
uv add pandas๋ฅผ ํ ํ, pyproject.toml์ ๋ค์๊ณผ ๊ฐ์ด ๋ณํ๋ค
[project]
name = "myproj"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.12"
dependencies = [
"pandas>=3.0.0",
]๊ทธ๋ฆฌ๊ณ uv.lock์ด๋ผ๋ ํ์ผ๋ ์๊ธฐ๋๋ฐ ๊ทธ ์์ ๋ณด๋ฉด pandas๊ฐ โ3.0.0โ ๋ฒ์ ์ผ๋ก ๊ณ ์ ๋์ด ์๊ณ numpy ๋ฑ ๋ค๋ฅธ ํจํค์ง๋ ํ์ธํ ์ ์๋ค
version = 1
revision = 3
requires-python = ">=3.12"
resolution-markers = [...]
[[package]]
name = "numpy"
version = "2.4.1"
source = {...}
sdist = {...}
wheels = [...]
[[package]]
name = "pandas"
version = "3.0.0"
...
[[package]]
name = "python-dateutil"
...
[[package]]
name = "six"
...
[[package]]
name = "tzdata"
...uv tree๋ฅผ ์คํํ๋ฉด pandas์ ํ์ํ ๋ค๋ฅธ ์์กด์ฑ ์๋ ํจํค์ง๋ค์ด ํจ๊ป ์ค์น๋ ๊ฒ์์ ์ ์ ์๋ค

์ฆ, uv๋ pyproject.toml์ ๊ธฐ๋ฐ์ผ๋ก ์ค์ ์ค์น๋๋ ํจํค์ง ๋ชฉ๋ก๊ณผ ๋ฒ์ ์ uv.lock์ ๊ธฐ๋ก(resolve)ํ๋ ๊ฒ์ ์ ์ ์๋ค
Resolve์ Install
- resolve :
pyproject.tomlโuv.lock
- ๊ฐ ํจํค์ง์ ์์กด์ฑ ํธ๋ฆฌ๋ฅผ ์ ๋ถ ํ์ธํด์ ๋ชจ๋ ์ ์ฝ์ ๋์์ ๋ง์กฑํ๋ ์กฐํฉ ํ์ํ์ฌ ์ ์ฅ
- install :
uv.lockโ ํจํค์ง ์ค์น
- ์ค์ ๊ฐ์ํ๊ฒฝ์ ํจํค์ง ์ค์น
- ๊ด๋ จ ๋ช ๋ น์ด
uv lock: resolve๋ง ์ํuv add: ์์กด์ฑ์ถ๊ฐ โ resolve โ installuv sync: (ํ์์) resolve โ install
uv sync --locked: install๋ง ํ์ฉ (pyproject์ ๋ค๋ฅด๋ฉด ์คํ์๋จ)uv run: (ํ์์) resolve โ (ํ์์) install โ ์คํ
uv run --locked: install ๋ฐ ์คํ๋ง ํ์ฉ (pyproject์ ๋ค๋ฅด๋ฉด ์คํ์๋จ)
uv lock
์ง์ uv lock์ผ๋ก resolve๋ง ์คํํ ์ ์๋ค
์์ uv add --no-sync๋ก pyproject.toml์๋ง dependency๋ฅผ ์ถ๊ฐํ๊ฑฐ๋ ํน์ ๋ชฉ์ ์ ์ํด resolve๋ฅผ ๋ถ๋ฆฌ์ํค๊ณ ์ถ์ ๋ ์ฌ์ฉํ๋ฉด ๋๋ค
uv lock # pyproject.toml ๊ธฐ์ค์ผ๋ก uv.lock๋ง ์์ฑuv sync
ํ์ฌ uv.lock ๋ด์ฉ์ ๊ธฐ์ค์ผ๋ก ๋ชจ๋ ํจํค์ง๋ฅผ ์ค์นํด์ ํ๋ก์ ํธ environment๋ฅผ ์
๋ฐ์ดํธํ๋ค
uv.lock๋ง ์์ผ๋ฉด uv sync๋ฅผ ํตํด ํด๋น ํ๋ก์ ํธ์ ํ๊ฒฝ์ ๋์ผํ๊ฒ ๋ณต์ ํ ์ ์๋ค
uv sync # uv.lock ๊ธฐ๋ฐ์ผ๋ก ์ค์น (defalut ๊ทธ๋ฃน๋ง)
uv sync --group lint # ํน์ ๊ทธ๋ฃน ํฌํจํด์ ์ค์น
uv sync --all-groups # ๋ชจ๋ ๊ทธ๋ฃน ์ค์น
uv sync --locked # uv.lock ์
๋ฐ์ดํธ ์์ด ํ์ฌ ๊ทธ๋๋ก ์ค์น (์ต์ ์๋๋ฉด ์๋ฌ)uv run
uv ๋ก ๊ด๋ฆฌํ๋ ํ๋ก์ ํธ์์ ํ์ด์ฌ ์คํฌ๋ฆฝํธ๋ฅผ ์คํํ ๋๋ ์์ uv run์ ๋ถ์ฌ์ฃผ๋ฉด ๋๋ค
๊ทธ๋ผ ๊ฐ์ํ๊ฒฝ(uv add๋ก ์๊ธด)์ ํ์ฑํํ ํ์๋ ์๊ณ ์์์ ๊ฒฝ๋ก๋ฅผ ์ก์์ ์คํฌ๋ฆฝํธ๋ฅผ ์คํํ๋ค
๊ทธ๋ฆฌ๊ณ ์ด๋ pyproject.toml๊ณผ uv.lock๊ณผ ์ค์ ์ค์น๋ ํจํค์ง๊ฐ ์ผ์น๋๋๋ก ๋๊ธฐํ์ฒ๋ฆฌ๋ฅผ ์์์ ํด์ค๋ค
uv run python main.py # resolve -> install -> ์คํ
uv run --locked python main.py # ํ์ฌ uv.lock ๊ธฐ์ค ์คํ (์ต์ ์๋๋ฉด ์๋ฌ)๊ธฐํ
uv export : uv.lock์ ๋ค๋ฅธ lockfile ํํ๋ก ์ถ๋ ฅ
uv export --format requirements.txt # ๊ธฐ๋ณธ๊ฐ
uv export --format pylock.toml
uv export > requirements.txt # ํ์ผ๋ก ์ ์ฅ
uv export --locked --format requirments.txt # uv.lock์ด ์ต์ ์ธ ๊ฒฝ์ฐ์๋ง export (์๋๋ฉด ์๋ฌ)
uv export --frozen --format requirments.txt # uv.lock ์์ ์ํ๊ณ ๊ทธ๋๋ก exportuv remove : ์ค์นํ ํจํค์ง ์ ๊ฑฐ ๋ฐ pyproject.toml์์๋ ์ ๊ฑฐ
uv remove pandasuv version : pyproject.toml์ ์๋ ํ๋ก์ ํธ์ ๋ฒ์ ์ ์ฝ๊ธฐ ๋ฐ ์
๋ฐ์ดํธ
uv version # ์์ : uv-test 0.1.0
uv version --bump minor # ์์ : uv-test 0.2.0
uv version --bump major # ์์ : uv-test 1.0.0
uv version --bump patch # ์์ : uv-test 1.0.1uv tree : ํ์ฌ ์ค์น๋ ํจํค์ง๋ค์ ์์กด์ฑ์ tree ํํ๋ก ์ถ๋ ฅ
uv-test v0.1.0
โโโ matplotlib v3.10.8
โ โโโ contourpy v1.3.3
โ โ โโโ numpy v2.4.1
โ โโโ cycler v0.12.1
โ โโโ fonttools v4.61.1
โ โโโ kiwisolver v1.4.9
โ โโโ numpy v2.4.1
โ โโโ packaging v26.0
โ โโโ pillow v12.1.0
โ โโโ pyparsing v3.3.2
โ โโโ python-dateutil v2.9.0.post0
โ โโโ six v1.17.0
โโโ numpy v2.4.1
โโโ pandas v3.0.0
โ โโโ numpy v2.4.1
โ โโโ python-dateutil v2.9.0.post0 (*)
โโโ pytest v9.0.2 (group: dev)
โโโ iniconfig v2.3.0
โโโ packaging v26.0
โโโ pluggy v1.6.0
โโโ pygments v2.19.2
(*) Package tree already displayed4. ๊ธฐ์กด ๋ฐฉ์๊ณผ ํธํ์ ์ํ ๋ช ๋ น์ด
uv์ ๋ฉ์ธ ๋ช ๋ น์ด๋
- uv init
- uv add
- uv lock
- uv sync
- uv run
์ด์ง๋ง, ๊ธฐ์กด ๋ฐฉ์๊ณผ ํธํ์ด ๋ ์ ์๋๋ก ์ข ๋ ์ต์ํ ํํ์ ๋ช ๋ น์ด๋ ์ ๊ณตํ๋ค
uv venv
uv venv --python 3.11.6 # .venv ํด๋์ 3.11.6 ๋ฒ์ ์ผ๋ก ๊ฐ์ํ๊ฒฝ ์ค์น (์์ผ๋ฉด ๋ค์ด๋ก๋)
uv venv --no-project --python 3.11.6 # .python-version ์์ด๋ 3.11.6์ผ๋ก ๊ฐ์ํ๊ฒฝ ์์ฑ
uv venv --prompt myproj # ๊ฐ์ํ๊ฒฝ ํ์ฑํํ๋ฉด ํ๋กฌํํธ๊ฐ (myproj)๋ก ๋ณด์
uv venv --seed # venv๋ง๋ค ๋, ๊ธฐ๋ณธ ํจํค์ง(pip, setuptools, wheel) ์ด๊ธฐ ์ฃผ์
uv venv /path/to/venv --python 3.11.6 # ๊ธฐ๋ณธ .venv๋์ ๋ด๊ฐ ์ง์ ํ ๊ฒฝ๋ก์ ๊ฐ์ํ๊ฒฝ ์์ฑuv pip
uv pip ๋ช ๋ น์ด vs uv ๋ช ๋ น์ด
- uv pip compile โ uv lock
- uv pip sync โ uv sync
- uv pip install โ uv add
- uv pip freeze โ uv export
uv pip compile : ์์กด์ฑํ์ผ ๊ธฐ๋ฐ์ผ๋ก ์ ๊ธํ์ผ ์์ฑ
uv pip compile requirements.in -o requirements.txt # requirements.in -> requirements.txt (๊ณ ์ ๋ฒ์ ์์ฑ)
uv pip compile pyproject.toml -o requirements.txt # pyproject.toml -> requirements.txt
uv pip compile requirements.in requirements-dev.in -o requirements-dev.txt # dev/test ๊ฐ์ ์ถ๊ฐ ์๊ตฌ๋ฅผ ํฉ์ณ์ ๋ณ๋ ์ ๊ธ ์์ฑ
uv pip compile requirements.in -o requirements.txt --upgrade-package ruff # ํน์ ํจํค์ง๋ง ๋ฒ์ ์ฌ๋ ค์ ์ฌ์ ๊ธ (๋๋จธ์ง๋ ์ต๋ํ ์ ์ง)
uv pip compile requirements.in --format pylock.toml -o pylock.toml # ํ์ค lockfile(pylock.toml)๋ก ์์ฑ (ํด ํธํ / ํ์ค ํฌ๋งท ํ์ํ ๋)uv pip sync : ์ ๊ธ ํ์ผ ๊ธฐ๋ฐ์ผ๋ก ํ๊ฒฝ ์์ฑ
uv pip sync requirements.txt
uv pip sync pyloc.toml
uv pip sync --python /path/to/venv/bin/python requirements.txtuv pip install: ํจํค์ง ์ถ๊ฐ/์ ๋ฐ์ดํธ ์ค์น
uv pip install flask # ๋จ์ผ ํจํค์ง ์ค์น
uv pip install "flask[dotenv]" # extras ํฌํจ ํจํค์ง ์ค์น
uv pip install -e . # editable ์ค์น
uv pip install -r requirements.txt # ํ์ผ์์ ์ผ๊ด์ค์น
uv pip install --python /path/to/python ruff # ํน์ ํ์ด์ฌ ์ง์ ํด์ ์ค์น
uv pip install --system ruff # ์์คํ
ํ์ด์ฌ์ ์ค์น(CI/์ปจํ
์ด๋์์ ์ข
์ข
์ฌ์ฉ)uv pip uninstall: ํจํค์ง ์ ๊ฑฐ
uv pip uninstall flaskuv pip freeze : ํ์ฌ ํ๊ฒฝ์ ์ค์น ํจํค์ง๋ฅผ requirements.txt ์คํ์ผ๋ก ์ถ๋ ฅ
uv pip freeze # ํ๋ฉด ์ถ๋ ฅ
uv pip freeze > requirements.txt # requirements.txt๋ก ์ ์ฅ๊ธฐํ
uv pip list # ์ค์น๋ ํจํค์ง ๋ชฉ๋ก
uv pip list --format json # json ํํ๋ก ์ถ๋ ฅ
uv pip show numpy # ํจํค์ง ์ค์น ๊ฒฝ๋ก
uv pip show --system numpy # ์์คํ
ํ์ด์ฌ์์ ํจํค์ง ์ค์น ๊ฒฝ๋ก
uv pip tree # ํจํค์ง๊ฐ ์์กด์ฑ tree๋ก ์ถ๋ ฅ
uv pip tree --depth 2 # tree ๊น์ด ์ ํ
uv pip check # ํ์ฌ ํ๊ฒฝ์ ์ถฉ๋/๋๋ฝ๋ ์์กด์ฑ ์ ๊ฒ5. ํฌ๋งคํ
ํ์ด์ฌ ํจํค์ง ๊ด๋ จ๋ ๊ฒ์ ์๋์ง๋ง, uv๊ฐ ์ ๊ณตํ๋ ์ ์ฉํ ๊ธฐ๋ฅ ์ค ํ๋๋ก ํฌ๋งคํ ์ด ์๋ค
๊ธฐ์กด์๋ ์ฝ๋ ์คํ์ผ, import ์คํ์ผ์ ์ ๋ฆฌํ๊ธฐ ์ํด isort, black, flake8 ๋ฑ์ ์ฌ์ฉํ์๋ค
- isort : import ๋ฌธ ์ ์ฉ ์ ๋ฆฌ ๋๊ตฌ
- ํ์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ / ์๋ํํฐ / ๋ก์ปฌ import ๊ตฌ๋ถ
- ์ํ๋ฒณ ์์ ์ ๋ ฌ
- unused import ์ ๊ฑฐ(์ ํ์ )
- black : ์ฝ๋ ํฌ๋งทํฐ
- ์ค ๊ธธ์ด, ๋ค์ฌ์ฐ๊ธฐ, ๋ฐ์ดํ, ์ค๋ฐ๊ฟ ๋ฑ ๊ฐ์
- flake8 : ๋ฆฐํฐ(linter)
- ๋ฌธ๋ฒ ์ค๋ฅ, ์คํ์ผ ์๋ฐ, ์ ์ฐ๋ ๋ณ์ ๋ฑ ๊ฒ์ฌ
- ์ค์ ๊ท์น์ ์ฌ๋ฌ ํ๋ฌ๊ทธ์ธ(pyflakes, pycodestyle ๋ฑ)์ ๋ฌถ์
ํ์ง๋ง ruff๋ uv ๋ฅผ ์ ์ํ astral์ฌ์์ ๋ง๋ formatter๋ก ์ ๊ธฐ๋ฅ๋ค์ ๋ชจ๋ ํฌํจํ๊ณ ์๋ค (์ฐธ๊ณ )
ruff ๋ฅผ ์ง์ uv add๋ก ์ค์นํ ๋ค uv run ruff format์ ์คํํด๋ ๋์ง๋ง,
uv format๋ช
๋ น์ด๋ฅผ ํตํด ๋ฐ๋ก ์ค์น ์์ด ๋ฐ๋ก ์ฌ์ฉํ ์ ์๋ค
uv format
uv format # `ruff format`๊ณผ ๋์ผ
uv format --check # reformatํ ํ์ผ ์๋์ง ํ์ธ
uv format --diff # reformatํ๋ฉด ๋ฌ๋ผ์ง๋ ๋ถ๋ถ ํ์ธ๋ํ pyproject.toml์ ๊ด๋ จ ์ค์ ์ ๋ฃ์ด ์ปค์คํฐ๋ง์ด์ง๋ ๊ฐ๋ฅํ๋ค (์ฐธ๊ณ )
[tool.ruff]
# Exclude a variety of commonly ignored directories.
exclude = [
".git",
".venv",
]
# Code Formatting (Black) configuration
line-length = 120
indent-width = 4
# Assume Python 3.12
target-version = "py312"
[tool.ruff.lint]
# Enable Pyflakes (`F`) and a subset of the pycodestyle (`E`) codes by default.
# Unlike Flake8, Ruff doesn't enable pycodestyle warnings (`W`) or
# McCabe complexity (`C901`) by default.
select = ["E4", "E7", "E9", "F", "I"]
ignore = []
# Allow fix for all enabled rules (when `--fix`) is provided.
fixable = ["ALL"]
unfixable = []
# Allow unused variables when underscore-prefixed.
dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
[tool.ruff.format]
# Like Black, use double quotes for strings.
quote-style = "double"
# Like Black, indent with spaces, rather than tabs.
indent-style = "space"
# Like Black, respect magic trailing commas.
skip-magic-trailing-comma = false
# Like Black, automatically detect the appropriate line ending.
line-ending = "auto"
# Enable auto-formatting of code examples in docstrings. Markdown,
# reStructuredText code/literal blocks and doctests are all supported.
#
# This is currently disabled by default, but it is planned for this
# to be opt-out in the future.
docstring-code-format = false
# Set the line length limit used when formatting code snippets in
# docstrings.
#
# This only has an effect when the `docstring-code-format` setting is
# enabled.
docstring-code-line-length = "dynamic"