summary refs log tree commit diff
diff options
context:
space:
mode:
authorOlivier Wilkinson (reivilibre) <oliverw@matrix.org>2022-05-25 12:26:55 +0100
committerOlivier Wilkinson (reivilibre) <oliverw@matrix.org>2022-05-25 12:26:55 +0100
commit038439a7d2102e019186a4c35b1688571d343270 (patch)
tree70b286d2b309f211b37d2f47a6b2eb7bb21b31b6
parentCorrect typo in changelog for #12858. (diff)
downloadsynapse-github/rei/strict_json_types.tar.xz
Signed-off-by: Olivier Wilkinson (reivilibre) <oliverw@matrix.org>
-rw-r--r--changelog.d/12873.misc1
-rw-r--r--synapse/types.py41
2 files changed, 42 insertions, 0 deletions
diff --git a/changelog.d/12873.misc b/changelog.d/12873.misc
new file mode 100644

index 0000000000..c441084264 --- /dev/null +++ b/changelog.d/12873.misc
@@ -0,0 +1 @@ +Add stricter JSON type annotations to the Module API's account data manager. \ No newline at end of file diff --git a/synapse/types.py b/synapse/types.py
index 6f7128ddd6..7200dedf5f 100644 --- a/synapse/types.py +++ b/synapse/types.py
@@ -26,6 +26,7 @@ from typing import ( MutableMapping, NoReturn, Optional, + Protocol, Set, Tuple, Type, @@ -77,6 +78,46 @@ JsonMapping = Mapping[str, Any] JsonSerializable = object +if TYPE_CHECKING: + # This is a very hacky way to have a strongly-typed JSON object + # that doesn't stop short at Dict[str, Any]. + # https://github.com/python/typing/issues/182#issuecomment-899624078 + + StrictJson = ... + + class StrictJsonArray(List[StrictJson], Protocol): # type: ignore + __class__: Type[List[StrictJson]] # type: ignore + + class StrictJsonDict(Dict[str, StrictJson], Protocol): # type: ignore + __class__: Type[Dict[str, StrictJson]] # type: ignore + + StrictJson = Union[None, float, str, StrictJsonArray, StrictJsonDict] # type: ignore[assignment] +else: + # We need some types for runtime. + StrictJson = Union[None, float, str, List[Any], Dict[str, Any]] + StrictJsonDict = Dict[str, StrictJson] + + +if TYPE_CHECKING: + # Analogous to StrictJson, this is a version that uses entirely frozen data. + + StrictFrozenJson = ... + + class StrictFrozenJsonArray(Tuple[StrictFrozenJson, ...], Protocol): # type: ignore + __class__: Type[Tuple[StrictFrozenJson, ...]] # type: ignore + + class StrictFrozenJsonDict(frozendict[str, StrictFrozenJson], Protocol): # type: ignore + __class__: Type[frozendict[str, StrictFrozenJson]] # type: ignore + + StrictFrozenJson = Union[ # type: ignore[assignment] + None, float, str, StrictFrozenJsonArray, StrictFrozenJsonDict + ] +else: + # We need some types for runtime. + StrictFrozenJson = Union[None, float, str, Tuple[Any, ...], frozendict[str, Any]] + StrictFrozenJsonDict = frozendict[str, StrictFrozenJson] + + # Note that this seems to require inheriting *directly* from Interface in order # for mypy-zope to realize it is an interface. class ISynapseReactor(