From 78ce4dc26fc09001338a2d95817cdfe686cf19db Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 15 Jul 2025 14:42:54 +0100 Subject: [PATCH] Bump mypy from 1.13.0 to 1.16.1 (#18653) --- changelog.d/18653.misc | 1 + poetry.lock | 85 +++++++++++++--------- synapse/config/cas.py | 3 + synapse/config/key.py | 5 +- synapse/config/workers.py | 8 +- synapse/handlers/auth.py | 1 + synapse/handlers/cas.py | 3 +- synapse/handlers/presence.py | 2 +- synapse/handlers/register.py | 2 +- synapse/handlers/send_email.py | 2 +- synapse/handlers/sso.py | 2 +- synapse/http/connectproxyclient.py | 33 +++++---- synapse/metrics/_reactor_metrics.py | 2 +- synapse/module_api/__init__.py | 2 +- synapse/storage/databases/main/state.py | 7 +- synapse/storage/engines/_base.py | 6 +- synapse/util/gai_resolver.py | 2 +- synapse/util/patch_inline_callbacks.py | 7 ++ tests/federation/test_federation_sender.py | 2 +- 19 files changed, 109 insertions(+), 66 deletions(-) create mode 100644 changelog.d/18653.misc diff --git a/changelog.d/18653.misc b/changelog.d/18653.misc new file mode 100644 index 000000000..d3a4e7c43 --- /dev/null +++ b/changelog.d/18653.misc @@ -0,0 +1 @@ +Fix typing errors with upgraded mypy version. diff --git a/poetry.lock b/poetry.lock index 711dd2f01..ed5028c01 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1425,50 +1425,51 @@ docs = ["sphinx (>=8,<9)", "sphinx-autobuild"] [[package]] name = "mypy" -version = "1.13.0" +version = "1.16.1" description = "Optional static typing for Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" groups = ["dev"] files = [ - {file = "mypy-1.13.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6607e0f1dd1fb7f0aca14d936d13fd19eba5e17e1cd2a14f808fa5f8f6d8f60a"}, - {file = "mypy-1.13.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8a21be69bd26fa81b1f80a61ee7ab05b076c674d9b18fb56239d72e21d9f4c80"}, - {file = "mypy-1.13.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7b2353a44d2179846a096e25691d54d59904559f4232519d420d64da6828a3a7"}, - {file = "mypy-1.13.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0730d1c6a2739d4511dc4253f8274cdd140c55c32dfb0a4cf8b7a43f40abfa6f"}, - {file = "mypy-1.13.0-cp310-cp310-win_amd64.whl", hash = "sha256:c5fc54dbb712ff5e5a0fca797e6e0aa25726c7e72c6a5850cfd2adbc1eb0a372"}, - {file = "mypy-1.13.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:581665e6f3a8a9078f28d5502f4c334c0c8d802ef55ea0e7276a6e409bc0d82d"}, - {file = "mypy-1.13.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3ddb5b9bf82e05cc9a627e84707b528e5c7caaa1c55c69e175abb15a761cec2d"}, - {file = "mypy-1.13.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:20c7ee0bc0d5a9595c46f38beb04201f2620065a93755704e141fcac9f59db2b"}, - {file = "mypy-1.13.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3790ded76f0b34bc9c8ba4def8f919dd6a46db0f5a6610fb994fe8efdd447f73"}, - {file = "mypy-1.13.0-cp311-cp311-win_amd64.whl", hash = "sha256:51f869f4b6b538229c1d1bcc1dd7d119817206e2bc54e8e374b3dfa202defcca"}, - {file = "mypy-1.13.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:5c7051a3461ae84dfb5dd15eff5094640c61c5f22257c8b766794e6dd85e72d5"}, - {file = "mypy-1.13.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:39bb21c69a5d6342f4ce526e4584bc5c197fd20a60d14a8624d8743fffb9472e"}, - {file = "mypy-1.13.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:164f28cb9d6367439031f4c81e84d3ccaa1e19232d9d05d37cb0bd880d3f93c2"}, - {file = "mypy-1.13.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a4c1bfcdbce96ff5d96fc9b08e3831acb30dc44ab02671eca5953eadad07d6d0"}, - {file = "mypy-1.13.0-cp312-cp312-win_amd64.whl", hash = "sha256:a0affb3a79a256b4183ba09811e3577c5163ed06685e4d4b46429a271ba174d2"}, - {file = "mypy-1.13.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a7b44178c9760ce1a43f544e595d35ed61ac2c3de306599fa59b38a6048e1aa7"}, - {file = "mypy-1.13.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5d5092efb8516d08440e36626f0153b5006d4088c1d663d88bf79625af3d1d62"}, - {file = "mypy-1.13.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:de2904956dac40ced10931ac967ae63c5089bd498542194b436eb097a9f77bc8"}, - {file = "mypy-1.13.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:7bfd8836970d33c2105562650656b6846149374dc8ed77d98424b40b09340ba7"}, - {file = "mypy-1.13.0-cp313-cp313-win_amd64.whl", hash = "sha256:9f73dba9ec77acb86457a8fc04b5239822df0c14a082564737833d2963677dbc"}, - {file = "mypy-1.13.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:100fac22ce82925f676a734af0db922ecfea991e1d7ec0ceb1e115ebe501301a"}, - {file = "mypy-1.13.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7bcb0bb7f42a978bb323a7c88f1081d1b5dee77ca86f4100735a6f541299d8fb"}, - {file = "mypy-1.13.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bde31fc887c213e223bbfc34328070996061b0833b0a4cfec53745ed61f3519b"}, - {file = "mypy-1.13.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:07de989f89786f62b937851295ed62e51774722e5444a27cecca993fc3f9cd74"}, - {file = "mypy-1.13.0-cp38-cp38-win_amd64.whl", hash = "sha256:4bde84334fbe19bad704b3f5b78c4abd35ff1026f8ba72b29de70dda0916beb6"}, - {file = "mypy-1.13.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0246bcb1b5de7f08f2826451abd947bf656945209b140d16ed317f65a17dc7dc"}, - {file = "mypy-1.13.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:7f5b7deae912cf8b77e990b9280f170381fdfbddf61b4ef80927edd813163732"}, - {file = "mypy-1.13.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7029881ec6ffb8bc233a4fa364736789582c738217b133f1b55967115288a2bc"}, - {file = "mypy-1.13.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:3e38b980e5681f28f033f3be86b099a247b13c491f14bb8b1e1e134d23bb599d"}, - {file = "mypy-1.13.0-cp39-cp39-win_amd64.whl", hash = "sha256:a6789be98a2017c912ae6ccb77ea553bbaf13d27605d2ca20a76dfbced631b24"}, - {file = "mypy-1.13.0-py3-none-any.whl", hash = "sha256:9c250883f9fd81d212e0952c92dbfcc96fc237f4b7c92f56ac81fd48460b3e5a"}, - {file = "mypy-1.13.0.tar.gz", hash = "sha256:0291a61b6fbf3e6673e3405cfcc0e7650bebc7939659fdca2702958038bd835e"}, + {file = "mypy-1.16.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b4f0fed1022a63c6fec38f28b7fc77fca47fd490445c69d0a66266c59dd0b88a"}, + {file = "mypy-1.16.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:86042bbf9f5a05ea000d3203cf87aa9d0ccf9a01f73f71c58979eb9249f46d72"}, + {file = "mypy-1.16.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ea7469ee5902c95542bea7ee545f7006508c65c8c54b06dc2c92676ce526f3ea"}, + {file = "mypy-1.16.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:352025753ef6a83cb9e7f2427319bb7875d1fdda8439d1e23de12ab164179574"}, + {file = "mypy-1.16.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ff9fa5b16e4c1364eb89a4d16bcda9987f05d39604e1e6c35378a2987c1aac2d"}, + {file = "mypy-1.16.1-cp310-cp310-win_amd64.whl", hash = "sha256:1256688e284632382f8f3b9e2123df7d279f603c561f099758e66dd6ed4e8bd6"}, + {file = "mypy-1.16.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:472e4e4c100062488ec643f6162dd0d5208e33e2f34544e1fc931372e806c0cc"}, + {file = "mypy-1.16.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ea16e2a7d2714277e349e24d19a782a663a34ed60864006e8585db08f8ad1782"}, + {file = "mypy-1.16.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:08e850ea22adc4d8a4014651575567b0318ede51e8e9fe7a68f25391af699507"}, + {file = "mypy-1.16.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:22d76a63a42619bfb90122889b903519149879ddbf2ba4251834727944c8baca"}, + {file = "mypy-1.16.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2c7ce0662b6b9dc8f4ed86eb7a5d505ee3298c04b40ec13b30e572c0e5ae17c4"}, + {file = "mypy-1.16.1-cp311-cp311-win_amd64.whl", hash = "sha256:211287e98e05352a2e1d4e8759c5490925a7c784ddc84207f4714822f8cf99b6"}, + {file = "mypy-1.16.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:af4792433f09575d9eeca5c63d7d90ca4aeceda9d8355e136f80f8967639183d"}, + {file = "mypy-1.16.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:66df38405fd8466ce3517eda1f6640611a0b8e70895e2a9462d1d4323c5eb4b9"}, + {file = "mypy-1.16.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:44e7acddb3c48bd2713994d098729494117803616e116032af192871aed80b79"}, + {file = "mypy-1.16.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0ab5eca37b50188163fa7c1b73c685ac66c4e9bdee4a85c9adac0e91d8895e15"}, + {file = "mypy-1.16.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:dedb6229b2c9086247e21a83c309754b9058b438704ad2f6807f0d8227f6ebdd"}, + {file = "mypy-1.16.1-cp312-cp312-win_amd64.whl", hash = "sha256:1f0435cf920e287ff68af3d10a118a73f212deb2ce087619eb4e648116d1fe9b"}, + {file = "mypy-1.16.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ddc91eb318c8751c69ddb200a5937f1232ee8efb4e64e9f4bc475a33719de438"}, + {file = "mypy-1.16.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:87ff2c13d58bdc4bbe7dc0dedfe622c0f04e2cb2a492269f3b418df2de05c536"}, + {file = "mypy-1.16.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0a7cfb0fe29fe5a9841b7c8ee6dffb52382c45acdf68f032145b75620acfbd6f"}, + {file = "mypy-1.16.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:051e1677689c9d9578b9c7f4d206d763f9bbd95723cd1416fad50db49d52f359"}, + {file = "mypy-1.16.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d5d2309511cc56c021b4b4e462907c2b12f669b2dbeb68300110ec27723971be"}, + {file = "mypy-1.16.1-cp313-cp313-win_amd64.whl", hash = "sha256:4f58ac32771341e38a853c5d0ec0dfe27e18e27da9cdb8bbc882d2249c71a3ee"}, + {file = "mypy-1.16.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7fc688329af6a287567f45cc1cefb9db662defeb14625213a5b7da6e692e2069"}, + {file = "mypy-1.16.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5e198ab3f55924c03ead626ff424cad1732d0d391478dfbf7bb97b34602395da"}, + {file = "mypy-1.16.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:09aa4f91ada245f0a45dbc47e548fd94e0dd5a8433e0114917dc3b526912a30c"}, + {file = "mypy-1.16.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:13c7cd5b1cb2909aa318a90fd1b7e31f17c50b242953e7dd58345b2a814f6383"}, + {file = "mypy-1.16.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:58e07fb958bc5d752a280da0e890c538f1515b79a65757bbdc54252ba82e0b40"}, + {file = "mypy-1.16.1-cp39-cp39-win_amd64.whl", hash = "sha256:f895078594d918f93337a505f8add9bd654d1a24962b4c6ed9390e12531eb31b"}, + {file = "mypy-1.16.1-py3-none-any.whl", hash = "sha256:5fc2ac4027d0ef28d6ba69a0343737a23c4d1b83672bf38d1fe237bdc0643b37"}, + {file = "mypy-1.16.1.tar.gz", hash = "sha256:6bd00a0a2094841c5e47e7374bb42b83d64c527a502e3334e1173a0c24437bab"}, ] [package.dependencies] -mypy-extensions = ">=1.0.0" +mypy_extensions = ">=1.0.0" +pathspec = ">=0.9.0" tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} -typing-extensions = ">=4.6.0" +typing_extensions = ">=4.6.0" [package.extras] dmypy = ["psutil (>=4.0)"] @@ -1566,6 +1567,18 @@ files = [ [package.extras] dev = ["jinja2"] +[[package]] +name = "pathspec" +version = "0.12.1" +description = "Utility library for gitignore style pattern matching of file paths." +optional = false +python-versions = ">=3.8" +groups = ["dev"] +files = [ + {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, + {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, +] + [[package]] name = "phonenumbers" version = "9.0.9" diff --git a/synapse/config/cas.py b/synapse/config/cas.py index c32bf3695..60d66d701 100644 --- a/synapse/config/cas.py +++ b/synapse/config/cas.py @@ -42,6 +42,9 @@ class CasConfig(Config): self.cas_enabled = cas_config and cas_config.get("enabled", True) if self.cas_enabled: + if not isinstance(cas_config, dict): + raise ConfigError("Must be a dictionary", ("cas_config",)) + self.cas_server_url = cas_config["server_url"] # TODO Update this to a _synapse URL. diff --git a/synapse/config/key.py b/synapse/config/key.py index 29c558448..f78ff5114 100644 --- a/synapse/config/key.py +++ b/synapse/config/key.py @@ -212,11 +212,14 @@ class KeyConfig(Config): "Config options that expect an in-line secret as value are disabled", ("form_secret",), ) + if form_secret is not None and not isinstance(form_secret, str): + raise ConfigError("Config option must be a string", ("form_secret",)) + form_secret_path = config.get("form_secret_path", None) if form_secret_path: if form_secret: raise ConfigError(CONFLICTING_FORM_SECRET_OPTS_ERROR) - self.form_secret = read_file( + self.form_secret: Optional[str] = read_file( form_secret_path, ("form_secret_path",) ).strip() else: diff --git a/synapse/config/workers.py b/synapse/config/workers.py index c486c8127..69036f9b5 100644 --- a/synapse/config/workers.py +++ b/synapse/config/workers.py @@ -238,10 +238,16 @@ class WorkerConfig(Config): if worker_replication_secret_path: if worker_replication_secret: raise ConfigError(CONFLICTING_WORKER_REPLICATION_SECRET_OPTS_ERROR) - self.worker_replication_secret = read_file( + self.worker_replication_secret: Optional[str] = read_file( worker_replication_secret_path, ("worker_replication_secret_path",) ).strip() else: + if worker_replication_secret is not None and not isinstance( + worker_replication_secret, str + ): + raise ConfigError( + "Config option must be a string", ("worker_replication_secret",) + ) self.worker_replication_secret = worker_replication_secret self.worker_name = config.get("worker_name", self.worker_app) diff --git a/synapse/handlers/auth.py b/synapse/handlers/auth.py index 9e3e70ec1..257453674 100644 --- a/synapse/handlers/auth.py +++ b/synapse/handlers/auth.py @@ -174,6 +174,7 @@ def login_id_phone_to_thirdparty(identifier: JsonDict) -> Dict[str, str]: # Accept both "phone" and "number" as valid keys in m.id.phone phone_number = identifier.get("phone", identifier["number"]) + assert isinstance(phone_number, str) # Convert user-provided phone number to a consistent representation msisdn = phone_number_to_msisdn(identifier["country"], phone_number) diff --git a/synapse/handlers/cas.py b/synapse/handlers/cas.py index cc3d641b7..fbe79c2e4 100644 --- a/synapse/handlers/cas.py +++ b/synapse/handlers/cas.py @@ -378,7 +378,8 @@ class CasHandler: # Arbitrarily use the first attribute found. display_name = cas_response.attributes.get( - self._cas_displayname_attribute, [None] + self._cas_displayname_attribute, # type: ignore[arg-type] + [None], )[0] return UserAttributes(localpart=localpart, display_name=display_name) diff --git a/synapse/handlers/presence.py b/synapse/handlers/presence.py index 390cafa8f..fb5d691d6 100644 --- a/synapse/handlers/presence.py +++ b/synapse/handlers/presence.py @@ -1405,7 +1405,7 @@ class PresenceHandler(BasePresenceHandler): # Based on the state of each user's device calculate the new presence state. presence = _combine_device_states(devices.values()) - new_fields = {"state": presence} + new_fields: JsonDict = {"state": presence} if presence == PresenceState.ONLINE or presence == PresenceState.BUSY: new_fields["last_active_ts"] = now diff --git a/synapse/handlers/register.py b/synapse/handlers/register.py index b90126f9c..1e1f0c79c 100644 --- a/synapse/handlers/register.py +++ b/synapse/handlers/register.py @@ -557,7 +557,7 @@ class RegistrationHandler: if join_rules_event: join_rule = join_rules_event.content.get("join_rule", None) requires_invite = ( - join_rule and join_rule != JoinRules.PUBLIC + join_rule is not None and join_rule != JoinRules.PUBLIC ) # Send the invite, if necessary. diff --git a/synapse/handlers/send_email.py b/synapse/handlers/send_email.py index 353991573..92fed980e 100644 --- a/synapse/handlers/send_email.py +++ b/synapse/handlers/send_email.py @@ -197,7 +197,7 @@ class SendEmailHandler: additional_headers: A map of additional headers to include. """ try: - from_string = self._from % {"app": app_name} + from_string = self._from % {"app": app_name} # type: ignore[operator] except (KeyError, TypeError): from_string = self._from diff --git a/synapse/handlers/sso.py b/synapse/handlers/sso.py index 1cdf63264..0dd64618e 100644 --- a/synapse/handlers/sso.py +++ b/synapse/handlers/sso.py @@ -818,7 +818,7 @@ class SsoHandler: server_name = avatar_url_parts[-2] media_id = avatar_url_parts[-1] if self._is_mine_server_name(server_name): - media = await self._media_repo.store.get_local_media(media_id) # type: ignore[has-type] + media = await self._media_repo.store.get_local_media(media_id) if media is not None and upload_name == media.upload_name: logger.info("skipping saving the user avatar") return True diff --git a/synapse/http/connectproxyclient.py b/synapse/http/connectproxyclient.py index 4e4d78cb8..db803bc75 100644 --- a/synapse/http/connectproxyclient.py +++ b/synapse/http/connectproxyclient.py @@ -33,10 +33,11 @@ from twisted.internet.interfaces import ( IAddress, IConnector, IProtocol, + IProtocolFactory, IReactorCore, IStreamClientEndpoint, ) -from twisted.internet.protocol import ClientFactory, Protocol, connectionDone +from twisted.internet.protocol import ClientFactory, connectionDone from twisted.python.failure import Failure from twisted.web import http @@ -116,11 +117,7 @@ class HTTPConnectProxyEndpoint: def __repr__(self) -> str: return "" % (self._proxy_endpoint,) - # Mypy encounters a false positive here: it complains that ClientFactory - # is incompatible with IProtocolFactory. But ClientFactory inherits from - # Factory, which implements IProtocolFactory. So I think this is a bug - # in mypy-zope. - def connect(self, protocolFactory: ClientFactory) -> "defer.Deferred[IProtocol]": # type: ignore[override] + def connect(self, protocolFactory: IProtocolFactory) -> "defer.Deferred[IProtocol]": f = HTTPProxiedClientFactory( self._host, self._port, protocolFactory, self._proxy_creds ) @@ -148,7 +145,7 @@ class HTTPProxiedClientFactory(protocol.ClientFactory): self, dst_host: bytes, dst_port: int, - wrapped_factory: ClientFactory, + wrapped_factory: IProtocolFactory, proxy_creds: Optional[ProxyCredentials], ): self.dst_host = dst_host @@ -158,7 +155,10 @@ class HTTPProxiedClientFactory(protocol.ClientFactory): self.on_connection: "defer.Deferred[None]" = defer.Deferred() def startedConnecting(self, connector: IConnector) -> None: - return self.wrapped_factory.startedConnecting(connector) + # We expect the wrapped factory to be a ClientFactory, but the generic + # interfaces only guarantee that it implements IProtocolFactory. + if isinstance(self.wrapped_factory, ClientFactory): + return self.wrapped_factory.startedConnecting(connector) def buildProtocol(self, addr: IAddress) -> "HTTPConnectProtocol": wrapped_protocol = self.wrapped_factory.buildProtocol(addr) @@ -177,13 +177,15 @@ class HTTPProxiedClientFactory(protocol.ClientFactory): logger.debug("Connection to proxy failed: %s", reason) if not self.on_connection.called: self.on_connection.errback(reason) - return self.wrapped_factory.clientConnectionFailed(connector, reason) + if isinstance(self.wrapped_factory, ClientFactory): + return self.wrapped_factory.clientConnectionFailed(connector, reason) def clientConnectionLost(self, connector: IConnector, reason: Failure) -> None: logger.debug("Connection to proxy lost: %s", reason) if not self.on_connection.called: self.on_connection.errback(reason) - return self.wrapped_factory.clientConnectionLost(connector, reason) + if isinstance(self.wrapped_factory, ClientFactory): + return self.wrapped_factory.clientConnectionLost(connector, reason) class HTTPConnectProtocol(protocol.Protocol): @@ -208,7 +210,7 @@ class HTTPConnectProtocol(protocol.Protocol): self, host: bytes, port: int, - wrapped_protocol: Protocol, + wrapped_protocol: IProtocol, connected_deferred: defer.Deferred, proxy_creds: Optional[ProxyCredentials], ): @@ -223,11 +225,14 @@ class HTTPConnectProtocol(protocol.Protocol): ) self.http_setup_client.on_connected.addCallback(self.proxyConnected) + # Set once we start connecting to the wrapped protocol + self.wrapped_connection_started = False + def connectionMade(self) -> None: self.http_setup_client.makeConnection(self.transport) def connectionLost(self, reason: Failure = connectionDone) -> None: - if self.wrapped_protocol.connected: + if self.wrapped_connection_started: self.wrapped_protocol.connectionLost(reason) self.http_setup_client.connectionLost(reason) @@ -236,6 +241,8 @@ class HTTPConnectProtocol(protocol.Protocol): self.connected_deferred.errback(reason) def proxyConnected(self, _: Union[None, "defer.Deferred[None]"]) -> None: + self.wrapped_connection_started = True + assert self.transport is not None self.wrapped_protocol.makeConnection(self.transport) self.connected_deferred.callback(self.wrapped_protocol) @@ -247,7 +254,7 @@ class HTTPConnectProtocol(protocol.Protocol): def dataReceived(self, data: bytes) -> None: # if we've set up the HTTP protocol, we can send the data there - if self.wrapped_protocol.connected: + if self.wrapped_connection_started: return self.wrapped_protocol.dataReceived(data) # otherwise, we must still be setting up the connection: send the data to the diff --git a/synapse/metrics/_reactor_metrics.py b/synapse/metrics/_reactor_metrics.py index c0a4ee16e..fda0cd018 100644 --- a/synapse/metrics/_reactor_metrics.py +++ b/synapse/metrics/_reactor_metrics.py @@ -33,7 +33,7 @@ from twisted.internet.asyncioreactor import AsyncioSelectorReactor from synapse.metrics._types import Collector try: - from selectors import KqueueSelector + from selectors import KqueueSelector # type: ignore[attr-defined] except ImportError: class KqueueSelector: # type: ignore[no-redef] diff --git a/synapse/module_api/__init__.py b/synapse/module_api/__init__.py index b1a2476da..dd58d3aed 100644 --- a/synapse/module_api/__init__.py +++ b/synapse/module_api/__init__.py @@ -284,7 +284,7 @@ class ModuleApi: try: app_name = self._hs.config.email.email_app_name - self._from_string = self._hs.config.email.email_notif_from % { + self._from_string = self._hs.config.email.email_notif_from % { # type: ignore[operator] "app": app_name } except (KeyError, TypeError): diff --git a/synapse/storage/databases/main/state.py b/synapse/storage/databases/main/state.py index 788f7d1e3..cfcc731f8 100644 --- a/synapse/storage/databases/main/state.py +++ b/synapse/storage/databases/main/state.py @@ -990,11 +990,12 @@ class StateMapWrapper(Dict[StateKey, str]): raise Exception("State map was filtered and doesn't include: %s", key) return super().__getitem__(key) + @overload # type: ignore[override] + def get(self, key: StateKey, default: None = None, /) -> Optional[str]: ... @overload - def get(self, key: Tuple[str, str]) -> Optional[str]: ... - + def get(self, key: StateKey, default: str, /) -> str: ... @overload - def get(self, key: Tuple[str, str], default: Union[str, _T]) -> Union[str, _T]: ... + def get(self, key: StateKey, default: _T, /) -> Union[str, _T]: ... def get( self, key: StateKey, default: Union[str, _T, None] = None diff --git a/synapse/storage/engines/_base.py b/synapse/storage/engines/_base.py index 9d82c5938..9fec42c2e 100644 --- a/synapse/storage/engines/_base.py +++ b/synapse/storage/engines/_base.py @@ -34,9 +34,9 @@ AUTO_INCREMENT_PRIMARY_KEYPLACEHOLDER = "$%AUTO_INCREMENT_PRIMARY_KEY%$" class IsolationLevel(IntEnum): - READ_COMMITTED: int = 1 - REPEATABLE_READ: int = 2 - SERIALIZABLE: int = 3 + READ_COMMITTED = 1 + REPEATABLE_READ = 2 + SERIALIZABLE = 3 class IncorrectDatabaseSetup(RuntimeError): diff --git a/synapse/util/gai_resolver.py b/synapse/util/gai_resolver.py index fecf829ad..3c7a966e8 100644 --- a/synapse/util/gai_resolver.py +++ b/synapse/util/gai_resolver.py @@ -97,7 +97,7 @@ _GETADDRINFO_RESULT = List[ SocketKind, int, str, - Union[Tuple[str, int], Tuple[str, int, int, int]], + Union[Tuple[str, int], Tuple[str, int, int, int], Tuple[int, bytes]], ] ] diff --git a/synapse/util/patch_inline_callbacks.py b/synapse/util/patch_inline_callbacks.py index beea4d288..c776ad65b 100644 --- a/synapse/util/patch_inline_callbacks.py +++ b/synapse/util/patch_inline_callbacks.py @@ -20,6 +20,7 @@ import functools import sys +from types import GeneratorType from typing import Any, Callable, Generator, List, TypeVar, cast from typing_extensions import ParamSpec @@ -151,6 +152,12 @@ def _check_yield_points( ) -> Generator["Deferred[object]", object, T]: gen = f(*args, **kwargs) + # We only patch if we have a native generator function, as we rely on + # `gen.gi_frame`. + if not isinstance(gen, GeneratorType): + ret = yield from gen + return ret + last_yield_line_no = gen.gi_frame.f_lineno result: Any = None while True: diff --git a/tests/federation/test_federation_sender.py b/tests/federation/test_federation_sender.py index cd906bbbc..64e8c1281 100644 --- a/tests/federation/test_federation_sender.py +++ b/tests/federation/test_federation_sender.py @@ -672,7 +672,7 @@ class FederationSenderDevicesTestCases(HomeserverTestCase): self.assertEqual(edu["edu_type"], EduTypes.DEVICE_LIST_UPDATE) c = edu["content"] if stream_id is not None: - self.assertEqual(c["prev_id"], [stream_id]) # type: ignore[unreachable] + self.assertEqual(c["prev_id"], [stream_id]) self.assertGreaterEqual(c["stream_id"], stream_id) stream_id = c["stream_id"] devices = {edu["content"]["device_id"] for edu in self.edus}