Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mypy --strict for sydent.http.matrixfederationagent #444

Merged
merged 21 commits into from
Oct 28, 2021
Merged
Show file tree
Hide file tree
Changes from all 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/444.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Get `sydent.http.matrixfederationagent` to pass `mypy --strict`.
11 changes: 3 additions & 8 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -49,16 +49,11 @@ strict = true
files = [
# Find files that pass with
# find sydent tests -type d -not -name __pycache__ -exec bash -c "mypy --strict '{}' > /dev/null" \; -print
# TODO "sydent/*.py"
"sydent/config",
"sydent/db",
"sydent/http/auth.py",
"sydent/http/blacklisting_reactor.py",
"sydent/http/federation_tls_options.py",
"sydent/http/httpclient.py",
"sydent/http/httpcommon.py",
"sydent/http/httpsclient.py",
"sydent/http/httpserver.py",
"sydent/http/srvresolver.py",
"sydent/http/*.py",
# TODO "sydent/http/servlets",
"sydent/hs_federation",
"sydent/replication",
"sydent/sms",
Expand Down
32 changes: 32 additions & 0 deletions stubs/twisted/internet/endpoints.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
from typing import Any, AnyStr, Optional

from twisted.internet import interfaces
from twisted.internet.defer import Deferred
from twisted.internet.interfaces import (
IOpenSSLClientConnectionCreator,
IProtocol,
IProtocolFactory,
IStreamClientEndpoint,
)
from zope.interface import implementer

@implementer(interfaces.IStreamClientEndpoint)
class HostnameEndpoint:
# Reactor should be a "provider of L{IReactorTCP}, L{IReactorTime} and
# either L{IReactorPluggableNameResolver} or L{IReactorPluggableResolver}."
# I don't know how to encode that in the type system.
Comment on lines +15 to +17
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sounds 'impossible' as you'd probably want to be able to specify multiple bounds which I can't see how to do

def __init__(
self,
reactor: object,
host: AnyStr,
port: int,
timeout: float = 30,
bindAddress: Optional[bytes] = None,
attemptDelay: Optional[float] = None,
): ...
def connect(self, protocol_factory: IProtocolFactory) -> Deferred[IProtocol]: ...

def wrapClientTLS(
connectionCreator: IOpenSSLClientConnectionCreator,
wrappedEndpoint: IStreamClientEndpoint,
) -> IStreamClientEndpoint: ...
2 changes: 1 addition & 1 deletion stubs/twisted/python/log.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ from twisted.python.failure import Failure
def err(
_stuff: Union[None, Exception, Failure] = None,
_why: Optional[str] = None,
**kw: Any,
**kw: object,
) -> None: ...
46 changes: 38 additions & 8 deletions stubs/twisted/web/client.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,13 @@ from twisted.internet.interfaces import (
)
from twisted.internet.task import Cooperator
from twisted.web.http_headers import Headers
from twisted.web.iweb import IAgent, IBodyProducer, IPolicyForHTTPS, IResponse
from twisted.web.iweb import (
IAgent,
IAgentEndpointFactory,
IBodyProducer,
IPolicyForHTTPS,
IResponse,
)
from zope.interface import implementer

C = TypeVar("C")
Expand All @@ -20,13 +26,23 @@ class BrowserLikePolicyForHTTPS:
self, hostname: bytes, port: int
) -> IOpenSSLClientConnectionCreator: ...

class HTTPConnectionPool: ...
class HTTPConnectionPool:
persistent: bool
maxPersistentPerHost: int
cachedConnectionTimeout: float
retryAutomatically: bool
def __init__(self, reactor: object, persistent: bool = True): ...

@implementer(IAgent)
class Agent:
# Here and in `usingEndpointFactory`, reactor should be a "provider of
# L{IReactorTCP}, L{IReactorTime} and either
# L{IReactorPluggableNameResolver} or L{IReactorPluggableResolver}."
# I don't know how to encode that in the type system; see also
# https://github.com/Shoobx/mypy-zope/issues/58
def __init__(
self,
reactor: Any,
reactor: object,
contextFactory: IPolicyForHTTPS = BrowserLikePolicyForHTTPS(),
connectTimeout: Optional[float] = None,
bindAddress: Optional[bytes] = None,
Expand All @@ -39,17 +55,20 @@ class Agent:
headers: Optional[Headers] = None,
bodyProducer: Optional[IBodyProducer] = None,
) -> Deferred[IResponse]: ...
@classmethod
def usingEndpointFactory(
cls: Type[C],
reactor: object,
endpointFactory: IAgentEndpointFactory,
pool: Optional[HTTPConnectionPool] = None,
) -> C: ...

@implementer(IBodyProducer)
class FileBodyProducer:
def __init__(
self,
inputFile: BinaryIO,
# Type safety: twisted.internet.task.cooperate is a function with the
# same signature as Cooperator.cooperate. (It just wraps a module-level
# global cooperator.) But there's no easy way to annotate "either this
# type or a specific module".
cooperator: Cooperator = twisted.internet.task, # type: ignore[assignment]
cooperator: Cooperator = ...,
readSize: int = 2 ** 16,
): ...
# Length is either `int` or the opaque object UNKNOWN_LENGTH.
Expand Down Expand Up @@ -95,3 +114,14 @@ class URI:
): ...
@classmethod
def fromBytes(cls: Type[C], uri: bytes, defaultPort: Optional[int] = None) -> C: ...

@implementer(IAgent)
class RedirectAgent:
def __init__(self, Agent: Agent, redirectLimit: int = 20): ...
def request(
self,
method: bytes,
uri: bytes,
headers: Optional[Headers] = None,
bodyProducer: Optional[IBodyProducer] = None,
) -> Deferred[IResponse]: ...
2 changes: 2 additions & 0 deletions stubs/twisted/web/http.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,5 @@ class Request:
class PotentialDataLoss(Exception): ...

CACHED: object

def stringToDatetime(dateString: bytes) -> int: ...
7 changes: 6 additions & 1 deletion sydent/http/httpclient.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,12 @@ class FederationHttpClient(HTTPClient[MatrixFederationAgent]):
def __init__(self, sydent: "Sydent") -> None:
self.sydent = sydent
self.agent = MatrixFederationAgent(
BlacklistingReactorWrapper(
# Type-safety: I don't have a good way of expressing that
# the reactor is IReactorTCP, IReactorTime and
# IReactorPluggableNameResolver all at once. But it is, because
# it wraps the sydent reactor.
# TODO: can we introduce a SydentReactor type like SynapseReactor?
BlacklistingReactorWrapper( # type: ignore[arg-type]
reactor=self.sydent.reactor,
ip_whitelist=sydent.config.general.ip_whitelist,
ip_blacklist=sydent.config.general.ip_blacklist,
Expand Down
Loading