30.8 C
New York
Friday, April 17, 2026

Python Mission Setup 2026: uv + Ruff + Ty + Polars



Picture by Editor

 

Introduction

 
Python venture setup used to imply making a dozen small choices earlier than you wrote your first helpful line of code. Which atmosphere supervisor? Which dependency instrument? Which formatter? Which linter? Which sort checker? And in case your venture touched knowledge, had been you supposed to begin with pandas, DuckDB, or one thing newer?

In 2026, that setup could be a lot easier.

For many new initiatives, the cleanest default stack is:

  • uv for Python set up, environments, dependency administration, locking, and command operating.
  • Ruff for linting and formatting.
  • Ty for kind checking.
  • Polars for dataframe work.

This stack is quick, trendy, and notably coherent. Three of the 4 instruments (uv, Ruff, and Ty) really come from the identical firm, Astral, which suggests they combine seamlessly with one another and along with your pyproject.toml.

 

Understanding Why This Stack Works

 
Older setups usually regarded like this:

pyenv + pip + venv + pip-tools or Poetry + Black + isort + Flake8 + mypy + pandas

 

This labored, nevertheless it created vital overlap, inconsistency, and upkeep overhead. You had separate instruments for atmosphere setup, dependency locking, formatting, import sorting, linting, and typing. Each new venture began with a selection explosion. The 2026 default stack collapses all of that. The tip result’s fewer instruments, fewer configuration recordsdata, and fewer friction when onboarding contributors or wiring up steady integration (CI). Earlier than leaping into setup, let’s take a fast have a look at what every instrument within the 2026 stack is doing:

  1. uv: That is the bottom of your venture setup. It creates the venture, manages variations, handles dependencies, and runs your code. As a substitute of manually organising digital environments and putting in packages, uv handles the heavy lifting. It retains your atmosphere constant utilizing a lockfile and ensures every thing is right earlier than operating any command.
  2. Ruff: That is your all-in-one instrument for code high quality. This can be very quick, checks for points, fixes lots of them mechanically, and in addition codecs your code. You need to use it as an alternative of instruments like Black, isort, Flake8, and others.
  3. Ty: This can be a newer instrument for kind checking. It helps catch errors by checking varieties in your code and works with numerous editors. Whereas newer than instruments like mypy or Pyright, it’s optimized for contemporary workflows.
  4. Polars: This can be a trendy library for working with dataframes. It focuses on environment friendly knowledge processing utilizing lazy execution, which suggests it optimizes queries earlier than operating them. This makes it sooner and extra reminiscence environment friendly than pandas, particularly for big knowledge duties.

 

Reviewing Conditions

 
The setup is kind of easy. Listed below are the few issues that you must get began:

  • Terminal: macOS Terminal, Home windows PowerShell, or any Linux shell.
  • Web connection: Required for the one-time uv installer and package deal downloads.
  • Code editor: VS Code is really helpful as a result of it really works effectively with Ruff and Ty, however any editor is okay.
  • Git: Required for model management; notice that uv initializes a Git repository mechanically.

That’s it. You do not want Python pre-installed. You do not want pip, venv, pyenv, or conda. uv handles set up and atmosphere administration for you.

 

Step 1: Putting in uv

 
uv offers a standalone installer that works on macOS, Linux, and Home windows with out requiring Python or Rust to be current in your machine.

macOS and Linux:

curl -LsSf https://astral.sh/uv/set up.sh | sh

 

Home windows PowerShell:

powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/set up.ps1 | iex"

 

After set up, restart your terminal and confirm:

 

Output:

uv 0.8.0 (Homebrew 2025-07-17)

 

This single binary now replaces pyenv, pip, venv, pip-tools, and the venture administration layer of Poetry.

 

Step 2: Making a New Mission

 
Navigate to your venture listing and scaffold a brand new one:

uv init my-project
cd my-project

 

uv creates a clear beginning construction:

my-project/
├── .python-version
├── pyproject.toml
├── README.md
└── predominant.py

 

Reshape it right into a src/ structure, which improves imports, packaging, check isolation, and type-checker configuration:

mkdir -p src/my_project exams knowledge/uncooked knowledge/processed
mv predominant.py src/my_project/predominant.py
contact src/my_project/__init__.py exams/test_main.py

 

Your construction ought to now seem like this:

my-project/
├── .python-version
├── README.md
├── pyproject.toml
├── uv.lock
├── src/
│   └── my_project/
│       ├── __init__.py
│       └── predominant.py
├── exams/
│   └── test_main.py
└── knowledge/
    ├── uncooked/
    └── processed/

 

In case you want a particular model (e.g. 3.12), uv can set up and pin it:

