[Avg. reading time: 17 minutes]

Python Developer Tools

PEP

PEP, or Python Enhancement Proposal, is the official style guide for Python code. It provides conventions and recommendations for writing readable, consistent, and maintainable Python code.

PEP Conventions

  • PEP 8 : Style guide for Python code (most famous).
  • PEP 20 : "The Zen of Python" (guiding principles).
  • PEP 484 : Type hints (basis for MyPy).
  • PEP 517/518 : Build system interfaces (basis for pyproject.toml, used by Poetry/UV).
  • PEP 572 : Assignment expressions (the := walrus operator).
  • PEP 440 : Mention versions in Libraries

Indentation

  • Use 4 spaces per indentation level
  • Continuation lines should align with opening delimiter or be indented by 4 spaces.

Line Length

  • Limit lines to a maximum of 79 characters.
  • For docstrings and comments, limit lines to 72 characters.

Blank Lines

  • Use 2 blank lines before top-level functions and class definitions.
  • Use 1 blank line between methods inside a class.

Imports

  • Imports should be on separate lines.
  • Group imports into three sections: standard library, third-party libraries, and local application imports.
  • Use absolute imports whenever possible.
# Correct
    import os
    import sys

# Wrong
    import sys, os

Naming Conventions

  • Use snake_case for function and variable names.
  • Use CamelCase for class names.
  • Use UPPER_SNAKE_CASE for constants.
  • Avoid single-character variable names except for counters or indices.

Whitespace

  • Don’t pad inside parentheses/brackets/braces.
  • Use one space around operators and after commas, but not before commas.
  • No extra spaces when aligning assignments.

Comments

  • Write comments that are clear, concise, and helpful.
  • Use complete sentences and capitalize the first word.
  • Use # for inline comments, but avoid them where the code is self-explanatory.

Docstrings

  • Use triple quotes (""") for multiline docstrings.
  • Describe the purpose, arguments, and return values of functions and methods.

Code Layout

  • Keep function definitions and calls readable.
  • Avoid writing too many nested blocks.

Consistency

  • Consistency within a project outweighs strict adherence.
  • If you must diverge, be internally consistent.

PEP 20 - The Zen of Python

https://peps.python.org/pep-0020/

Simple is better than complex

Complex

result = (lambda x: (x*x + 2*x + 1))(5)

Simple

x = 5
result = (x + 1) ** 2

Readability counts

No Good

a=10;b=20;c=a+b;print(c)

Good

first_value = 10
second_value = 20
sum_of_values = first_value + second_value
print(sum_of_values)

Errors should never pass silently

No Good

try:
    x = int("abc")
except:
    pass

Good

try:
    x = int("abc")
except ValueError as e:
    print("Conversion failed:", e)

PEP 572

Walrus Operator :=

Assignment within Expression Operator

Old Way

inputs = []
current = input("Write something ('quit' to stop): ")
while current != "quit":
    inputs.append(current)
    current = input("Write something ('quit' to stop): ")

Using Walrus

inputs = []
while (current := input("Write something ('quit' to stop): ")) != "quit":
    inputs.append(current)

Another Example

Old Way

import re

m = re.search(r"\d+", text)
if m:
    print(m.group())

New Way

import re

if (m := re.search(r"\d+", text)):
    print(m.group())

Linting

Linting is the process of automatically checking your Python code for:

  • Syntax errors

  • Stylistic issues (PEP 8 violations)

  • Potential bugs or bad practices

  • Keeps your code consistent and readable.

  • Helps catch errors early before runtime.

  • Encourages team-wide coding standards.


# Incorrect
import sys, os

# Correct
import os
import sys
# Bad spacing
x= 5+3

# Good spacing
x = 5 + 3

Ruff : Linter and Code Formatter

Ruff is a fast, modern tool written in Rust that helps keep your Python code:

  • Consistent (follows PEP 8)
  • Clean (removes unused imports, fixes spacing, etc.)
  • Correct (catches potential errors)

Install

uv add ruff

Verify

ruff --version 
ruff --help

example.py

import os, sys 

def greet(name): 
  print(f"Hello, {name}")

def message(name): print(f"Hi, {name}")

def calc_sum(a, b): return a+b

greet('World')
greet('Ruff')
message('Ruff')

uv run ruff check example.py
uv run ruff check example.py --fix
uv run ruff format example.py --check
uv run ruff check example.py

PEP 484 - MyPy : Type Checking Tool

Python is a Dynamically typed programming language. Meaning

x=26 x= "hello"

both are valid.

MyPy is introduced to make it statically typed.

mypy is a static type checker for Python. It checks your code against the type hints you provide, ensuring that the types are consistent throughout the codebase.

It primarily focuses on type correctness—verifying that variables, function arguments, return types, and expressions match the expected types.

What mypy checks:

  • Variable reassignment types
  • Function arguments
  • Return types
  • Expressions and operations
  • Control flow narrowing

What mypy does not do:

  • Runtime validation
  • Performance checks
  • Logical correctness

Install

    uv add mypy

    or

    pip install mypy

Example 1 : sample.py

x = 1
x = 1.0
x = True
x = "test"
x = b"test"

print(x)

uv run mypy sample.py

or

mypy sample.py

Example 2: Type Safety

def add(a: int, b: int) -> int:
    return a + b

print(add(100, 123))
print(add("hello", "world"))

Example 3: Return Type Violation

def divide(a: int, b: int) -> int:
    if b == 0:
        return "invalid"
    return a // b

Example 4: Optional Types

from typing import Optional

def get_username(user_id: int) -> Optional[str]:
    if user_id == 0:
        return None
    return "admin"

name = get_username(0)
print(name.upper())

What is wrong in this? name can also be None and there is no upper for None

#mypy #pep #ruff #lintVer 6.0.18

Last change: 2026-03-03