The guide + private style inspector

Write Pythonpeople trust.

Learn the standard, then check your own code against it. Get line-level guidance for readable, typed, testable, production-ready Python—without sending your code anywhere.

Evidence-led, not dogmatic.
Reviewed against primary sources · July 2026

service.py ● typed
from collections.abc import Iterable


def active_names(
    users: Iterable[User],
) -> list[str]:
    """Return sorted names of active users."""
    return sorted(
        user.name
        for user in users
        if user.is_active
    )
All checks passed 0.18s
Aa Readable by defaultOptimize for the next person.
Low noiseTools handle the trivia.

Built-in utility

Paste. Inspect.
Improve.

Get an immediate, line-by-line review based on this guide’s core principles. Every finding explains what matters and suggests a concrete next move.

Private by designYour code never leaves this browser.
Your Python
0 lines · 0 characters
+ Enter

FORMATIndentation · whitespace · line length · statements

INTENTNaming · docstrings · type contracts · complexity

SAFETYExceptions · secrets · shell use · timeouts

SCOPEFast heuristic review · not a parser or CI replacement

01Instant style reviewLine-level, private feedback

02PEP 8 groundedCanonical rules, with context

03Production mindedTypes, tests, security, CI

04Actionable guidanceEvery finding explains why

The north star

Style is how code
communicates intent.

Great Python feels unsurprising. Readers spend their attention on the problem—not decoding clever syntax, inconsistent structure, or invisible side effects.

01

Readability counts

Choose explicit names, linear control flow, and small interfaces. Code is read far more often than it is written.

Make intent visible
02

Boundaries matter

Validate at the edges, type public contracts, and keep side effects easy to find. Make invalid states hard to represent.

Design clear contracts
03

Automate consistency

Let formatters, linters, type checkers, and tests settle mechanical questions before review begins.

Build the safety net

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.

— The Zen of Python, PEP 20

The practical guide

From first line to
production.

Use these as strong defaults. Every rule has a purpose; when the rule obscures that purpose, use judgment and document the exception.

01

Format & name

Remove friction
before it starts.

Formatting should be boring, predictable, and automated. Names should carry enough meaning that comments explain why, not what a variable contains.

01.1

Indent with four spaces

Never mix tabs and spaces. Use hanging indents for multiline expressions, and align closing delimiters with the construct that opened them.

result = build_report(
    source,
    include_meta=True,
)
01.2

Use a deliberate line length

PEP 8 specifies 79 characters for code and 72 for flowing text. Many formatter-led teams adopt 88. Pick one limit, configure it once, and let the formatter enforce it.

79canonical88common formatter default
01.3

Name for the reader

Use snake_case for functions and variables, PascalCase for classes, and UPPER_SNAKE_CASE for constants. Avoid vague containers like data, info, and utils.

invoice_totalvariable PaymentClientclass MAX_RETRIESconstant
× Avoid
Hidden meaning
def calc(d, f=False):
    x = sum(i["v"] for i in d)
    return x * 1.2 if f else x
Prefer
Intent in the names
def invoice_total(
    line_items: Iterable[LineItem],
    *,
    include_tax: bool = False,
) -> Decimal:
    subtotal = sum(item.price for item in line_items)
    return subtotal * TAX_RATE if include_tax else subtotal
02

Pythonic patterns

Idiomatic,
not clever.

Pythonic code uses the language’s strengths without turning every expression into a puzzle. Prefer a clear loop over a dense comprehension with nested conditions.

Guard early

Return or raise at the boundary so the happy path stays flat and readable.

Use truth naturally

Prefer if items to if len(items) > 0; use is None when None has distinct meaning.

Compare correctly

Use is for identity, == for value, and chained comparisons for ranges.

Iterate directly

Reach for enumerate, zip, and dictionary views before manually managing indices.

orders.py
def dispatch(order: Order, warehouse: Warehouse) -> Receipt:
    """Dispatch an order or raise a precise domain error."""
    if not order.items:
        raise EmptyOrderError(order.id)

    if order.status is not OrderStatus.PAID:
        raise OrderNotPaidError(order.id)

    available_items = [
        item for item in order.items if warehouse.has_stock(item.sku)
    ]
    return warehouse.dispatch(available_items)
1 Guard clauses expose invalid states. 2 An enum makes a closed state explicit. 3 A short comprehension has one job.
03