uv python set up 3.12
uv python pin 3.12

 

The pin command writes the model to .python-version, guaranteeing each crew member makes use of the identical interpreter.

 

Step 3: Including Dependencies

 
Including dependencies is a single command that resolves, installs, and locks concurrently:

 

uv mechanically creates a digital atmosphere (.venv/) if one doesn’t exist, resolves the dependency tree, installs packages, and updates uv.lock with precise, pinned variations.

For instruments wanted solely throughout improvement, use the --dev flag:

uv add --dev ruff ty pytest

 

This locations them in a separate [dependency-groups] part in pyproject.toml, preserving manufacturing dependencies lean. You by no means have to run supply .venv/bin/activate; while you use uv run, it mechanically prompts the proper atmosphere.

 

Step 4: Configuring Ruff (Linting and Formatting)

 
Ruff is configured instantly inside your pyproject.toml. Add the next sections:

[tool.ruff]
line-length = 100
target-version = "py312"

[tool.ruff.lint]
choose = ["E4", "E7", "E9", "F", "B", "I", "UP"]

[tool.ruff.format]
docstring-code-format = true
quote-style = "double"

 

A 100-character line size is an effective compromise for contemporary screens. Rule teams flake8-bugbear (B), isort (I), and pyupgrade (UP) add actual worth with out overwhelming a brand new repository.

Operating Ruff:

# Lint your code
uv run ruff examine .

# Auto-fix points the place attainable
uv run ruff examine --fix .

# Format your code
uv run ruff format .

 

Discover the sample: uv run . You by no means set up instruments globally or activate environments manually.

 

Step 5: Configuring Ty for Sort Checking

 
Ty can also be configured in pyproject.toml. Add these sections:

[tool.ty.environment]
root = ["./src"]

[tool.ty.rules]
all = "warn"

[[tool.ty.overrides]]
embody = ["src/**"]

[tool.ty.overrides.rules]
possibly-unresolved-reference = "error"

[tool.ty.terminal]
error-on-warning = false
output-format = "full"

 

