Skip to content

Commit 9242941

Browse files
authored
Merge branch 'master' into fix/ordinary-connect-no-path
2 parents fd104ad + adcb88c commit 9242941

File tree

7 files changed

+27
-30
lines changed

7 files changed

+27
-30
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ jobs:
1818
- "3.12"
1919
- "3.13"
2020
- "3.14"
21-
- "pypy3.9"
21+
- "pypy3.11"
2222

2323
steps:
2424
- uses: actions/checkout@v2

CHANGELOG.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,17 @@ dev
77
**API Changes (Backward Incompatible)**
88

99
- Support for Python 3.9 has been removed.
10+
- Support for PyPy 3.9 has been removed.
1011

1112
**API Changes (Backward Compatible)**
1213

1314
- Support for Python 3.14 has been added.
15+
- Support for PyPy 3.11 has been added.
1416
- Align CONNECT pseudo-header validation with RFC 9113 s8.3 and RFC 8441 s4.
1517
Ordinary CONNECT now requires ``:method=CONNECT`` and ``:authority``, and
1618
forbids ``:scheme``/``:path``. Extended CONNECT (e.g., WebSocket) requires
1719
``:scheme``, ``:path``, ``:authority`` plus ``:protocol``. (PR #1309)
1820

19-
2021
**Bugfixes**
2122

2223
-

pyproject.toml

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,16 @@
22
# https://packaging.python.org/en/latest/specifications/pyproject-toml/
33

44
[build-system]
5-
requires = ["setuptools"]
5+
requires = ["setuptools>=77"]
66
build-backend = "setuptools.build_meta"
77

88
[project]
99
name = "h2"
1010
description = "Pure-Python HTTP/2 protocol implementation"
1111
readme = { file = "README.rst", content-type = "text/x-rst" }
12-
license = { file = "LICENSE" }
12+
13+
license = "MIT"
14+
license-files = [ "LICENSE" ]
1315

1416
authors = [
1517
{ name = "Cory Benfield", email = "cory@lukasa.co.uk" }
@@ -29,7 +31,6 @@ dynamic = ["version"]
2931
classifiers = [
3032
"Development Status :: 5 - Production/Stable",
3133
"Intended Audience :: Developers",
32-
"License :: OSI Approved :: MIT License",
3334
"Programming Language :: Python",
3435
"Programming Language :: Python :: 3 :: Only",
3536
"Programming Language :: Python :: 3",
@@ -72,9 +73,9 @@ linting = [
7273
packaging = [
7374
"check-manifest==0.50",
7475
"readme-renderer==44.0",
75-
"build>=1.2.2,<2",
76-
"twine>=6.1.0,<7",
77-
"wheel>=0.45.0,<1",
76+
"build>=1.3.0,<2",
77+
"twine>=6.2.0,<7",
78+
"wheel>=0.45.1,<1",
7879
]
7980

8081
docs = [
@@ -132,7 +133,6 @@ lint.ignore = [
132133
"TD002", # readability
133134
"TD003", # readability
134135
"S101", # readability
135-
"PD901", # readability
136136
"ERA001", # readability
137137
"ARG001", # readability
138138
"ARG002", # readability
@@ -170,7 +170,7 @@ source = [
170170

171171
[tool.tox]
172172
min_version = "4.23.2"
173-
env_list = [ "py310", "py311", "py312", "py313", "py314", "pypy3", "lint", "docs", "packaging" ]
173+
env_list = [ "py310", "py311", "py312", "py313", "py314", "pypy311", "lint", "docs", "packaging" ]
174174

175175
[tool.tox.gh-actions]
176176
python = """
@@ -179,7 +179,7 @@ python = """
179179
3.12: py312
180180
3.13: py313
181181
3.14: py314
182-
pypy3: pypy3
182+
pypy3.11: pypy311
183183
"""
184184

185185
[tool.tox.env_run_base]
@@ -188,12 +188,6 @@ commands = [
188188
["python", "-bb", "-m", "pytest", "--cov-report=xml", "--cov-report=term", "--cov=h2", { replace = "posargs", extend = true }]
189189
]
190190

191-
[tool.tox.env.pypy3]
192-
# temporarily disable coverage testing on PyPy due to performance problems
193-
commands = [
194-
["pytest", { replace = "posargs", extend = true }]
195-
]
196-
197191
[tool.tox.env.lint]
198192
dependency_groups = ["linting"]
199193
commands = [

src/h2/connection.py

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

99
import base64
1010
from enum import Enum, IntEnum
11-
from typing import TYPE_CHECKING, Any, Callable
11+
from typing import TYPE_CHECKING, Any
1212

1313
from hpack.exceptions import HPACKError, OversizedHeaderListError
1414
from hpack.hpack import Decoder, Encoder
@@ -66,7 +66,7 @@
6666
from .windows import WindowManager
6767

6868
if TYPE_CHECKING: # pragma: no cover
69-
from collections.abc import Iterable
69+
from collections.abc import Callable, Iterable
7070

7171
from hpack.struct import Header, HeaderWeaklyTyped
7272

src/h2/events.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
from __future__ import annotations
1212

1313
import binascii
14-
import sys
1514
from dataclasses import dataclass
1615
from typing import TYPE_CHECKING, Any
1716

@@ -24,10 +23,7 @@
2423
from .errors import ErrorCodes
2524

2625

27-
if sys.version_info < (3, 10): # pragma: no cover
28-
kw_only: dict[str, bool] = {}
29-
else: # pragma: no cover
30-
kw_only = {"kw_only": True}
26+
kw_only = {"kw_only": True}
3127

3228

3329
_LAZY_INIT: Any = object()

src/h2/settings.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
import collections
1212
import enum
1313
from collections.abc import Iterator, MutableMapping
14-
from typing import Union
1514

1615
from hyperframe.frame import SettingsFrame
1716

@@ -90,7 +89,7 @@ def __repr__(self) -> str:
9089
)
9190

9291

93-
class Settings(MutableMapping[Union[SettingCodes, int], int]): # noqa: PLW1641
92+
class Settings(MutableMapping[SettingCodes | int, int]):
9493
"""
9594
An object that encapsulates HTTP/2 settings state.
9695
@@ -307,6 +306,10 @@ def __ne__(self, other: object) -> bool:
307306
return not self == other
308307
return NotImplemented
309308

309+
# be explicit that Settings is not providing a hash implementation
310+
# see https://docs.python.org/3/reference/datamodel.html#object.__hash__
311+
__hash__ = MutableMapping.__hash__
312+
310313

311314
def _validate_setting(setting: SettingCodes | int, value: int) -> ErrorCodes:
312315
"""

src/h2/stream.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from __future__ import annotations
88

99
from enum import Enum, IntEnum
10-
from typing import TYPE_CHECKING, Any, Union, cast
10+
from typing import TYPE_CHECKING, Any, cast
1111

1212
from hpack import HeaderTuple
1313
from hyperframe.frame import AltSvcFrame, ContinuationFrame, DataFrame, Frame, HeadersFrame, PushPromiseFrame, RstStreamFrame, WindowUpdateFrame
@@ -968,7 +968,10 @@ def send_data(self,
968968
self.state_machine.process_input(StreamInputs.SEND_DATA)
969969

970970
df = DataFrame(self.stream_id)
971-
df.data = data.tobytes() if isinstance(data, memoryview) else data
971+
if isinstance(data, memoryview):
972+
df.data = data.tobytes()
973+
else:
974+
df.data = data
972975
if end_stream:
973976
self.state_machine.process_input(StreamInputs.SEND_END_STREAM)
974977
df.flags.add("END_STREAM")
@@ -1076,7 +1079,7 @@ def receive_headers(self,
10761079

10771080
events = self.state_machine.process_input(input_)
10781081
headers_event = cast(
1079-
"Union[RequestReceived, ResponseReceived, TrailersReceived, InformationalResponseReceived]",
1082+
"RequestReceived | ResponseReceived | TrailersReceived | InformationalResponseReceived",
10801083
events[0],
10811084
)
10821085

@@ -1086,7 +1089,7 @@ def receive_headers(self,
10861089
)
10871090
# We ensured it's not an information response at the beginning of the method.
10881091
cast(
1089-
"Union[RequestReceived, ResponseReceived, TrailersReceived]",
1092+
"RequestReceived | ResponseReceived | TrailersReceived",
10901093
headers_event,
10911094
).stream_ended = cast("StreamEnded", es_events[0])
10921095
events += es_events

0 commit comments

Comments
 (0)