Blame

77ba1d Melisha Dsouza 2026-01-16 07:46:25 1
# **Python**
2
3
**Scope**: This document defines the mandatory standards for all Python code to ensure readability, maintainability, security, and performance.
4
5
### **1. Code Layout & Formatting**
6
#### **1.1 Indentation**
7
- **Rule**: Use 4 spaces per indentation level.
8
- **Prohibited**: Never use tabs.
9
10
#### **1.2 Line Length**
11
- **Standard**: Limit all lines to a maximum of 79 characters (PEP 8 standard).
12
- **Modern Exception**: For complex configurations or type hints, 88 characters (Black formatter default) is acceptable if agreed upon by the team.
13
- **Handling**: Break long lines using parentheses `()`, not backslashes `\`.
14
15
```Python
16
# Good
17
user_permissions = (
18
"read_access",
19
"write_access",
20
"delete_access",
21
"admin_access"
22
)
23
```
24
25
#### **1.3 Imports**
26
- **Order**:
27
- Standard Library (e.g., `os`, `sys`)
28
- Third-Party (e.g., `requests`, `pandas`)
29
- Local Application (e.g., `from myapp.utils import helper`)
30
- **Style**: Use absolute imports. Avoid wildcard imports (`from module import *`).
31
32
#### **1.4 Whitespace**
33
- **Operators**: Surround binary operators with a single space (`x = 12`).
34
- **Definitions**: One space after the colon in type hints (`age: int`).
35
- **Functions**: Two blank lines before top-level functions; one blank line before methods inside a class.
36
37
### **2. Naming Conventions**
38
Follow strict PEP 8 naming to communicate intent instantly.
39
40
| Entity | Convention | Example |
41
| --------- | --------------------- | ---------------------- |
42
| Modules | `snake_case` | `data_processor.py` |
43
| Classes | `PascalCase` | `UserProfile` |
44
| Functions | `snake_case` | `calculate_total()` |
45
| Variables | `snake_case` | `is_active`, `user_id` |
46
| Constants | `SCREAMING_SNAKE` | `MAX_RETRIES = 3` |
47
| Private | `_leading_underscore` | `_internal_cache` |
48
49
### **3. Modern Type Hinting (Python 3.10+)**
50
Type hinting is no longer optional; it is mandatory for maintainability.
51
52
#### **3.1 Syntax**
53
- **Rule**: Use the modern pipe | operator for Unions instead of importing `Union` or `Optional`.
54
- **Return Types**: Always specify the return type, even if it is `None`.
55
```Python
56
57
# Bad (Old Style)
58
from typing import List, Optional
59
def find_user(ids: List[int]) -> Optional[str]: ...
60
61
# Good (Modern Style)
62
def find_user(ids: list[int]) -> str | None:
63
...
64
```
65
66
#### **3.2 Collections**
67
- **Rule**: Use standard collections `(list, dict, tuple)` instead of `typing.List` or `typing.Dict`.
68
69
### **4. Documentation & Docstrings**
70
#### **4.1 Format**
71
- **Standard**: Use the Google Style docstring format. It is cleaner and more readable than reStructuredText.
72
- **Requirement**: All public modules, classes, and functions must have a docstring.
73
74
```Python
75
def connect_to_db(timeout: int = 10) -> bool:
76
"""Establishes a connection to the primary database.
77
78
Args:
79
timeout (int): Max time in seconds to wait for connection.
80
81
Returns:
82
bool: True if connection successful, False otherwise.
83
84
Raises:
85
ConnectionError: If the network is down.
86
"""
87
pass
88
```
89
#### **4.2 Comments**
90
- **Rule**: Comments must explain "Why", not "What".
91
- **Maintenance**: Delete commented-out code immediately. Do not commit dead code.
92
93
### **5. Programming Best Practices**
94
**5.1 Error Handling**
95
- **Prohibited**: Never use bare except:.
96
- **Best Practice**: Catch specific exceptions.
97
- **Chaining**: When re-raising an exception, use `raise ... from e` to preserve the stack trace.
98
```Python
99
# Good
100
try:
101
process_data()
102
except ValueError as e:
103
raise DataProcessingError("Invalid data format") from e
104
```
105
106
#### **5.2 Conditionals & Truthiness**
107
- Explicit is better: Use `if x is None:` instead `of if x == None:`.
108
- Implicit False: Use implicit boolean checks for lists/strings.
109
- Yes: `if my_list:` (Checks if list is not empty)
110
- No: `if len(my_list) > 0:`
111
112
#### **5.3 Magic Numbers**
113
- **Rule**: Replace raw numbers/strings with named constants or Enums.
114
115
```Python
116
from enum import Enum
117
118
class Status(Enum):
119
PENDING = "pending"
120
ACTIVE = "active"
121
122
# Usage
123
if user.status == Status.ACTIVE:
124
...
125
```
126
127
### **6. Async & Performance (Modern Standards)**
128
#### **6.1 Async/Await**
129
- **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`).
130
- **Safe Handling**: Use `TaskGroup` (Python 3.11+) for managing concurrent tasks safely.
131
#### **6.2 Loops**
132
- **Rule**: Use `enumerate()` for indexing.
133
- **Rule**: Prefer List Comprehensions for simple transformations, but use `for` loops if the logic is complex.
134
135
### **7. Security & Privacy**
136
- **Secrets**: Never commit API keys, passwords, or tokens to Git. Use `.env` files and `pydantic-settings`.
137
- **Inputs**: Always validate user input. Never pass user input directly to `eval(), exec(),` or raw SQL queries (use ORM or parameterized queries).
138
139
### **8. Automation & Tooling**
140
Manual enforcement is unreliable. The project can use the following automated tools:
141
- **Ruff**: The modern, high-speed replacement for Flake8 and isort.
142
- **Black**: For uncompromising code formatting.
143
- **Mypy**: For static type checking.
144
- **Pre-commit**: To run these checks before every commit.
145
Configuration (`pyproject.toml`)
146
147
Copy this configuration to standardise your team's tooling:
148
```Python
149
[tool.ruff]
150
line-length = 79
151
select = ["E", "F", "I", "UP", "B"] # Enforce PEP8, Imports, pyupgrade, Bugbear
152
153
[tool.mypy]
154
strict = true
155
ignore_missing_imports = true
156
```
157
158
**Recommended folder structure for modern Python projects)**
159
```
160
project_root/
161
162
├── src/
163
│ └── my_package/
164
│ ├── __init__.py
165
│ ├── main.py
166
│ └── utils.py
167
├── tests/
168
│ ├── __init__.py
169
│ └── test_main.py
170
├── .env # Secrets (GitIgnored)
171
├── .gitignore
172
├── pyproject.toml # Tooling Config
173
└── README.md
174
```