Merge remote-tracking branch 'upstream/release-v1.54'

This commit is contained in:
Tulir Asokan 2022-03-08 16:46:02 +02:00
commit 5cdff802d1
9 changed files with 167 additions and 21 deletions

View file

@ -47,7 +47,7 @@ try:
except ImportError:
pass
__version__ = "1.54.0rc1"
__version__ = "1.54.0"
if bool(os.environ.get("SYNAPSE_TEST_PATCH_LOG_CONTEXTS", False)):
# We import here so that we don't have to install a bunch of deps when

View file

@ -174,7 +174,9 @@ class ThirdPartyEventRules:
] = None,
on_new_event: Optional[ON_NEW_EVENT_CALLBACK] = None,
on_profile_update: Optional[ON_PROFILE_UPDATE_CALLBACK] = None,
on_deactivation: Optional[ON_USER_DEACTIVATION_STATUS_CHANGED_CALLBACK] = None,
on_user_deactivation_status_changed: Optional[
ON_USER_DEACTIVATION_STATUS_CHANGED_CALLBACK
] = None,
) -> None:
"""Register callbacks from modules for each hook."""
if check_event_allowed is not None:
@ -199,8 +201,10 @@ class ThirdPartyEventRules:
if on_profile_update is not None:
self._on_profile_update_callbacks.append(on_profile_update)
if on_deactivation is not None:
self._on_user_deactivation_status_changed_callbacks.append(on_deactivation)
if on_user_deactivation_status_changed is not None:
self._on_user_deactivation_status_changed_callbacks.append(
on_user_deactivation_status_changed,
)
async def check_event_allowed(
self, event: EventBase, context: EventContext

View file

@ -59,6 +59,8 @@ from synapse.events.third_party_rules import (
CHECK_VISIBILITY_CAN_BE_MODIFIED_CALLBACK,
ON_CREATE_ROOM_CALLBACK,
ON_NEW_EVENT_CALLBACK,
ON_PROFILE_UPDATE_CALLBACK,
ON_USER_DEACTIVATION_STATUS_CHANGED_CALLBACK,
)
from synapse.handlers.account_validity import (
IS_USER_EXPIRED_CALLBACK,
@ -281,6 +283,10 @@ class ModuleApi:
CHECK_VISIBILITY_CAN_BE_MODIFIED_CALLBACK
] = None,
on_new_event: Optional[ON_NEW_EVENT_CALLBACK] = None,
on_profile_update: Optional[ON_PROFILE_UPDATE_CALLBACK] = None,
on_user_deactivation_status_changed: Optional[
ON_USER_DEACTIVATION_STATUS_CHANGED_CALLBACK
] = None,
) -> None:
"""Registers callbacks for third party event rules capabilities.
@ -292,6 +298,8 @@ class ModuleApi:
check_threepid_can_be_invited=check_threepid_can_be_invited,
check_visibility_can_be_modified=check_visibility_can_be_modified,
on_new_event=on_new_event,
on_profile_update=on_profile_update,
on_user_deactivation_status_changed=on_user_deactivation_status_changed,
)
def register_presence_router_callbacks(

View file

@ -83,8 +83,8 @@ REQUIREMENTS = [
# ijson 3.1.4 fixes a bug with "." in property names
"ijson>=3.1.4",
"matrix-common~=1.1.0",
# For runtime introspection of our dependencies
"packaging~=21.3",
# We need packaging.requirements.Requirement, added in 16.1.
"packaging>=16.1",
]
CONDITIONAL_REQUIREMENTS = {

View file

@ -1,3 +1,25 @@
# Copyright 2022 The Matrix.org Foundation C.I.C.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
"""
This module exposes a single function which checks synapse's dependencies are present
and correctly versioned. It makes use of `importlib.metadata` to do so. The details
are a bit murky: there's no easy way to get a map from "extras" to the packages they
require. But this is probably just symptomatic of Python's package management.
"""
import logging
from typing import Iterable, NamedTuple, Optional
@ -10,6 +32,8 @@ try:
except ImportError:
import importlib_metadata as metadata # type: ignore[no-redef]
__all__ = ["check_requirements"]
class DependencyException(Exception):
@property
@ -29,7 +53,17 @@ class DependencyException(Exception):
yield '"' + i + '"'
EXTRAS = set(metadata.metadata(DISTRIBUTION_NAME).get_all("Provides-Extra"))
DEV_EXTRAS = {"lint", "mypy", "test", "dev"}
RUNTIME_EXTRAS = (
set(metadata.metadata(DISTRIBUTION_NAME).get_all("Provides-Extra")) - DEV_EXTRAS
)
VERSION = metadata.version(DISTRIBUTION_NAME)
def _is_dev_dependency(req: Requirement) -> bool:
return req.marker is not None and any(
req.marker.evaluate({"extra": e}) for e in DEV_EXTRAS
)
class Dependency(NamedTuple):
@ -43,6 +77,9 @@ def _generic_dependencies() -> Iterable[Dependency]:
assert requirements is not None
for raw_requirement in requirements:
req = Requirement(raw_requirement)
if _is_dev_dependency(req):
continue
# https://packaging.pypa.io/en/latest/markers.html#usage notes that
# > Evaluating an extra marker with no environment is an error
# so we pass in a dummy empty extra value here.
@ -56,6 +93,8 @@ def _dependencies_for_extra(extra: str) -> Iterable[Dependency]:
assert requirements is not None
for raw_requirement in requirements:
req = Requirement(raw_requirement)
if _is_dev_dependency(req):
continue
# Exclude mandatory deps by only selecting deps needed with this extra.
if (
req.marker is not None
@ -67,18 +106,26 @@ def _dependencies_for_extra(extra: str) -> Iterable[Dependency]:
def _not_installed(requirement: Requirement, extra: Optional[str] = None) -> str:
if extra:
return f"Need {requirement.name} for {extra}, but it is not installed"
return (
f"Synapse {VERSION} needs {requirement.name} for {extra}, "
f"but it is not installed"
)
else:
return f"Need {requirement.name}, but it is not installed"
return f"Synapse {VERSION} needs {requirement.name}, but it is not installed"
def _incorrect_version(
requirement: Requirement, got: str, extra: Optional[str] = None
) -> str:
if extra:
return f"Need {requirement} for {extra}, but got {requirement.name}=={got}"
return (
f"Synapse {VERSION} needs {requirement} for {extra}, "
f"but got {requirement.name}=={got}"
)
else:
return f"Need {requirement}, but got {requirement.name}=={got}"
return (
f"Synapse {VERSION} needs {requirement}, but got {requirement.name}=={got}"
)
def check_requirements(extra: Optional[str] = None) -> None:
@ -100,10 +147,10 @@ def check_requirements(extra: Optional[str] = None) -> None:
# First work out which dependencies are required, and which are optional.
if extra is None:
dependencies = _generic_dependencies()
elif extra in EXTRAS:
elif extra in RUNTIME_EXTRAS:
dependencies = _dependencies_for_extra(extra)
else:
raise ValueError(f"Synapse does not provide the feature '{extra}'")
raise ValueError(f"Synapse {VERSION} does not provide the feature '{extra}'")
deps_unfulfilled = []
errors = []
@ -116,7 +163,8 @@ def check_requirements(extra: Optional[str] = None) -> None:
deps_unfulfilled.append(requirement.name)
errors.append(_not_installed(requirement, extra))
else:
if not requirement.specifier.contains(dist.version):
# We specify prereleases=True to allow prereleases such as RCs.
if not requirement.specifier.contains(dist.version, prereleases=True):
deps_unfulfilled.append(requirement.name)
errors.append(_incorrect_version(requirement, dist.version, extra))