# 📘 Python Specific Coding Rules

### 📘 Rule PY001 – Adhere to PEP 8 Style Guide

- **Objective**: Maintain a consistent and readable codebase following Python's official standards.
- **Details**:
    - Use 4 spaces per indentation level.
    - Limit line length to 79 characters.
    - Use `snake_case` for functions/variables and `PascalCase` for classes.
- **Applies to**: Python
- **Tool**: ruff, flake8, black
- **Principle**: CODE_QUALITY
- **Version**: 1.0
- **Status**: activated
- **Severity**: major

### 📘 Rule PY002 – Mandatory Type Hinting

- **Objective**: Improve code clarity, enable better IDE support, and catch type-related bugs early.
- **Details**:
    - Use type annotations for all function parameters and return types.
    - Use `typing` module for complex types (List, Dict, Optional).
- **Applies to**: Python 3.6+
- **Tool**: mypy, Pyright
- **Principle**: CODE_QUALITY, RELIABILITY
- **Version**: 1.0
- **Status**: activated
- **Severity**: major

**Good example**:
```python
def get_user_name(user_id: int) -> str:
    return db.fetch_name(user_id)
```

**Bad example**:
```python
def get_user_name(user_id):
    return db.fetch_name(user_id)
```

### 📘 Rule PY003 – Explicit Error Handling

- **Objective**: Prevent catching unexpected errors and ensure specific failure handling.
- **Details**:
    - Never use bare `except:` blocks.
    - Always catch specific exceptions (e.g., `ValueError`, `KeyError`).
- **Applies to**: Python
- **Tool**: pylint, ruff
- **Principle**: RELIABILITY
- **Version**: 1.0
- **Status**: activated
- **Severity**: critical

### 📘 Rule PY004 – Use logging instead of print

- **Objective**: Better event tracking, filtering, and production observability.
- **Details**:
    - Use the `logging` module for any non-ephemeral messaging.
    - Choose appropriate levels: `DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL`.
- **Applies to**: Python
- **Tool**: Manual Review, ruff
- **Principle**: MAINTAINABILITY
- **Version**: 1.0
- **Status**: activated
- **Severity**: major

### 📘 Rule PY005 – Context Managers for Resource Handling

- **Objective**: Ensure resources like files and network connections are closed properly.
- **Details**:
    - Use the `with` statement for resource management.
- **Applies to**: Python
- **Tool**: pylint, ruff
- **Principle**: RELIABILITY
- **Version**: 1.0
- **Status**: activated
- **Severity**: major

**Good example**:
```python
with open("data.txt", "r") as f:
    content = f.read()
```

### 📘 Rule PY006 – Avoid Mutable Default Arguments

- **Objective**: Prevent unexpected state sharing between function calls.
- **Details**:
    - Never use list or dict as a default value in function signature.
    - Use `None` as default and initialize inside the function.
- **Applies to**: Python
- **Tool**: pylint, ruff
- **Principle**: RELIABILITY
- **Version**: 1.0
- **Status**: activated
- **Severity**: major

**Good example**:
```python
def add_item(item, items=None):
    if items is None:
        items = []
    items.append(item)
    return items
```

**Bad example**:
```python
def add_item(item, items=[]): # items is shared across calls!
    items.append(item)
    return items
```
