Skip to content

Commit 1f602d5

Browse files
committed
Drop 3.9
1 parent 1425e7e commit 1f602d5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+177
-214
lines changed

.github/workflows/autodeps.yml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,26 +26,27 @@ jobs:
2626
- name: Setup python
2727
uses: actions/setup-python@v5
2828
with:
29-
python-version: "3.9"
29+
python-version: "3.10"
3030

3131
- name: Bump dependencies
3232
run: |
3333
python -m pip install -U pip pre-commit
3434
python -m pip install -r test-requirements.txt
35-
uv pip compile --universal --python-version=3.9 --upgrade test-requirements.in -o test-requirements.txt
35+
uv pip compile --universal --python-version=3.10 --upgrade test-requirements.in -o test-requirements.txt
3636
uv pip compile --universal --python-version=3.11 --upgrade docs-requirements.in -o docs-requirements.txt
3737
pre-commit autoupdate --jobs 0
3838
3939
- name: Install new requirements
4040
run: python -m pip install -r test-requirements.txt
4141

4242
# apply newer versions' formatting
43+
# TODO: are the following two required given they are in pre-commit?
4344
- name: Black
4445
run: black src/trio
4546

4647
- name: uv
4748
run: |
48-
uv pip compile --universal --python-version=3.9 test-requirements.in -o test-requirements.txt
49+
uv pip compile --universal --python-version=3.10 test-requirements.in -o test-requirements.txt
4950
uv pip compile --universal --python-version=3.11 docs-requirements.in -o docs-requirements.txt
5051
5152
- name: Commit changes and create automerge PR