Types & boundaries

Turn assumptions
into contracts.

Type hints make interfaces searchable and mistakes cheaper. They are most valuable at public APIs, domain boundaries, and code that changes often.

Wide in

Accept the broadest interface you need: Iterable, Sequence, Mapping, or a Protocol.

Narrow out

Return a concrete, predictable type. Avoid unions that force every caller to branch.

Any with intent

Use object for an unknown-but-type-safe value; reserve Any for truly dynamic boundaries.

pricing.py
from collections.abc import Iterable
from dataclasses import dataclass
from decimal import Decimal
from typing import Protocol

class Priced(Protocol):
    @property
    def price(self) -> Decimal: ...

@dataclass(frozen=True, slots=True)
class BasketSummary:
    item_count: int
    total: Decimal

def summarize(items: Iterable[Priced]) -> BasketSummary:
    prices = [item.price for item in items]
    return BasketSummary(len(prices), sum(prices, start=Decimal()))
i

Set a version floor. Declare requires-python, then use the modern syntax that floor supports. For current code, prefer built-in generics such as list[str] and unions such as str | None.

04

Functions & data

Keep the center
of gravity small.

Functions

  • Do one thing at one level of abstraction.
  • Make dependencies and side effects explicit.
  • Use keyword-only arguments for booleans and ambiguous values.
  • Return consistently; do not mix values and implicit None.

Data & classes

  • Prefer plain data structures until behavior needs a home.
  • Use dataclasses for value-oriented records.
  • Prefer composition over inheritance.
  • Expose small public APIs; keep internals replaceable.
05

Errors & logging

Fail with context,
not confusion.

Exceptions are part of your API. Catch only what you can handle, preserve the cause, and make the operational trail useful without leaking sensitive data.

× Avoid
Swallowed failure
try:
    charge(card)
except Exception:
    print("Something went wrong")
    return False
Prefer
Precise and traceable
try:
    receipt = gateway.charge(request)
except GatewayTimeout as exc:
    logger.warning(
        "Payment timed out",
        extra={"order_id": order.id},
    )
    raise PaymentUnavailable(order.id) from exc
05.1

Use domain exceptions

Name the failure in the language of the caller. Keep exception hierarchies shallow.

05.2

Libraries log, applications configure

Create module loggers with logging.getLogger(__name__). Do not call basicConfig from a library.

05.3

Never log secrets

Treat tokens, credentials, payment data, and personal information as toxic. Redact at the boundary.

06

Project structure

Make the right place
obvious.

acme-payments/

├── pyproject.toml
├── README.md
├── src/
│   └── acme_payments/
│       ├── __init__.py
│       ├── domain/
│       ├── services/
│       └── adapters/
└── tests/
    ├── unit/
    └── integration/
01

Use pyproject.toml

Centralize build metadata and supported tool configuration.

02

Consider a src layout

It prevents accidental imports from the repository root and makes packaging mistakes visible.

03

Organize by responsibility

Prefer cohesive modules over a catch-all utils.py. Mirror concepts, not framework jargon.

Import order

1Standard library2Third party3Local package
One import per line; blank lines between groups; avoid wildcard imports.
07

Testing

Test behavior,
not choreography.

FastUnit tests run constantly.

FocusedOne behavior, clear failure.

FaithfulIntegration tests cover real boundaries.

IndependentNo order or shared-state surprises.

test_pricing.py
import pytest

@pytest.mark.parametrize(
    ("subtotal", "discount", "expected"),
    [
        (Decimal("100"), Decimal("0.10"), Decimal("90.00")),
        (Decimal("0"), Decimal("0.10"), Decimal("0.00")),
    ],
)
def test_discounted_total(subtotal, discount, expected):
    assert discounted_total(subtotal, discount) == expected

Coverage is a map, not a target. Use it to find untested risk; a high percentage cannot prove useful assertions.

08

Reliability

Be safe under
real conditions.

Security

  • Never hard-code secrets.
  • Validate untrusted input at boundaries.
  • Avoid eval, unsafe deserialization, and shell strings.
  • Audit dependencies and lock applications reproducibly.

Performance

  • Measure before optimizing.
  • Fix algorithms and I/O before micro-tuning syntax.
  • Benchmark representative workloads.
  • Keep performance choices readable and documented.