This configuration begins Ty in warning mode, which is good for adoption. You repair apparent points first, then step by step promote guidelines to errors. Preserving knowledge/** excluded prevents type-checker noise from non-code directories.

 

Step 6: Configuring pytest

 
Add a piece for pytest:

[tool.pytest.ini_options]
testpaths = ["tests"]

 

Run your check suite with:

 

Step 7: Inspecting the Full pyproject.toml

 
Here’s what your ultimate configuration appears to be like like with every thing wired up — one file, each instrument configured, with no scattered config recordsdata:

[project]
title = "my-project"
model = "0.1.0"
description = "Fashionable Python venture with uv, Ruff, Ty, and Polars"
readme = "README.md"
requires-python = ">=3.13"
dependencies = [
    "polars>=1.39.3",
]

[dependency-groups]
dev = [
    "pytest>=9.0.2",
    "ruff>=0.15.8",
    "ty>=0.0.26",
]

[tool.ruff]
line-length = 100
target-version = "py312"

[tool.ruff.lint]
choose = ["E4", "E7", "E9", "F", "B", "I", "UP"]

[tool.ruff.format]
docstring-code-format = true
quote-style = "double"

[tool.ty.environment]
root = ["./src"]

[tool.ty.rules]
all = "warn"

[[tool.ty.overrides]]
embody = ["src/**"]

[tool.ty.overrides.rules]
possibly-unresolved-reference = "error"

[tool.ty.terminal]
error-on-warning = false
output-format = "full"

[tool.pytest.ini_options]
testpaths = ["tests"]

 

Step 8: Writing Code with Polars

 
Substitute the contents of src/my_project/predominant.py with code that workouts the Polars aspect of the stack:

"""Pattern knowledge evaluation with Polars."""

import polars as pl

def build_report(path: str) -> pl.DataFrame:
    """Construct a income abstract from uncooked knowledge utilizing the lazy API."""
    q = (
        pl.scan_csv(path)
        .filter(pl.col("standing") == "energetic")
        .with_columns(
            revenue_per_user=(pl.col("income") / pl.col("customers")).alias("rpu")
        )
        .group_by("section")
        .agg(
            pl.len().alias("rows"),
            pl.col("income").sum().alias("income"),
            pl.col("rpu").imply().alias("avg_rpu"),
        )
        .type("income", descending=True)
    )
    return q.gather()

def predominant() -> None:
    """Entry level with pattern in-memory knowledge."""
    df = pl.DataFrame(
        {
            "section": ["Enterprise", "SMB", "Enterprise", "SMB", "Enterprise"],
            "standing": ["active", "active", "churned", "active", "active"],
            "income": [12000, 3500, 8000, 4200, 15000],
            "customers": [120, 70, 80, 84, 150],
        }
    )

    abstract = (
        df.lazy()
        .filter(pl.col("standing") == "energetic")
        .with_columns(
            (pl.col("income") / pl.col("customers")).spherical(2).alias("rpu")
        )
        .group_by("section")
        .agg(
            pl.len().alias("rows"),
            pl.col("income").sum().alias("total_revenue"),
            pl.col("rpu").imply().spherical(2).alias("avg_rpu"),
        )
        .type("total_revenue", descending=True)
        .gather()
    )

    print("Income Abstract:")
    print(abstract)

if __name__ == "__main__":
    predominant()

 

Earlier than operating, you want a construct system in pyproject.toml so uv installs your venture as a package deal. We are going to use Hatchling:

cat >> pyproject.toml << 'EOF'

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.construct"

[tool.hatch.build.targets.wheel]
packages = ["src/my_project"]
EOF

 

Then sync and run:

uv sync
uv run python -m my_project.predominant

 

You need to see a formatted Polars desk:

Income Abstract:
form: (2, 4)
┌────────────┬──────┬───────────────┬─────────┐
│ section    ┆ rows ┆ total_revenue ┆ avg_rpu │
│ ---        ┆ ---  ┆ ---           ┆ ---     │
│ str        ┆ u32  ┆ i64           ┆ f64     │
╞════════════╪══════╪═══════════════╪═════════╡
│ Enterprise ┆ 2    ┆ 27000         ┆ 100.0   │
│ SMB        ┆ 2    ┆ 7700          ┆ 50.0    │
└────────────┴──────┴───────────────┴─────────┘

 

Managing the Every day Workflow

 
As soon as the venture is about up, the day-to-day loop is simple:

# Pull newest, sync dependencies
git pull
uv sync

# Write code...

# Earlier than committing: lint, format, type-check, check
uv run ruff examine --fix .
uv run ruff format .
uv run ty examine
uv run pytest

# Commit
git add .
git commit -m "feat: add income report module"

 

Altering the Manner You Write Python with Polars

 
The largest mindset shift on this stack is on the info aspect. With Polars, your defaults needs to be:

  • Expressions over row-wise operations. Polars expressions let the engine vectorize and parallelize operations. Keep away from person outlined capabilities (UDFs) until there isn’t a native different, as UDFs are considerably slower.
  • Lazy execution over keen loading. Use scan_csv() as an alternative of read_csv(). This creates a LazyFrame that builds a question plan, permitting the optimizer to push filters down and eradicate unused columns.
  • Parquet-first workflows over CSV-heavy pipelines. sample for inside knowledge preparation appears to be like like this.

 

Evaluating When This Setup Is Not the Finest Match

 
You might have considered trying a unique selection if:

  • Your crew has a mature Poetry or mypy workflow that’s working effectively.
  • Your codebase relies upon closely on pandas-specific APIs or ecosystem libraries.
  • Your group is standardized on Pyright.
  • You’re working in a legacy repository the place altering instruments would create extra disruption than worth.

 

Implementing Professional Suggestions

 

  1. By no means activate digital environments manually. Use uv run for every thing to make sure you are utilizing the proper atmosphere.
  2. All the time commit uv.lock to model management. This ensures the venture runs identically on each machine.
  3. Use --frozen in CI. This installs dependencies from the lockfile for sooner, extra dependable builds.
  4. Use uvx for one-off instruments. Run instruments with out putting in them in your venture.
  5. Use Ruff’s --fix flag liberally. It might probably auto-fix unused imports, outdated syntax, and extra.
  6. Choose the lazy API by default. Use scan_csv() and solely name .gather() on the finish.
  7. Centralize configuration. Use pyproject.toml as the one supply of reality for all instruments.

 

Concluding Ideas

 
The 2026 Python default stack reduces setup effort and encourages higher practices: locked environments, a single configuration file, quick suggestions, and optimized knowledge pipelines. Give it a strive; when you expertise environment-agnostic execution, you’ll perceive why builders are switching.
 
 

Kanwal Mehreen is a machine studying engineer and a technical author with a profound ardour for knowledge science and the intersection of AI with drugs. She co-authored the book “Maximizing Productiveness with ChatGPT”. As a Google Technology Scholar 2022 for APAC, she champions range and educational excellence. She’s additionally acknowledged as a Teradata Variety in Tech Scholar, Mitacs Globalink Analysis Scholar, and Harvard WeCode Scholar. Kanwal is an ardent advocate for change, having based FEMCodes to empower girls in STEM fields.

Related Articles

Latest Articles