Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

disallow-untyped-defs in docker and stubs directories #12528

Merged
merged 7 commits into from
Apr 25, 2022
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/12528.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add type hints so `docker` and `stubs` directories pass `mypy --disallow-untyped-defs`.
24 changes: 13 additions & 11 deletions docker/configure_workers_and_start.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
import os
import subprocess
import sys
from typing import Any, Dict, Mapping, Set
from typing import Any, Dict, List, Mapping, MutableMapping, NoReturn, Set

import jinja2
import yaml
Expand Down Expand Up @@ -201,7 +201,7 @@


# Utility functions
def log(txt: str):
def log(txt: str) -> None:
"""Log something to the stdout.

Args:
Expand All @@ -210,7 +210,7 @@ def log(txt: str):
print(txt)


def error(txt: str):
def error(txt: str) -> NoReturn:
"""Log something and exit with an error code.

Args:
Expand All @@ -220,7 +220,7 @@ def error(txt: str):
sys.exit(2)


def convert(src: str, dst: str, **template_vars):
def convert(src: str, dst: str, **template_vars: object) -> None:
"""Generate a file from a template

Args:
Expand Down Expand Up @@ -290,7 +290,7 @@ def add_sharding_to_shared_config(
shared_config.setdefault("media_instance_running_background_jobs", worker_name)


def generate_base_homeserver_config():
def generate_base_homeserver_config() -> None:
"""Starts Synapse and generates a basic homeserver config, which will later be
modified for worker support.

Expand All @@ -302,12 +302,14 @@ def generate_base_homeserver_config():
subprocess.check_output(["/usr/local/bin/python", "/start.py", "migrate_config"])


def generate_worker_files(environ, config_path: str, data_dir: str):
def generate_worker_files(
environ: Mapping[str, str], config_path: str, data_dir: str
) -> None:
"""Read the desired list of workers from environment variables and generate
shared homeserver, nginx and supervisord configs.

Args:
environ: _Environ[str]
environ: os.environ instance.
config_path: The location of the generated Synapse main worker config file.
data_dir: The location of the synapse data directory. Where log and
user-facing config files live.
Expand Down Expand Up @@ -369,13 +371,13 @@ def generate_worker_files(environ, config_path: str, data_dir: str):
nginx_locations = {}

# Read the desired worker configuration from the environment
worker_types = environ.get("SYNAPSE_WORKER_TYPES")
if worker_types is None:
worker_types_env = environ.get("SYNAPSE_WORKER_TYPES")
if worker_types_env is None:
# No workers, just the main process
worker_types = []
else:
# Split type names by comma
worker_types = worker_types.split(",")
worker_types = worker_types_env.split(",")

# Create the worker configuration directory if it doesn't already exist
os.makedirs("/conf/workers", exist_ok=True)
Expand Down Expand Up @@ -547,7 +549,7 @@ def generate_worker_log_config(
return log_config_filepath


def main(args, environ):
def main(args: List[str], environ: MutableMapping[str, str]) -> None:
squahtx marked this conversation as resolved.
Show resolved Hide resolved
config_dir = environ.get("SYNAPSE_CONFIG_DIR", "/data")
config_path = environ.get("SYNAPSE_CONFIG_PATH", config_dir + "/homeserver.yaml")
data_dir = environ.get("SYNAPSE_DATA_DIR", "/data")
Expand Down
42 changes: 24 additions & 18 deletions docker/start.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,28 @@
import platform
import subprocess
import sys
from typing import Any, Dict, List, Mapping, MutableMapping, NoReturn, Optional

import jinja2


# Utility functions
def log(txt):
def log(txt: str) -> None:
print(txt, file=sys.stderr)


def error(txt):
def error(txt: str) -> NoReturn:
log(txt)
sys.exit(2)


def convert(src, dst, environ):
def convert(src: str, dst: str, environ: Mapping[str, object]) -> None:
"""Generate a file from a template

Args:
src (str): path to input file
dst (str): path to file to write
environ (dict): environment dictionary, for replacement mappings.
src: path to input file
dst: path to file to write
environ: environment dictionary, for replacement mappings.
"""
with open(src) as infile:
template = infile.read()
Expand All @@ -35,25 +36,30 @@ def convert(src, dst, environ):
outfile.write(rendered)


def generate_config_from_template(config_dir, config_path, environ, ownership):
def generate_config_from_template(
config_dir: str,
config_path: str,
os_environ: Mapping[str, str],
ownership: Optional[str],
) -> None:
"""Generate a homeserver.yaml from environment variables

