Skip to content

Instantly share code, notes, and snippets.

@shiumachi
Last active July 14, 2025 01:25
Show Gist options
  • Save shiumachi/0b07ff295fc5dd0ddf909b471d04c474 to your computer and use it in GitHub Desktop.
Save shiumachi/0b07ff295fc5dd0ddf909b471d04c474 to your computer and use it in GitHub Desktop.
Copilot Instructions for Python
applyTo description
**/*.py,**/*.pyi
Coding standards and best practices for Python 3.10+

Python Coding Guidelines (Python 3.10+)

These guidelines supplement the general coding principles and should be prioritized for all Python code generation and modification.

1. Style and Formatting

  • Formatter and Linter Compliance: Generate code that complies with the conventions of formatters like black and linters like ruff (or flake8). 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, and PascalCase 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).

2. Type Hinting

  • 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 older typing.List and typing.Dict unless backward compatibility is required.
    • Use the union type operator (|) for optional types (e.g., str | None). Avoid the older Optional[str].
  • Readability: Use TypeAlias from the typing 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]:
    ...

3. Docstrings

  • 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 ...

4. Error Handling

  • Specific Exceptions: Catch specific exceptions (e.g., ValueError, FileNotFoundError) rather than a generic Exception or a bare except:. 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.

5. Pythonic Code & Modern Features

  • 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.

6. Patterns to Avoid

  • 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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment