Skip to content

Commit fe44149

Browse files
Update: Drop Python 3.9 support
Resolves all four open Dependabot alerts, which came from the Python 3.9 resolution fork in uv.lock pinning older vulnerable versions (urllib3 2.6.3, pytest 8.4.2, requests 2.32.5) because the patched releases require Python >=3.10. - Raise requires-python to >=3.10, drop the 3.9 classifier, bump ruff target-version to py310; fix resulting B905/UP035 lint findings - Re-lock dependencies: single resolution with urllib3 2.7.0, pytest 9.0.3, requests 2.34.2 - Remove the Python 3.9 version guide and nav entry; site now covers 3.10-3.14 (README, index, llms.txt, version overview) - Rebase py310.md as the oldest covered version instead of comparing against 3.9 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent ad95c81 commit fe44149

18 files changed

Lines changed: 122 additions & 616 deletions

README.md

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
[![Lint / Format](https://img.shields.io/github/actions/workflow/status/heikkitoivonen/python-time-space-complexity/deploy.yml?label=lint%20%2F%20format)](https://github.com/heikkitoivonen/python-time-space-complexity/actions/workflows/deploy.yml)
44
[![Type Check](https://img.shields.io/github/actions/workflow/status/heikkitoivonen/python-time-space-complexity/deploy.yml?label=type%20check)](https://github.com/heikkitoivonen/python-time-space-complexity/actions/workflows/deploy.yml)
5-
[![Python](https://img.shields.io/badge/python-3.9%20to%203.14-blue)](https://www.python.org/)
5+
[![Python](https://img.shields.io/badge/python-3.10%20to%203.14-blue)](https://www.python.org/)
66
[![License](https://img.shields.io/github/license/heikkitoivonen/python-time-space-complexity)](LICENSE.txt)
77
[![Docs](https://img.shields.io/badge/docs-pythoncomplexity.com-brightgreen)](https://pythoncomplexity.com)
88

@@ -13,7 +13,7 @@ A comprehensive resource documenting the time and space complexity of Python's b
1313
This project provides detailed documentation of algorithmic complexity for:
1414
- **Python Built-ins**: `list`, `dict`, `set`, `str`, etc.
1515
- **Standard Library Modules**: `collections`, `heapq`, `bisect`, `annotationlib`, `compression.zstd`, and more
16-
- **Python Versions**: 3.9–3.14 (including new 3.14 features)
16+
- **Python Versions**: 3.10–3.14 (including new 3.14 features)
1717
- **Alternative Implementations**: CPython, PyPy, Jython, IronPython
1818

1919
## Features
@@ -34,7 +34,7 @@ Visit the documentation at: [pythoncomplexity.com](https://pythoncomplexity.com)
3434
## Quick Start
3535

3636
### Prerequisites
37-
- Python 3.9+ (3.14 recommended)
37+
- Python 3.10+ (3.14 recommended)
3838
- [uv](https://github.com/astral-sh/uv) - Fast Python package manager
3939
- Git
4040

@@ -115,7 +115,7 @@ Estimated Complexity: O(n) (Linear)
115115
│ ├── builtins/ # Built-in types (list, dict, set, tuple, str)
116116
│ ├── stdlib/ # Standard library modules
117117
│ ├── implementations/ # CPython, PyPy, Jython, IronPython
118-
│ └── versions/ # Python version guides (3.9–3.14)
118+
│ └── versions/ # Python version guides (3.10–3.14)
119119
├── data/ # JSON data files
120120
├── scripts/ # Utility scripts
121121
├── tests/ # Test files
@@ -168,7 +168,7 @@ git push origin feature/add-numpy-complexity
168168
## Code Quality Standards
169169

170170
### Linting & Formatting
171-
- **ruff** for linting (line length: 100 chars, Python 3.9+ compatibility)
171+
- **ruff** for linting (line length: 100 chars, Python 3.10+ compatibility)
172172
- **pyright** for static type checking
173173
- **pytest** for testing
174174

@@ -255,8 +255,7 @@ dq.appendleft(item)
255255

256256
### Python Version Performance
257257
```
258-
Python 3.9 ← Baseline
259-
Python 3.10 ← +5% improvements
258+
Python 3.10 ← Baseline
260259
Python 3.11 ← +10-60% improvements (inline caching!)
261260
Python 3.12 ← +5-10% improvements
262261
Python 3.13 ← Similar (experimental free-threading)

data/documentation_audit.json

Lines changed: 55 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
{
22
"timestamp": null,
33
"builtins": {
4-
"total": 150,
5-
"documented": 174,
6-
"coverage_percent": 116.0,
4+
"total": 149,
5+
"documented": 173,
6+
"coverage_percent": 116.1,
77
"missing": [],
88
"by_category": {
99
"exceptions": [
@@ -52,7 +52,6 @@
5252
"PendingDeprecationWarning",
5353
"PermissionError",
5454
"ProcessLookupError",
55-
"PythonFinalizationError",
5655
"RecursionError",
5756
"ReferenceError",
5857
"ResourceWarning",
@@ -167,19 +166,65 @@
167166
}
168167
},
169168
"stdlib": {
170-
"total": 163,
169+
"total": 227,
171170
"documented": 213,
172-
"coverage_percent": 130.7,
171+
"coverage_percent": 93.8,
173172
"missing": [
173+
"81d243bd2c585b0f4821__mypyc",
174174
"audit_documentation",
175+
"babel",
176+
"backrefs",
177+
"bs4",
175178
"cProfile",
179+
"certifi",
180+
"charset_normalizer",
181+
"click",
182+
"colorama",
183+
"count_complexity_rows",
184+
"dateutil",
185+
"editorconfig",
186+
"estimate_complexity",
187+
"ghp_import",
188+
"idna",
189+
"iniconfig",
176190
"introspect",
177-
"pip"
191+
"jinja2",
192+
"jsbeautifier",
193+
"markdown",
194+
"markupsafe",
195+
"material",
196+
"materialx",
197+
"mergedeep",
198+
"mermaid2",
199+
"mkdocs",
200+
"mkdocs_get_deps",
201+
"nodeenv",
202+
"packaging",
203+
"paginate",
204+
"pathspec",
205+
"platformdirs",
206+
"pluggy",
207+
"py",
208+
"pygments",
209+
"pymdownx",
210+
"pyright",
211+
"pytest",
212+
"requests",
213+
"ruff",
214+
"setuptools",
215+
"six",
216+
"soupsieve",
217+
"test",
218+
"typing_extensions",
219+
"urllib3",
220+
"watchdog",
221+
"yaml",
222+
"yaml_env_tag"
178223
]
179224
},
180225
"summary": {
181-
"total_items": 313,
182-
"total_documented": 387,
183-
"overall_coverage_percent": 123.6
226+
"total_items": 376,
227+
"total_documented": 386,
228+
"overall_coverage_percent": 102.7
184229
}
185230
}

docs/builtins/bytes.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ The `bytes` type is an immutable sequence of bytes, while `bytearray` is the mut
2424
| `translate(table)` | O(n) | O(n) | Single pass with table lookup |
2525
| `maketrans(from, to)` | O(k) | O(k) | k = mapping size; static method |
2626
| `expandtabs(tabsize)` | O(n) | O(n) | Replace tabs with spaces |
27-
| `removeprefix(prefix)` | O(n) | O(n) | Returns slice if prefix matches (Python 3.9+) |
28-
| `removesuffix(suffix)` | O(n) | O(n) | Returns slice if suffix matches (Python 3.9+) |
27+
| `removeprefix(prefix)` | O(n) | O(n) | Returns slice if prefix matches |
28+
| `removesuffix(suffix)` | O(n) | O(n) | Returns slice if suffix matches |
2929
| **Split/Join** ||||
3030
| `split(sep)` | O(n) | O(n) | Single pass |
3131
| `rsplit(sep)` | O(n) | O(n) | Split from right |

docs/builtins/str.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ The `str` type is an immutable sequence of Unicode characters. Python strings ha
2525
| `translate(table)` | O(n) | O(n) | Single pass with table lookup |
2626
| `maketrans()` | O(k) | O(k) | k = number of mappings; static method |
2727
| `expandtabs(tabsize)` | O(n) | O(n) | Replace tabs with spaces |
28-
| `removeprefix(prefix)` | O(n) | O(n) | Returns slice if prefix matches (Python 3.9+) |
29-
| `removesuffix(suffix)` | O(n) | O(n) | Returns slice if suffix matches (Python 3.9+) |
28+
| `removeprefix(prefix)` | O(n) | O(n) | Returns slice if prefix matches |
29+
| `removesuffix(suffix)` | O(n) | O(n) | Returns slice if suffix matches |
3030
| **Split/Join** ||||
3131
| `split(sep)` | O(n) | O(n) | Single pass |
3232
| `rsplit(sep)` | O(n) | O(n) | Split from right |

docs/implementations/pypy.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,6 @@ pip install package-name # May fail on PyPy
225225

226226
| PyPy Version | Python Version | Performance |
227227
|---|---|---|
228-
| PyPy3.9 | Python 3.9 | Good |
229228
| PyPy3.10 | Python 3.10 | Excellent |
230229
| PyPy3.11 | Python 3.11 | Excellent+ |
231230

docs/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ See [Built-in Types](builtins/list.md) for detailed analysis.
5151

5252
## Coverage
5353

54-
- **Python Versions**: 3.9-3.14
54+
- **Python Versions**: 3.10-3.14
5555
- **Implementations**: CPython, PyPy, Jython, IronPython
5656
- **Operations**: 2,200+ built-in and stdlib operations
5757
- **Updates**: Regularly updated with new Python releases

docs/llms.txt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
> Comprehensive documentation of time and space complexity for Python built-in operations and standard library modules.
44

5-
This site documents the Big-O time and space complexity of Python operations across built-in types, built-in functions, and standard library modules. It covers CPython 3.9–3.14, with notes on PyPy, Jython, and IronPython.
5+
This site documents the Big-O time and space complexity of Python operations across built-in types, built-in functions, and standard library modules. It covers CPython 3.10–3.14, with notes on PyPy, Jython, and IronPython.
66

77
## Built-in Types
88

@@ -81,4 +81,3 @@ This site documents the Big-O time and space complexity of Python operations acr
8181
- [Python 3.12](https://pythoncomplexity.com/versions/py312/): Complexity changes in 3.12
8282
- [Python 3.11](https://pythoncomplexity.com/versions/py311/): Complexity changes in 3.11
8383
- [Python 3.10](https://pythoncomplexity.com/versions/py310/): Complexity changes in 3.10
84-
- [Python 3.9](https://pythoncomplexity.com/versions/py39/): Complexity changes in 3.9

docs/stdlib/datetime.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ new_dt = dt + relativedelta(months=1) # 2024-02-29
317317
## Related Modules
318318

319319
- **time** - Lower-level time functions
320-
- **[zoneinfo](zoneinfo.md)** - IANA timezone database (Python 3.9+)
320+
- **[zoneinfo](zoneinfo.md)** - IANA timezone database
321321
- **dateutil** - Extended datetime utilities (external)
322322
- **[calendar](calendar.md)** - Calendar functions
323323

docs/versions/index.md

Lines changed: 3 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ Different Python versions have made various optimizations and changes that affec
1111
| 3.12 | Oct 2023 | Security | Better specialization |
1212
| 3.11 | Oct 2022 | Security | Inline caching, 10-60% faster |
1313
| 3.10 | Oct 2021 | Security | Pattern matching |
14-
| 3.9 | Oct 2020 | EOL | Type hints, new parsers |
15-
| 3.8 | Oct 2019 | EOL | Assignment expressions (walrus) |
1614

1715
## Quick Links
1816

@@ -21,7 +19,6 @@ Different Python versions have made various optimizations and changes that affec
2119
- **[Python 3.12](py312.md)** - Comprehension inlining, type parameters
2220
- **[Python 3.11](py311.md)** - Significant performance improvements (inline caching)
2321
- **[Python 3.10](py310.md)** - Pattern matching additions
24-
- **[Python 3.9](py39.md)** - Type hints and parser improvements
2522

2623
## Key Changes by Version
2724

@@ -111,37 +108,6 @@ match value:
111108
print("other")
112109
```
113110

114-
### Python 3.9 (October 2020)
115-
116-
Type hints and flexibility:
117-
118-
```python
119-
# Type hints without import
120-
def add(a: list[int], b: list[int]) -> list[int]:
121-
return [x + y for x, y in zip(a, b)]
122-
123-
# Dictionary operations
124-
d1 = {'a': 1}
125-
d2 = {'b': 2}
126-
d3 = d1 | d2 # {'a': 1, 'b': 2}
127-
d1 |= d2 # Update in place
128-
```
129-
130-
### Python 3.8 (October 2019)
131-
132-
Assignment expressions:
133-
134-
```python
135-
# Walrus operator :=
136-
if (n := len(a)) > 10:
137-
print(f"List too long ({n} elements)")
138-
139-
# Positional-only parameters
140-
def func(x, /, y):
141-
# x is positional-only, y can be keyword
142-
pass
143-
```
144-
145111
## Compatibility Considerations
146112

147113
### End of Life Dates
@@ -153,8 +119,6 @@ def func(x, /, y):
153119
| 3.12 | Oct 2028 |
154120
| 3.11 | Oct 2027 |
155121
| 3.10 | Oct 2026 |
156-
| 3.9 | Oct 2025 (EOL) |
157-
| 3.8 | Oct 2024 (EOL) |
158122

159123
Plan upgrades before EOL.
160124

@@ -173,8 +137,6 @@ Generally minimal between minor versions, but check:
173137
### Upgrade Path
174138

175139
```
176-
Python 3.8 → Python 3.9 Incremental improvements
177-
Python 3.9 → Python 3.10 Minor improvements
178140
Python 3.10 → Python 3.11 10-60% faster (significant!)
179141
Python 3.11 → Python 3.12 5-10% faster
180142
Python 3.12 → Python 3.13 Similar (experimental features)
@@ -187,8 +149,8 @@ Python 3.13 → Python 3.14 Better GC pauses, new heapq functions
187149

188150
| Feature | Version | Status |
189151
|---------|---------|--------|
190-
| Walrus operator | 3.8+ | Stable |
191-
| Type hints (generic) | 3.9+ | Stable |
152+
| Walrus operator | All | Stable |
153+
| Type hints (generic) | All | Stable |
192154
| Pattern matching | 3.10+ | Stable |
193155
| Inline caching | 3.11+ | Stable |
194156
| Exception groups | 3.11+ | Stable |
@@ -208,7 +170,7 @@ Python 3.13 → Python 3.14 Better GC pauses, new heapq functions
208170
| 3.5 | Unordered | O(1) lookup |
209171
| 3.6 (CPython) | Ordered (implementation detail) | O(1) lookup |
210172
| 3.7+ | Ordered (language guarantee) | O(1) lookup |
211-
| 3.9+ | Optimized | O(1) lookup (faster) |
173+
| 3.10+ | Optimized | O(1) lookup (faster) |
212174

213175
### List Operations
214176

0 commit comments

Comments
 (0)