Args:
config_dir (str): where to put generated config files
config_path (str): where to put the main config file
environ (dict): environment dictionary
ownership (str|None): "<user>:<group>" string which will be used to set
config_dir: where to put generated config files
config_path: where to put the main config file
os_environ: environment mapping
ownership: "<user>:<group>" string which will be used to set
ownership of the generated configs. If None, ownership will not change.
"""
for v in ("SYNAPSE_SERVER_NAME", "SYNAPSE_REPORT_STATS"):
if v not in environ:
if v not in os_environ:
error(
"Environment variable '%s' is mandatory when generating a config file."
% (v,)
)

# populate some params from data files (if they exist, else create new ones)
environ = environ.copy()
environ: Dict[str, Any] = dict(os_environ)
secrets = {
"registration": "SYNAPSE_REGISTRATION_SHARED_SECRET",
"macaroon": "SYNAPSE_MACAROON_SECRET_KEY",
Expand Down Expand Up @@ -83,7 +89,7 @@ def generate_config_from_template(config_dir, config_path, environ, ownership):

# Convert SYNAPSE_NO_TLS to boolean if exists
if "SYNAPSE_NO_TLS" in environ:
tlsanswerstring = str.lower(environ["SYNAPSE_NO_TLS"])
tlsanswerstring = str.lower(environ["SYNAPSE_NO_TLS"]) # type
squahtx marked this conversation as resolved.
Show resolved Hide resolved
if tlsanswerstring in ("true", "on", "1", "yes"):
environ["SYNAPSE_NO_TLS"] = True
else:
Expand Down Expand Up @@ -127,12 +133,12 @@ def generate_config_from_template(config_dir, config_path, environ, ownership):
subprocess.check_output(args)


def run_generate_config(environ, ownership):
def run_generate_config(environ: Mapping[str, str], ownership: Optional[str]) -> None:
"""Run synapse with a --generate-config param to generate a template config file

Args:
environ (dict): env var dict
ownership (str|None): "userid:groupid" arg for chmod. If None, ownership will not change.
environ: env vars from `os.enrivon`.
ownership: "userid:groupid" arg for chmod. If None, ownership will not change.

Never returns.
"""
Expand Down Expand Up @@ -178,7 +184,7 @@ def run_generate_config(environ, ownership):
os.execv(sys.executable, args)


def main(args, environ):
def main(args: List[str], environ: MutableMapping[str, str]) -> None:
mode = args[1] if len(args) > 1 else "run"

# if we were given an explicit user to switch to, do so
Expand Down
2 changes: 1 addition & 1 deletion stubs/sortedcontainers/sorteddict.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ class SortedDict(Dict[_KT, _VT]):
self,
start: Optional[int] = ...,
stop: Optional[int] = ...,
reverse=bool,
reverse: bool = ...,
) -> Iterator[_KT]: ...
def bisect_left(self, value: _KT) -> int: ...
def bisect_right(self, value: _KT) -> int: ...
Expand Down
6 changes: 3 additions & 3 deletions stubs/sortedcontainers/sortedlist.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ class SortedList(MutableSequence[_T]):
self,
start: Optional[int] = ...,
stop: Optional[int] = ...,
reverse=bool,
reverse: bool = ...,
) -> Iterator[_T]: ...
def _islice(
self,
Expand Down Expand Up @@ -153,14 +153,14 @@ class SortedKeyList(SortedList[_T]):
maximum: Optional[int] = ...,
inclusive: Tuple[bool, bool] = ...,
reverse: bool = ...,
): ...
) -> Iterator[_T]: ...
def irange_key(
self,
min_key: Optional[Any] = ...,
max_key: Optional[Any] = ...,
inclusive: Tuple[bool, bool] = ...,
reserve: bool = ...,
): ...
) -> Iterator[_T]: ...
def bisect_left(self, value: _T) -> int: ...
def bisect_right(self, value: _T) -> int: ...
def bisect(self, value: _T) -> int: ...
Expand Down
2 changes: 1 addition & 1 deletion stubs/sortedcontainers/sortedset.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ class SortedSet(MutableSet[_T], Sequence[_T]):
self,
start: Optional[int] = ...,
stop: Optional[int] = ...,
reverse=bool,
reverse: bool = ...,
) -> Iterator[_T]: ...
def irange(
self,
Expand Down
12 changes: 7 additions & 5 deletions stubs/txredisapi.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ from typing import Any, List, Optional, Type, Union

from twisted.internet import protocol
from twisted.internet.defer import Deferred
from twisted.internet.interfaces import IAddress
from twisted.python.failure import Failure

class RedisProtocol(protocol.Protocol):
def publish(self, channel: str, message: bytes) -> "Deferred[None]": ...
Expand All @@ -34,11 +36,11 @@ class RedisProtocol(protocol.Protocol):
def get(self, key: str) -> "Deferred[Any]": ...

class SubscriberProtocol(RedisProtocol):
def __init__(self, *args, **kwargs): ...
def __init__(self, *args: object, **kwargs: object): ...
password: Optional[str]
def subscribe(self, channels: Union[str, List[str]]): ...
def connectionMade(self): ...
def connectionLost(self, reason): ...
def subscribe(self, channels: Union[str, List[str]]) -> "Deferred[None]": ...
def connectionMade(self) -> None: ...
def connectionLost(self, reason: Failure = ...) -> None: ...
squahtx marked this conversation as resolved.
Show resolved Hide resolved

def lazyConnection(
host: str = ...,
Expand Down Expand Up @@ -74,7 +76,7 @@ class RedisFactory(protocol.ReconnectingClientFactory):
replyTimeout: Optional[int] = None,
convertNumbers: Optional[int] = True,
): ...
def buildProtocol(self, addr) -> RedisProtocol: ...
def buildProtocol(self, addr: IAddress) -> RedisProtocol: ...

class SubscriberFactory(RedisFactory):
def __init__(self) -> None: ...