Skip to content

Commit c121874

Browse files
committed
Drop support for Python 3.9
1 parent 4ab2a41 commit c121874

File tree

7 files changed

+15
-232
lines changed

7 files changed

+15
-232
lines changed

.github/copilot-instructions.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Single-file implementation in `trycast/__init__.py` (~1300 lines).
1010

1111
### Version Compatibility Strategy
1212

13-
**Critical**: trycast supports Python 3.9-3.13 with extensive conditional imports:
13+
**Critical**: trycast supports Python 3.10-3.13 with extensive conditional imports:
1414
- Use `sys.version_info >= (major, minor)` checks to conditionally import features
1515
- Import from `typing_extensions` as fallback for older Python versions
1616
- Example pattern (lines 43-50, 53-65, 67-77):
@@ -56,7 +56,7 @@ When adding features, test against all typecheckers: `make typecheck` runs mypy,
5656

5757
### Testing Commands (Makefile)
5858
- `make test` - Run unittest against current Python version
59-
- `make testall` - Run tox across Python 3.9-3.13 (uses venv3.9/, venv3.10/, etc.)
59+
- `make testall` - Run tox across Python 3.10-3.13 (uses venv3.10/, venv3.11/, etc.)
6060
- `make typecheck` - Run all typecheckers (mypy, pyright, pyre)
6161
- `make format` - Format with black + isort
6262
- `make lint` - Check black/isort/flake8 compliance
@@ -72,7 +72,7 @@ When adding features, test against all typecheckers: `make typecheck` runs mypy,
7272
- Example: `python -m timeit -s 'from benchmarks import http_request_parsing_example__fail as b' 'b.run()'`
7373

7474
### Virtual Environments
75-
Multiple venvs for each Python version: `venv3.9/`, `venv3.10/`, ..., `venv3.13/`. Use Poetry for dependency management.
75+
Multiple venvs for each Python version: `venv3.10/`, `venv3.11/`, ..., `venv3.13/`. Use Poetry for dependency management.
7676

7777
## Critical Patterns
7878

.github/workflows/ci.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ jobs:
77
matrix:
88
# All available versions of Python:
99
# https://github.com/actions/python-versions/blob/main/versions-manifest.json
10-
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
10+
python-version: ["3.10", "3.11", "3.12", "3.13"]
1111
fail-fast: false
1212
steps:
1313
- name: Checkout code

README.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,6 @@ python -m pip install trycast
217217
218218
- So that `trycast()` can recognize TypedDicts with mixed required and
219219
not-required keys correctly:
220-
* Use Python 3.9+.
221220
* Prefer using `typing.TypedDict` instead of `typing_extensions.TypedDict`.
222221
223222
@@ -514,7 +513,7 @@ raised exceptions, and other details.
514513
515514
### main (v2.0.0)
516515
517-
* Drop support for Python 3.8.
516+
* Drop support for Python 3.8 and Python 3.9.
518517
* Drop support for Python 3.8's neutered TypedDict,
519518
which lacks metadata present in later versions.
520519
* Drop support for Pytype type checker, since it has been

poetry.lock

Lines changed: 5 additions & 204 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ classifiers = [ # https://pypi.org/classifiers/
1616
"License :: OSI Approved :: MIT License",
1717
"Operating System :: OS Independent",
1818
"Programming Language :: Python :: 3",
19-
"Programming Language :: Python :: 3.9",
2019
"Programming Language :: Python :: 3.10",
2120
"Programming Language :: Python :: 3.11",
2221
"Programming Language :: Python :: 3.12",
@@ -29,7 +28,7 @@ classifiers = [ # https://pypi.org/classifiers/
2928
"Release notes" = "https://github.com/davidfstr/trycast#changelog"
3029

3130
[tool.poetry.dependencies]
32-
python = ">=3.9"
31+
python = ">=3.10"
3332

3433
[tool.poetry.group.dev.dependencies]
3534
mypy = "*"
@@ -84,7 +83,7 @@ line_length = 88
8483
legacy_tox_ini = """
8584
8685
[tox]
87-
envlist = py39,py310,py311,py312,py313
86+
envlist = py310,py311,py312,py313
8887
isolated_build = True
8988
9089
[testenv]

tests.py

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2724,16 +2724,11 @@ def assertRaisesEqual(
27242724
else:
27252725
self.fail(f"Expected {tp}")
27262726

2727+
# TODO: Inline unique implementation
27272728
@staticmethod
27282729
def _typing_error_messages(template: str) -> List[str]:
2729-
python_3_9 = (
2730-
template.replace("Literal", "typing.Literal")
2731-
.replace("NoReturn", "typing.NoReturn")
2732-
.replace("Union", "typing.Union")
2733-
)
27342730
return [
27352731
template,
2736-
python_3_9, # for Python 3.9
27372732
]
27382733

27392734

trycast/__init__.py

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -146,19 +146,8 @@ def _is_typed_dict(tp: object) -> bool:
146146

147147

148148
# _is_newtype
149-
if NewType.__class__.__name__ == "function": # type: ignore[reportGeneralTypeIssues] # pyright
150-
# Python 3.9
151-
def _is_newtype(tp: object) -> bool:
152-
return (
153-
hasattr(tp, "__class__")
154-
and tp.__class__.__name__ == "function"
155-
and hasattr(tp, "__qualname__")
156-
and tp.__qualname__.startswith("NewType.<locals>") # type: ignore[attr-defined]
157-
and hasattr(tp, "__module__")
158-
and tp.__module__ == "typing"
159-
)
160-
161-
elif NewType.__class__.__name__ == "type": # type: ignore[reportGeneralTypeIssues] # pyright
149+
# TODO: Inline unique implementation
150+
if NewType.__class__.__name__ == "type": # type: ignore[reportGeneralTypeIssues] # pyright
162151
# Python 3.10+
163152
def _is_newtype(tp: object) -> bool:
164153
return isinstance(tp, NewType) # type: ignore[arg-type]

0 commit comments

Comments
 (0)