applyTo | description |
---|---|
**/*.py,**/*.pyi |
Coding standards and best practices for Python 3.10+ |
These guidelines supplement the general coding principles and should be prioritized for all Python code generation and modification.
- Formatter and Linter Compliance: Generate code that complies with the conventions of formatters like
black
and linters likeruff
(orflake8
). This ensures consistent formatting and helps prevent static analysis errors.- Indentation: 4 spaces.
- Line Length: Adhere to a maximum of 88 characters, per
black
's default. - Naming Conventions: Use
snake_case
for functions and variables, andPascalCase
for classes.
- Imports: Group imports in the following order: standard library, third-party libraries, then local application modules. Sort imports alphabetically within each group (following
isort
conventions).
- Mandatory: All new function and method signatures (arguments and return values) must include type hints.
- Modern Syntax (Python 3.10+):
- Use built-in generic types (e.g.,
list[str]
,dict[str, int]
). Avoid the oldertyping.List
andtyping.Dict
unless backward compatibility is required. - Use the union type operator (
|
) for optional types (e.g.,str | None
). Avoid the olderOptional[str]
.
- Use built-in generic types (e.g.,
- Readability: Use
TypeAlias
from thetyping
module to give clear names to complex type definitions.
# Example: Modern Type Hinting
from typing import TypeAlias
JsonPayload: TypeAlias = dict[str, "JsonPayload"] | list["JsonPayload"] | str | int | float | bool | None
def process_data(data: list[str], active: bool | None = None) -> dict[str, int]:
...
- Mandatory: Write docstrings for all public modules, functions, classes, and methods.
- Recommended Style: Use Google Python Style. It clearly separates the purpose, arguments, return values, and potential exceptions.
- Content: The docstring should explain the what and why of the code. Avoid duplicating type information that is already present in the type hints.
# Example: Google Style Docstring
def connect_to_database(host: str, port: int) -> Connection:
"""Establishes a connection to the database and returns a connection object.
Args:
host: The hostname of the database to connect to.
port: The port number for the connection.
Returns:
A connection object to the database on success.
Raises:
ConnectionError: If connecting to the specified host or port fails.
"""
# ... implementation ...
- Specific Exceptions: Catch specific exceptions (e.g.,
ValueError
,FileNotFoundError
) rather than a genericException
or a bareexcept:
. This makes debugging easier and the code more robust. - Custom Exceptions: For application-specific error conditions, it is recommended to define custom exception classes that inherit from the built-in
Exception
.
- Idioms: Actively use Pythonic idioms for concise, readable code. This includes list comprehensions, generator expressions, context managers (
with
statement), and f-strings for formatting. - Structural Pattern Matching (Python 3.10+): For complex conditional logic, consider using
match...case
statements to create more readable and robust code where appropriate.
- Mutable Default Arguments: Do not use mutable default arguments like lists or dictionaries. Instead, use
None
as the default and create the object inside the function.
# Anti-pattern (incorrect)
def add_item(item, items_list=[]):
items_list.append(item)
return items_list
# Recommended pattern (correct)
def add_item(item: str, items_list: list[str] | None = None) -> list[str]:
if items_list is None:
items_list = []
items_list.append(item)
return items_list
- Wildcard Imports: Avoid wildcard imports (
from module import *
). They pollute the namespace and make code difficult to read and debug.