Commit 77ba1d
2026-01-16 07:46:25 Melisha Dsouza: Python| /dev/null .. CMMI/Guidelines/Coding Standard/Python.md | |
| @@ 0,0 1,174 @@ | |
| + | # **Python** |
| + | |
| + | **Scope**: This document defines the mandatory standards for all Python code to ensure readability, maintainability, security, and performance. |
| + | |
| + | ### **1. Code Layout & Formatting** |
| + | #### **1.1 Indentation** |
| + | - **Rule**: Use 4 spaces per indentation level. |
| + | - **Prohibited**: Never use tabs. |
| + | |
| + | #### **1.2 Line Length** |
| + | - **Standard**: Limit all lines to a maximum of 79 characters (PEP 8 standard). |
| + | - **Modern Exception**: For complex configurations or type hints, 88 characters (Black formatter default) is acceptable if agreed upon by the team. |
| + | - **Handling**: Break long lines using parentheses `()`, not backslashes `\`. |
| + | |
| + | ```Python |
| + | # Good |
| + | user_permissions = ( |
| + | "read_access", |
| + | "write_access", |
| + | "delete_access", |
| + | "admin_access" |
| + | ) |
| + | ``` |
| + | |
| + | #### **1.3 Imports** |
| + | - **Order**: |
| + | - Standard Library (e.g., `os`, `sys`) |
| + | - Third-Party (e.g., `requests`, `pandas`) |
| + | - Local Application (e.g., `from myapp.utils import helper`) |
| + | - **Style**: Use absolute imports. Avoid wildcard imports (`from module import *`). |
| + | |
| + | #### **1.4 Whitespace** |
| + | - **Operators**: Surround binary operators with a single space (`x = 12`). |
| + | - **Definitions**: One space after the colon in type hints (`age: int`). |
| + | - **Functions**: Two blank lines before top-level functions; one blank line before methods inside a class. |
| + | |
| + | ### **2. Naming Conventions** |
| + | Follow strict PEP 8 naming to communicate intent instantly. |
| + | |
| + | | Entity | Convention | Example | |
| + | | --------- | --------------------- | ---------------------- | |
| + | | Modules | `snake_case` | `data_processor.py` | |
| + | | Classes | `PascalCase` | `UserProfile` | |
| + | | Functions | `snake_case` | `calculate_total()` | |
| + | | Variables | `snake_case` | `is_active`, `user_id` | |
| + | | Constants | `SCREAMING_SNAKE` | `MAX_RETRIES = 3` | |
| + | | Private | `_leading_underscore` | `_internal_cache` | |
| + | |
| + | ### **3. Modern Type Hinting (Python 3.10+)** |
| + | Type hinting is no longer optional; it is mandatory for maintainability. |
| + | |
| + | #### **3.1 Syntax** |
| + | - **Rule**: Use the modern pipe | operator for Unions instead of importing `Union` or `Optional`. |
| + | - **Return Types**: Always specify the return type, even if it is `None`. |
| + | ```Python |
| + | |
| + | # Bad (Old Style) |
| + | from typing import List, Optional |
| + | def find_user(ids: List[int]) -> Optional[str]: ... |
| + | |
| + | # Good (Modern Style) |
| + | def find_user(ids: list[int]) -> str | None: |
| + | ... |
| + | ``` |
| + | |
| + | #### **3.2 Collections** |
| + | - **Rule**: Use standard collections `(list, dict, tuple)` instead of `typing.List` or `typing.Dict`. |
| + | |
| + | ### **4. Documentation & Docstrings** |
| + | #### **4.1 Format** |
| + | - **Standard**: Use the Google Style docstring format. It is cleaner and more readable than reStructuredText. |
| + | - **Requirement**: All public modules, classes, and functions must have a docstring. |
| + | |
| + | ```Python |
| + | def connect_to_db(timeout: int = 10) -> bool: |
| + | """Establishes a connection to the primary database. |
| + | |
| + | Args: |
| + | timeout (int): Max time in seconds to wait for connection. |
| + | |
| + | Returns: |
| + | bool: True if connection successful, False otherwise. |
| + | |
| + | Raises: |
| + | ConnectionError: If the network is down. |
| + | """ |
| + | pass |
| + | ``` |
| + | #### **4.2 Comments** |
| + | - **Rule**: Comments must explain "Why", not "What". |
| + | - **Maintenance**: Delete commented-out code immediately. Do not commit dead code. |
| + | |
| + | ### **5. Programming Best Practices** |
| + | **5.1 Error Handling** |
| + | - **Prohibited**: Never use bare except:. |
| + | - **Best Practice**: Catch specific exceptions. |
| + | - **Chaining**: When re-raising an exception, use `raise ... from e` to preserve the stack trace. |
| + | ```Python |
| + | # Good |
| + | try: |
| + | process_data() |
| + | except ValueError as e: |
| + | raise DataProcessingError("Invalid data format") from e |
| + | ``` |
| + | |
| + | #### **5.2 Conditionals & Truthiness** |
| + | - Explicit is better: Use `if x is None:` instead `of if x == None:`. |
| + | - Implicit False: Use implicit boolean checks for lists/strings. |
| + | - Yes: `if my_list:` (Checks if list is not empty) |
| + | - No: `if len(my_list) > 0:` |
| + | |
| + | #### **5.3 Magic Numbers** |
| + | - **Rule**: Replace raw numbers/strings with named constants or Enums. |
| + | |
| + | ```Python |
| + | from enum import Enum |
| + | |
| + | class Status(Enum): |
| + | PENDING = "pending" |
| + | ACTIVE = "active" |
| + | |
| + | # Usage |
| + | if user.status == Status.ACTIVE: |
| + | ... |
| + | ``` |
| + | |
| + | ### **6. Async & Performance (Modern Standards)** |
| + | #### **6.1 Async/Await** |
| + | - **Rule**: Do not use blocking code (e.g., `time.sleep, requests.get`) inside `async` functions. Use `await asyncio.sleep` or asynchronous libraries (e.g., `httpx`). |
| + | - **Safe Handling**: Use `TaskGroup` (Python 3.11+) for managing concurrent tasks safely. |
| + | #### **6.2 Loops** |
| + | - **Rule**: Use `enumerate()` for indexing. |
| + | - **Rule**: Prefer List Comprehensions for simple transformations, but use `for` loops if the logic is complex. |
| + | |
| + | ### **7. Security & Privacy** |
| + | - **Secrets**: Never commit API keys, passwords, or tokens to Git. Use `.env` files and `pydantic-settings`. |
| + | - **Inputs**: Always validate user input. Never pass user input directly to `eval(), exec(),` or raw SQL queries (use ORM or parameterized queries). |
| + | |
| + | ### **8. Automation & Tooling** |
| + | Manual enforcement is unreliable. The project can use the following automated tools: |
| + | - **Ruff**: The modern, high-speed replacement for Flake8 and isort. |
| + | - **Black**: For uncompromising code formatting. |
| + | - **Mypy**: For static type checking. |
| + | - **Pre-commit**: To run these checks before every commit. |
| + | Configuration (`pyproject.toml`) |
| + | |
| + | Copy this configuration to standardise your team's tooling: |
| + | ```Python |
| + | [tool.ruff] |
| + | line-length = 79 |
| + | select = ["E", "F", "I", "UP", "B"] # Enforce PEP8, Imports, pyupgrade, Bugbear |
| + | |
| + | [tool.mypy] |
| + | strict = true |
| + | ignore_missing_imports = true |
| + | ``` |
| + | |
| + | **Recommended folder structure for modern Python projects)** |
| + | ``` |
| + | project_root/ |
| + | │ |
| + | ├── src/ |
| + | │ └── my_package/ |
| + | │ ├── __init__.py |
| + | │ ├── main.py |
| + | │ └── utils.py |
| + | ├── tests/ |
| + | │ ├── __init__.py |
| + | │ └── test_main.py |
| + | ├── .env # Secrets (GitIgnored) |
| + | ├── .gitignore |
| + | ├── pyproject.toml # Tooling Config |
| + | └── README.md |
| + | ``` |