6/16/2025

These rules focus on Trio code in Python. They cover code quality, like using `flake8-async` and following PEP 8. For code structure, it details directory layout, module organization, and component architecture. Also includes design patterns, anti - patterns, performance, security, testing, and tooling guidance.


## Code Organization and Structure

- **Directory Structure:**
    - A typical project structure might look like this:
        
        my_project/
        ├── src/
        │   ├── __init__.py
        │   ├── main.py  # Entry point
        │   ├── utils.py # Utility functions
        │   ├── services/
        │   │   ├── __init__.py
        │   │   ├── http_service.py
        │   │   └── db_service.py
        │   └── models/
        │       ├── __init__.py
        │       └── user.py
        ├── tests/
        │   ├── __init__.py
        │   ├── test_main.py
        │   ├── test_utils.py
        │   ├── services/
        │   │   ├── test_http_service.py
        │   │   └── test_db_service.py
        │   └── models/
        │       └── test_user.py
        ├── README.md
        ├── pyproject.toml  # Project configuration (poetry, pipenv)
        └── .gitignore
        
    - Use a `src` directory to hold the main application code.  This helps separate application code from configuration and documentation.
    - Keep tests in a separate `tests` directory, mirroring the structure of `src`.

- **File Naming Conventions:**
    - Use lowercase names for files and modules (e.g., `http_service.py`, `utils.py`).
    - Test files should be prefixed with `test_` (e.g., `test_http_service.py`).

- **Module Organization:**
    - Organize code into logical modules based on functionality (e.g., `services`, `models`, `utils`).
    - Use `__init__.py` files to make directories importable as packages.
    - Avoid circular dependencies between modules.

- **Component Architecture:**
    - Consider using a layered architecture (e.g., presentation, business logic, data access) to separate concerns.
    - Dependency Injection: Use dependency injection to make components more testable and reusable.

- **Code Splitting:**
    - Break down large modules into smaller, more manageable files.
    - Consider splitting modules based on functionality or responsibilities.

## Common Patterns and Anti-patterns

- **Design Patterns:**
    - **Asynchronous Factory:**  Use factories to create asynchronous resources (e.g., connections) to manage initialization efficiently.
        python
        async def create_db_connection():
            conn = await connect_to_db()
            return conn
        
        async def main():
            conn = await create_db_connection()
            # Use the connection
        
    - **Resource Pooling:** Implement resource pooling for database connections or network connections to reduce overhead.

- **Recommended Approaches:**
    - Use nurseries for structured concurrency.
    - Use streams (`trio.Stream`) for communication between tasks.
    - Use channels (`trio.QueueChannel`) for passing data between tasks.

- **Anti-patterns:**
    - **Sleeping without Cancellation:** Avoid using `time.sleep()` directly, as it blocks the event loop and ignores cancellation. Use `await trio.sleep()` instead.
    - **Long-Running Synchronous Operations:**  Don't perform CPU-bound operations directly in async functions. Offload them to separate threads or processes.
    - **Ignoring Cancellation:** Ensure that your async functions handle cancellation requests (`trio.Cancelled`).
    - **Unstructured Concurrency:**  Avoid spawning tasks without proper management (e.g., without using nurseries). This can lead to orphaned tasks and difficult debugging.

- **State Management:**
    - Immutable Data: Prefer immutable data structures to avoid race conditions and simplify reasoning about state.
    - Task-Local Storage: Use `trio.TaskLocal` to store task-specific data.
    - Thread-Safe Data Structures: If shared mutable state is necessary, use thread-safe data structures (e.g., `trio.Lock`, `trio.Semaphore`).

- **Error Handling:**
    - Use `try...except` blocks to handle exceptions within async functions.
    - Propagate exceptions appropriately to the nursery for proper error handling.
    - Consider using exception groups to handle multiple exceptions that occur concurrently.

## Performance Considerations

- **Optimization Techniques:**
    - Minimize context switching:  Reduce unnecessary `await` calls.
    - Use efficient data structures: Choose appropriate data structures for your specific use case.
    - Avoid excessive copying:  Use views or iterators when possible to avoid copying large data structures.

- **Memory Management:**
    - Release resources promptly: Use `with` statements or `try...finally` blocks to ensure that resources are released even if exceptions occur.
    - Avoid circular references: Be mindful of potential circular references, which can prevent garbage collection.

## Security Best Practices

- **Common Vulnerabilities:**
    - **Race Conditions:**  Be aware of potential race conditions when accessing shared mutable state.
    - **Cancellation Errors:** Improper cancellation handling can lead to resource leaks or incorrect program behavior.

- **Input Validation:**
    - Validate all external inputs to prevent injection attacks and other security vulnerabilities.
    - Sanitize user inputs before using them in database queries or other sensitive operations.

- **Authentication and Authorization:**
    - Use established authentication and authorization libraries.
    - Implement proper access controls to protect sensitive data.

- **Data Protection:**
    - Encrypt sensitive data at rest and in transit.
    - Use secure communication protocols (e.g., HTTPS).

- **Secure API Communication:**
    - Validate all API requests and responses.
    - Implement rate limiting to prevent abuse.

## Testing Approaches

- **Unit Testing:**
    - Use `trio.testing` to write unit tests for async functions.
    - Use `trio.testing.MockClock` to control time in tests.
    - Mock external dependencies to isolate the code being tested.

- **Integration Testing:**
    - Test the interaction between different components of your application.
    - Use real or simulated external services to test the integration with external systems.

- **End-to-End Testing:**
    - Test the entire application flow from the user interface to the database.

- **Test Organization:**
    - Organize tests in a directory structure that mirrors the structure of your application code.
    - Write clear and concise test names that describe the behavior being tested.

- **Mocking and Stubbing:**
    - Use mocking libraries like `unittest.mock` to replace external dependencies with mock objects.
    - Use stubbing to provide predefined responses for external dependencies.

## Common Pitfalls and Gotchas

- **Frequent Mistakes:**
    - Blocking the event loop with synchronous operations.
    - Ignoring cancellation requests.
    - Using `time.sleep()` instead of `trio.sleep()`.
    - Not handling exceptions properly.

- **Edge Cases:**
    - Handling timeouts and deadlines.
    - Dealing with cancellation in complex workflows.
    - Managing resources in the presence of exceptions and cancellations.

- **Version-Specific Issues:**
    - Be aware of any known bugs or limitations in specific versions of Trio.

- **Compatibility Concerns:**
    - Ensure compatibility between Trio and other libraries you are using.

- **Debugging Strategies:**
    - Use debuggers like `pdb` or `ipdb` to step through your code and inspect variables.
    - Use logging to track the execution flow of your application.
    - Use Trio's built-in debugging tools to identify performance bottlenecks and other issues.

## Tooling and Environment

- **Recommended Development Tools:**
    - VS Code with the Python extension.
    - PyCharm.
    - IPython or Jupyter Notebook for interactive development.

- **Build Configuration:**
    - Use a build system like `poetry` or `pipenv` to manage dependencies.

- **Linting and Formatting:**
    - Use `flake8` and `black` to ensure consistent code style.
    - Configure your editor to automatically format code on save.

- **Deployment:**
    - Use a process manager like `systemd` or `supervisor` to manage your application.

- **CI/CD Integration:**
    - Use CI/CD tools like GitHub Actions or GitLab CI to automate testing and deployment.