This document provides guidelines for maintaining high-quality Python code. These rules MUST be followed by all AI coding agents and contributors.
All code you write MUST be fully optimized.
"Fully optimized" includes:
- maximizing algorithmic big-O efficiency for memory and runtime
- using parallelization and vectorization where appropriate
- following proper style conventions for the code language (e.g. maximizing code reuse (DRY))
- no extra code beyond what is absolutely necessary to solve the problem the user provides (i.e. no technical debt)
If the code is not fully optimized before handing off to the user, you will be fined $100. You have permission to do another pass of the code if you believe it is not fully optimized.
- Use
uvfor Python package management and to create a.venvif it is not present. - Ensure
ipykernelandipywidgetsis installed in.venvfor Jupyter Notebook compatability. This should not be in package requirements. - Use
tqdmto track long-running loops within Jupyter Notebooks. Thedescriptionof the progress bar should be contextually sensitive. - Use
orjsonfor JSON loading/dumping. - When reporting error to the console, use
logger.errorinstead ofprint. - For data science:
- ALWAYS use
polarsinstead ofpandasfor data frame manipulation. - If a
polarsdataframe will be printed, NEVER simultaneously print the number of entries in the dataframe nor the schema as it is redundant. - NEVER ingest more than 10 rows of a data frame at a time. Only analyze subsets of code to avoid overloading your memory context.
- ALWAYS use
- For creating databases:
- Do not denormalized unless explicitly prompted to do so.
- Always use the most appropriate datatype, such as
DATETIME/TIMESTAMPfor datetime-related fields. - Use
ARRAYdatatypes for nested fields. NEVER save asTEXT/STRING.
- In Jupyter Notebooks, DataFrame objects within conditional blocks should be explicitly
print()as they will not be printed automatically.
- MUST use meaningful, descriptive variable and function names
- MUST follow PEP 8 style guidelines
- MUST use 4 spaces for indentation (never tabs)
- NEVER use emoji, or unicode that emulates emoji (e.g. β, β). The only exception is when writing tests and testing the impact of multibyte characters.
- Use snake_case for functions/variables, PascalCase for classes, UPPER_CASE for constants
- Limit line length to 88 characters (ruff formatter standard)
- MUST include docstrings for all public functions, classes, and methods
- MUST document function parameters, return values, and exceptions raised
- Keep comments up-to-date with code changes
- Include examples in docstrings for complex functions
Example docstring:
def calculate_total(items: list[dict], tax_rate: float = 0.0) -> float:
"""Calculate the total cost of items including tax.
Args:
items: List of item dictionaries with 'price' keys
tax_rate: Tax rate as decimal (e.g., 0.08 for 8%)
Returns:
Total cost including tax
Raises:
ValueError: If items is empty or tax_rate is negative
"""- MUST use type hints for all function signatures (parameters and return values)
- NEVER use
Anytype unless absolutely necessary - MUST run mypy and resolve all type errors
- Use
Optional[T]orT | Nonefor nullable types
- NEVER silently swallow exceptions without logging
- MUST never use bare
except:clauses - MUST catch specific exceptions rather than broad exception types
- MUST use context managers (
withstatements) for resource cleanup - Provide meaningful error messages
- MUST keep functions focused on a single responsibility
- NEVER use mutable objects (lists, dicts) as default argument values
- Limit function parameters to 5 or fewer
- Return early to reduce nesting
- MUST keep classes focused on a single responsibility
- MUST keep
__init__simple; avoid complex logic - Use dataclasses for simple data containers
- Prefer composition over inheritance
- Avoid creating additional class functions if they are not necessary
- Use
@propertyfor computed attributes
- MUST write unit tests for all new functions and classes
- MUST mock external dependencies (APIs, databases, file systems)
- MUST use pytest as the testing framework
- NEVER run tests you generate without first saving them as their own discrete file
- NEVER delete files created as a part of testing.
- Ensure the folder used for test outputs is present in
.gitignore - Follow the Arrange-Act-Assert pattern
- Do not commit commented-out tests
- MUST avoid wildcard imports (
from module import *) - MUST document dependencies in
pyproject.toml - Use
uvfor fast package management and dependency resolution - Organize imports: standard library, third-party, local imports
- Use
isortto automate import formatting
- NEVER use mutable default arguments
- MUST use context managers (
withstatement) for file/resource management - MUST use
isfor comparing withNone,True,False - MUST use f-strings for string formatting
- Use list comprehensions and generator expressions
- Use
enumerate()instead of manual counter variables
- NEVER store secrets, API keys, or passwords in code. Only store them in
.env.- Ensure
.envis declared in.gitignore. - NEVER print or log URLs to console if they contain an API key.
- Ensure
- MUST use environment variables for sensitive configuration
- NEVER log sensitive information (passwords, tokens, PII)
- MUST write clear, descriptive commit messages
- NEVER commit commented-out code; delete it
- NEVER commit debug print statements or breakpoints
- NEVER commit credentials or sensitive data
- MUST use Ruff for code formatting and linting (replaces Black, isort, flake8)
- MUST use mypy for static type checking
- Use
uvfor package management (faster alternative to pip) - Use pytest for testing
- All tests pass
- Type checking passes (mypy)
- Code formatter and linter pass (Ruff)
- All functions have docstrings and type hints
- No commented-out code or debug statements
- No hardcoded credentials
Remember: Prioritize clarity and maintainability over cleverness.
Very good, well-described and structured πππ―