diff --git a/changelog.d/19274.bugfix b/changelog.d/19274.bugfix new file mode 100644 index 00000000000..7f16711a9c6 --- /dev/null +++ b/changelog.d/19274.bugfix @@ -0,0 +1 @@ +Fix bug introduced in 1.143.0 that broke support for older versions of zope-interface. diff --git a/poetry.lock b/poetry.lock index 271be1456e4..e8192cfc5cd 100644 --- a/poetry.lock +++ b/poetry.lock @@ -31,7 +31,7 @@ description = "The ultimate Python library in building OAuth and OpenID Connect optional = true python-versions = ">=3.9" groups = ["main"] -markers = "extra == \"all\" or extra == \"jwt\" or extra == \"oidc\"" +markers = "extra == \"oidc\" or extra == \"jwt\" or extra == \"all\"" files = [ {file = "authlib-1.6.5-py2.py3-none-any.whl", hash = "sha256:3e0e0507807f842b02175507bdee8957a1d5707fd4afb17c32fb43fee90b6e3a"}, {file = "authlib-1.6.5.tar.gz", hash = "sha256:6aaf9c79b7cc96c900f0b284061691c5d4e61221640a948fe690b556a6d6d10b"}, @@ -481,7 +481,7 @@ description = "XML bomb protection for Python stdlib modules" optional = true python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" groups = ["main"] -markers = "extra == \"all\" or extra == \"saml2\"" +markers = "extra == \"saml2\" or extra == \"all\"" files = [ {file = "defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61"}, {file = "defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69"}, @@ -506,7 +506,7 @@ description = "XPath 1.0/2.0/3.0/3.1 parsers and selectors for ElementTree and l optional = true python-versions = ">=3.7" groups = ["main"] -markers = "extra == \"all\" or extra == \"saml2\"" +markers = "extra == \"saml2\" or extra == \"all\"" files = [ {file = "elementpath-4.1.5-py3-none-any.whl", hash = "sha256:2ac1a2fb31eb22bbbf817f8cf6752f844513216263f0e3892c8e79782fe4bb55"}, {file = "elementpath-4.1.5.tar.gz", hash = "sha256:c2d6dc524b29ef751ecfc416b0627668119d8812441c555d7471da41d4bacb8d"}, @@ -556,7 +556,7 @@ description = "Python wrapper for hiredis" optional = true python-versions = ">=3.8" groups = ["main"] -markers = "extra == \"all\" or extra == \"redis\"" +markers = "extra == \"redis\" or extra == \"all\"" files = [ {file = "hiredis-3.3.0-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:9937d9b69321b393fbace69f55423480f098120bc55a3316e1ca3508c4dbbd6f"}, {file = "hiredis-3.3.0-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:50351b77f89ba6a22aff430b993653847f36b71d444509036baa0f2d79d1ebf4"}, @@ -879,7 +879,7 @@ description = "Jaeger Python OpenTracing Tracer implementation" optional = true python-versions = ">=3.7" groups = ["main"] -markers = "extra == \"all\" or extra == \"opentracing\"" +markers = "extra == \"opentracing\" or extra == \"all\"" files = [ {file = "jaeger-client-4.8.0.tar.gz", hash = "sha256:3157836edab8e2c209bd2d6ae61113db36f7ee399e66b1dcbb715d87ab49bfe0"}, ] @@ -1017,7 +1017,7 @@ description = "A strictly RFC 4510 conforming LDAP V3 pure Python client library optional = true python-versions = "*" groups = ["main"] -markers = "extra == \"all\" or extra == \"matrix-synapse-ldap3\"" +markers = "extra == \"matrix-synapse-ldap3\" or extra == \"all\"" files = [ {file = "ldap3-2.9.1-py2.py3-none-any.whl", hash = "sha256:5869596fc4948797020d3f03b7939da938778a0f9e2009f7a072ccf92b8e8d70"}, {file = "ldap3-2.9.1.tar.gz", hash = "sha256:f3e7fc4718e3f09dda568b57100095e0ce58633bcabbed8667ce3f8fbaa4229f"}, @@ -1033,7 +1033,7 @@ description = "Powerful and Pythonic XML processing library combining libxml2/li optional = true python-versions = ">=3.8" groups = ["main"] -markers = "extra == \"all\" or extra == \"url-preview\"" +markers = "extra == \"url-preview\" or extra == \"all\"" files = [ {file = "lxml-6.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e77dd455b9a16bbd2a5036a63ddbd479c19572af81b624e79ef422f929eef388"}, {file = "lxml-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5d444858b9f07cefff6455b983aea9a67f7462ba1f6cbe4a21e8bf6791bf2153"}, @@ -1319,7 +1319,7 @@ description = "An LDAP3 auth provider for Synapse" optional = true python-versions = ">=3.7" groups = ["main"] -markers = "extra == \"all\" or extra == \"matrix-synapse-ldap3\"" +markers = "extra == \"matrix-synapse-ldap3\" or extra == \"all\"" files = [ {file = "matrix-synapse-ldap3-0.3.0.tar.gz", hash = "sha256:8bb6517173164d4b9cc44f49de411d8cebdb2e705d5dd1ea1f38733c4a009e1d"}, {file = "matrix_synapse_ldap3-0.3.0-py3-none-any.whl", hash = "sha256:8b4d701f8702551e98cc1d8c20dbed532de5613584c08d0df22de376ba99159d"}, @@ -1561,7 +1561,7 @@ description = "OpenTracing API for Python. See documentation at http://opentraci optional = true python-versions = "*" groups = ["main"] -markers = "extra == \"all\" or extra == \"opentracing\"" +markers = "extra == \"opentracing\" or extra == \"all\"" files = [ {file = "opentracing-2.4.0.tar.gz", hash = "sha256:a173117e6ef580d55874734d1fa7ecb6f3655160b8b8974a2a1e98e5ec9c840d"}, ] @@ -1751,7 +1751,7 @@ description = "psycopg2 - Python-PostgreSQL Database Adapter" optional = true python-versions = ">=3.9" groups = ["main"] -markers = "extra == \"all\" or extra == \"postgres\"" +markers = "extra == \"postgres\" or extra == \"all\"" files = [ {file = "psycopg2-2.9.11-cp310-cp310-win_amd64.whl", hash = "sha256:103e857f46bb76908768ead4e2d0ba1d1a130e7b8ed77d3ae91e8b33481813e8"}, {file = "psycopg2-2.9.11-cp311-cp311-win_amd64.whl", hash = "sha256:210daed32e18f35e3140a1ebe059ac29209dd96468f2f7559aa59f75ee82a5cb"}, @@ -1769,7 +1769,7 @@ description = ".. image:: https://travis-ci.org/chtd/psycopg2cffi.svg?branch=mas optional = true python-versions = "*" groups = ["main"] -markers = "platform_python_implementation == \"PyPy\" and (extra == \"all\" or extra == \"postgres\")" +markers = "platform_python_implementation == \"PyPy\" and (extra == \"postgres\" or extra == \"all\")" files = [ {file = "psycopg2cffi-2.9.0.tar.gz", hash = "sha256:7e272edcd837de3a1d12b62185eb85c45a19feda9e62fa1b120c54f9e8d35c52"}, ] @@ -1785,7 +1785,7 @@ description = "A Simple library to enable psycopg2 compatability" optional = true python-versions = "*" groups = ["main"] -markers = "platform_python_implementation == \"PyPy\" and (extra == \"all\" or extra == \"postgres\")" +markers = "platform_python_implementation == \"PyPy\" and (extra == \"postgres\" or extra == \"all\")" files = [ {file = "psycopg2cffi-compat-1.1.tar.gz", hash = "sha256:d25e921748475522b33d13420aad5c2831c743227dc1f1f2585e0fdb5c914e05"}, ] @@ -2067,7 +2067,7 @@ description = "A development tool to measure, monitor and analyze the memory beh optional = true python-versions = ">=3.6" groups = ["main"] -markers = "extra == \"all\" or extra == \"cache-memory\"" +markers = "extra == \"cache-memory\" or extra == \"all\"" files = [ {file = "Pympler-1.0.1-py3-none-any.whl", hash = "sha256:d260dda9ae781e1eab6ea15bacb84015849833ba5555f141d2d9b7b7473b307d"}, {file = "Pympler-1.0.1.tar.gz", hash = "sha256:993f1a3599ca3f4fcd7160c7545ad06310c9e12f70174ae7ae8d4e25f6c5d3fa"}, @@ -2127,7 +2127,7 @@ description = "Python implementation of SAML Version 2 Standard" optional = true python-versions = ">=3.9,<4.0" groups = ["main"] -markers = "extra == \"all\" or extra == \"saml2\"" +markers = "extra == \"saml2\" or extra == \"all\"" files = [ {file = "pysaml2-7.5.0-py3-none-any.whl", hash = "sha256:bc6627cc344476a83c757f440a73fda1369f13b6fda1b4e16bca63ffbabb5318"}, {file = "pysaml2-7.5.0.tar.gz", hash = "sha256:f36871d4e5ee857c6b85532e942550d2cf90ea4ee943d75eb681044bbc4f54f7"}, @@ -2152,7 +2152,7 @@ description = "Extensions to the standard Python datetime module" optional = true python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" groups = ["main"] -markers = "extra == \"all\" or extra == \"saml2\"" +markers = "extra == \"saml2\" or extra == \"all\"" files = [ {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, @@ -2180,7 +2180,7 @@ description = "World timezone definitions, modern and historical" optional = true python-versions = "*" groups = ["main"] -markers = "extra == \"all\" or extra == \"saml2\"" +markers = "extra == \"saml2\" or extra == \"all\"" files = [ {file = "pytz-2022.7.1-py2.py3-none-any.whl", hash = "sha256:78f4f37d8198e0627c5f1143240bb0206b8691d8d7ac6d78fee88b78733f8c4a"}, {file = "pytz-2022.7.1.tar.gz", hash = "sha256:01a0681c4b9684a28304615eba55d1ab31ae00bf68ec157ec3708a8182dbbcd0"}, @@ -2584,7 +2584,7 @@ description = "Python client for Sentry (https://sentry.io)" optional = true python-versions = ">=3.6" groups = ["main"] -markers = "extra == \"all\" or extra == \"sentry\"" +markers = "extra == \"sentry\" or extra == \"all\"" files = [ {file = "sentry_sdk-2.46.0-py2.py3-none-any.whl", hash = "sha256:4eeeb60198074dff8d066ea153fa6f241fef1668c10900ea53a4200abc8da9b1"}, {file = "sentry_sdk-2.46.0.tar.gz", hash = "sha256:91821a23460725734b7741523021601593f35731808afc0bb2ba46c27b8acd91"}, @@ -2794,7 +2794,7 @@ description = "Tornado IOLoop Backed Concurrent Futures" optional = true python-versions = "*" groups = ["main"] -markers = "extra == \"all\" or extra == \"opentracing\"" +markers = "extra == \"opentracing\" or extra == \"all\"" files = [ {file = "threadloop-1.0.2-py2-none-any.whl", hash = "sha256:5c90dbefab6ffbdba26afb4829d2a9df8275d13ac7dc58dccb0e279992679599"}, {file = "threadloop-1.0.2.tar.gz", hash = "sha256:8b180aac31013de13c2ad5c834819771992d350267bddb854613ae77ef571944"}, @@ -2810,7 +2810,7 @@ description = "Python bindings for the Apache Thrift RPC system" optional = true python-versions = "*" groups = ["main"] -markers = "extra == \"all\" or extra == \"opentracing\"" +markers = "extra == \"opentracing\" or extra == \"all\"" files = [ {file = "thrift-0.16.0.tar.gz", hash = "sha256:2b5b6488fcded21f9d312aa23c9ff6a0195d0f6ae26ddbd5ad9e3e25dfc14408"}, ] @@ -2883,7 +2883,7 @@ description = "Tornado is a Python web framework and asynchronous networking lib optional = true python-versions = ">=3.9" groups = ["main"] -markers = "extra == \"all\" or extra == \"opentracing\"" +markers = "extra == \"opentracing\" or extra == \"all\"" files = [ {file = "tornado-6.5-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:f81067dad2e4443b015368b24e802d0083fecada4f0a4572fdb72fc06e54a9a6"}, {file = "tornado-6.5-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:9ac1cbe1db860b3cbb251e795c701c41d343f06a96049d6274e7c77559117e41"}, @@ -3017,7 +3017,7 @@ description = "non-blocking redis client for python" optional = true python-versions = "*" groups = ["main"] -markers = "extra == \"all\" or extra == \"redis\"" +markers = "extra == \"redis\" or extra == \"all\"" files = [ {file = "txredisapi-1.4.11-py3-none-any.whl", hash = "sha256:ac64d7a9342b58edca13ef267d4fa7637c1aa63f8595e066801c1e8b56b22d0b"}, {file = "txredisapi-1.4.11.tar.gz", hash = "sha256:3eb1af99aefdefb59eb877b1dd08861efad60915e30ad5bf3d5bf6c5cedcdbc6"}, @@ -3263,7 +3263,7 @@ description = "An XML Schema validator and decoder" optional = true python-versions = ">=3.7" groups = ["main"] -markers = "extra == \"all\" or extra == \"saml2\"" +markers = "extra == \"saml2\" or extra == \"all\"" files = [ {file = "xmlschema-2.4.0-py3-none-any.whl", hash = "sha256:dc87be0caaa61f42649899189aab2fd8e0d567f2cf548433ba7b79278d231a4a"}, {file = "xmlschema-2.4.0.tar.gz", hash = "sha256:d74cd0c10866ac609e1ef94a5a69b018ad16e39077bc6393408b40c6babee793"}, @@ -3398,4 +3398,4 @@ url-preview = ["lxml"] [metadata] lock-version = "2.1" python-versions = ">=3.10.0,<4.0.0" -content-hash = "98b9062f48205a3bcc99b43ae665083d360a15d4a208927fa978df9c36fd5315" +content-hash = "3453d2083c99be926c6402985cda7615510a1dae823e0d348880386fc80e9eb5" diff --git a/pyproject.toml b/pyproject.toml index ce2ecf63634..8c391e81233 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -40,6 +40,14 @@ dependencies = [ # lives hard (as of 2025-07, distro support is Ubuntu LTS: 22.1, Debian stable: 22.4, # RHEL 9: 22.10) "Twisted[tls]>=21.2.0", + # We don't explicitly depend on zope-interface. Twisted pulls it in implicitly as a dependency. + # We add an explicit dependency here to ensure the versions of zope-interface Synapse supports + # includes those which are available on our supported platforms. + # Specifying the dependency explicitly will ensure we test with the lowest version during the + # olddeps CI tests. + # 5.2 is the current version in Debian oldstable. If we don't care to support that, then 5.4 is + # the minimum version from Ubuntu 22.04 and RHEL 9. (as of 2025-12) + "zope-interface>=5.2", "treq>=21.5.0", # Twisted has required pyopenssl 16.0 since about Twisted 16.6. "pyOpenSSL>=16.0.0", @@ -260,15 +268,10 @@ select = [ "G", # pyupgrade "UP006", - "UP007", - "UP045", ] extend-safe-fixes = [ # pyupgrade rules compatible with Python >= 3.9 "UP006", - "UP007", - # pyupgrade rules compatible with Python >= 3.10 - "UP045", # Allow ruff to automatically fix trailing spaces within a multi-line string/comment. "W293" ] diff --git a/synapse/app/_base.py b/synapse/app/_base.py index d1ed1201e5a..f24958196bc 100644 --- a/synapse/app/_base.py +++ b/synapse/app/_base.py @@ -36,6 +36,7 @@ Awaitable, Callable, NoReturn, + Optional, cast, ) from wsgiref.simple_server import WSGIServer @@ -455,7 +456,7 @@ def listen_http( root_resource: Resource, version_string: str, max_request_body_size: int, - context_factory: IOpenSSLContextFactory | None, + context_factory: Optional[IOpenSSLContextFactory], reactor: ISynapseReactor = reactor, ) -> list[Port]: """ diff --git a/synapse/app/admin_cmd.py b/synapse/app/admin_cmd.py index facc98164e7..0614c805dad 100644 --- a/synapse/app/admin_cmd.py +++ b/synapse/app/admin_cmd.py @@ -24,7 +24,7 @@ import os import sys import tempfile -from typing import Mapping, Sequence +from typing import Mapping, Optional, Sequence from twisted.internet import defer, task @@ -291,7 +291,7 @@ def load_config(argv_options: list[str]) -> tuple[HomeServerConfig, argparse.Nam def create_homeserver( config: HomeServerConfig, - reactor: ISynapseReactor | None = None, + reactor: Optional[ISynapseReactor] = None, ) -> AdminCmdServer: """ Create a homeserver instance for the Synapse admin command process. diff --git a/synapse/app/generic_worker.py b/synapse/app/generic_worker.py index 9939c0fe7d7..0a4abd18393 100644 --- a/synapse/app/generic_worker.py +++ b/synapse/app/generic_worker.py @@ -21,6 +21,7 @@ # import logging import sys +from typing import Optional from twisted.web.resource import Resource @@ -335,7 +336,7 @@ def load_config(argv_options: list[str]) -> HomeServerConfig: def create_homeserver( config: HomeServerConfig, - reactor: ISynapseReactor | None = None, + reactor: Optional[ISynapseReactor] = None, ) -> GenericWorkerServer: """ Create a homeserver instance for the Synapse worker process. diff --git a/synapse/app/homeserver.py b/synapse/app/homeserver.py index bd2956d9e18..2b1760416b0 100644 --- a/synapse/app/homeserver.py +++ b/synapse/app/homeserver.py @@ -22,7 +22,7 @@ import logging import os import sys -from typing import Iterable +from typing import Iterable, Optional from twisted.internet.tcp import Port from twisted.web.resource import EncodingResourceWrapper, Resource @@ -350,7 +350,7 @@ def load_or_generate_config(argv_options: list[str]) -> HomeServerConfig: def create_homeserver( config: HomeServerConfig, - reactor: ISynapseReactor | None = None, + reactor: Optional[ISynapseReactor] = None, ) -> SynapseHomeServer: """ Create a homeserver instance for the Synapse main process. diff --git a/synapse/handlers/delayed_events.py b/synapse/handlers/delayed_events.py index cb0a4dd6b23..c58d1d42bcf 100644 --- a/synapse/handlers/delayed_events.py +++ b/synapse/handlers/delayed_events.py @@ -13,7 +13,7 @@ # import logging -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Optional from twisted.internet.interfaces import IDelayedCall @@ -74,7 +74,7 @@ def __init__(self, hs: "HomeServer"): cfg=self._config.ratelimiting.rc_delayed_event_mgmt, ) - self._next_delayed_event_call: IDelayedCall | None = None + self._next_delayed_event_call: Optional[IDelayedCall] = None # The current position in the current_state_delta stream self._event_pos: int | None = None diff --git a/synapse/handlers/message.py b/synapse/handlers/message.py index a6499de3a87..7808bd68cbf 100644 --- a/synapse/handlers/message.py +++ b/synapse/handlers/message.py @@ -22,7 +22,7 @@ import logging import random from http import HTTPStatus -from typing import TYPE_CHECKING, Any, Mapping, Sequence +from typing import TYPE_CHECKING, Any, Mapping, Optional, Sequence from canonicaljson import encode_canonical_json @@ -111,7 +111,7 @@ def __init__(self, hs: "HomeServer"): # The scheduled call to self._expire_event. None if no call is currently # scheduled. - self._scheduled_expiry: IDelayedCall | None = None + self._scheduled_expiry: Optional[IDelayedCall] = None if not hs.config.worker.worker_app: self.hs.run_as_background_process( diff --git a/synapse/handlers/user_directory.py b/synapse/handlers/user_directory.py index 36b037e8e1f..e5c4de03c5a 100644 --- a/synapse/handlers/user_directory.py +++ b/synapse/handlers/user_directory.py @@ -21,7 +21,7 @@ import logging from http import HTTPStatus -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Optional from twisted.internet.interfaces import IDelayedCall @@ -125,7 +125,7 @@ def __init__(self, hs: "HomeServer"): # Guard to ensure we only have one process for refreshing remote profiles self._is_refreshing_remote_profiles = False # Handle to cancel the `call_later` of `kick_off_remote_profile_refresh_process` - self._refresh_remote_profiles_call_later: IDelayedCall | None = None + self._refresh_remote_profiles_call_later: Optional[IDelayedCall] = None # Guard to ensure we only have one process for refreshing remote profiles # for the given servers. diff --git a/synapse/http/client.py b/synapse/http/client.py index f0b9201086d..05c5f13a874 100644 --- a/synapse/http/client.py +++ b/synapse/http/client.py @@ -28,6 +28,7 @@ BinaryIO, Callable, Mapping, + Optional, Protocol, ) @@ -313,7 +314,7 @@ def request( method: bytes, uri: bytes, headers: Headers | None = None, - bodyProducer: IBodyProducer | None = None, + bodyProducer: Optional[IBodyProducer] = None, ) -> defer.Deferred: h = urllib.parse.urlparse(uri.decode("ascii")) @@ -1033,7 +1034,7 @@ class BodyExceededMaxSize(Exception): class _DiscardBodyWithMaxSizeProtocol(protocol.Protocol): """A protocol which immediately errors upon receiving data.""" - transport: ITCPTransport | None = None + transport: Optional[ITCPTransport] = None def __init__(self, deferred: defer.Deferred): self.deferred = deferred @@ -1075,7 +1076,7 @@ class _MultipartParserProtocol(protocol.Protocol): Protocol to read and parse a MSC3916 multipart/mixed response """ - transport: ITCPTransport | None = None + transport: Optional[ITCPTransport] = None def __init__( self, @@ -1188,7 +1189,7 @@ def connectionLost(self, reason: Failure = connectionDone) -> None: class _ReadBodyWithMaxSizeProtocol(protocol.Protocol): """A protocol which reads body to a stream, erroring if the body exceeds a maximum size.""" - transport: ITCPTransport | None = None + transport: Optional[ITCPTransport] = None def __init__( self, stream: ByteWriteable, deferred: defer.Deferred, max_size: int | None diff --git a/synapse/http/federation/matrix_federation_agent.py b/synapse/http/federation/matrix_federation_agent.py index c3ba26fe039..a0167659f19 100644 --- a/synapse/http/federation/matrix_federation_agent.py +++ b/synapse/http/federation/matrix_federation_agent.py @@ -19,7 +19,7 @@ # import logging import urllib.parse -from typing import Any, Generator +from typing import Any, Generator, Optional from urllib.request import ( # type: ignore[attr-defined] proxy_bypass_environment, ) @@ -173,7 +173,7 @@ def request( method: bytes, uri: bytes, headers: Headers | None = None, - bodyProducer: IBodyProducer | None = None, + bodyProducer: Optional[IBodyProducer] = None, ) -> Generator[defer.Deferred, Any, IResponse]: """ Args: diff --git a/synapse/http/matrixfederationclient.py b/synapse/http/matrixfederationclient.py index 7090960cfbb..dbd4f1e4b6a 100644 --- a/synapse/http/matrixfederationclient.py +++ b/synapse/http/matrixfederationclient.py @@ -33,6 +33,7 @@ Callable, Generic, Literal, + Optional, TextIO, TypeVar, cast, @@ -691,7 +692,7 @@ async def _send_request( destination_bytes, method_bytes, url_to_sign_bytes, json ) data = encode_canonical_json(json) - producer: IBodyProducer | None = QuieterFileBodyProducer( + producer: Optional[IBodyProducer] = QuieterFileBodyProducer( BytesIO(data), cooperator=self._cooperator ) else: diff --git a/synapse/http/proxy.py b/synapse/http/proxy.py index c7f5e39dd89..b3a2f84f29a 100644 --- a/synapse/http/proxy.py +++ b/synapse/http/proxy.py @@ -22,7 +22,7 @@ import json import logging import urllib.parse -from typing import TYPE_CHECKING, Any, cast +from typing import TYPE_CHECKING, Any, Optional, cast from twisted.internet import protocol from twisted.internet.interfaces import ITCPTransport @@ -237,7 +237,7 @@ class _ProxyResponseBody(protocol.Protocol): request. """ - transport: ITCPTransport | None = None + transport: Optional[ITCPTransport] = None def __init__(self, request: "SynapseRequest") -> None: self._request = request diff --git a/synapse/http/proxyagent.py b/synapse/http/proxyagent.py index d315ce84758..1f8e58efbc8 100644 --- a/synapse/http/proxyagent.py +++ b/synapse/http/proxyagent.py @@ -21,7 +21,7 @@ import logging import random import re -from typing import Any, Collection, Sequence, cast +from typing import Any, Collection, Optional, Sequence, cast from urllib.parse import urlparse from urllib.request import ( # type: ignore[attr-defined] proxy_bypass_environment, @@ -119,8 +119,8 @@ def __init__( self, *, reactor: IReactorCore, - proxy_reactor: IReactorCore | None = None, - contextFactory: IPolicyForHTTPS | None = None, + proxy_reactor: Optional[IReactorCore] = None, + contextFactory: Optional[IPolicyForHTTPS] = None, connectTimeout: float | None = None, bindAddress: bytes | None = None, pool: HTTPConnectionPool | None = None, @@ -175,7 +175,7 @@ def __init__( self._policy_for_https = contextFactory self._reactor = cast(IReactorTime, reactor) - self._federation_proxy_endpoint: IStreamClientEndpoint | None = None + self._federation_proxy_endpoint: Optional[IStreamClientEndpoint] = None self._federation_proxy_credentials: ProxyCredentials | None = None if federation_proxy_locations: assert federation_proxy_credentials is not None, ( @@ -221,7 +221,7 @@ def request( method: bytes, uri: bytes, headers: Headers | None = None, - bodyProducer: IBodyProducer | None = None, + bodyProducer: Optional[IBodyProducer] = None, ) -> "defer.Deferred[IResponse]": """ Issue a request to the server indicated by the given uri. @@ -365,11 +365,11 @@ def request( def http_proxy_endpoint( proxy: bytes | None, reactor: IReactorCore, - tls_options_factory: IPolicyForHTTPS | None, + tls_options_factory: Optional[IPolicyForHTTPS], timeout: float = 30, bindAddress: bytes | str | tuple[bytes | str, int] | None = None, attemptDelay: float | None = None, -) -> tuple[IStreamClientEndpoint | None, ProxyCredentials | None]: +) -> tuple[Optional[IStreamClientEndpoint], ProxyCredentials | None]: """Parses an http proxy setting and returns an endpoint for the proxy Args: diff --git a/synapse/http/replicationagent.py b/synapse/http/replicationagent.py index 708e4c386be..3d47107cf24 100644 --- a/synapse/http/replicationagent.py +++ b/synapse/http/replicationagent.py @@ -20,6 +20,7 @@ # import logging +from typing import Optional from zope.interface import implementer @@ -149,7 +150,7 @@ def request( method: bytes, uri: bytes, headers: Headers | None = None, - bodyProducer: IBodyProducer | None = None, + bodyProducer: Optional[IBodyProducer] = None, ) -> "defer.Deferred[IResponse]": """ Issue a request to the server indicated by the given uri. diff --git a/synapse/logging/_remote.py b/synapse/logging/_remote.py index e3e0ba4beb7..72faa3c7460 100644 --- a/synapse/logging/_remote.py +++ b/synapse/logging/_remote.py @@ -25,7 +25,7 @@ from collections import deque from ipaddress import IPv4Address, IPv6Address, ip_address from math import floor -from typing import Callable +from typing import Callable, Optional import attr from zope.interface import implementer @@ -113,7 +113,7 @@ def __init__( port: int, maximum_buffer: int = 1000, level: int = logging.NOTSET, - _reactor: IReactorTime | None = None, + _reactor: Optional[IReactorTime] = None, ): super().__init__(level=level) self.host = host diff --git a/synapse/logging/handlers.py b/synapse/logging/handlers.py index 976c7075d41..984d7c22383 100644 --- a/synapse/logging/handlers.py +++ b/synapse/logging/handlers.py @@ -3,7 +3,7 @@ from logging import Handler, LogRecord from logging.handlers import MemoryHandler from threading import Thread -from typing import cast +from typing import Optional, cast from twisted.internet.interfaces import IReactorCore @@ -26,7 +26,7 @@ def __init__( target: Handler | None = None, flushOnClose: bool = True, period: float = 5.0, - reactor: IReactorCore | None = None, + reactor: Optional[IReactorCore] = None, ) -> None: """ period: the period between automatic flushes diff --git a/synapse/media/_base.py b/synapse/media/_base.py index 0fe2e5b529c..78849308766 100644 --- a/synapse/media/_base.py +++ b/synapse/media/_base.py @@ -30,6 +30,7 @@ Awaitable, BinaryIO, Generator, + Optional, ) import attr @@ -705,7 +706,7 @@ def __init__(self, hs: "HomeServer") -> None: self.file: BinaryIO | None = None self.deferred: "Deferred[None]" = Deferred() - self.consumer: interfaces.IConsumer | None = None + self.consumer: Optional[IConsumer] = None # Signals if the thread should keep reading/sending data. Set means # continue, clear means pause. diff --git a/synapse/push/emailpusher.py b/synapse/push/emailpusher.py index ce4a2102e4d..c44222f6ea1 100644 --- a/synapse/push/emailpusher.py +++ b/synapse/push/emailpusher.py @@ -20,7 +20,7 @@ # import logging -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Optional from twisted.internet.error import AlreadyCalled, AlreadyCancelled from twisted.internet.interfaces import IDelayedCall @@ -71,7 +71,7 @@ def __init__(self, hs: "HomeServer", pusher_config: PusherConfig, mailer: Mailer self.server_name = hs.hostname self.store = self.hs.get_datastores().main self.email = pusher_config.pushkey - self.timed_call: IDelayedCall | None = None + self.timed_call: Optional[IDelayedCall] = None self.throttle_params: dict[str, ThrottleParams] = {} self._inited = False diff --git a/synapse/push/httppusher.py b/synapse/push/httppusher.py index 1e7e742dddd..fdfae234be7 100644 --- a/synapse/push/httppusher.py +++ b/synapse/push/httppusher.py @@ -21,7 +21,7 @@ import logging import random import urllib.parse -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Optional from prometheus_client import Counter @@ -120,7 +120,7 @@ def __init__(self, hs: "HomeServer", pusher_config: PusherConfig): self.data = pusher_config.data self.backoff_delay = HttpPusher.INITIAL_BACKOFF_SEC self.failing_since = pusher_config.failing_since - self.timed_call: IDelayedCall | None = None + self.timed_call: Optional[IDelayedCall] = None self._is_processing = False self._group_unread_count_by_room = ( hs.config.push.push_group_unread_count_by_room diff --git a/synapse/server.py b/synapse/server.py index 88662c5b28e..be83a59b885 100644 --- a/synapse/server.py +++ b/synapse/server.py @@ -34,6 +34,7 @@ Any, Awaitable, Callable, + Optional, TypeVar, cast, ) @@ -320,7 +321,7 @@ def __init__( self, hostname: str, config: HomeServerConfig, - reactor: ISynapseReactor | None = None, + reactor: Optional[ISynapseReactor] = None, ): """ Args: @@ -353,7 +354,7 @@ def __init__( self._module_web_resources_consumed = False # This attribute is set by the free function `refresh_certificate`. - self.tls_server_context_factory: IOpenSSLContextFactory | None = None + self.tls_server_context_factory: Optional[IOpenSSLContextFactory] = None self._is_shutdown = False self._async_shutdown_handlers: list[ShutdownInfo] = [] diff --git a/synapse/util/file_consumer.py b/synapse/util/file_consumer.py index 8d646840843..c473c524f6f 100644 --- a/synapse/util/file_consumer.py +++ b/synapse/util/file_consumer.py @@ -19,7 +19,7 @@ # import queue -from typing import Any, BinaryIO, cast +from typing import Any, BinaryIO, Optional, Union, cast from twisted.internet import threads from twisted.internet.defer import Deferred @@ -50,7 +50,7 @@ def __init__(self, file_obj: BinaryIO, reactor: ISynapseReactor) -> None: self._reactor: ISynapseReactor = reactor # Producer we're registered with - self._producer: IPushProducer | IPullProducer | None = None + self._producer: Optional[Union[IPushProducer, IPullProducer]] = None # True if PushProducer, false if PullProducer self.streaming = False @@ -72,7 +72,7 @@ def __init__(self, file_obj: BinaryIO, reactor: ISynapseReactor) -> None: self._write_exception: Exception | None = None def registerProducer( - self, producer: IPushProducer | IPullProducer, streaming: bool + self, producer: Union[IPushProducer, IPullProducer], streaming: bool ) -> None: """Part of IConsumer interface diff --git a/tests/server.py b/tests/server.py index 4fb7dea5ec0..65ef0d991d5 100644 --- a/tests/server.py +++ b/tests/server.py @@ -146,7 +146,7 @@ class FakeChannel: _reactor: MemoryReactorClock result: dict = attr.Factory(dict) _ip: str = "127.0.0.1" - _producer: IPullProducer | IPushProducer | None = None + _producer: Optional[Union[IPullProducer, IPushProducer]] = None resource_usage: ContextResourceUsage | None = None _request: Request | None = None @@ -248,7 +248,7 @@ def registerProducer(self, producer: IProducer, streaming: bool) -> None: # TODO This should ensure that the IProducer is an IPushProducer or # IPullProducer, unfortunately twisted.protocols.basic.FileSender does # implement those, but doesn't declare it. - self._producer = cast(IPushProducer | IPullProducer, producer) + self._producer = cast(Union[IPushProducer, IPullProducer], producer) self.producerStreaming = streaming def _produce() -> None: @@ -841,7 +841,7 @@ class FakeTransport: """Test reactor """ - _protocol: IProtocol | None = None + _protocol: Optional[IProtocol] = None """The Protocol which is producing data for this transport. Optional, but if set will get called back for connectionLost() notifications etc. """ @@ -860,7 +860,7 @@ class FakeTransport: disconnected = False connected = True buffer: bytes = b"" - producer: IPushProducer | None = None + producer: Optional[IPushProducer] = None autoflush: bool = True def getPeer(self) -> IPv4Address | IPv6Address: @@ -1062,7 +1062,7 @@ def setup_test_homeserver( cleanup_func: Callable[[Callable[[], Optional["Deferred[None]"]]], None], server_name: str = "test", config: HomeServerConfig | None = None, - reactor: ISynapseReactor | None = None, + reactor: Optional[ISynapseReactor] = None, homeserver_to_use: type[HomeServer] = TestHomeServer, db_txn_limit: int | None = None, **extra_homeserver_attributes: Any, diff --git a/tests/unittest.py b/tests/unittest.py index 7ea29364db2..6022c750d03 100644 --- a/tests/unittest.py +++ b/tests/unittest.py @@ -37,6 +37,7 @@ Iterable, Mapping, NoReturn, + Optional, Protocol, TypeVar, ) @@ -636,7 +637,7 @@ def setup_test_homeserver( self, server_name: str | None = None, config: JsonDict | None = None, - reactor: ISynapseReactor | None = None, + reactor: Optional[ISynapseReactor] = None, clock: Clock | None = None, **extra_homeserver_attributes: Any, ) -> HomeServer: