Declare Support for Python 3.12 (#6434)

This commit is contained in:
Maximilian Hils 2023-10-31 18:57:21 +01:00 committed by GitHub
parent f55ee1d44f
commit c637032af8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 56 additions and 45 deletions

View File

@ -1 +1 @@
3.11
3.12

View File

@ -42,10 +42,12 @@ jobs:
matrix:
include:
- os: ubuntu-latest
py: "3.11"
py: "3.12"
- os: windows-latest
py: "3.11"
py: "3.12"
- os: macos-latest
py: "3.12"
- os: ubuntu-latest
py: "3.11"
- os: ubuntu-latest
py: "3.10"

View File

@ -10,6 +10,8 @@
([#6410](https://github.com/mitmproxy/mitmproxy/pull/6410), @mmaxim)
* Fix path() documentation that the return value might include the query string
([#6412](https://github.com/mitmproxy/mitmproxy/pull/6412), @tddschn)
* mitmproxy now officially supports Python 3.12.
([#6434](https://github.com/mitmproxy/mitmproxy/pull/6434), @mhils)
* Fix root-relative URLs so that mitmweb can run in subdirectories.
([#6411](https://github.com/mitmproxy/mitmproxy/pull/6411), @davet2001)
* Add an optional parameter(ldap search filter key) to ProxyAuth-LDAP.

View File

@ -71,9 +71,12 @@ class MitmLogHandler(logging.Handler):
def filter(self, record: logging.LogRecord) -> bool:
# We can't remove stale handlers here because that would modify .handlers during iteration!
return super().filter(record) and (
not self._initiated_in_test
or self._initiated_in_test == os.environ.get("PYTEST_CURRENT_TEST")
return bool(
super().filter(record)
and (
not self._initiated_in_test
or self._initiated_in_test == os.environ.get("PYTEST_CURRENT_TEST")
)
)
def install(self) -> None:

View File

@ -286,7 +286,8 @@ class AsyncioServerInstance(ServerInstance[M], metaclass=ABCMeta):
try:
for s in self._servers:
s.close()
await asyncio.gather(*[s.wait_closed() for s in self._servers])
# https://github.com/python/cpython/issues/104344
# await asyncio.gather(*[s.wait_closed() for s in self._servers])
finally:
# we always reset _server and ignore failures
self._servers = []

View File

@ -18,6 +18,7 @@ classifiers = [
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: Implementation :: CPython",
"Topic :: Security",
"Topic :: Internet :: WWW/HTTP",
@ -30,7 +31,7 @@ classifiers = [
# https://packaging.python.org/en/latest/discussions/install-requires-vs-requirements/#install-requires
# It is not considered best practice to use install_requires to pin dependencies to specific versions.
dependencies = [
"aioquic_mitmproxy>=0.9.20,<0.10",
"aioquic_mitmproxy>=0.9.21,<0.10",
"asgiref>=3.2.10,<3.8",
"Brotli>=1.0,<1.2",
"certifi>=2019.9.11", # no semver here - this should always be on the last release!
@ -204,13 +205,13 @@ commands =
[testenv:mypy]
deps =
mypy==1.4.1
mypy==1.6.1
types-certifi==2021.10.8.3
types-Flask==1.1.6
types-Werkzeug==1.0.9
types-requests==2.31.0.2
types-requests==2.31.0.10
types-cryptography==3.3.23.2
types-pyOpenSSL==23.2.0.2
types-pyOpenSSL==23.3.0.0
-e .[dev]
commands =

View File

@ -281,7 +281,7 @@ class TestNextLayer:
@dataclass
class TestConf:
class TConf:
before: list[type[Layer]]
after: list[type[Layer]]
proxy_mode: str = "regular"
@ -296,14 +296,14 @@ class TestConf:
explicit_proxy_configs = [
pytest.param(
TestConf(
TConf(
before=[modes.HttpProxy],
after=[modes.HttpProxy, HttpLayer],
),
id=f"explicit proxy: regular http",
),
pytest.param(
TestConf(
TConf(
before=[modes.HttpProxy],
after=[modes.HttpProxy, ClientTLSLayer, HttpLayer],
data_client=client_hello_no_extensions,
@ -311,14 +311,14 @@ explicit_proxy_configs = [
id=f"explicit proxy: secure web proxy",
),
pytest.param(
TestConf(
TConf(
before=[modes.HttpUpstreamProxy],
after=[modes.HttpUpstreamProxy, HttpLayer],
),
id=f"explicit proxy: upstream proxy",
),
pytest.param(
TestConf(
TConf(
before=[modes.HttpUpstreamProxy],
after=[modes.HttpUpstreamProxy, ClientQuicLayer, HttpLayer],
transport_protocol="udp",
@ -326,7 +326,7 @@ explicit_proxy_configs = [
id=f"explicit proxy: experimental http3",
),
pytest.param(
TestConf(
TConf(
before=[
modes.HttpProxy,
partial(HttpLayer, mode=HTTPMode.regular),
@ -338,7 +338,7 @@ explicit_proxy_configs = [
id=f"explicit proxy: HTTP over regular proxy",
),
pytest.param(
TestConf(
TConf(
before=[
modes.HttpProxy,
partial(HttpLayer, mode=HTTPMode.regular),
@ -356,7 +356,7 @@ explicit_proxy_configs = [
id=f"explicit proxy: TLS over regular proxy",
),
pytest.param(
TestConf(
TConf(
before=[
modes.HttpProxy,
partial(HttpLayer, mode=HTTPMode.regular),
@ -377,7 +377,7 @@ explicit_proxy_configs = [
id=f"explicit proxy: HTTPS over regular proxy",
),
pytest.param(
TestConf(
TConf(
before=[
modes.HttpProxy,
partial(HttpLayer, mode=HTTPMode.regular),
@ -404,7 +404,7 @@ for proto_plain, proto_enc, app_layer in [
reverse_proxy_configs.extend(
[
pytest.param(
TestConf(
TConf(
before=[modes.ReverseProxy],
after=[modes.ReverseProxy, app_layer],
proxy_mode=f"reverse:{proto_plain}://example.com:42",
@ -412,7 +412,7 @@ for proto_plain, proto_enc, app_layer in [
id=f"reverse proxy: {proto_plain} -> {proto_plain}",
),
pytest.param(
TestConf(
TConf(
before=[modes.ReverseProxy],
after=[
modes.ReverseProxy,
@ -426,7 +426,7 @@ for proto_plain, proto_enc, app_layer in [
id=f"reverse proxy: {proto_enc} -> {proto_enc}",
),
pytest.param(
TestConf(
TConf(
before=[modes.ReverseProxy],
after=[modes.ReverseProxy, ClientTLSLayer, app_layer],
proxy_mode=f"reverse:{proto_plain}://example.com:42",
@ -435,7 +435,7 @@ for proto_plain, proto_enc, app_layer in [
id=f"reverse proxy: {proto_enc} -> {proto_plain}",
),
pytest.param(
TestConf(
TConf(
before=[modes.ReverseProxy],
after=[modes.ReverseProxy, ServerTLSLayer, app_layer],
proxy_mode=f"reverse:{proto_enc}://example.com:42",
@ -448,7 +448,7 @@ for proto_plain, proto_enc, app_layer in [
reverse_proxy_configs.extend(
[
pytest.param(
TestConf(
TConf(
before=[modes.ReverseProxy],
after=[modes.ReverseProxy, DNSLayer],
proxy_mode="reverse:dns://example.com:53",
@ -456,7 +456,7 @@ reverse_proxy_configs.extend(
id="reverse proxy: dns",
),
pytest.param(
TestConf(
TConf(
before=[modes.ReverseProxy],
after=[modes.ReverseProxy, ServerQuicLayer, ClientQuicLayer, HttpLayer],
proxy_mode="reverse:http3://example.com",
@ -464,7 +464,7 @@ reverse_proxy_configs.extend(
id="reverse proxy: http3",
),
pytest.param(
TestConf(
TConf(
before=[modes.ReverseProxy],
after=[
modes.ReverseProxy,
@ -481,7 +481,7 @@ reverse_proxy_configs.extend(
transparent_proxy_configs = [
pytest.param(
TestConf(
TConf(
before=[modes.TransparentProxy],
after=[modes.TransparentProxy, ServerTLSLayer, ClientTLSLayer],
data_client=client_hello_no_extensions,
@ -489,7 +489,7 @@ transparent_proxy_configs = [
id=f"transparent proxy: tls",
),
pytest.param(
TestConf(
TConf(
before=[modes.TransparentProxy],
after=[modes.TransparentProxy, ServerTLSLayer, ClientTLSLayer],
data_client=dtls_client_hello_with_extensions,
@ -498,7 +498,7 @@ transparent_proxy_configs = [
id=f"transparent proxy: dtls",
),
pytest.param(
TestConf(
TConf(
before=[modes.TransparentProxy],
after=[modes.TransparentProxy, ServerQuicLayer, ClientQuicLayer],
data_client=quic_client_hello,
@ -507,7 +507,7 @@ transparent_proxy_configs = [
id="transparent proxy: quic",
),
pytest.param(
TestConf(
TConf(
before=[modes.TransparentProxy],
after=[modes.TransparentProxy, TCPLayer],
data_server=b"220 service ready",
@ -515,7 +515,7 @@ transparent_proxy_configs = [
id="transparent proxy: raw tcp",
),
pytest.param(
http := TestConf(
http := TConf(
before=[modes.TransparentProxy],
after=[modes.TransparentProxy, HttpLayer],
data_client=b"GET / HTTP/1.1\r\n",
@ -540,7 +540,7 @@ transparent_proxy_configs = [
id="transparent proxy: ignore_hosts",
),
pytest.param(
dns := TestConf(
dns := TConf(
before=[modes.TransparentProxy],
after=[modes.TransparentProxy, DNSLayer],
transport_protocol="udp",
@ -549,7 +549,7 @@ transparent_proxy_configs = [
id="transparent proxy: dns",
),
pytest.param(
TestConf(
TConf(
before=[modes.TransparentProxy],
after=[modes.TransparentProxy, UDPLayer],
transport_protocol="udp",
@ -577,7 +577,7 @@ transparent_proxy_configs = [
],
)
def test_next_layer(
test_conf: TestConf,
test_conf: TConf,
):
nl = NextLayer()
with taddons.context(nl) as tctx:

View File

@ -62,9 +62,7 @@ def test_pack():
name = f"www.{label}.com"
with pytest.raises(
ValueError,
match=re.escape(
"encoding with 'idna' codec failed (UnicodeError: label too long)"
),
match="label too long",
):
domain_names.pack(name)
assert domain_names.pack("www.example.org") == b"\x03www\x07example\x03org\x00"

View File

@ -840,7 +840,7 @@ class TestServerTLS:
playbook
>> events.Wakeup(playbook.actual[9])
<< commands.Log(
"Server QUIC handshake failed. hostname 'wrong.host.mitmproxy.org' doesn't match 'example.mitmproxy.org'",
"Server QUIC handshake failed. Certificate does not match hostname 'wrong.host.mitmproxy.org'",
WARNING,
)
<< tls.TlsFailedServerHook(tls_hook_data)
@ -848,12 +848,12 @@ class TestServerTLS:
<< commands.CloseConnection(tctx.server)
<< commands.SendData(
tctx.client,
b"open-connection failed: hostname 'wrong.host.mitmproxy.org' doesn't match 'example.mitmproxy.org'",
b"open-connection failed: Certificate does not match hostname 'wrong.host.mitmproxy.org'",
)
)
assert (
tls_hook_data().conn.error
== "hostname 'wrong.host.mitmproxy.org' doesn't match 'example.mitmproxy.org'"
== "Certificate does not match hostname 'wrong.host.mitmproxy.org'"
)
assert not tctx.server.tls_established
@ -1133,7 +1133,7 @@ class TestClientTLS:
playbook
>> events.Wakeup(playbook.actual[7])
<< commands.Log(
"Client QUIC handshake failed. hostname 'wrong.host.mitmproxy.org' doesn't match 'example.mitmproxy.org'",
"Client QUIC handshake failed. Certificate does not match hostname 'wrong.host.mitmproxy.org'",
WARNING,
)
<< tls.TlsFailedClientHook(tls_hook_data)

View File

@ -48,7 +48,11 @@ async def test_last_exception_and_running(monkeypatch):
manager = MagicMock()
err = ValueError("something else")
async def _raise(*_):
def _raise(*_):
nonlocal err
raise err
async def _raise_async(*_):
nonlocal err
raise err
@ -57,12 +61,12 @@ async def test_last_exception_and_running(monkeypatch):
await inst1.start()
assert inst1.last_exception is None
assert inst1.is_running
monkeypatch.setattr(inst1._servers[0], "wait_closed", _raise)
monkeypatch.setattr(inst1._servers[0], "close", _raise)
with pytest.raises(type(err), match=str(err)):
await inst1.stop()
assert inst1.last_exception is err
monkeypatch.setattr(asyncio, "start_server", _raise)
monkeypatch.setattr(asyncio, "start_server", _raise_async)
inst2 = ServerInstance.make("regular@127.0.0.1:0", manager)
assert inst2.last_exception is None
with pytest.raises(type(err), match=str(err)):