mirror of
https://mau.dev/maunium/synapse.git
synced 2024-11-14 14:01:59 +01:00
Merge remote-tracking branch 'upstream/release-v1.54'
This commit is contained in:
commit
5cdff802d1
9 changed files with 167 additions and 21 deletions
26
CHANGES.md
26
CHANGES.md
|
@ -1,15 +1,33 @@
|
||||||
Synapse 1.54.0rc1 (2022-03-02)
|
Synapse 1.54.0 (2022-03-08)
|
||||||
==============================
|
===========================
|
||||||
|
|
||||||
Please note that this will be the last release of Synapse that is compatible with Mjolnir 1.3.1 and earlier.
|
Please note that this will be the last release of Synapse that is compatible with Mjolnir 1.3.1 and earlier.
|
||||||
Administrators of servers which have the Mjolnir module installed are advised to upgrade Mjolnir to version 1.3.2 or later.
|
Administrators of servers which have the Mjolnir module installed are advised to upgrade Mjolnir to version 1.3.2 or later.
|
||||||
|
|
||||||
|
|
||||||
|
Bugfixes
|
||||||
|
--------
|
||||||
|
|
||||||
|
- Fix a bug introduced in Synapse 1.54.0rc1 preventing the new module callbacks introduced in this release from being registered by modules. ([\#12141](https://github.com/matrix-org/synapse/issues/12141))
|
||||||
|
- Fix a bug introduced in Synapse 1.54.0rc1 where runtime dependency version checks would mistakenly check development dependencies if they were present and would not accept pre-release versions of dependencies. ([\#12129](https://github.com/matrix-org/synapse/issues/12129), [\#12177](https://github.com/matrix-org/synapse/issues/12177))
|
||||||
|
|
||||||
|
|
||||||
|
Internal Changes
|
||||||
|
----------------
|
||||||
|
|
||||||
|
- Update release script to insert the previous version when writing "No significant changes" line in the changelog. ([\#12127](https://github.com/matrix-org/synapse/issues/12127))
|
||||||
|
- Relax the version guard for "packaging" added in [\#12088](https://github.com/matrix-org/synapse/issues/12088). ([\#12166](https://github.com/matrix-org/synapse/issues/12166))
|
||||||
|
|
||||||
|
|
||||||
|
Synapse 1.54.0rc1 (2022-03-02)
|
||||||
|
==============================
|
||||||
|
|
||||||
|
|
||||||
Features
|
Features
|
||||||
--------
|
--------
|
||||||
|
|
||||||
- Add support for [MSC3202](https://github.com/matrix-org/matrix-doc/pull/3202): sending one-time key counts and fallback key usage states to Application Services. ([\#11617](https://github.com/matrix-org/synapse/issues/11617))
|
- Add support for [MSC3202](https://github.com/matrix-org/matrix-doc/pull/3202): sending one-time key counts and fallback key usage states to Application Services. ([\#11617](https://github.com/matrix-org/synapse/issues/11617))
|
||||||
- Improve the preview that is produced when generating URL previews for some web pages. Contributed by @AndrewRyanChama. ([\#11985](https://github.com/matrix-org/synapse/issues/11985))
|
- Improve the generated URL previews for some web pages. Contributed by @AndrewRyanChama. ([\#11985](https://github.com/matrix-org/synapse/issues/11985))
|
||||||
- Track cache invalidations in Prometheus metrics, as already happens for cache eviction based on size or time. ([\#12000](https://github.com/matrix-org/synapse/issues/12000))
|
- Track cache invalidations in Prometheus metrics, as already happens for cache eviction based on size or time. ([\#12000](https://github.com/matrix-org/synapse/issues/12000))
|
||||||
- Implement experimental support for [MSC3720](https://github.com/matrix-org/matrix-doc/pull/3720) (account status endpoints). ([\#12001](https://github.com/matrix-org/synapse/issues/12001), [\#12067](https://github.com/matrix-org/synapse/issues/12067))
|
- Implement experimental support for [MSC3720](https://github.com/matrix-org/matrix-doc/pull/3720) (account status endpoints). ([\#12001](https://github.com/matrix-org/synapse/issues/12001), [\#12067](https://github.com/matrix-org/synapse/issues/12067))
|
||||||
- Enable modules to set a custom display name when registering a user. ([\#12009](https://github.com/matrix-org/synapse/issues/12009))
|
- Enable modules to set a custom display name when registering a user. ([\#12009](https://github.com/matrix-org/synapse/issues/12009))
|
||||||
|
@ -23,7 +41,7 @@ Bugfixes
|
||||||
--------
|
--------
|
||||||
|
|
||||||
- Fix a bug introduced in Synapse 1.48.0 where an edit of the latest event in a thread would not be properly applied to the thread summary. ([\#11992](https://github.com/matrix-org/synapse/issues/11992))
|
- Fix a bug introduced in Synapse 1.48.0 where an edit of the latest event in a thread would not be properly applied to the thread summary. ([\#11992](https://github.com/matrix-org/synapse/issues/11992))
|
||||||
- Fix long-standing bug where `get_rooms_for_user` was not correctly invalidated for remote users when the server left a room. ([\#11999](https://github.com/matrix-org/synapse/issues/11999))
|
- Fix long-standing bug where the `get_rooms_for_user` cache was not correctly invalidated for remote users when the server left a room. ([\#11999](https://github.com/matrix-org/synapse/issues/11999))
|
||||||
- Fix a 500 error with Postgres when looking backwards with the [MSC3030](https://github.com/matrix-org/matrix-doc/pull/3030) `/timestamp_to_event?dir=b` endpoint. ([\#12024](https://github.com/matrix-org/synapse/issues/12024))
|
- Fix a 500 error with Postgres when looking backwards with the [MSC3030](https://github.com/matrix-org/matrix-doc/pull/3030) `/timestamp_to_event?dir=b` endpoint. ([\#12024](https://github.com/matrix-org/synapse/issues/12024))
|
||||||
- Properly fix a long-standing bug where wrong data could be inserted into the `event_search` table when using SQLite. This could block running `synapse_port_db` with an `argument of type 'int' is not iterable` error. This bug was partially fixed by a change in Synapse 1.44.0. ([\#12037](https://github.com/matrix-org/synapse/issues/12037))
|
- Properly fix a long-standing bug where wrong data could be inserted into the `event_search` table when using SQLite. This could block running `synapse_port_db` with an `argument of type 'int' is not iterable` error. This bug was partially fixed by a change in Synapse 1.44.0. ([\#12037](https://github.com/matrix-org/synapse/issues/12037))
|
||||||
- Fix slow performance of `/logout` in some cases where refresh tokens are in use. The slowness existed since the initial implementation of refresh tokens in version 1.38.0. ([\#12056](https://github.com/matrix-org/synapse/issues/12056))
|
- Fix slow performance of `/logout` in some cases where refresh tokens are in use. The slowness existed since the initial implementation of refresh tokens in version 1.38.0. ([\#12056](https://github.com/matrix-org/synapse/issues/12056))
|
||||||
|
|
6
debian/changelog
vendored
6
debian/changelog
vendored
|
@ -1,3 +1,9 @@
|
||||||
|
matrix-synapse-py3 (1.54.0) stable; urgency=medium
|
||||||
|
|
||||||
|
* New synapse release 1.54.0.
|
||||||
|
|
||||||
|
-- Synapse Packaging team <packages@matrix.org> Tue, 08 Mar 2022 10:54:52 +0000
|
||||||
|
|
||||||
matrix-synapse-py3 (1.54.0~rc1) stable; urgency=medium
|
matrix-synapse-py3 (1.54.0~rc1) stable; urgency=medium
|
||||||
|
|
||||||
* New synapse release 1.54.0~rc1.
|
* New synapse release 1.54.0~rc1.
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
"""An interactive script for doing a release. See `cli()` below.
|
"""An interactive script for doing a release. See `cli()` below.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import glob
|
||||||
|
import os
|
||||||
import re
|
import re
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
@ -209,8 +211,8 @@ def prepare():
|
||||||
with open("synapse/__init__.py", "w") as f:
|
with open("synapse/__init__.py", "w") as f:
|
||||||
f.write(parsed_synapse_ast.dumps())
|
f.write(parsed_synapse_ast.dumps())
|
||||||
|
|
||||||
# Generate changelogs
|
# Generate changelogs.
|
||||||
run_until_successful("python3 -m towncrier", shell=True)
|
generate_and_write_changelog(current_version)
|
||||||
|
|
||||||
# Generate debian changelogs
|
# Generate debian changelogs
|
||||||
if parsed_new_version.pre is not None:
|
if parsed_new_version.pre is not None:
|
||||||
|
@ -523,5 +525,29 @@ def get_changes_for_version(wanted_version: version.Version) -> str:
|
||||||
return "\n".join(version_changelog)
|
return "\n".join(version_changelog)
|
||||||
|
|
||||||
|
|
||||||
|
def generate_and_write_changelog(current_version: version.Version):
|
||||||
|
# We do this by getting a draft so that we can edit it before writing to the
|
||||||
|
# changelog.
|
||||||
|
result = run_until_successful(
|
||||||
|
"python3 -m towncrier --draft", shell=True, capture_output=True
|
||||||
|
)
|
||||||
|
new_changes = result.stdout.decode("utf-8")
|
||||||
|
new_changes = new_changes.replace(
|
||||||
|
"No significant changes.", f"No significant changes since {current_version}."
|
||||||
|
)
|
||||||
|
|
||||||
|
# Prepend changes to changelog
|
||||||
|
with open("CHANGES.md", "r+") as f:
|
||||||
|
existing_content = f.read()
|
||||||
|
f.seek(0, 0)
|
||||||
|
f.write(new_changes)
|
||||||
|
f.write("\n")
|
||||||
|
f.write(existing_content)
|
||||||
|
|
||||||
|
# Remove all the news fragments
|
||||||
|
for f in glob.iglob("changelog.d/*.*"):
|
||||||
|
os.remove(f)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
cli()
|
cli()
|
||||||
|
|
|
@ -47,7 +47,7 @@ try:
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
__version__ = "1.54.0rc1"
|
__version__ = "1.54.0"
|
||||||
|
|
||||||
if bool(os.environ.get("SYNAPSE_TEST_PATCH_LOG_CONTEXTS", False)):
|
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
|
# We import here so that we don't have to install a bunch of deps when
|
||||||
|
|
|
@ -174,7 +174,9 @@ class ThirdPartyEventRules:
|
||||||
] = None,
|
] = None,
|
||||||
on_new_event: Optional[ON_NEW_EVENT_CALLBACK] = None,
|
on_new_event: Optional[ON_NEW_EVENT_CALLBACK] = None,
|
||||||
on_profile_update: Optional[ON_PROFILE_UPDATE_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:
|
) -> None:
|
||||||
"""Register callbacks from modules for each hook."""
|
"""Register callbacks from modules for each hook."""
|
||||||
if check_event_allowed is not None:
|
if check_event_allowed is not None:
|
||||||
|
@ -199,8 +201,10 @@ class ThirdPartyEventRules:
|
||||||
if on_profile_update is not None:
|
if on_profile_update is not None:
|
||||||
self._on_profile_update_callbacks.append(on_profile_update)
|
self._on_profile_update_callbacks.append(on_profile_update)
|
||||||
|
|
||||||
if on_deactivation is not None:
|
if on_user_deactivation_status_changed is not None:
|
||||||
self._on_user_deactivation_status_changed_callbacks.append(on_deactivation)
|
self._on_user_deactivation_status_changed_callbacks.append(
|
||||||
|
on_user_deactivation_status_changed,
|
||||||
|
)
|
||||||
|
|
||||||
async def check_event_allowed(
|
async def check_event_allowed(
|
||||||
self, event: EventBase, context: EventContext
|
self, event: EventBase, context: EventContext
|
||||||
|
|
|
@ -59,6 +59,8 @@ from synapse.events.third_party_rules import (
|
||||||
CHECK_VISIBILITY_CAN_BE_MODIFIED_CALLBACK,
|
CHECK_VISIBILITY_CAN_BE_MODIFIED_CALLBACK,
|
||||||
ON_CREATE_ROOM_CALLBACK,
|
ON_CREATE_ROOM_CALLBACK,
|
||||||
ON_NEW_EVENT_CALLBACK,
|
ON_NEW_EVENT_CALLBACK,
|
||||||
|
ON_PROFILE_UPDATE_CALLBACK,
|
||||||
|
ON_USER_DEACTIVATION_STATUS_CHANGED_CALLBACK,
|
||||||
)
|
)
|
||||||
from synapse.handlers.account_validity import (
|
from synapse.handlers.account_validity import (
|
||||||
IS_USER_EXPIRED_CALLBACK,
|
IS_USER_EXPIRED_CALLBACK,
|
||||||
|
@ -281,6 +283,10 @@ class ModuleApi:
|
||||||
CHECK_VISIBILITY_CAN_BE_MODIFIED_CALLBACK
|
CHECK_VISIBILITY_CAN_BE_MODIFIED_CALLBACK
|
||||||
] = None,
|
] = None,
|
||||||
on_new_event: Optional[ON_NEW_EVENT_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:
|
) -> None:
|
||||||
"""Registers callbacks for third party event rules capabilities.
|
"""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_threepid_can_be_invited=check_threepid_can_be_invited,
|
||||||
check_visibility_can_be_modified=check_visibility_can_be_modified,
|
check_visibility_can_be_modified=check_visibility_can_be_modified,
|
||||||
on_new_event=on_new_event,
|
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(
|
def register_presence_router_callbacks(
|
||||||
|
|
|
@ -83,8 +83,8 @@ REQUIREMENTS = [
|
||||||
# ijson 3.1.4 fixes a bug with "." in property names
|
# ijson 3.1.4 fixes a bug with "." in property names
|
||||||
"ijson>=3.1.4",
|
"ijson>=3.1.4",
|
||||||
"matrix-common~=1.1.0",
|
"matrix-common~=1.1.0",
|
||||||
# For runtime introspection of our dependencies
|
# We need packaging.requirements.Requirement, added in 16.1.
|
||||||
"packaging~=21.3",
|
"packaging>=16.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
CONDITIONAL_REQUIREMENTS = {
|
CONDITIONAL_REQUIREMENTS = {
|
||||||
|
|
|
@ -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
|
import logging
|
||||||
from typing import Iterable, NamedTuple, Optional
|
from typing import Iterable, NamedTuple, Optional
|
||||||
|
|
||||||
|
@ -10,6 +32,8 @@ try:
|
||||||
except ImportError:
|
except ImportError:
|
||||||
import importlib_metadata as metadata # type: ignore[no-redef]
|
import importlib_metadata as metadata # type: ignore[no-redef]
|
||||||
|
|
||||||
|
__all__ = ["check_requirements"]
|
||||||
|
|
||||||
|
|
||||||
class DependencyException(Exception):
|
class DependencyException(Exception):
|
||||||
@property
|
@property
|
||||||
|
@ -29,7 +53,17 @@ class DependencyException(Exception):
|
||||||
yield '"' + i + '"'
|
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):
|
class Dependency(NamedTuple):
|
||||||
|
@ -43,6 +77,9 @@ def _generic_dependencies() -> Iterable[Dependency]:
|
||||||
assert requirements is not None
|
assert requirements is not None
|
||||||
for raw_requirement in requirements:
|
for raw_requirement in requirements:
|
||||||
req = Requirement(raw_requirement)
|
req = Requirement(raw_requirement)
|
||||||
|
if _is_dev_dependency(req):
|
||||||
|
continue
|
||||||
|
|
||||||
# https://packaging.pypa.io/en/latest/markers.html#usage notes that
|
# https://packaging.pypa.io/en/latest/markers.html#usage notes that
|
||||||
# > Evaluating an extra marker with no environment is an error
|
# > Evaluating an extra marker with no environment is an error
|
||||||
# so we pass in a dummy empty extra value here.
|
# 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
|
assert requirements is not None
|
||||||
for raw_requirement in requirements:
|
for raw_requirement in requirements:
|
||||||
req = Requirement(raw_requirement)
|
req = Requirement(raw_requirement)
|
||||||
|
if _is_dev_dependency(req):
|
||||||
|
continue
|
||||||
# Exclude mandatory deps by only selecting deps needed with this extra.
|
# Exclude mandatory deps by only selecting deps needed with this extra.
|
||||||
if (
|
if (
|
||||||
req.marker is not None
|
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:
|
def _not_installed(requirement: Requirement, extra: Optional[str] = None) -> str:
|
||||||
if extra:
|
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:
|
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(
|
def _incorrect_version(
|
||||||
requirement: Requirement, got: str, extra: Optional[str] = None
|
requirement: Requirement, got: str, extra: Optional[str] = None
|
||||||
) -> str:
|
) -> str:
|
||||||
if extra:
|
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:
|
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:
|
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.
|
# First work out which dependencies are required, and which are optional.
|
||||||
if extra is None:
|
if extra is None:
|
||||||
dependencies = _generic_dependencies()
|
dependencies = _generic_dependencies()
|
||||||
elif extra in EXTRAS:
|
elif extra in RUNTIME_EXTRAS:
|
||||||
dependencies = _dependencies_for_extra(extra)
|
dependencies = _dependencies_for_extra(extra)
|
||||||
else:
|
else:
|
||||||
raise ValueError(f"Synapse does not provide the feature '{extra}'")
|
raise ValueError(f"Synapse {VERSION} does not provide the feature '{extra}'")
|
||||||
|
|
||||||
deps_unfulfilled = []
|
deps_unfulfilled = []
|
||||||
errors = []
|
errors = []
|
||||||
|
@ -116,7 +163,8 @@ def check_requirements(extra: Optional[str] = None) -> None:
|
||||||
deps_unfulfilled.append(requirement.name)
|
deps_unfulfilled.append(requirement.name)
|
||||||
errors.append(_not_installed(requirement, extra))
|
errors.append(_not_installed(requirement, extra))
|
||||||
else:
|
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)
|
deps_unfulfilled.append(requirement.name)
|
||||||
errors.append(_incorrect_version(requirement, dist.version, extra))
|
errors.append(_incorrect_version(requirement, dist.version, extra))
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,9 @@ class DummyDistribution(metadata.Distribution):
|
||||||
|
|
||||||
|
|
||||||
old = DummyDistribution("0.1.2")
|
old = DummyDistribution("0.1.2")
|
||||||
|
old_release_candidate = DummyDistribution("0.1.2rc3")
|
||||||
new = DummyDistribution("1.2.3")
|
new = DummyDistribution("1.2.3")
|
||||||
|
new_release_candidate = DummyDistribution("1.2.3rc4")
|
||||||
|
|
||||||
# could probably use stdlib TestCase --- no need for twisted here
|
# could probably use stdlib TestCase --- no need for twisted here
|
||||||
|
|
||||||
|
@ -65,6 +67,23 @@ class TestDependencyChecker(TestCase):
|
||||||
# should not raise
|
# should not raise
|
||||||
check_requirements()
|
check_requirements()
|
||||||
|
|
||||||
|
def test_checks_ignore_dev_dependencies(self) -> None:
|
||||||
|
"""Bot generic and per-extra checks should ignore dev dependencies."""
|
||||||
|
with patch(
|
||||||
|
"synapse.util.check_dependencies.metadata.requires",
|
||||||
|
return_value=["dummypkg >= 1; extra == 'mypy'"],
|
||||||
|
), patch("synapse.util.check_dependencies.RUNTIME_EXTRAS", {"cool-extra"}):
|
||||||
|
# We're testing that none of these calls raise.
|
||||||
|
with self.mock_installed_package(None):
|
||||||
|
check_requirements()
|
||||||
|
check_requirements("cool-extra")
|
||||||
|
with self.mock_installed_package(old):
|
||||||
|
check_requirements()
|
||||||
|
check_requirements("cool-extra")
|
||||||
|
with self.mock_installed_package(new):
|
||||||
|
check_requirements()
|
||||||
|
check_requirements("cool-extra")
|
||||||
|
|
||||||
def test_generic_check_of_optional_dependency(self) -> None:
|
def test_generic_check_of_optional_dependency(self) -> None:
|
||||||
"""Complain if an optional package is old."""
|
"""Complain if an optional package is old."""
|
||||||
with patch(
|
with patch(
|
||||||
|
@ -85,11 +104,28 @@ class TestDependencyChecker(TestCase):
|
||||||
with patch(
|
with patch(
|
||||||
"synapse.util.check_dependencies.metadata.requires",
|
"synapse.util.check_dependencies.metadata.requires",
|
||||||
return_value=["dummypkg >= 1; extra == 'cool-extra'"],
|
return_value=["dummypkg >= 1; extra == 'cool-extra'"],
|
||||||
), patch("synapse.util.check_dependencies.EXTRAS", {"cool-extra"}):
|
), patch("synapse.util.check_dependencies.RUNTIME_EXTRAS", {"cool-extra"}):
|
||||||
with self.mock_installed_package(None):
|
with self.mock_installed_package(None):
|
||||||
self.assertRaises(DependencyException, check_requirements, "cool-extra")
|
self.assertRaises(DependencyException, check_requirements, "cool-extra")
|
||||||
with self.mock_installed_package(old):
|
with self.mock_installed_package(old):
|
||||||
self.assertRaises(DependencyException, check_requirements, "cool-extra")
|
self.assertRaises(DependencyException, check_requirements, "cool-extra")
|
||||||
with self.mock_installed_package(new):
|
with self.mock_installed_package(new):
|
||||||
|
# should not raise
|
||||||
|
check_requirements("cool-extra")
|
||||||
|
|
||||||
|
def test_release_candidates_satisfy_dependency(self) -> None:
|
||||||
|
"""
|
||||||
|
Tests that release candidates count as far as satisfying a dependency
|
||||||
|
is concerned.
|
||||||
|
(Regression test, see #12176.)
|
||||||
|
"""
|
||||||
|
with patch(
|
||||||
|
"synapse.util.check_dependencies.metadata.requires",
|
||||||
|
return_value=["dummypkg >= 1"],
|
||||||
|
):
|
||||||
|
with self.mock_installed_package(old_release_candidate):
|
||||||
|
self.assertRaises(DependencyException, check_requirements)
|
||||||
|
|
||||||
|
with self.mock_installed_package(new_release_candidate):
|
||||||
# should not raise
|
# should not raise
|
||||||
check_requirements()
|
check_requirements()
|
||||||
|
|
Loading…
Reference in a new issue