Skip to content

Commit 0e7383b

Browse files
authored
chore!: drop Python 3.10, which reached end of life (#270)
1 parent 70f67c6 commit 0e7383b

4 files changed

Lines changed: 14 additions & 20 deletions

File tree

‎.github/workflows/_checks.yml‎

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ jobs:
1212
with:
1313
enable-cache: true
1414
cache-dependency-glob: "**/pyproject.toml"
15-
- run: uv python install 3.10
16-
- run: uv python pin 3.10
15+
- run: uv python install 3.11
16+
- run: uv python pin 3.11
1717
- run: just install lint-ci
1818
- run: just adr-check
1919

@@ -49,7 +49,6 @@ jobs:
4949
fail-fast: false
5050
matrix:
5151
python-version:
52-
- "3.10"
5352
- "3.11"
5453
- "3.12"
5554
- "3.13"
@@ -96,7 +95,7 @@ jobs:
9695
with:
9796
enable-cache: true
9897
cache-dependency-glob: "**/pyproject.toml"
99-
- run: uv python install 3.10
98+
- run: uv python install 3.11
10099
- name: Each extra installs and imports in isolation
101100
run: |
102101
set -uo pipefail
@@ -110,12 +109,12 @@ jobs:
110109
faststream faststream-sentry faststream-otl faststream-logging faststream-metrics faststream-all \
111110
fastmcp fastmcp-metrics fastmcp-all"
112111
failed=""
113-
uv venv --python 3.10 .v-bare >/dev/null
112+
uv venv --python 3.11 .v-bare >/dev/null
114113
if uv pip install --python .v-bare/bin/python . >/dev/null 2>&1 \
115114
&& .v-bare/bin/python -c "import lite_bootstrap"; then :; else failed="$failed __bare__"; fi
116115
rm -rf .v-bare
117116
for e in $extras; do
118-
uv venv --python 3.10 ".v-$e" >/dev/null
117+
uv venv --python 3.11 ".v-$e" >/dev/null
119118
if uv pip install --python ".v-$e/bin/python" ".[$e]" >/dev/null 2>&1 \
120119
&& ".v-$e/bin/python" -c "import lite_bootstrap"; then :; else failed="$failed $e"; fi
121120
rm -rf ".v-$e"
@@ -138,7 +137,7 @@ jobs:
138137
strategy:
139138
fail-fast: false
140139
matrix:
141-
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
140+
python-version: ["3.11", "3.12", "3.13", "3.14"]
142141
target: [free, fastapi, litestar, faststream, fastmcp]
143142
# These `include` entries name an existing `target`, so each adds `extras` to that
144143
# target's five combinations rather than creating a job of its own. `free` carries

‎.github/workflows/security-audit.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ jobs:
1818
with:
1919
enable-cache: true
2020
cache-dependency-glob: "**/pyproject.toml"
21-
- run: uv python install 3.10
21+
- run: uv python install 3.11
2222
- name: Export locked dependencies
2323
run: uv export --all-extras --no-hashes > /tmp/requirements.txt
2424
- name: Install pip-audit

‎lite_bootstrap/instruments/base.py‎

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import dataclasses
22
import typing
33

4-
import typing_extensions
5-
64

75
@dataclasses.dataclass(kw_only=True, slots=True, frozen=True)
86
class BaseConfig:
@@ -21,13 +19,13 @@ def __post_init__(self) -> None:
2119
"""
2220

2321
@classmethod
24-
def from_dict(cls, data: dict[str, typing.Any]) -> typing_extensions.Self:
22+
def from_dict(cls, data: dict[str, typing.Any]) -> typing.Self:
2523
"""Build a config from a dict; unknown keys are silently dropped, explicit None overrides defaults."""
2624
field_names = {f.name for f in dataclasses.fields(cls)}
2725
return cls(**{k: v for k, v in data.items() if k in field_names})
2826

2927
@classmethod
30-
def from_object(cls, obj: object) -> typing_extensions.Self:
28+
def from_object(cls, obj: object) -> typing.Self:
3129
"""Build a config by merging non-None attributes from obj; None or missing attributes fall back to defaults."""
3230
field_names = {f.name for f in dataclasses.fields(cls)}
3331
prepared_data = {field: value for field in field_names if (value := getattr(obj, field, None)) is not None}

‎pyproject.toml‎

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,12 @@ authors = [
55
{ name = "Artur Shiriev", email = "me@shiriev.ru" },
66
]
77
readme = "README.md"
8-
requires-python = ">=3.10,<4"
8+
requires-python = ">=3.11,<4"
99
license = "MIT"
1010
keywords = ["microservices", "bootstrap", "opentelemetry", "sentry", "prometheus", "healthcheck", "fastapi", "litestar", "faststream", "structlog", "fastmcp", "python"]
1111
classifiers = [
1212
"Development Status :: 5 - Production/Stable",
1313
"Intended Audience :: Developers",
14-
"Programming Language :: Python :: 3.10",
1514
"Programming Language :: Python :: 3.11",
1615
"Programming Language :: Python :: 3.12",
1716
"Programming Language :: Python :: 3.13",
@@ -21,11 +20,9 @@ classifiers = [
2120
]
2221
version = "0"
2322
dependencies = [
24-
# Runtime use: `typing_extensions.Self` (base.py) and `typing_extensions.TypedDict`
25-
# (healthchecks) — the latter is required by pydantic/FastAPI on Python < 3.12
26-
# (`typing.TypedDict` is rejected there). Pure Python, so ft-friendly.
27-
# >=4.0 for `Self`; >=4.6 because 4.4 and 4.5 raise on import under Python >=3.12
28-
# (they subclass `typing.TypeVar`). The higher floor wins.
23+
# Runtime use: `typing_extensions.TypedDict` (healthchecks), required by pydantic/FastAPI on
24+
# Python < 3.12 (`typing.TypedDict` is rejected there). Pure Python, so ft-friendly.
25+
# >=4.6 because 4.4 and 4.5 raise on import under Python >=3.12 (they subclass `typing.TypeVar`).
2926
"typing-extensions>=4.6",
3027
]
3128

@@ -49,7 +46,7 @@ sentry = [
4946
# >=1.31 for the `max_value_length` init option; >=2.1 for sentry_sdk.set_tags (plural,
5047
# SentryInstrument.bootstrap) -- the higher floor wins.
5148
# 2.1 predates Python 3.13's FrameLocalsProxy, which the SDK fails to pickle when capturing a
52-
# request, and 3.14 needs later fixes again. Marked rather than raised, so 3.10-3.12 keep 2.1.
49+
# request, and 3.14 needs later fixes again. Marked rather than raised, so 3.11-3.12 keep 2.1.
5350
# 2.69.0 signs `sentry-trace`/`baggage` into SigV4 SignedHeaders and then rewrites them after
5451
# signing, so every aiobotocore AWS call inside a transaction fails with SignatureDoesNotMatch
5552
# (getsentry/sentry-python#7426, fixed in 2.69.1).

0 commit comments

Comments
 (0)