Concurrency

  • Use asyncio for structured I/O concurrency.
  • Use threads for blocking I/O.
  • Use processes—or validated free-threaded builds—for CPU work.
  • Always set timeouts and bound fan-out.
!

Make failure finite. Network calls need explicit timeouts, retries need backoff and a cap, queues need bounds, and shutdown paths need tests.

The modern toolchain

Automate the
boring parts.

Use one command locally and the same command in CI. The exact tools can change; the feedback loop should remain fast and dependable.

A pragmatic baseline

One file.
Shared expectations.

Put supported configuration in pyproject.toml. Start with a focused rule set; add stricter rules because they catch problems your team actually has—not because a tool offers them.

  • Formatting and imports are automatic.
  • Rule selection is explicit and reviewable.
  • The Python floor is declared once.
pyproject.toml
[project]
name = "your-project"
version = "0.1.0"
requires-python = ">=3.12"

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

[tool.ruff.lint]
select = [
    "E",   # pycodestyle errors
    "F",   # Pyflakes
    "I",   # import sorting
    "UP",  # modern Python syntax
    "B",   # bugbear
    "SIM", # simplification
]

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

[tool.pytest.ini_options]
addopts = ["--strict-markers", "--strict-config"]
testpaths = ["tests"]

[tool.mypy]
python_version = "3.12"
warn_unused_configs = true
check_untyped_defs = true
no_implicit_optional = true

NoteThis is a starting point, not universal law. Match requires-python, Ruff’s target, and your type checker’s Python version to the oldest runtime you actually support.

Before you merge

The ten-minute
quality pass.

A compact review for the risks automation cannot fully understand. Your progress is saved on this device.

0/ 10 complete

The Python bookshelf

Six books worth
keeping close.

Category-defining bestsellers and enduring practitioner favorites, selected for a useful path from first program to maintainable production systems.

Start hereCrash CourseAutomate

Write better codeEffectiveFluent

Build for changeRobustArchitecture

Cover of Python Crash Course, 3rd Edition
World bestseller
Beginner2022

Python Crash Course

Eric Matthes · 3rd edition

A fast, project-led introduction that moves from syntax and testing to games, data visualization, and web applications.

Best forOne confident, structured first book
View at publisher
Cover of Automate the Boring Stuff with Python, 3rd Edition
Practical favorite
Beginner2025

Automate the Boring Stuff

Al Sweigart · 3rd edition

Turns fundamentals into immediate wins: files, spreadsheets, PDFs, web tasks, databases, messages, and desktop automation.

Best forLearning by making work disappear
View at publisher
Cover of Effective Python, Third Edition
Best-practice desk guide
Intermediate2024

Effective Python

Brett Slatkin · 3rd edition

Concise, specific guidance on Pythonic thinking, functions, comprehensions, classes, concurrency, testing, and performance.

Best forTurning working Python into excellent Python
View at publisher
Cover of Fluent Python, 2nd Edition
Modern Python classic
Intermediate–advanced2022

Fluent Python

Luciano Ramalho · 2nd edition

A deep tour of Python’s data model, functions, typing, protocols, generators, concurrency, and metaprogramming.

Best forUnderstanding how Python really wants to work
View at publisher
Cover of Robust Python
Team-scale favorite
Intermediate–advanced2021

Robust Python

Patrick Viafore

Types, interface design, extensibility, static analysis, and testing strategies for codebases that need to survive change.

Best forMaking intent and maintainability explicit
View at publisher
Cover of Architecture Patterns with Python
Systems design pick
Intermediate–advanced2020

Architecture Patterns with Python

Harry Percival · Bob Gregory

A hands-on guide to domain models, repositories, units of work, dependency inversion, message buses, and event-driven systems.

Best forOrganizing complex business applications
View at publisher

Editorial noteSelections are independent and use current English-language editions reviewed July 2026. “World bestseller” reflects the publisher’s description of Python Crash Course; the remaining labels are editorial recommendations, not live sales rankings. No affiliate links or paid placements.

Primary sources

Go deeper.

This guide synthesizes standards and practice. When precision matters, follow the living source.

Python is a trademark of the Python Software Foundation. This independent guide is not affiliated with or endorsed by the PSF. Last editorial review: July 18, 2026.

Copied to clipboard