.github/workflows/ci.yml

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -155,18 +155,18 @@ jobs:
155155
strategy:
156156
fail-fast: false
157157
matrix:
158-
python: ['3.9', '3.10', '3.11', '3.12', '3.13', '3.14']
158+
python: ['3.10', '3.11', '3.12', '3.13', '3.14']
159159
arch: ['x86', 'x64']
160160
lsp: ['']
161161
lsp_extract_file: ['']
162162
extra_name: ['']
163163
include:
164-
- python: '3.9'
164+
- python: '3.10'
165165
arch: 'x64'
166166
lsp: 'https://raw.githubusercontent.com/python-trio/trio-ci-assets/master/komodia-based-vpn-setup.zip'
167167
lsp_extract_file: 'komodia-based-vpn-setup.exe'
168168
extra_name: ', with Komodia LSP'
169-
- python: '3.9'
169+
- python: '3.10'
170170
arch: 'x64'
171171
lsp: 'https://www.proxifier.com/download/legacy/ProxifierSetup342.exe'
172172
lsp_extract_file: ''
@@ -176,7 +176,7 @@ jobs:
176176
lsp: ''
177177
lsp_extract_file: ''
178178
extra_name: ''
179-
#- python: '3.9'
179+
#- python: '3.10'
180180
# arch: 'x64'
181181
# lsp: 'http://download.pctools.com/mirror/updates/9.0.0.2308-SDavfree-lite_en.exe'
182182
# lsp_extract_file: ''
@@ -228,7 +228,7 @@ jobs:
228228
strategy:
229229
fail-fast: false
230230
matrix:
231-
python: ['pypy-3.11', '3.9', '3.10', '3.11', '3.12', '3.13', '3.14']
231+
python: ['pypy-3.11', '3.10', '3.10', '3.11', '3.12', '3.13', '3.14']
232232
check_formatting: ['0']
233233
no_test_requirements: ['0']
234234
extra_name: ['']
@@ -237,7 +237,7 @@ jobs:
237237
check_formatting: '1'
238238
extra_name: ', check formatting'
239239
# separate test run that doesn't install test-requirements.txt
240-
- python: '3.9'
240+
- python: '3.10'
241241
no_test_requirements: '1'
242242
extra_name: ', no test-requirements'
243243
continue-on-error: >-
@@ -301,7 +301,7 @@ jobs:
301301
strategy:
302302
fail-fast: false
303303
matrix:
304-
python: ['pypy-3.11', '3.9', '3.10', '3.11', '3.12', '3.13', '3.14']
304+
python: ['pypy-3.11', '3.10', '3.11', '3.12', '3.13', '3.14']
305305
continue-on-error: >-
306306
${{
307307
(
@@ -389,14 +389,17 @@ jobs:
389389
fail-fast: false
390390
matrix:
391391
include:
392-
- python: '3.9' # We support running on cython 2 and 3 for 3.9
393-
cython: '<3' # cython 2
394-
- python: '3.9'
395-
cython: '>=3' # cython 3 (or greater)
396-
- python: '3.11' # 3.11 is the last version Cy2 supports
397-
cython: '<3' # cython 2
398-
- python: '3.13' # We support running cython3 on 3.13
399-
cython: '>=3' # cython 3 (or greater)
392+
# Cython 2 supports 3.10 and 3.11 and Cython 3 supports all versions we do,
393+
# so test both the lowest and higher version for both
394+
- python: '3.10'
395+
cython: '<3'
396+
- python: '3.11'
397+
cython: '<3'
398+
# TODO: technically we should pin cython versions
399+
- python: '3.10'
400+
cython: '>=3'
401+
- python: '3.14'
402+
cython: '>=3'
400403
steps:
401404
- name: Retrieve the project source from an sdist inside the GHA artifact
402405
uses: re-actors/checkout-python-sdist@release/v2

.github/workflows/release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616
persist-credentials: false
1717
- uses: actions/setup-python@v5
1818
with:
19-
python-version: "3.9"
19+
python-version: "3.10"
2020
- run: python -m pip install build
2121
- run: python -m build
2222

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ repos:
8080
name: uv pip-compile test-requirements.in
8181
args: [
8282
"--universal",
83-
"--python-version=3.9",
83+
"--python-version=3.10",
8484
"test-requirements.in",
8585
"-o",
8686
"test-requirements.txt"]

README.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ demonstration of implementing the "Happy Eyeballs" algorithm in an
9292
older library versus Trio.
9393

9494
**Cool, but will it work on my system?** Probably! As long as you have
95-
some kind of Python 3.9-or-better (CPython or `currently maintained versions of
95+
some kind of Python 3.10-or-better (CPython or `currently maintained versions of
9696
PyPy3 <https://doc.pypy.org/en/latest/faq.html#which-python-versions-does-pypy-implement>`__
9797
are both fine), and are using Linux, macOS, Windows, or FreeBSD, then Trio
9898
will work. Other environments might work too, but those

docs/source/index.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ Vital statistics:
4545

4646
* Supported environments: We test on
4747

48-
- Python: 3.9+ (CPython and PyPy)
48+
- Python: 3.10+ (CPython and PyPy)
4949
- Windows, macOS, Linux (glibc and musl), FreeBSD
5050

5151
Other environments might also work; give it a try and see.

docs/source/tutorial.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ Okay, ready? Let's get started.
8888
Before you begin
8989
----------------
9090

91-
1. Make sure you're using Python 3.9 or newer.
91+
1. Make sure you're using Python 3.10 or newer.
9292

9393
2. ``python3 -m pip install --upgrade trio`` (or on Windows, maybe
9494
``py -3 -m pip install --upgrade trio`` – `details

pyproject.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,15 @@ classifiers = [
2626
"Programming Language :: Python :: Implementation :: CPython",
2727
"Programming Language :: Python :: Implementation :: PyPy",
2828
"Programming Language :: Python :: 3 :: Only",
29-
"Programming Language :: Python :: 3.9",
3029
"Programming Language :: Python :: 3.10",
3130
"Programming Language :: Python :: 3.11",
3231
"Programming Language :: Python :: 3.12",
3332
"Programming Language :: Python :: 3.13",
33+
"Programming Language :: Python :: 3.14",
3434
"Topic :: System :: Networking",
3535
"Typing :: Typed",
3636
]
37-
requires-python = ">=3.9"
37+
requires-python = ">=3.10"
3838
dependencies = [
3939
# attrs 19.2.0 adds `eq` option to decorators
4040
# attrs 20.1.0 adds @frozen
@@ -215,7 +215,7 @@ disallow_untyped_defs = true
215215
check_untyped_defs = true
216216

217217
[tool.pyright]
218-
pythonVersion = "3.9"
218+
pythonVersion = "3.10"
219219
reportUnnecessaryTypeIgnoreComment = true
220220
typeCheckingMode = "strict"
221221

src/trio/_channel.py

Lines changed: 21 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
MultipleExceptionError,
2323
NoPublicConstructor,
2424
final,
25-
generic_function,
2625
raise_single_exception_from_group,
2726
)
2827

@@ -48,6 +47,20 @@
4847
def _open_memory_channel(
4948
max_buffer_size: int | float, # noqa: PYI041
5049
) -> tuple[MemorySendChannel[T], MemoryReceiveChannel[T]]:
50+
if max_buffer_size != inf and not isinstance(max_buffer_size, int):
51+
raise TypeError("max_buffer_size must be an integer or math.inf")
52+
if max_buffer_size < 0:
53+
raise ValueError("max_buffer_size must be >= 0")
54+
state: MemoryChannelState[T] = MemoryChannelState(max_buffer_size)
55+
return (
56+
MemorySendChannel[T]._create(state),
57+
MemoryReceiveChannel[T]._create(state),
58+
)
59+
60+
61+
# written as a class so you can say open_memory_channel[int](5)
62+
@final
63+
class open_memory_channel(tuple["MemorySendChannel[T]", "MemoryReceiveChannel[T]"]):
5164
"""Open a channel for passing objects between tasks within a process.
5265
5366
Memory channels are lightweight, cheap to allocate, and entirely
@@ -99,36 +112,15 @@ def _open_memory_channel(
99112
this channel (summing over all clones).
100113
101114
"""
102-
if max_buffer_size != inf and not isinstance(max_buffer_size, int):
103-
raise TypeError("max_buffer_size must be an integer or math.inf")
104-
if max_buffer_size < 0:
105-
raise ValueError("max_buffer_size must be >= 0")
106-
state: MemoryChannelState[T] = MemoryChannelState(max_buffer_size)
107-
return (
108-
MemorySendChannel[T]._create(state),
109-
MemoryReceiveChannel[T]._create(state),
110-
)
111115

116+
def __new__( # type: ignore[misc] # "must return a subtype"
117+
cls,
118+
max_buffer_size: int | float, # noqa: PYI041
119+
) -> tuple[MemorySendChannel[T], MemoryReceiveChannel[T]]:
120+
return _open_memory_channel(max_buffer_size)
112121

113-
# This workaround requires python3.9+, once older python versions are not supported
114-
# or there's a better way of achieving type-checking on a generic factory function,
115-
# it could replace the normal function header
116-
if TYPE_CHECKING:
117-
# written as a class so you can say open_memory_channel[int](5)
118-
class open_memory_channel(tuple["MemorySendChannel[T]", "MemoryReceiveChannel[T]"]):
119-
def __new__( # type: ignore[misc] # "must return a subtype"
120-
cls,
121-
max_buffer_size: int | float, # noqa: PYI041
122-
) -> tuple[MemorySendChannel[T], MemoryReceiveChannel[T]]:
123-
return _open_memory_channel(max_buffer_size)
124-
125-
def __init__(self, max_buffer_size: int | float) -> None: # noqa: PYI041
126-
...
127-
128-
else:
129-
# apply the generic_function decorator to make open_memory_channel indexable
130-
# so it's valid to say e.g. ``open_memory_channel[bytes](5)`` at runtime
131-
open_memory_channel = generic_function(_open_memory_channel)
122+
def __init__(self, max_buffer_size: int | float) -> None: # noqa: PYI041
123+
...
132124

133125

134126
@attrs.frozen

src/trio/_core/_exceptions.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@
99

1010
if TYPE_CHECKING:
1111
from collections.abc import Callable
12+
from typing import TypeAlias
1213

13-
from typing_extensions import Self, TypeAlias
14+
from typing_extensions import Self
1415

1516
CancelReasonLiteral: TypeAlias = Literal[
1617
"KeyboardInterrupt",

0 commit comments

Comments
 (0)