From 8bcbdecc3ae18a9d10638d1c7ef78df0ed131add Mon Sep 17 00:00:00 2001 From: starlet-dx <15929766099@163.com> Date: Wed, 29 May 2024 09:44:10 +0800 Subject: [PATCH] Update to 1.4.6 for fix CVE-2024-34083 (cherry picked from commit 2a06f343f6aacff94c24b399d86fca5d309af438) --- ...-Implement-Unthreaded-Controller-256.patch | 2009 ------------ 0002-Code-Hygiene-259.patch | 2725 ----------------- 0003-URGENT-Fix-RTD-docs-gen.patch | 24 - 0004-Make-Sphinx-RTD-deps-SSOT.patch | 120 - 1.4.2.tar.gz | Bin 139929 -> 0 bytes 284.patch | 46 - CVE-2024-27305.patch | 160 - aiosmtpd-1.4.6.tar.gz | Bin 0 -> 152775 bytes python-aiosmtpd.spec | 16 +- 9 files changed, 7 insertions(+), 5093 deletions(-) delete mode 100644 0001-Implement-Unthreaded-Controller-256.patch delete mode 100644 0002-Code-Hygiene-259.patch delete mode 100644 0003-URGENT-Fix-RTD-docs-gen.patch delete mode 100644 0004-Make-Sphinx-RTD-deps-SSOT.patch delete mode 100644 1.4.2.tar.gz delete mode 100644 284.patch delete mode 100644 CVE-2024-27305.patch create mode 100644 aiosmtpd-1.4.6.tar.gz diff --git a/0001-Implement-Unthreaded-Controller-256.patch b/0001-Implement-Unthreaded-Controller-256.patch deleted file mode 100644 index f3dc2b0..0000000 --- a/0001-Implement-Unthreaded-Controller-256.patch +++ /dev/null @@ -1,2009 +0,0 @@ -From 747a7c467d45354d8d1ea72bc9d2fce15e186479 Mon Sep 17 00:00:00 2001 -From: Pandu E POLUAN -Date: Tue, 9 Mar 2021 00:25:48 +0700 -Subject: [PATCH 1/4] Implement Unthreaded Controller (#256) - -* Complete rewrite of aiosmtpd.controller -* Implement Unthreaded Controllers -* Implement tests of Unthreaded Controllers -* Improve other tests -* Improve coverage by replacing nocover's with conditional pragmas -* Suppress exception ignored during __del__ -* Blackification -* Update badges -* Tidy up table + link to Public PGP on GH -* Bump version to 1.5.0a1 and update NEWS.rst ---- - DESCRIPTION.rst | 45 ++- - README.rst | 24 +- - aiosmtpd/__init__.py | 2 +- - aiosmtpd/controller.py | 296 ++++++++++++---- - aiosmtpd/docs/NEWS.rst | 12 + - aiosmtpd/docs/controller.rst | 642 +++++++++++++++++++++++----------- - aiosmtpd/docs/smtp.rst | 10 +- - aiosmtpd/handlers.py | 11 +- - aiosmtpd/proxy_protocol.py | 2 +- - aiosmtpd/tests/conftest.py | 15 + - aiosmtpd/tests/test_main.py | 27 +- - aiosmtpd/tests/test_server.py | 248 ++++++++++--- - pyproject.toml | 6 +- - 13 files changed, 958 insertions(+), 382 deletions(-) - -diff --git a/DESCRIPTION.rst b/DESCRIPTION.rst -index 9ec007b..caa9e7a 100644 ---- a/DESCRIPTION.rst -+++ b/DESCRIPTION.rst -@@ -2,16 +2,22 @@ - aiosmtpd - asyncio based SMTP server - ###################################### - --| |github license| |_| |PyPI Version| |PyPI Python| --| |GA badge| |codecov| |_| |LGTM.com| |readthedocs| |_| --| |GH Release| |_| |PullRequests| |_| |LastCommit| -+| |github license| |_| |PyPI Version| |_| |PyPI Python| -+| |GA badge| |_| |codecov| |_| |LGTM.com| |_| |readthedocs| -+| |GH Release| |_| |GH PRs| |_| |GH LastCommit| - | - - .. |_| unicode:: 0xA0 - :trim: --.. |github license| image:: https://img.shields.io/github/license/aio-libs/aiosmtpd -+.. |github license| image:: https://img.shields.io/github/license/aio-libs/aiosmtpd?logo=Open+Source+Initiative&logoColor=0F0 - :target: https://github.com/aio-libs/aiosmtpd/blob/master/LICENSE - :alt: Project License on GitHub -+.. |PyPI Version| image:: https://img.shields.io/pypi/v/aiosmtpd?logo=pypi&logoColor=yellow -+ :target: https://pypi.org/project/aiosmtpd/ -+ :alt: PyPI Package -+.. |PyPI Python| image:: https://img.shields.io/pypi/pyversions/aiosmtpd?logo=python&logoColor=yellow -+ :target: https://pypi.org/project/aiosmtpd/ -+ :alt: Supported Python Versions - .. .. For |GA badge|, don't forget to check actual workflow name in unit-testing-and-coverage.yml - .. |GA badge| image:: https://github.com/aio-libs/aiosmtpd/workflows/aiosmtpd%20CI/badge.svg - :target: https://github.com/aio-libs/aiosmtpd/actions -@@ -25,21 +31,15 @@ - .. |readthedocs| image:: https://img.shields.io/readthedocs/aiosmtpd?logo=Read+the+Docs - :target: https://aiosmtpd.readthedocs.io/en/latest/?badge=latest - :alt: Documentation Status --.. |PyPI Version| image:: https://badge.fury.io/py/aiosmtpd.svg -- :target: https://badge.fury.io/py/aiosmtpd -- :alt: PyPI Package --.. |PyPI Python| image:: https://img.shields.io/pypi/pyversions/aiosmtpd.svg -- :target: https://pypi.org/project/aiosmtpd/ -- :alt: Supported Python Versions - .. .. Do NOT include the Discourse badge! - .. .. Below are badges just for PyPI - .. |GH Release| image:: https://img.shields.io/github/v/release/aio-libs/aiosmtpd?logo=github - :target: https://github.com/aio-libs/aiosmtpd/releases - :alt: GitHub latest release --.. |PullRequests| image:: https://img.shields.io/github/issues-pr/aio-libs/aiosmtpd?logo=GitHub -+.. |GH PRs| image:: https://img.shields.io/github/issues-pr/aio-libs/aiosmtpd?logo=GitHub - :target: https://github.com/aio-libs/aiosmtpd/pulls - :alt: GitHub pull requests --.. |LastCommit| image:: https://img.shields.io/github/last-commit/aio-libs/aiosmtpd?logo=GitHub -+.. |GH LastCommit| image:: https://img.shields.io/github/last-commit/aio-libs/aiosmtpd?logo=GitHub - :target: https://github.com/aio-libs/aiosmtpd/commits/master - :alt: GitHub last commit - -@@ -61,10 +61,19 @@ Starting version 1.3.1, - files provided through PyPI or `GitHub Releases`_ - will be signed using one of the following GPG Keys: - --+-------------------------+----------------+------------------------------+ --| GPG Key ID | Owner | Email | --+=========================+================+==============================+ --| ``5D60 CE28 9CD7 C258`` | Pandu E POLUAN | pepoluan at gmail period com | --+-------------------------+----------------+------------------------------+ -- - .. _`GitHub Releases`: https://github.com/aio-libs/aiosmtpd/releases -+ -+.. .. In the second column of the table, prefix each line with "| " -+ .. In the third column, refrain from putting in a direct link to keep the table tidy. -+ Rather, use the |...|_ construct and do the replacement+linking directive below the table -+ -++-------------------------+--------------------------------+-----------+ -+| GPG Key ID | Owner / Email | Key | -++=========================+================================+===========+ -+| ``5D60 CE28 9CD7 C258`` | | Pandu POLUAN / | |pep_gh|_ | -+| | | pepoluan at gmail period com | | -++-------------------------+--------------------------------+-----------+ -+ -+.. .. The |_| contruct is U+00A0 (non-breaking space), defined at the start of the file -+.. |pep_gh| replace:: On |_| GitHub -+.. _`pep_gh`: https://github.com/pepoluan.gpg -diff --git a/README.rst b/README.rst -index 35dcb88..2c1bab7 100644 ---- a/README.rst -+++ b/README.rst -@@ -2,14 +2,22 @@ - aiosmtpd - An asyncio based SMTP server - ========================================= - --| |github license| |PyPI| |PyPI Python| --| |GA badge| |codecov| |LGTM.com| |readthedocs| -+| |github license| |_| |PyPI Version| |_| |PyPI Python| -+| |GA badge| |_| |codecov| |_| |LGTM.com| |_| |readthedocs| - | - | |Discourse| - --.. |github license| image:: https://img.shields.io/github/license/aio-libs/aiosmtpd -+.. |_| unicode:: 0xA0 -+ :trim: -+.. |github license| image:: https://img.shields.io/github/license/aio-libs/aiosmtpd?logo=Open+Source+Initiative&logoColor=0F0 - :target: https://github.com/aio-libs/aiosmtpd/blob/master/LICENSE - :alt: Project License on GitHub -+.. |PyPI Version| image:: https://img.shields.io/pypi/v/aiosmtpd?logo=pypi&logoColor=yellow -+ :target: https://pypi.org/project/aiosmtpd/ -+ :alt: PyPI Package -+.. |PyPI Python| image:: https://img.shields.io/pypi/pyversions/aiosmtpd?logo=python&logoColor=yellow -+ :target: https://pypi.org/project/aiosmtpd/ -+ :alt: Supported Python Versions - .. .. For |GA badge|, don't forget to check actual workflow name in unit-testing-and-coverage.yml - .. |GA badge| image:: https://github.com/aio-libs/aiosmtpd/workflows/aiosmtpd%20CI/badge.svg - :target: https://github.com/aio-libs/aiosmtpd/actions -@@ -20,15 +28,9 @@ - .. |LGTM.com| image:: https://img.shields.io/lgtm/grade/python/github/aio-libs/aiosmtpd.svg?logo=lgtm&logoWidth=18 - :target: https://lgtm.com/projects/g/aio-libs/aiosmtpd/context:python - :alt: Semmle/LGTM.com quality --.. |readthedocs| image:: https://readthedocs.org/projects/aiosmtpd/badge/?version=latest -- :target: https://aiosmtpd.readthedocs.io/en/latest/?badge=latest -+.. |readthedocs| image:: https://img.shields.io/readthedocs/aiosmtpd?logo=Read+the+Docs&logoColor=white -+ :target: https://aiosmtpd.readthedocs.io/en/latest/ - :alt: Documentation Status --.. |PyPI| image:: https://badge.fury.io/py/aiosmtpd.svg -- :target: https://badge.fury.io/py/aiosmtpd -- :alt: PyPI Package --.. |PyPI Python| image:: https://img.shields.io/pypi/pyversions/aiosmtpd.svg -- :target: https://pypi.org/project/aiosmtpd/ -- :alt: Supported Python Versions - .. .. If you edit the above badges, don't forget to edit setup.cfg - .. .. The |Discourse| badge MUST NOT be included in setup.cfg - .. |Discourse| image:: https://img.shields.io/discourse/status?server=https%3A%2F%2Faio-libs.discourse.group%2F&style=social -diff --git a/aiosmtpd/controller.py b/aiosmtpd/controller.py -index 2258c54..d3345b8 100644 ---- a/aiosmtpd/controller.py -+++ b/aiosmtpd/controller.py -@@ -5,6 +5,7 @@ import asyncio - import errno - import os - import ssl -+import sys - import threading - import time - from abc import ABCMeta, abstractmethod -@@ -19,6 +20,11 @@ try: - except ImportError: # pragma: on-not-win32 - AF_UNIX = None - from typing import Any, Coroutine, Dict, Optional, Union -+ -+if sys.version_info >= (3, 8): -+ from typing import Literal # pragma: py-lt-38 -+else: # pragma: py-ge-38 -+ from typing_extensions import Literal - from warnings import warn - - from public import public -@@ -38,13 +44,14 @@ class IP6_IS: - YES = {errno.EADDRINUSE} - - --def _has_ipv6(): -+def _has_ipv6() -> bool: - # Helper function to assist in mocking - return has_ipv6 - - - @public --def get_localhost() -> str: -+def get_localhost() -> Literal["::1", "127.0.0.1"]: -+ """Returns numeric address to localhost depending on IPv6 availability""" - # Ref: - # - https://github.com/urllib3/urllib3/pull/611#issuecomment-100954017 - # - https://github.com/python/cpython/blob/ : -@@ -91,24 +98,17 @@ class _FakeServer(asyncio.StreamReaderProtocol): - - - @public --class BaseThreadedController(metaclass=ABCMeta): -- """ -- `Documentation can be found here -- `_. -- """ -+class BaseController(metaclass=ABCMeta): -+ smtpd = None - server: Optional[AsyncServer] = None - server_coro: Optional[Coroutine] = None -- smtpd = None -- _factory_invoked: Optional[threading.Event] = None -- _thread: Optional[threading.Thread] = None -- _thread_exception: Optional[Exception] = None -+ _factory_invoked: threading.Event = None - - def __init__( - self, -- handler, -- loop=None, -+ handler: Any, -+ loop: asyncio.AbstractEventLoop = None, - *, -- ready_timeout: float, - ssl_context: Optional[ssl.SSLContext] = None, - # SMTP parameters - server_hostname: Optional[str] = None, -@@ -119,9 +119,6 @@ class BaseThreadedController(metaclass=ABCMeta): - self.loop = asyncio.new_event_loop() - else: - self.loop = loop -- self.ready_timeout = float( -- os.getenv("AIOSMTPD_CONTROLLER_TIMEOUT", ready_timeout) -- ) - self.ssl_context = ssl_context - self.SMTP_kwargs: Dict[str, Any] = {} - if "server_kwargs" in SMTP_parameters: -@@ -139,9 +136,11 @@ class BaseThreadedController(metaclass=ABCMeta): - # It actually conflicts with SMTP class's default, but the reasoning is - # discussed in the docs. - self.SMTP_kwargs.setdefault("enable_SMTPUTF8", True) -+ # -+ self._factory_invoked = threading.Event() - - def factory(self): -- """Allow subclasses to customize the handler/server creation.""" -+ """Subclasses can override this to customize the handler/server creation.""" - return SMTP(self.handler, **self.SMTP_kwargs) - - def _factory_invoker(self): -@@ -159,13 +158,72 @@ class BaseThreadedController(metaclass=ABCMeta): - - @abstractmethod - def _create_server(self) -> Coroutine: -- raise NotImplementedError # pragma: nocover -+ """ -+ Overridden by subclasses to actually perform the async binding to the -+ listener endpoint. When overridden, MUST refer the _factory_invoker() method. -+ """ -+ raise NotImplementedError -+ -+ def _cleanup(self): -+ """Reset internal variables to prevent contamination""" -+ self._thread_exception = None -+ self._factory_invoked.clear() -+ self.server_coro = None -+ self.server = None -+ self.smtpd = None -+ -+ def cancel_tasks(self, stop_loop: bool = True): -+ """ -+ Convenience method to stop the loop and cancel all tasks. -+ Use loop.call_soon_threadsafe() to invoke this. -+ """ -+ if stop_loop: # pragma: nobranch -+ self.loop.stop() -+ try: -+ _all_tasks = asyncio.all_tasks # pytype: disable=module-attr -+ except AttributeError: # pragma: py-gt-36 -+ _all_tasks = asyncio.Task.all_tasks -+ for task in _all_tasks(self.loop): -+ # This needs to be invoked in a thread-safe way -+ task.cancel() -+ -+ -+@public -+class BaseThreadedController(BaseController, metaclass=ABCMeta): -+ _thread: Optional[threading.Thread] = None -+ _thread_exception: Optional[Exception] = None -+ -+ def __init__( -+ self, -+ handler: Any, -+ loop: asyncio.AbstractEventLoop = None, -+ *, -+ ready_timeout: float = DEFAULT_READY_TIMEOUT, -+ ssl_context: Optional[ssl.SSLContext] = None, -+ # SMTP parameters -+ server_hostname: Optional[str] = None, -+ **SMTP_parameters, -+ ): -+ super().__init__( -+ handler, -+ loop, -+ ssl_context=ssl_context, -+ server_hostname=server_hostname, -+ **SMTP_parameters, -+ ) -+ self.ready_timeout = float( -+ os.getenv("AIOSMTPD_CONTROLLER_TIMEOUT", ready_timeout) -+ ) - - @abstractmethod - def _trigger_server(self): -- raise NotImplementedError # pragma: nocover -+ """ -+ Overridden by subclasses to trigger asyncio to actually initialize the SMTP -+ class (it's lazy initialization, done only on initial connection). -+ """ -+ raise NotImplementedError - -- def _run(self, ready_event): -+ def _run(self, ready_event: threading.Event): - asyncio.set_event_loop(self.loop) - try: - # Need to do two-step assignments here to ensure IDEs can properly -@@ -187,14 +245,19 @@ class BaseThreadedController(metaclass=ABCMeta): - return - self.loop.call_soon(ready_event.set) - self.loop.run_forever() -+ # We reach this point when loop is ended (by external code) -+ # Perform some stoppages to ensure endpoint no longer bound. - self.server.close() - self.loop.run_until_complete(self.server.wait_closed()) - self.loop.close() - self.server = None - - def start(self): -+ """ -+ Start a thread and run the asyncio event loop in that thread -+ """ - assert self._thread is None, "SMTP daemon already running" -- self._factory_invoked = threading.Event() -+ self._factory_invoked.clear() - - ready_event = threading.Event() - self._thread = threading.Thread(target=self._run, args=(ready_event,)) -@@ -240,43 +303,26 @@ class BaseThreadedController(metaclass=ABCMeta): - if self.smtpd is None: - raise RuntimeError("Unknown Error, failed to init SMTP server") - -- def _stop(self): -- self.loop.stop() -- try: -- _all_tasks = asyncio.all_tasks # pytype: disable=module-attr -- except AttributeError: # pragma: py-gt-36 -- _all_tasks = asyncio.Task.all_tasks -- for task in _all_tasks(self.loop): -- task.cancel() -- -- def stop(self, no_assert=False): -+ def stop(self, no_assert: bool = False): -+ """ -+ Stop the loop, the tasks in the loop, and terminate the thread as well. -+ """ - assert no_assert or self._thread is not None, "SMTP daemon not running" -- self.loop.call_soon_threadsafe(self._stop) -+ self.loop.call_soon_threadsafe(self.cancel_tasks) - if self._thread is not None: - self._thread.join() - self._thread = None -- self._thread_exception = None -- self._factory_invoked = None -- self.server_coro = None -- self.server = None -- self.smtpd = None -+ self._cleanup() - - - @public --class Controller(BaseThreadedController): -- """ -- `Documentation can be found here -- `_. -- """ -+class BaseUnthreadedController(BaseController, metaclass=ABCMeta): - def __init__( - self, -- handler, -- hostname: Optional[str] = None, -- port: int = 8025, -- loop=None, -+ handler: Any, -+ loop: asyncio.AbstractEventLoop = None, - *, -- ready_timeout: float = DEFAULT_READY_TIMEOUT, -- ssl_context: ssl.SSLContext = None, -+ ssl_context: Optional[ssl.SSLContext] = None, - # SMTP parameters - server_hostname: Optional[str] = None, - **SMTP_parameters, -@@ -284,15 +330,80 @@ class Controller(BaseThreadedController): - super().__init__( - handler, - loop, -- ready_timeout=ready_timeout, -+ ssl_context=ssl_context, - server_hostname=server_hostname, -- **SMTP_parameters -+ **SMTP_parameters, - ) -- self.hostname = get_localhost() if hostname is None else hostname -+ self.ended = threading.Event() -+ -+ def begin(self): -+ """ -+ Sets up the asyncio server task and inject it into the asyncio event loop. -+ Does NOT actually start the event loop itself. -+ """ -+ asyncio.set_event_loop(self.loop) -+ # Need to do two-step assignments here to ensure IDEs can properly -+ # detect the types of the vars. Cannot use `assert isinstance`, because -+ # Python 3.6 in asyncio debug mode has a bug wherein CoroWrapper is not -+ # an instance of Coroutine -+ self.server_coro = self._create_server() -+ srv: AsyncServer = self.loop.run_until_complete(self.server_coro) -+ self.server = srv -+ -+ async def finalize(self): -+ """ -+ Perform orderly closing of the server listener. -+ NOTE: This is an async method; await this from an async or use -+ loop.create_task() (if loop is still running), or -+ loop.run_until_complete() (if loop has stopped) -+ """ -+ self.ended.clear() -+ server = self.server -+ server.close() -+ await server.wait_closed() -+ self.server_coro.close() -+ self._cleanup() -+ self.ended.set() -+ -+ def end(self): -+ """ -+ Convenience method to asynchronously invoke finalize(). -+ Consider using loop.call_soon_threadsafe to invoke this method, especially -+ if your loop is running in a different thread. You can afterwards .wait() on -+ ended attribute (a threading.Event) to check for completion, if needed. -+ """ -+ self.ended.clear() -+ if self.loop.is_running(): -+ self.loop.create_task(self.finalize()) -+ else: -+ self.loop.run_until_complete(self.finalize()) -+ -+ -+@public -+class InetMixin(BaseController, metaclass=ABCMeta): -+ def __init__( -+ self, -+ handler: Any, -+ hostname: Optional[str] = None, -+ port: int = 8025, -+ loop: asyncio.AbstractEventLoop = None, -+ **kwargs, -+ ): -+ super().__init__( -+ handler, -+ loop, -+ **kwargs, -+ ) -+ self._localhost = get_localhost() -+ self.hostname = self._localhost if hostname is None else hostname - self.port = port -- self.ssl_context = ssl_context - - def _create_server(self) -> Coroutine: -+ """ -+ Creates a 'server task' that listens on an INET host:port. -+ Does NOT actually start the protocol object itself; -+ _factory_invoker() is only called upon fist connection attempt. -+ """ - return self.loop.create_server( - self._factory_invoker, - host=self.hostname, -@@ -308,42 +419,36 @@ class Controller(BaseThreadedController): - """ - # At this point, if self.hostname is Falsy, it most likely is "" (bind to all - # addresses). In such case, it should be safe to connect to localhost) -- hostname = self.hostname or get_localhost() -+ hostname = self.hostname or self._localhost - with ExitStack() as stk: - s = stk.enter_context(create_connection((hostname, self.port), 1.0)) - if self.ssl_context: - s = stk.enter_context(self.ssl_context.wrap_socket(s)) -- _ = s.recv(1024) -+ s.recv(1024) - - --class UnixSocketController(BaseThreadedController): # pragma: on-win32 on-cygwin -- """ -- `Documentation can be found here -- `_. -- """ -+@public -+class UnixSocketMixin(BaseController, metaclass=ABCMeta): # pragma: no-unixsock - def __init__( - self, -- handler, -- unix_socket: Optional[Union[str, Path]], -- loop=None, -- *, -- ready_timeout: float = DEFAULT_READY_TIMEOUT, -- ssl_context: ssl.SSLContext = None, -- # SMTP parameters -- server_hostname: str = None, -- **SMTP_parameters, -+ handler: Any, -+ unix_socket: Union[str, Path], -+ loop: asyncio.AbstractEventLoop = None, -+ **kwargs, - ): - super().__init__( - handler, - loop, -- ready_timeout=ready_timeout, -- ssl_context=ssl_context, -- server_hostname=server_hostname, -- **SMTP_parameters -+ **kwargs, - ) - self.unix_socket = str(unix_socket) - - def _create_server(self) -> Coroutine: -+ """ -+ Creates a 'server task' that listens on a Unix Socket file. -+ Does NOT actually start the protocol object itself; -+ _factory_invoker() is only called upon fist connection attempt. -+ """ - return self.loop.create_unix_server( - self._factory_invoker, - path=self.unix_socket, -@@ -351,9 +456,52 @@ class UnixSocketController(BaseThreadedController): # pragma: on-win32 on-cygwi - ) - - def _trigger_server(self): -+ """ -+ Opens a socket connection to the newly launched server, wrapping in an SSL -+ Context if necessary, and read some data from it to ensure that factory() -+ gets invoked. -+ """ - with ExitStack() as stk: - s: makesock = stk.enter_context(makesock(AF_UNIX, SOCK_STREAM)) - s.connect(self.unix_socket) - if self.ssl_context: - s = stk.enter_context(self.ssl_context.wrap_socket(s)) -- _ = s.recv(1024) -+ s.recv(1024) -+ -+ -+@public -+class Controller(InetMixin, BaseThreadedController): -+ """Provides a multithreaded controller that listens on an INET endpoint""" -+ -+ def _trigger_server(self): -+ # Prevent confusion on which _trigger_server() to invoke. -+ # Or so LGTM.com claimed -+ InetMixin._trigger_server(self) -+ -+ -+@public -+class UnixSocketController( # pragma: no-unixsock -+ UnixSocketMixin, BaseThreadedController -+): -+ """Provides a multithreaded controller that listens on a Unix Socket file""" -+ -+ def _trigger_server(self): # pragma: no-unixsock -+ # Prevent confusion on which _trigger_server() to invoke. -+ # Or so LGTM.com claimed -+ UnixSocketMixin._trigger_server(self) -+ -+ -+@public -+class UnthreadedController(InetMixin, BaseUnthreadedController): -+ """Provides an unthreaded controller that listens on an INET endpoint""" -+ -+ pass -+ -+ -+@public -+class UnixSocketUnthreadedController( # pragma: no-unixsock -+ UnixSocketMixin, BaseUnthreadedController -+): -+ """Provides an unthreaded controller that listens on a Unix Socket file""" -+ -+ pass -diff --git a/aiosmtpd/docs/NEWS.rst b/aiosmtpd/docs/NEWS.rst -index fb32de4..ce627a7 100644 ---- a/aiosmtpd/docs/NEWS.rst -+++ b/aiosmtpd/docs/NEWS.rst -@@ -3,6 +3,18 @@ - ################### - - -+1.5.0 (aiosmtpd-next-next) -+========================== -+ -+Added -+----- -+* Unthreaded Controllers (Closes #160) -+ -+Fixed/Improved -+-------------- -+* All Controllers now have more rationale design, as they are now composited from a Base + a Mixin -+ -+ - 1.4.2 (2021-03-08) - ===================== - -diff --git a/aiosmtpd/docs/controller.rst b/aiosmtpd/docs/controller.rst -index d3e08ed..e43720b 100644 ---- a/aiosmtpd/docs/controller.rst -+++ b/aiosmtpd/docs/controller.rst -@@ -5,15 +5,15 @@ - ==================== - - If you already have an `asyncio event loop`_, you can `create a server`_ using --the ``SMTP`` class as the *protocol factory*, and then run the loop forever. -+the :class:`~aiosmtpd.smtp.SMTP` class as the *protocol factory*, and then run the loop forever. - If you need to pass arguments to the ``SMTP`` constructor, use - :func:`functools.partial` or write your own wrapper function. You might also - want to add a signal handler so that the loop can be stopped, say when you hit - control-C. - --It's probably easier to use a *controller* which runs the SMTP server in a -+It's probably easier to use a *threaded controller* which runs the SMTP server in a - separate thread with a dedicated event loop. The controller provides useful --and reliable *start* and *stop* semantics so that the foreground thread -+and reliable ``start`` and ``stop`` semantics so that the foreground thread - doesn't block. Among other use cases, this makes it convenient to spin up an - SMTP server for unit tests. - -@@ -30,7 +30,7 @@ Using the controller - TCP-based Server - ---------------- - --The :class:`Controller` class creates a TCP-based server, -+The :class:`~aiosmtpd.controller.Controller` class creates a TCP-based server, - listening on an Internet endpoint (i.e., ``ip_address:port`` pair). - - Say you want to receive email for ``example.com`` and print incoming mail data -@@ -100,11 +100,11 @@ Connect to the server and send a message, which then gets printed by - End of message - - You'll notice that at the end of the ``DATA`` command, your handler's --``handle_DATA()`` method was called. The sender, recipients, and message -+:meth:`handle_DATA` method was called. The sender, recipients, and message - contents were taken from the envelope, and printed at the console. The - handler methods also returns a successful status message. - --The ``ExampleHandler`` class also implements a ``handle_RCPT()`` method. This -+The ``ExampleHandler`` class also implements a :meth:`handle_RCPT` method. This - gets called after the ``RCPT TO`` command is sanity checked. The method - ensures that all recipients are local to the ``@example.com`` domain, - returning an error status if not. It is the handler's responsibility to add -@@ -148,10 +148,11 @@ use to do some common tasks, and it's easy to write your own handler. For a - full overview of the methods that handler classes may implement, see the - section on :ref:`handler hooks `. - -+ - Unix Socket-based Server - ------------------------ - --The :class:`UnixSocketController` class creates a server listening to -+The :class:`~aiosmtpd.controller.UnixSocketController` class creates a server listening to - a Unix Socket (i.e., a special file that can act as a 'pipe' for interprocess - communication). - -@@ -168,8 +169,13 @@ with some differences: - >>> controller = UnixSocketController(Sink(), unix_socket="smtp_socket~") - >>> controller.start() - -+.. warning:: -+ -+ Do not exceed the Operating System limit for the length of the socket file path. -+ On Linux, the limit is 108 characters. On BSD OSes, it's 104 characters. -+ - **Rather than connecting to IP:port, you connect to the Socket file.** --Python's :class:`smtplib.SMTP` sadly cannot connect to a Unix Socket, -+Python's :class:`smtplib.SMTP` class sadly cannot connect to a Unix Socket, - so we need to handle it on our own here: - - .. doctest:: unix_socket -@@ -178,9 +184,8 @@ so we need to handle it on our own here: - >>> import socket - >>> sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) - >>> sock.connect("smtp_socket~") -- >>> resp = sock.recv(1024) -- >>> resp[0:4] -- b'220 ' -+ >>> sock.recv(1024) -+ b'220 ...' - - Try sending something, don't forget to end with ``"\r\n"``: - -@@ -189,9 +194,8 @@ Try sending something, don't forget to end with ``"\r\n"``: - - >>> sock.send(b"HELO example.org\r\n") - 18 -- >>> resp = sock.recv(1024) -- >>> resp[0:4] -- b'250 ' -+ >>> sock.recv(1024) -+ b'250 ...' - - And close everything when done: - -@@ -200,13 +204,116 @@ And close everything when done: - - >>> sock.send(b"QUIT\r\n") - 6 -- >>> resp = sock.recv(1024) -- >>> resp[0:4] -- b'221 ' -+ >>> sock.recv(1024) -+ b'221 Bye...' - >>> sock.close() - >>> controller.stop() - - -+.. _unthreaded: -+ -+Unthreaded Controllers -+---------------------- -+ -+In addition to the **threaded** controllers described above, -+``aiosmtpd`` also provides the following **UNthreaded** controllers: -+ -+* :class:`UnthreadedController` -- the unthreaded version of :class:`Controller` -+* :class:`UnixSocketUnthreadedController` -- the unthreaded version of :class:`UnixSocketController` -+ -+These classes are considered *advanced* classes, -+because you'll have to manage the event loop yourself. -+ -+For example, to start an unthreaded controller, -+you'll have to do something similar to this: -+ -+.. doctest:: unthreaded -+ -+ >>> import asyncio -+ >>> loop = asyncio.get_event_loop() -+ >>> from aiosmtpd.controller import UnthreadedController -+ >>> from aiosmtpd.handlers import Sink -+ >>> controller = UnthreadedController(Sink(), loop=loop) -+ >>> controller.begin() -+ -+Note that unlike the threaded counterparts, -+the method used to start the controller is named ``begin()``. -+And unlike the method in the threaded version, -+``begin()`` does NOT start the asyncio event loop; -+you'll have to start it yourself. -+ -+For the purposes of trying this, -+let's create a thread and have it run the asyncio event loop; -+we'll also schedule an autostop so it won't hang: -+ -+.. doctest:: unthreaded -+ -+ >>> def runner(): -+ ... # Set the delay to something long enough so you have time -+ ... # to do some testing -+ ... loop.call_later(3.0, loop.stop) -+ ... loop.run_forever() -+ >>> import threading -+ >>> thread = threading.Thread(target=runner) -+ >>> thread.setDaemon(True) -+ >>> thread.start() -+ >>> import time -+ >>> time.sleep(0.1) # Allow the loop to begin -+ -+At this point in time, the server would be listening: -+ -+.. doctest:: unthreaded -+ -+ >>> from smtplib import SMTP as Client -+ >>> client = Client(controller.hostname, controller.port) -+ >>> client.helo("example.com") -+ (250, ...) -+ >>> client.quit() -+ (221, b'Bye') -+ -+The complex thing will be to end it; -+that is why we're marking these classes as "advanced". -+ -+For our example here, -+since we have created an "autostop loop", -+all we have to do is wait for the runner thread to end: -+ -+.. doctest:: unthreaded -+ -+ >>> thread.join() -+ >>> loop.is_running() -+ False -+ -+We still need to do some cleanup to fully release the bound port. -+Since the loop has ended, we can simply call the :meth:`end` method: -+ -+.. doctest:: unthreaded -+ -+ >>> controller.end() -+ -+If you want to end the controller *but* keep the loop running, -+you'll have to do it like this:: -+ -+ loop.call_soon_threadsafe(controller.end) -+ # If you want to ensure that controller has stopped, you can wait() here: -+ controller.ended.wait(10.0) # Optional -+ -+You must remember to cleanup the canceled tasks yourself. -+We have provided a convenience method, -+:meth:`~aiosmtpd.controller.BaseController.cancel_tasks`:: -+ -+ # Will also stop the loop! -+ loop.call_soon_threadsafe(controller.cancel_tasks) -+ -+(If you invoke ``cancel_tasks`` with the parameter ``stop_loop=False``, -+then loop will NOT be stopped. -+That is a much too-advanced topic and we will not discuss it further in this documentation.) -+ -+The Unix Socket variant, ``UnixSocketUnthreadedController``, works in the same way. -+The difference is only in how to access the server, i.e., through a Unix Socket instead of TCP/IP. -+We'll leave out the details for you to figure it out yourself. -+ -+ - .. _enablesmtputf8: - - Enabling SMTPUTF8 -@@ -253,265 +360,398 @@ Controller API - - .. py:module:: aiosmtpd.controller - --.. class:: IP6_IS - -- .. py:attribute:: NO -- :type: set -+.. py:data:: DEFAULT_READY_TIMEOUT -+ :type: float -+ :value: 5.0 -+ -+ -+.. py:function:: get_localhost() - -- Contains constants from :mod:`errno` that will be raised by `socket.bind()` -- if IPv6 is not available on the system. -+ :return: The numeric address of the loopback interface; ``"::1"`` if IPv6 is supported, -+ ``"127.0.0.1"`` if IPv6 is not supported. -+ :rtype: Literal["::1", "127.0.0.1"] -+ -+ -+.. class:: IP6_IS - -- .. important:: -+ .. py:attribute:: NO -+ :type: set[int] - -- If your system does not have IPv6 support but :func:`get_localhost` -- raises an error instead of returning ``"127.0.0.1"``, -- you can add the error number into this attribute. -+ Contains constants from :mod:`errno` that will be raised by :meth:`socket.socket.bind` -+ if IPv6 is NOT available on the system. - - .. py:attribute:: YES -- :type: set -+ :type: set[int] - -- Contains constants from :mod:`errno` that will be raised by `socket.bind()` -- if IPv6 is not available on the system. -+ Contains constants from :mod:`errno` that will be raised by :meth:`socket.socket.bind` -+ if IPv6 IS available on the system. - --.. py:function:: get_localhost -+ .. note:: - -- :return: The numeric address of the loopback interface; ``"::1"`` if IPv6 is supported, -- ``"127.0.0.1"`` if IPv6 is not supported. -- :rtype: str -+ You can customize the contents of these attributes by adding/removing from them, -+ in case the behavior does not align with your expectations *and* -+ you cannot wait for a patch to be merged. - --.. class:: BaseThreadedController(\ -- handler, \ -- loop=None, \ -- *, \ -- ready_timeout, \ -- ssl_context=None, \ -- server_hostname=None, server_kwargs=None, **SMTP_parameters) - -- :param handler: Handler object -- :param loop: The asyncio event loop in which the server will run. -- If not given, :func:`asyncio.new_event_loop` will be called to create the event loop. -- :param ready_timeout: How long to wait until server starts. -- The :envvar:`AIOSMTPD_CONTROLLER_TIMEOUT` takes precedence over this parameter. -- See :attr:`ready_timeout` for more information. -- :type ready_timeout: float -- :param ssl_context: SSL Context to wrap the socket in. -- Will be passed-through to :meth:`~asyncio.loop.create_server` method -- :type ssl_context: ssl.SSLContext -- :param server_hostname: Server's hostname, -- will be passed-through as ``hostname`` parameter of :class:`~aiosmtpd.smtp.SMTP` -- :type server_hostname: Optional[str] -- :param server_kwargs: (DEPRECATED) A dict that -- will be passed-through as keyword arguments of :class:`~aiosmtpd.smtp.SMTP`. -- Explicitly listed keyword arguments going into ``**SMTP_parameters`` -- will take precedence over this parameter -- :type server_kwargs: Dict[str, Any] -- :param SMTP_parameters: Optional keyword arguments that -- will be passed-through as keyword arguments of :class:`~aiosmtpd.smtp.SMTP` -+.. class:: BaseController(\ -+ handler, \ -+ loop=None, \ -+ *, \ -+ ssl_context=None, \ -+ server_hostname=None, \ -+ server_kwargs=None, \ -+ **SMTP_parameters, \ -+ ) - -- .. important:: -+ This **Abstract Base Class** defines parameters, attributes, and methods common between -+ all concrete controller classes. - -- Usually, setting the ``ssl_context`` parameter will switch the protocol to ``SMTPS`` mode, -- implying unconditional encryption of the connection, -- and preventing the use of the ``STARTTLS`` mechanism. -+ :param handler: Handler object -+ :param loop: The asyncio event loop in which the server will run. -+ If not given, :func:`asyncio.new_event_loop` will be called to create the event loop. -+ :type loop: asyncio.AbstractEventLoop -+ :param ssl_context: SSL Context to wrap the socket in. -+ Will be passed-through to :meth:`~asyncio.loop.create_server` method -+ :type ssl_context: ssl.SSLContext -+ :param server_hostname: Server's hostname, -+ will be passed-through as ``hostname`` parameter of :class:`~aiosmtpd.smtp.SMTP` -+ :type server_hostname: Optional[str] -+ :param server_kwargs: *(DEPRECATED)* A dict that will be passed-through as keyword -+ arguments of :class:`~aiosmtpd.smtp.SMTP`. -+ This is DEPRECATED; please use ``**SMTP_parameters`` instead. -+ :type server_kwargs: dict -+ :param SMTP_parameters: Optional keyword arguments that -+ will be passed-through as keyword arguments of :class:`~aiosmtpd.smtp.SMTP` - -- Actual behavior depends on the subclass's implementation. -+ | -+ | :part:`Attributes` - -- | -- | :part:`Attributes` -+ .. attribute:: handler -+ :noindex: - -- .. attribute:: handler -- :noindex: -+ The instance of the event *handler* passed to the constructor. - -- The instance of the event *handler* passed to the constructor. -+ .. attribute:: loop -+ :noindex: - -- .. attribute:: loop -- :noindex: -+ The event loop being used. - -- The event loop being used. -+ .. attribute:: server - -- .. attribute:: ready_timeout -- :type: float -+ This is the server instance returned by -+ :meth:`_create_server` after the server has started. - -- The timeout value used to wait for the server to start. -+ You can retrieve the :class:`~socket.socket` objects the server is listening on -+ from the ``server.sockets`` attribute. - -- This will either be the value of -- the :envvar:`AIOSMTPD_CONTROLLER_TIMEOUT` environment variable (converted to float), -- or the :attr:`ready_timeout` parameter. -+ .. py:attribute:: smtpd -+ :type: aiosmtpd.smtp.SMTP - -- Setting this to a high value will NOT slow down controller startup, -- because it's a timeout limit rather than a sleep delay. -- However, you may want to reduce the default value to something 'just enough' -- so you don't have to wait too long for an exception, if problem arises. -+ The server instance (of class SMTP) created by :meth:`factory` after -+ the controller is started. - -- If this timeout is breached, a :class:`TimeoutError` exception will be raised. -+ | -+ | :part:`Methods` - -- .. attribute:: server -+ .. method:: factory() -> aiosmtpd.smtp.SMTP - -- This is the server instance returned by -- :meth:`_create_server` after the server has started. -+ You can override this method to create custom instances of -+ the :class:`~aiosmtpd.smtp.SMTP` class being controlled. - -- .. py:attribute:: smtpd -- :type: aiosmtpd.smtp.SMTP -+ By default, this creates an ``SMTP`` instance, -+ passing in your handler and setting flags from the :attr:`**SMTP_Parameters` parameter. - -- The server instance (of class SMTP) created by :meth:`factory` after -- the controller is started. -+ Examples of why you would want to override this method include -+ creating an :ref:`LMTP ` server instance instead of the standard ``SMTP`` server. - -- | -- | :part:`Methods` -+ .. py:method:: cancel_tasks(stop_loop=True) - -- .. py:method:: _create_server() -> Coroutine -- :abstractmethod: -+ :param stop_loop: If ``True``, stops the loop before canceling tasks. -+ :type stop_loop: bool - -- This method will be called by :meth:`_run` during :meth:`start` procedure. -+ This is a convenience class that will stop the loop & -+ cancel all asyncio tasks for you. - -- It must return a ``Coroutine`` object which will be executed by the asyncio event loop. - -- .. py:method:: _trigger_server() -> None -- :abstractmethod: -+.. class:: Controller(\ -+ handler, \ -+ hostname=None, \ -+ port=8025, \ -+ loop=None, \ -+ *, \ -+ ready_timeout=DEFAULT_READY_TIMEOUT, \ -+ ssl_context=None, \ -+ server_hostname=None, \ -+ server_kwargs=None, \ -+ **SMTP_parameters) - -- The :meth:`asyncio.loop.create_server` method (or its parallel) -- invokes :meth:`factory` "lazily", -- so exceptions in :meth:`factory` can go undetected during :meth:`start`. -+ A concrete subclass of :class:`BaseController` that provides -+ a threaded, INET listener. - -- This method will create a connection to the started server and 'exchange' some traffic, -- thus triggering :meth:`factory` invocation, -- allowing the Controller to catch exceptions during initialization. -+ :param hostname: Will be given to the event loop's :meth:`~asyncio.loop.create_server` method -+ as the ``host`` parameter, with a slight processing (see below) -+ :type hostname: Optional[str] -+ :param port: Will be passed-through to :meth:`~asyncio.loop.create_server` method -+ :type port: int -+ :param ready_timeout: How long to wait until server starts. -+ The :envvar:`AIOSMTPD_CONTROLLER_TIMEOUT` takes precedence over this parameter. -+ See :attr:`ready_timeout` for more information. -+ :type ready_timeout: float - -- .. method:: start() -> None -+ Other parameters are defined in the :class:`BaseController` class. - -- :raises TimeoutError: if the server takes too long to get ready, -- exceeding the ``ready_timeout`` parameter. -- :raises RuntimeError: if an unrecognized & unhandled error happened, -- resulting in non-creation of a server object -- (:attr:`smtpd` remains ``None``) -+ The ``hostname`` parameter will be passed to the event loop's -+ :meth:`~asyncio.loop.create_server` method as the ``host`` parameter, -+ :boldital:`except` ``None`` (default) will be translated to ``::1``. - -- Start the server in the subthread. -- The subthread is always a :class:`daemon thread ` -- (i.e., we always set ``thread.daemon=True``). -+ * To bind `dual-stack`_ locally, use ``localhost``. -+ * To bind `dual-stack`_ on all interfaces, use ``""`` (empty string). - -- Exceptions can be raised -- if the server does not start within :attr:`ready_timeout` seconds, -- or if any other exception occurs in :meth:`factory` while creating the server. -+ .. important:: - -- .. important:: -+ The ``hostname`` parameter does NOT get passed through to the SMTP instance; -+ if you want to give the SMTP instance a custom hostname -+ (e.g., for use in HELO/EHLO greeting), -+ you must pass it through the :attr:`server_hostname` parameter. - -- If :meth:`start` raises an Exception, -- cleanup is not performed automatically, -- to support deep inspection post-exception (if you wish to do so.) -- Cleanup must still be performed manually by calling :meth:`stop` -+ Explicitly defined SMTP keyword arguments will override keyword arguments of the -+ same names defined in the (deprecated) ``server_kwargs`` argument. - -- For example:: -+ .. doctest:: controller_kwargs - -- # Assume SomeController is a concrete subclass of BaseThreadedController -- controller = SomeController(handler) -- try: -- controller.start() -- except ...: -- ... exception handling and/or inspection ... -- finally: -- controller.stop() -+ >>> from aiosmtpd.controller import Controller -+ >>> from aiosmtpd.handlers import Sink -+ >>> controller = Controller( -+ ... Sink(), timeout=200, server_kwargs=dict(timeout=400) -+ ... ) -+ >>> controller.SMTP_kwargs["timeout"] -+ 200 - -- .. method:: stop() -> None -+ Finally, setting the ``ssl_context`` parameter will switch the protocol to ``SMTPS`` mode, -+ implying unconditional encryption of the connection, -+ and preventing the use of the ``STARTTLS`` mechanism. - -- :raises AssertionError: if :meth:`stop` is called before :meth:`start` is called successfully -+ Actual behavior depends on the subclass's implementation. - -- Stop the server and the event loop, and cancel all tasks. -+ | -+ | :part:`Attributes` - -- .. method:: factory() -> aiosmtpd.smtp.SMTP -+ In addition to those provided by :class:`BaseController`, -+ this class provides the following: - -- You can override this method to create custom instances of the ``SMTP`` -- class being controlled. -+ .. attribute:: hostname: str -+ port: int - -- By default, this creates an ``SMTP`` instance, -- passing in your handler and setting flags from the :attr:`**SMTP_Parameters` parameter. -+ The values of the *hostname* and *port* arguments. - -- Examples of why you would want to override this method include -- creating an :ref:`LMTP ` server instance instead of the standard ``SMTP`` server. -+ .. attribute:: ready_timeout -+ :type: float - -+ The timeout value used to wait for the server to start. - -+ This will either be the value of -+ the :envvar:`AIOSMTPD_CONTROLLER_TIMEOUT` environment variable (converted to float), -+ or the :attr:`ready_timeout` parameter. - --.. class:: Controller(\ -- handler, \ -- hostname=None, port=8025, \ -- loop=None, \ -- *, \ -- ready_timeout=3.0, \ -- ssl_context=None, \ -- server_hostname=None, server_kwargs=None, **SMTP_parameters) -- -- :param hostname: Will be given to the event loop's :meth:`~asyncio.loop.create_server` method -- as the ``host`` parameter, with a slight processing (see below) -- :type hostname: Optional[str] -- :param port: Will be passed-through to :meth:`~asyncio.loop.create_server` method -- :type port: int -+ Setting this to a high value will NOT slow down controller startup, -+ because it's a timeout limit rather than a sleep delay. -+ However, you may want to reduce the default value to something 'just enough' -+ so you don't have to wait too long for an exception, if problem arises. - -- .. note:: -+ If this timeout is breached, a :class:`TimeoutError` exception will be raised. -+ -+ | -+ | :part:`Methods` - -- The ``hostname`` parameter will be passed to the event loop's -- :meth:`~asyncio.loop.create_server` method as the ``host`` parameter, -- :boldital:`except` ``None`` (default) will be translated to ``::1``. -+ In addition to those provided by :class:`BaseController`, -+ this class provides the following: - -- * To bind `dual-stack`_ locally, use ``localhost``. -+ .. method:: start() -> None - -- * To bind `dual-stack`_ on all interfaces, use ``""`` (empty string). -+ :raises TimeoutError: if the server takes too long to get ready, -+ exceeding the ``ready_timeout`` parameter. -+ :raises RuntimeError: if an unrecognized & unhandled error happened, -+ resulting in non-creation of a server object -+ (:attr:`smtpd` remains ``None``) - -- .. important:: -+ Start the server in the subthread. -+ The subthread is always a :class:`daemon thread ` -+ (i.e., we always set ``thread.daemon=True``). - -- The ``hostname`` parameter does NOT get passed through to the SMTP instance; -- if you want to give the SMTP instance a custom hostname -- (e.g., for use in HELO/EHLO greeting), -- you must pass it through the :attr:`server_hostname` parameter. -+ Exceptions can be raised -+ if the server does not start within :attr:`ready_timeout` seconds, -+ or if any other exception occurs in :meth:`~BaseController.factory` -+ while creating the server. - -- .. important:: -+ .. important:: - -- Explicitly defined SMTP keyword arguments will override keyword arguments of the -- same names defined in the (deprecated) ``server_kwargs`` argument. -+ If :meth:`start` raises an Exception, -+ cleanup is not performed automatically, -+ to support deep inspection post-exception (if you wish to do so.) -+ Cleanup must still be performed manually by calling :meth:`stop` - -- >>> from aiosmtpd.handlers import Sink -- >>> controller = Controller(Sink(), timeout=200, server_kwargs=dict(timeout=400)) -- >>> controller.SMTP_kwargs["timeout"] -- 200 -+ For example:: - -- One example is the ``enable_SMTPUTF8`` flag described in the -- :ref:`Enabling SMTPUTF8 section ` above. -+ # Assume SomeController is a concrete subclass of BaseThreadedController -+ controller = SomeController(handler) -+ try: -+ controller.start() -+ except ...: -+ ... exception handling and/or inspection ... -+ finally: -+ controller.stop() - -- | -- | :part:`Attributes` -+ .. method:: stop(no_assert=False) -> None - -- .. attribute:: hostname: str -- port: int -- :noindex: -+ :param no_assert: If ``True``, skip the assertion step so an ``AssertionError`` will -+ not be raised if thread had not been started successfully. -+ :type no_assert: bool - -- The values of the *hostname* and *port* arguments. -+ :raises AssertionError: if this method is called before -+ :meth:`start` is called successfully *AND* ``no_assert=False`` - -- Other parameters, attributes, and methods are identical to :class:`BaseThreadedController` -- and thus are not repeated nor explained here. -+ Stop the server and the event loop, and cancel all tasks -+ via :meth:`~BaseController.cancel_tasks`. - - - .. class:: UnixSocketController(\ -- handler, \ -- unix_socket, \ -- loop=None, \ -- *, \ -- ready_timeout=3.0, \ -- ssl_context=None, \ -- server_hostname=None,\ -- **SMTP_parameters) -+ handler, \ -+ unix_socket, \ -+ loop=None, \ -+ *, \ -+ ready_timeout=DEFAULT_READY_TIMEOUT, \ -+ ssl_context=None, \ -+ server_hostname=None, \ -+ **SMTP_parameters) -+ -+ A concrete subclass of :class:`BaseController` that provides -+ a threaded, Unix Socket listener. -+ -+ :param unix_socket: Socket file, -+ will be passed-through to :meth:`asyncio.loop.create_unix_server` -+ :type unix_socket: Union[str, pathlib.Path] -+ -+ For the other parameters, see the description under :class:`Controller` -+ -+ | -+ | :part:`Attributes` -+ -+ .. py:attribute:: unix_socket -+ :type: str -+ -+ The stringified version of the ``unix_socket`` parameter -+ -+ Other attributes (except ``hostname`` and ``port``) are identical to :class:`Controller` -+ and thus are not repeated nor explained here. -+ -+ | -+ | :part:`Methods` -+ -+ All methods are identical to :class:`Controller` -+ and thus are not repeated nor explained here. -+ -+ -+.. class:: UnthreadedController(\ -+ handler, \ -+ hostname=None, \ -+ port=8025, \ -+ loop=None, \ -+ *, \ -+ ssl_context=None, \ -+ server_hostname=None, \ -+ server_kwargs=None, \ -+ **SMTP_parameters) -+ -+ .. versionadded:: 1.5.0 -+ -+ A concrete subclass of :class:`BaseController` that provides -+ an UNthreaded, INET listener. -+ -+ Parameters are identical to the :class:`Controller` class. -+ -+ | -+ | :part:`Attributes` -+ -+ Attributes are identical to the :class:`Controller` class with one addition: -+ -+ .. py:attribute:: ended -+ :type: threading.Event -+ -+ An ``Event`` that can be ``.wait()``-ed when ending the controller. -+ Please see the :ref:`Unthreaded Controllers ` section for more info. -+ -+ | -+ | :part:`Methods` -+ -+ In addition to those provided by :class:`BaseController`, -+ this class provides the following: -+ -+ .. py:method:: begin -+ -+ Initializes the server task and insert it into the asyncio event loop. -+ -+ .. note:: -+ -+ The SMTP class itself will only be initialized upon first connection -+ to the server task. -+ -+ .. py:method:: finalize -+ :async: -+ -+ Perform orderly closing of the server listener. -+ If you need to close the server from a non-async function, -+ you can use the :meth:`~UnthreadedController.end` method instead. -+ -+ Upon completion of this method, the :attr:`ended` attribute will be ``set()``. -+ -+ .. py:method:: end -+ -+ This is a convenience method that will asynchronously invoke the -+ :meth:`finalize` method. -+ This method non-async, and thus is callable from non-async functions. -+ -+ .. note:: -+ -+ If the asyncio event loop has been stopped, -+ then it is safe to invoke this method directly. -+ Otherwise, it is recommended to invoke this method -+ using the :meth:`~asyncio.loop.call_soon_threadsafe` method. -+ -+ -+.. class:: UnixSocketUnthreadedController(\ -+ handler, \ -+ unix_socket, \ -+ loop=None, \ -+ *, \ -+ ssl_context=None, \ -+ server_hostname=None,\ -+ server_kwargs=None, \ -+ **SMTP_parameters) -+ -+ .. versionadded:: 1.5.0 -+ -+ A concrete subclass of :class:`BaseController` that provides -+ an UNthreaded, Unix Socket listener. -+ -+ Parameters are identical to the :class:`UnixSocketController` class. -+ -+ | -+ | :part:`Attributes` - -- :param unix_socket: Socket file, -- will be passed-through to :meth:`asyncio.loop.create_unix_server` -- :type unix_socket: Union[str, pathlib.Path] -+ Attributes are identical to the :class:`UnixSocketController` class, -+ with the following addition: - -- | -- | :part:`Attributes` -+ .. py:attribute:: ended -+ :type: threading.Event - -- .. py:attribute:: unix_socket -- :type: str -+ An ``Event`` that can be ``.wait()``-ed when ending the controller. -+ Please see the :ref:`Unthreaded Controllers ` section for more info. - -- The stringified version of the ``unix_socket`` parameter -+ | -+ | :part:`Methods` - -- Other parameters, attributes, and methods are identical to :class:`BaseThreadedController` -- and thus are not repeated nor explained here. -+ Methods are identical to the :class:`UnthreadedController` class. - - - .. _`asyncio event loop`: https://docs.python.org/3/library/asyncio-eventloop.html -diff --git a/aiosmtpd/docs/smtp.rst b/aiosmtpd/docs/smtp.rst -index f48b717..3305079 100644 ---- a/aiosmtpd/docs/smtp.rst -+++ b/aiosmtpd/docs/smtp.rst -@@ -99,7 +99,8 @@ Server hooks - The ``SMTP`` server class also implements some hooks which your subclass can - override to provide additional responses. - --``ehlo_hook()`` -+.. py:function:: ehlo_hook() -+ - This hook makes it possible for subclasses to return additional ``EHLO`` - responses. This method, called *asynchronously* and taking no arguments, - can do whatever it wants, including (most commonly) pushing new -@@ -107,12 +108,17 @@ override to provide additional responses. - before the standard ``250 HELP`` which ends the ``EHLO`` response from the - server. - --``rset_hook()`` -+ .. deprecated:: 1.2 -+ -+.. py:function:: rset_hook() -+ - This hook makes it possible to return additional ``RSET`` responses. This - method, called *asynchronously* and taking no arguments, is called just - before the standard ``250 OK`` which ends the ``RSET`` response from the - server. - -+ .. deprecated:: 1.2 -+ - - .. _smtp_api: - -diff --git a/aiosmtpd/handlers.py b/aiosmtpd/handlers.py -index b13dd12..ada1e91 100644 ---- a/aiosmtpd/handlers.py -+++ b/aiosmtpd/handlers.py -@@ -15,6 +15,7 @@ import mailbox - import re - import smtplib - import sys -+from abc import ABCMeta, abstractmethod - from email import message_from_bytes, message_from_string - - from public import public -@@ -148,7 +149,7 @@ class Sink: - - - @public --class Message: -+class Message(metaclass=ABCMeta): - def __init__(self, message_class=None): - self.message_class = message_class - -@@ -172,12 +173,13 @@ class Message: - message['X-RcptTo'] = COMMASPACE.join(envelope.rcpt_tos) - return message - -+ @abstractmethod - def handle_message(self, message): -- raise NotImplementedError # pragma: nocover -+ raise NotImplementedError - - - @public --class AsyncMessage(Message): -+class AsyncMessage(Message, metaclass=ABCMeta): - def __init__(self, message_class=None, *, loop=None): - super().__init__(message_class) - self.loop = loop or asyncio.get_event_loop() -@@ -187,8 +189,9 @@ class AsyncMessage(Message): - await self.handle_message(message) - return '250 OK' - -+ @abstractmethod - async def handle_message(self, message): -- raise NotImplementedError # pragma: nocover -+ raise NotImplementedError - - - @public -diff --git a/aiosmtpd/proxy_protocol.py b/aiosmtpd/proxy_protocol.py -index a171211..621098c 100644 ---- a/aiosmtpd/proxy_protocol.py -+++ b/aiosmtpd/proxy_protocol.py -@@ -99,7 +99,7 @@ class UnknownTypeTLV(KeyError): - - - @public --class AsyncReader(Protocol): # pragma: nocover -+class AsyncReader(Protocol): - async def read(self, num_bytes: Optional[int] = None) -> bytes: - ... - return b"" -diff --git a/aiosmtpd/tests/conftest.py b/aiosmtpd/tests/conftest.py -index 08fc0e8..d0a6cd3 100644 ---- a/aiosmtpd/tests/conftest.py -+++ b/aiosmtpd/tests/conftest.py -@@ -29,6 +29,7 @@ __all__ = [ - "controller_data", - "handler_data", - "Global", -+ "AUTOSTOP_DELAY", - "SERVER_CRT", - "SERVER_KEY", - ] -@@ -64,6 +65,9 @@ class Global: - cls.SrvAddr = HostPort(contr.hostname, contr.port) - - -+# If less than 1.0, might cause intermittent error if test system -+# is too busy/overloaded. -+AUTOSTOP_DELAY = 1.0 - SERVER_CRT = resource_filename("aiosmtpd.tests.certs", "server.crt") - SERVER_KEY = resource_filename("aiosmtpd.tests.certs", "server.key") - -@@ -204,6 +208,17 @@ def temp_event_loop() -> Generator[asyncio.AbstractEventLoop, None, None]: - asyncio.set_event_loop(default_loop) - - -+@pytest.fixture -+def autostop_loop(temp_event_loop) -> Generator[asyncio.AbstractEventLoop, None, None]: -+ # Create a new event loop, and arrange for that loop to end almost -+ # immediately. This will allow the calls to main() in these tests to -+ # also exit almost immediately. Otherwise, the foreground test -+ # process will hang. -+ temp_event_loop.call_later(AUTOSTOP_DELAY, temp_event_loop.stop) -+ # -+ yield temp_event_loop -+ -+ - @pytest.fixture - def plain_controller(get_handler, get_controller) -> Generator[Controller, None, None]: - """ -diff --git a/aiosmtpd/tests/test_main.py b/aiosmtpd/tests/test_main.py -index f9ac424..36992f3 100644 ---- a/aiosmtpd/tests/test_main.py -+++ b/aiosmtpd/tests/test_main.py -@@ -16,8 +16,9 @@ import pytest - from aiosmtpd import __version__ - from aiosmtpd.handlers import Debugging - from aiosmtpd.main import main, parseargs -+from aiosmtpd.testing.helpers import catchup_delay - from aiosmtpd.testing.statuscodes import SMTP_STATUS_CODES as S --from aiosmtpd.tests.conftest import SERVER_CRT, SERVER_KEY -+from aiosmtpd.tests.conftest import AUTOSTOP_DELAY, SERVER_CRT, SERVER_KEY - - try: - import pwd -@@ -27,10 +28,6 @@ except ImportError: - HAS_SETUID = hasattr(os, "setuid") - MAIL_LOG = logging.getLogger("mail.log") - --# If less than 1.0, might cause intermittent error if test system --# is too busy/overloaded. --AUTOSTOP_DELAY = 1.0 -- - - # region ##### Custom Handlers ######################################################## - -@@ -53,17 +50,6 @@ class NullHandler: - # region ##### Fixtures ############################################################### - - --@pytest.fixture --def autostop_loop(temp_event_loop) -> Generator[asyncio.AbstractEventLoop, None, None]: -- # Create a new event loop, and arrange for that loop to end almost -- # immediately. This will allow the calls to main() in these tests to -- # also exit almost immediately. Otherwise, the foreground test -- # process will hang. -- temp_event_loop.call_later(AUTOSTOP_DELAY, temp_event_loop.stop) -- # -- yield temp_event_loop -- -- - @pytest.fixture - def nobody_uid() -> Generator[int, None, None]: - if pwd is None: -@@ -97,10 +83,10 @@ def watch_for_tls(ready_flag, retq: MP.Queue): - req_tls = False - ready_flag.set() - start = time.monotonic() -- delay = AUTOSTOP_DELAY * 1.5 -+ delay = AUTOSTOP_DELAY * 4 - while (time.monotonic() - start) <= delay: - try: -- with SMTPClient("localhost", 8025) as client: -+ with SMTPClient("localhost", 8025, timeout=0.1) as client: - resp = client.docmd("HELP", "HELO") - if resp == S.S530_STARTTLS_FIRST: - req_tls = True -@@ -121,7 +107,7 @@ def watch_for_smtps(ready_flag, retq: MP.Queue): - delay = AUTOSTOP_DELAY * 1.5 - while (time.monotonic() - start) <= delay: - try: -- with SMTP_SSL("localhost", 8025) as client: -+ with SMTP_SSL("localhost", 8025, timeout=0.1) as client: - client.ehlo("exemple.org") - has_smtps = True - break -@@ -215,6 +201,7 @@ class TestMainByWatcher: - with watcher_process(watch_for_tls) as retq: - temp_event_loop.call_later(AUTOSTOP_DELAY, temp_event_loop.stop) - main_n("--tlscert", str(SERVER_CRT), "--tlskey", str(SERVER_KEY)) -+ catchup_delay() - has_starttls = retq.get() - assert has_starttls is True - require_tls = retq.get() -@@ -230,6 +217,7 @@ class TestMainByWatcher: - str(SERVER_KEY), - "--no-requiretls", - ) -+ catchup_delay() - has_starttls = retq.get() - assert has_starttls is True - require_tls = retq.get() -@@ -239,6 +227,7 @@ class TestMainByWatcher: - with watcher_process(watch_for_smtps) as retq: - temp_event_loop.call_later(AUTOSTOP_DELAY, temp_event_loop.stop) - main_n("--smtpscert", str(SERVER_CRT), "--smtpskey", str(SERVER_KEY)) -+ catchup_delay() - has_smtps = retq.get() - assert has_smtps is True - -diff --git a/aiosmtpd/tests/test_server.py b/aiosmtpd/tests/test_server.py -index 99c5630..41225dc 100644 ---- a/aiosmtpd/tests/test_server.py -+++ b/aiosmtpd/tests/test_server.py -@@ -3,16 +3,18 @@ - - """Test other aspects of the server implementation.""" - -+import asyncio - import errno - import platform - import socket --import ssl - import time - from contextlib import ExitStack - from functools import partial - from pathlib import Path -+from smtplib import SMTP as SMTPClient, SMTPServerDisconnected - from tempfile import mkdtemp --from typing import Generator -+from threading import Thread -+from typing import Generator, Optional - - import pytest - from pytest_mock import MockFixture -@@ -20,13 +22,17 @@ from pytest_mock import MockFixture - from aiosmtpd.controller import ( - Controller, - UnixSocketController, -+ UnthreadedController, -+ UnixSocketMixin, -+ UnixSocketUnthreadedController, - _FakeServer, - get_localhost, - ) - from aiosmtpd.handlers import Sink - from aiosmtpd.smtp import SMTP as Server -+from aiosmtpd.testing.helpers import catchup_delay - --from .conftest import Global -+from .conftest import Global, AUTOSTOP_DELAY - - - class SlowStartController(Controller): -@@ -91,6 +97,45 @@ def safe_socket_dir() -> Generator[Path, None, None]: - tmpdir.rmdir() - - -+def assert_smtp_socket(controller: UnixSocketMixin): -+ assert Path(controller.unix_socket).exists() -+ sockfile = controller.unix_socket -+ ssl_context = controller.ssl_context -+ with ExitStack() as stk: -+ sock: socket.socket = stk.enter_context( -+ socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) -+ ) -+ sock.settimeout(AUTOSTOP_DELAY) -+ sock.connect(str(sockfile)) -+ if ssl_context: -+ sock = stk.enter_context(ssl_context.wrap_socket(sock)) -+ catchup_delay() -+ try: -+ resp = sock.recv(1024) -+ except socket.timeout: -+ return False -+ if not resp: -+ return False -+ assert resp.startswith(b"220 ") -+ assert resp.endswith(b"\r\n") -+ sock.send(b"EHLO socket.test\r\n") -+ # We need to "build" resparr because, especially when socket is wrapped -+ # in SSL, the SMTP server takes it sweet time responding with the list -+ # of ESMTP features ... -+ resparr = bytearray() -+ while not resparr.endswith(b"250 HELP\r\n"): -+ catchup_delay() -+ resp = sock.recv(1024) -+ if not resp: -+ break -+ resparr += resp -+ assert resparr.endswith(b"250 HELP\r\n") -+ sock.send(b"QUIT\r\n") -+ catchup_delay() -+ resp = sock.recv(1024) -+ assert resp.startswith(b"221") -+ -+ - class TestServer: - """Tests for the aiosmtpd.smtp.SMTP class""" - -@@ -272,10 +317,7 @@ class TestController: - - # Apparently errno.E* constants adapts to the OS, so on Windows they will - # automatically use the analogous WSAE* constants -- @pytest.mark.parametrize( -- "err", -- [errno.EADDRNOTAVAIL, errno.EAFNOSUPPORT] -- ) -+ @pytest.mark.parametrize("err", [errno.EADDRNOTAVAIL, errno.EAFNOSUPPORT]) - def test_getlocalhost_6no(self, mocker, err): - mock_makesock: mocker.Mock = mocker.patch( - "aiosmtpd.controller.makesock", -@@ -320,70 +362,176 @@ class TestController: - @pytest.mark.skipif(in_cygwin(), reason="Cygwin AF_UNIX is problematic") - @pytest.mark.skipif(in_win32(), reason="Win32 does not yet fully implement AF_UNIX") - class TestUnixSocketController: -- sockfile: Path = None -- -- def _assert_good_server(self, ssl_context: ssl.SSLContext = None): -- # Note: all those time.sleep()s are necessary -- # Remember that we're running in "Threaded" mode, and there's the GIL... -- # The time.sleep()s lets go of the GIL allowing the asyncio loop to move -- # forward -- assert self.sockfile.exists() -- with ExitStack() as stk: -- sock: socket.socket = stk.enter_context( -- socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) -- ) -- sock.connect(str(self.sockfile)) -- if ssl_context: -- sock = stk.enter_context(ssl_context.wrap_socket(sock)) -- time.sleep(0.1) -- resp = sock.recv(1024) -- assert resp.startswith(b"220 ") -- assert resp.endswith(b"\r\n") -- sock.send(b"EHLO socket.test\r\n") -- # We need to "build" resparr because, especially when socket is wrapped -- # in SSL, the SMTP server takes it sweet time responding with the list -- # of ESMTP features ... -- resparr = bytearray() -- while not resparr.endswith(b"250 HELP\r\n"): -- time.sleep(0.1) -- resp = sock.recv(1024) -- if not resp: -- break -- resparr += resp -- assert resparr.endswith(b"250 HELP\r\n") -- sock.send(b"QUIT\r\n") -- time.sleep(0.1) -- resp = sock.recv(1024) -- assert resp.startswith(b"221") -- - def test_server_creation(self, safe_socket_dir): -- self.sockfile = safe_socket_dir / "smtp" -- cont = UnixSocketController(Sink(), unix_socket=self.sockfile) -+ sockfile = safe_socket_dir / "smtp" -+ cont = UnixSocketController(Sink(), unix_socket=sockfile) - try: - cont.start() -- self._assert_good_server() -+ assert_smtp_socket(cont) - finally: - cont.stop() - - def test_server_creation_ssl(self, safe_socket_dir, ssl_context_server): -- self.sockfile = safe_socket_dir / "smtp" -+ sockfile = safe_socket_dir / "smtp" - cont = UnixSocketController( -- Sink(), unix_socket=self.sockfile, ssl_context=ssl_context_server -+ Sink(), unix_socket=sockfile, ssl_context=ssl_context_server - ) - try: - cont.start() - # Allow additional time for SSL to kick in -- time.sleep(0.1) -- self._assert_good_server(ssl_context_server) -+ catchup_delay() -+ assert_smtp_socket(cont) - finally: - cont.stop() - - -+class TestUnthreaded: -+ @pytest.fixture -+ def runner(self): -+ thread: Optional[Thread] = None -+ -+ def _runner(loop: asyncio.AbstractEventLoop): -+ loop.run_forever() -+ -+ def starter(loop: asyncio.AbstractEventLoop): -+ nonlocal thread -+ thread = Thread(target=_runner, args=(loop,)) -+ thread.setDaemon(True) -+ thread.start() -+ catchup_delay() -+ -+ def joiner(timeout: float = None): -+ nonlocal thread -+ assert isinstance(thread, Thread) -+ thread.join(timeout=timeout) -+ -+ def is_alive(): -+ nonlocal thread -+ assert isinstance(thread, Thread) -+ return thread.is_alive() -+ -+ starter.join = joiner -+ starter.is_alive = is_alive -+ return starter -+ -+ @pytest.mark.skipif(in_cygwin(), reason="Cygwin AF_UNIX is problematic") -+ @pytest.mark.skipif(in_win32(), reason="Win32 does not yet fully implement AF_UNIX") -+ def test_unixsocket(self, safe_socket_dir, autostop_loop, runner): -+ sockfile = safe_socket_dir / "smtp" -+ cont = UnixSocketUnthreadedController( -+ Sink(), unix_socket=sockfile, loop=autostop_loop -+ ) -+ cont.begin() -+ # Make sure event loop is not running (will be started in thread) -+ assert autostop_loop.is_running() is False -+ runner(autostop_loop) -+ # Make sure event loop is up and running (started within thread) -+ assert autostop_loop.is_running() is True -+ # Check we can connect -+ assert_smtp_socket(cont) -+ # Wait until thread ends, which it will be when the loop autostops -+ runner.join(timeout=AUTOSTOP_DELAY) -+ assert runner.is_alive() is False -+ catchup_delay() -+ assert autostop_loop.is_running() is False -+ # At this point, the loop _has_ stopped, but the task is still listening -+ assert assert_smtp_socket(cont) is False -+ # Stop the task -+ cont.end() -+ catchup_delay() -+ # Now the listener has gone away -+ # noinspection PyTypeChecker -+ with pytest.raises((socket.timeout, ConnectionError)): -+ assert_smtp_socket(cont) -+ -+ @pytest.mark.filterwarnings( -+ "ignore::pytest.PytestUnraisableExceptionWarning" -+ ) -+ def test_inet_loopstop(self, autostop_loop, runner): -+ """ -+ Verify behavior when the loop is stopped before controller is stopped -+ """ -+ autostop_loop.set_debug(True) -+ cont = UnthreadedController(Sink(), loop=autostop_loop) -+ cont.begin() -+ # Make sure event loop is not running (will be started in thread) -+ assert autostop_loop.is_running() is False -+ runner(autostop_loop) -+ # Make sure event loop is up and running (started within thread) -+ assert autostop_loop.is_running() is True -+ # Check we can connect -+ with SMTPClient(cont.hostname, cont.port, timeout=AUTOSTOP_DELAY) as client: -+ code, _ = client.helo("example.org") -+ assert code == 250 -+ # Wait until thread ends, which it will be when the loop autostops -+ runner.join(timeout=AUTOSTOP_DELAY) -+ assert runner.is_alive() is False -+ catchup_delay() -+ assert autostop_loop.is_running() is False -+ # At this point, the loop _has_ stopped, but the task is still listening, -+ # so rather than socket.timeout, we'll get a refusal instead, thus causing -+ # SMTPServerDisconnected -+ with pytest.raises(SMTPServerDisconnected): -+ SMTPClient(cont.hostname, cont.port, timeout=0.1) -+ cont.end() -+ catchup_delay() -+ cont.ended.wait() -+ # Now the listener has gone away, and thus we will end up with socket.timeout -+ # or ConnectionError (depending on OS) -+ # noinspection PyTypeChecker -+ with pytest.raises((socket.timeout, ConnectionError)): -+ SMTPClient(cont.hostname, cont.port, timeout=0.1) -+ -+ @pytest.mark.filterwarnings( -+ "ignore::pytest.PytestUnraisableExceptionWarning" -+ ) -+ def test_inet_contstop(self, temp_event_loop, runner): -+ """ -+ Verify behavior when the controller is stopped before loop is stopped -+ """ -+ cont = UnthreadedController(Sink(), loop=temp_event_loop) -+ cont.begin() -+ # Make sure event loop is not running (will be started in thread) -+ assert temp_event_loop.is_running() is False -+ runner(temp_event_loop) -+ # Make sure event loop is up and running -+ assert temp_event_loop.is_running() is True -+ try: -+ # Check that we can connect -+ with SMTPClient(cont.hostname, cont.port, timeout=AUTOSTOP_DELAY) as client: -+ code, _ = client.helo("example.org") -+ assert code == 250 -+ client.quit() -+ catchup_delay() -+ temp_event_loop.call_soon_threadsafe(cont.end) -+ for _ in range(10): # 10 is arbitrary -+ catchup_delay() # effectively yield to other threads/event loop -+ if cont.ended.wait(1.0): -+ break -+ assert temp_event_loop.is_running() is True -+ # Because we've called .end() there, the server listener should've gone -+ # away, so we should end up with a socket.timeout or ConnectionError or -+ # SMTPServerDisconnected (depending on lotsa factors) -+ expect_errs = (socket.timeout, ConnectionError, SMTPServerDisconnected) -+ # noinspection PyTypeChecker -+ with pytest.raises(expect_errs): -+ SMTPClient(cont.hostname, cont.port, timeout=0.1) -+ finally: -+ # Wrap up, or else we'll hang -+ temp_event_loop.call_soon_threadsafe(cont.cancel_tasks) -+ catchup_delay() -+ runner.join() -+ assert runner.is_alive() is False -+ assert temp_event_loop.is_running() is False -+ assert temp_event_loop.is_closed() is False -+ -+ - class TestFactory: - def test_normal_situation(self): - cont = Controller(Sink()) - try: - cont.start() -+ catchup_delay() - assert cont.smtpd is not None - assert cont._thread_exception is None - finally: -diff --git a/pyproject.toml b/pyproject.toml -index b61bfa6..e067d36 100644 ---- a/pyproject.toml -+++ b/pyproject.toml -@@ -3,7 +3,6 @@ requires = ["setuptools", "wheel"] - build-backend = "setuptools.build_meta" - - [tool.pytest.ini_options] --# addopts = """--doctest-glob="*.rst" --strict-markers -rfEX""" - addopts = """--strict-markers -rfEX""" - markers = [ - "client_data", -@@ -37,6 +36,7 @@ source = [ - [tool.coverage.coverage_conditional_plugin.rules] - # Here we specify our pragma rules: - py-ge-38 = "sys_version_info >= (3, 8)" -+py-lt-38 = "sys_version_info < (3, 8)" - py-gt-36 = "sys_version_info > (3, 6)" - has-mypy = "is_installed('mypy')" - has-pwd = "is_installed('pwd')" -@@ -47,10 +47,14 @@ on-wsl = "'Microsoft' in platform_release" - # As of 2021-02-07, only WSL has a kernel with "Microsoft" in the version. - on-not-win32 = "sys_platform != 'win32'" - on-cygwin = "sys_platform == 'cygwin'" -+no-unixsock = "sys_platform in {'win32', 'cygwin'}" - - [tool.coverage.report] - exclude_lines = [ - "pragma: nocover", -+ "pragma: no cover", -+ "@abstract", -+ 'class \S+\(Protocol\):' - ] - fail_under = 100 - show_missing = true --- -2.32.0 - diff --git a/0002-Code-Hygiene-259.patch b/0002-Code-Hygiene-259.patch deleted file mode 100644 index add742c..0000000 --- a/0002-Code-Hygiene-259.patch +++ /dev/null @@ -1,2725 +0,0 @@ -From 1a1c1bb15d4659f1076c7e14a064721761d81aa6 Mon Sep 17 00:00:00 2001 -From: Pandu E POLUAN -Date: Tue, 23 Mar 2021 13:31:32 +0700 -Subject: [PATCH 2/4] Code Hygiene (#259) - -* Activate LOTS of flake8 plugins to enforce code hygiene -* Tune Annotation Thresholds -* Add Annotation -* Add pytest-mock to the deps of "docs" -* Fix post-rebase flake8 complaints -* Update NEWS.rst -* Move flake8 plugins into a pseudo-section in tox.ini -* Create concrete class for MessageHandler -* Bump Version to 1.5.0a2 -* Experimentally enable tox-ing on 3.10 -* Use typing.ByteString instead of custom AnyBytes ---- - .../workflows/unit-testing-and-coverage.yml | 10 +- - aiosmtpd/__init__.py | 2 +- - aiosmtpd/controller.py | 10 +- - aiosmtpd/docs/NEWS.rst | 5 +- - aiosmtpd/docs/_exts/autoprogramm.py | 64 ++++--- - aiosmtpd/docs/conf.py | 9 +- - aiosmtpd/docs/proxyprotocol.rst | 6 +- - aiosmtpd/docs/smtp.rst | 2 +- - aiosmtpd/handlers.py | 158 +++++++++++------- - aiosmtpd/lmtp.py | 6 +- - aiosmtpd/main.py | 11 +- - aiosmtpd/proxy_protocol.py | 32 ++-- - aiosmtpd/qa/test_0packaging.py | 38 ++++- - aiosmtpd/qa/test_1testsuite.py | 6 +- - aiosmtpd/smtp.py | 124 ++++++++------ - aiosmtpd/testing/helpers.py | 10 +- - aiosmtpd/tests/conftest.py | 48 +++--- - aiosmtpd/tests/test_handlers.py | 90 +++++++--- - aiosmtpd/tests/test_main.py | 16 +- - aiosmtpd/tests/test_proxyprotocol.py | 67 +++++--- - aiosmtpd/tests/test_server.py | 26 +-- - aiosmtpd/tests/test_smtp.py | 89 +++++----- - aiosmtpd/tests/test_starttls.py | 17 +- - housekeep.py | 3 +- - setup.cfg | 52 +++++- - tox.ini | 57 ++++++- - 26 files changed, 627 insertions(+), 331 deletions(-) - -diff --git a/.github/workflows/unit-testing-and-coverage.yml b/.github/workflows/unit-testing-and-coverage.yml -index f7b0e32..ebc2248 100644 ---- a/.github/workflows/unit-testing-and-coverage.yml -+++ b/.github/workflows/unit-testing-and-coverage.yml -@@ -38,9 +38,17 @@ jobs: - python -m pip install --upgrade pip setuptools wheel - python setup.py develop - - name: "flake8 Style Checking" -+ shell: bash - # language=bash - run: | -- pip install colorama flake8 flake8-bugbear -+ # A bunch of flake8 plugins... -+ grab_f8_plugins=( -+ "from configparser import ConfigParser;" -+ "config = ConfigParser();" -+ "config.read('tox.ini');" -+ "print(config['flake8_plugins']['deps']);" -+ ) -+ pip install colorama flake8 $(python -c "${grab_f8_plugins[*]}") - python -m flake8 aiosmtpd setup.py housekeep.py release.py - - name: "Docs Checking" - # language=bash -diff --git a/aiosmtpd/controller.py b/aiosmtpd/controller.py -index d3345b8..79bdbd0 100644 ---- a/aiosmtpd/controller.py -+++ b/aiosmtpd/controller.py -@@ -85,7 +85,7 @@ class _FakeServer(asyncio.StreamReaderProtocol): - factory() failed to instantiate an SMTP instance. - """ - -- def __init__(self, loop): -+ def __init__(self, loop: asyncio.AbstractEventLoop): - # Imitate what SMTP does - super().__init__( - asyncio.StreamReader(loop=loop), -@@ -93,7 +93,9 @@ class _FakeServer(asyncio.StreamReaderProtocol): - loop=loop, - ) - -- def _client_connected_cb(self, reader, writer): -+ def _client_connected_cb( -+ self, reader: asyncio.StreamReader, writer: asyncio.StreamWriter -+ ) -> None: - pass - - -@@ -143,7 +145,7 @@ class BaseController(metaclass=ABCMeta): - """Subclasses can override this to customize the handler/server creation.""" - return SMTP(self.handler, **self.SMTP_kwargs) - -- def _factory_invoker(self): -+ def _factory_invoker(self) -> Union[SMTP, _FakeServer]: - """Wraps factory() to catch exceptions during instantiation""" - try: - self.smtpd = self.factory() -@@ -223,7 +225,7 @@ class BaseThreadedController(BaseController, metaclass=ABCMeta): - """ - raise NotImplementedError - -- def _run(self, ready_event: threading.Event): -+ def _run(self, ready_event: threading.Event) -> None: - asyncio.set_event_loop(self.loop) - try: - # Need to do two-step assignments here to ensure IDEs can properly -diff --git a/aiosmtpd/docs/NEWS.rst b/aiosmtpd/docs/NEWS.rst -index ce627a7..eea911d 100644 ---- a/aiosmtpd/docs/NEWS.rst -+++ b/aiosmtpd/docs/NEWS.rst -@@ -3,8 +3,8 @@ - ################### - - --1.5.0 (aiosmtpd-next-next) --========================== -+1.5.0 (aiosmtpd-next) -+===================== - - Added - ----- -@@ -13,6 +13,7 @@ Added - Fixed/Improved - -------------- - * All Controllers now have more rationale design, as they are now composited from a Base + a Mixin -+* A whole bunch of annotations - - - 1.4.2 (2021-03-08) -diff --git a/aiosmtpd/docs/_exts/autoprogramm.py b/aiosmtpd/docs/_exts/autoprogramm.py -index 69088be..c23bd2f 100644 ---- a/aiosmtpd/docs/_exts/autoprogramm.py -+++ b/aiosmtpd/docs/_exts/autoprogramm.py -@@ -32,6 +32,7 @@ import argparse - import builtins - import collections - import os -+import sphinx - - from docutils import nodes - from docutils.parsers.rst import Directive -@@ -39,13 +40,13 @@ from docutils.parsers.rst.directives import unchanged - from docutils.statemachine import StringList - from functools import reduce - from sphinx.util.nodes import nested_parse_with_titles --from typing import List -+from typing import Any, Dict, List, Optional, Tuple - - - __all__ = ("AutoprogrammDirective", "import_object", "scan_programs", "setup") - - --def get_subparser_action(parser): -+def get_subparser_action(parser: argparse.ArgumentParser) -> argparse._SubParsersAction: - neg1_action = parser._actions[-1] - - if isinstance(neg1_action, argparse._SubParsersAction): -@@ -56,7 +57,13 @@ def get_subparser_action(parser): - return a - - --def scan_programs(parser, command=None, maxdepth=0, depth=0, groups=False): -+def scan_programs( -+ parser: argparse.ArgumentParser, -+ command: List[str] = None, -+ maxdepth: int = 0, -+ depth: int = 0, -+ groups: bool = False, -+): - if command is None: - command = [] - -@@ -79,6 +86,7 @@ def scan_programs(parser, command=None, maxdepth=0, depth=0, groups=False): - subp_action = get_subparser_action(parser) - - if subp_action: -+ # noinspection PyUnresolvedReferences - choices = subp_action.choices.items() - - if not ( -@@ -89,11 +97,10 @@ def scan_programs(parser, command=None, maxdepth=0, depth=0, groups=False): - - for cmd, sub in choices: - if isinstance(sub, argparse.ArgumentParser): -- for program in scan_programs(sub, command + [cmd], maxdepth, depth + 1): -- yield program -+ yield from scan_programs(sub, command + [cmd], maxdepth, depth + 1) - - --def scan_options(actions): -+def scan_options(actions: list): - for arg in actions: - if not (arg.option_strings or isinstance(arg, argparse._SubParsersAction)): - yield format_positional_argument(arg) -@@ -103,13 +110,13 @@ def scan_options(actions): - yield format_option(arg) - - --def format_positional_argument(arg): -+def format_positional_argument(arg: argparse.Action) -> Tuple[List[str], str]: - desc = (arg.help or "") % {"default": arg.default} - name = arg.metavar or arg.dest - return [name], desc - - --def format_option(arg): -+def format_option(arg: argparse.Action) -> Tuple[List[str], str]: - desc = (arg.help or "") % {"default": arg.default} - - if not isinstance(arg, (argparse._StoreAction, argparse._AppendAction)): -@@ -131,7 +138,7 @@ def format_option(arg): - return names, desc - - --def import_object(import_name): -+def import_object(import_name: str) -> Any: - module_name, expr = import_name.split(":", 1) - try: - mod = __import__(module_name) -@@ -151,7 +158,8 @@ def import_object(import_name): - with open(f[0]) as fobj: - codestring = fobj.read() - foo = imp.new_module("foo") -- exec(codestring, foo.__dict__) # nosec -+ # noinspection BuiltinExec -+ exec(codestring, foo.__dict__) # noqa: DUO105 # nosec - - sys.modules["foo"] = foo - mod = __import__("foo") -@@ -163,7 +171,7 @@ def import_object(import_name): - globals_ = builtins - if not isinstance(globals_, dict): - globals_ = globals_.__dict__ -- return eval(expr, globals_, mod.__dict__) # nosec -+ return eval(expr, globals_, mod.__dict__) # noqa: DUO104 # nosec - - - class AutoprogrammDirective(Directive): -@@ -204,13 +212,16 @@ class AutoprogrammDirective(Directive): - - if start_command: - -- def get_start_cmd_parser(p): -+ def get_start_cmd_parser( -+ p: argparse.ArgumentParser, -+ ) -> argparse.ArgumentParser: - looking_for = start_command.pop(0) - action = get_subparser_action(p) - - if not action: - raise ValueError("No actions for command " + looking_for) - -+ # noinspection PyUnresolvedReferences - subp = action.choices[looking_for] - - if start_command: -@@ -263,7 +274,7 @@ class AutoprogrammDirective(Directive): - options_adornment=options_adornment, - ) - -- def run(self): -+ def run(self) -> list: - node = nodes.section() - node.document = self.state.document - result = StringList() -@@ -274,17 +285,17 @@ class AutoprogrammDirective(Directive): - - - def render_rst( -- title, -- options, -- is_program, -- is_subgroup, -- description, -- usage, -- usage_strip, -- usage_codeblock, -- epilog, -- options_title, -- options_adornment, -+ title: str, -+ options: List[Tuple[List[str], str]], -+ is_program: bool, -+ is_subgroup: bool, -+ description: str, -+ usage: Optional[str], -+ usage_strip: bool, -+ usage_codeblock: bool, -+ epilog: str, -+ options_title: str, -+ options_adornment: str, - ): - if usage_strip: - to_strip = title.rsplit(" ", 1)[0] -@@ -310,8 +321,7 @@ def render_rst( - yield ("!" if is_subgroup else "?") * len(title) - yield "" - -- for line in (description or "").splitlines(): -- yield line -+ yield from (description or "").splitlines() - yield "" - - if usage is None: -@@ -340,7 +350,7 @@ def render_rst( - yield line or "" - - --def setup(app): -+def setup(app: sphinx.application.Sphinx) -> Dict[str, Any]: - app.add_directive("autoprogramm", AutoprogrammDirective) - return { - "version": "0.2a0", -diff --git a/aiosmtpd/docs/conf.py b/aiosmtpd/docs/conf.py -index 6ee2d05..d3273f1 100644 ---- a/aiosmtpd/docs/conf.py -+++ b/aiosmtpd/docs/conf.py -@@ -1,6 +1,7 @@ --# -*- coding: utf-8 -*- --# --# aiosmtpd documentation build configuration file, created by -+# Copyright 2014-2021 The aiosmtpd Developers -+# SPDX-License-Identifier: Apache-2.0 -+ -+# aiosmtpd documentation build configuration file, originally created by - # sphinx-quickstart on Fri Oct 16 12:18:52 2015. - # - # This file is execfile()d with the current directory set to its -@@ -331,5 +332,5 @@ texinfo_documents = [ - # endregion - - --def setup(app): -+def setup(app): # noqa: ANN001 - app.add_css_file("aiosmtpd.css") -diff --git a/aiosmtpd/docs/proxyprotocol.rst b/aiosmtpd/docs/proxyprotocol.rst -index 30e01b7..eac41b0 100644 ---- a/aiosmtpd/docs/proxyprotocol.rst -+++ b/aiosmtpd/docs/proxyprotocol.rst -@@ -203,7 +203,7 @@ Enums - Valid only for address family of :attr:`AF.INET` or :attr:`AF.INET6` - - .. py:attribute:: rest -- :type: Union[bytes, bytearray] -+ :type: ByteString - - The contents depend on the version of the PROXY header *and* (for version 2) - the address family. -@@ -374,7 +374,7 @@ Enums - .. py:classmethod:: from_raw(raw) -> Optional[ProxyTLV] - - :param raw: The raw bytes containing the TLV Vectors -- :type raw: Union[bytes, bytearray] -+ :type raw: ByteString - :return: A new instance of ProxyTLV, or ``None`` if parsing failed - - This triggers the parsing of raw bytes/bytearray into a ProxyTLV instance. -@@ -387,7 +387,7 @@ Enums - .. py:classmethod:: parse(chunk, partial_ok=True) -> Dict[str, Any] - - :param chunk: The bytes to parse into TLV Vectors -- :type chunk: Union[bytes, bytearray] -+ :type chunk: ByteString - :param partial_ok: If ``True``, return partially-parsed TLV Vectors as is. - If ``False``, (re)raise ``MalformedTLV`` - :type partial_ok: bool -diff --git a/aiosmtpd/docs/smtp.rst b/aiosmtpd/docs/smtp.rst -index 3305079..b647e32 100644 ---- a/aiosmtpd/docs/smtp.rst -+++ b/aiosmtpd/docs/smtp.rst -@@ -499,7 +499,7 @@ aiosmtpd.smtp - - :param challenge: The SMTP AUTH challenge to send to the client. - May be in plaintext, may be in base64. Do NOT prefix with "334 "! -- :type challenge: Union[str, bytes, bytearray] -+ :type challenge: AnyStr - :param encode_to_b64: If true, will perform base64-encoding before sending - the challenge to the client. - :type encode_to_b64: bool -diff --git a/aiosmtpd/handlers.py b/aiosmtpd/handlers.py -index ada1e91..b22821e 100644 ---- a/aiosmtpd/handlers.py -+++ b/aiosmtpd/handlers.py -@@ -10,91 +10,114 @@ your own handling of messages. Implement only the methods you care about. - """ - - import asyncio -+import io - import logging - import mailbox -+import os - import re - import smtplib - import sys - from abc import ABCMeta, abstractmethod --from email import message_from_bytes, message_from_string -+from argparse import ArgumentParser -+from email.message import Message as Em_Message -+from email.parser import BytesParser, Parser -+from typing import AnyStr, Dict, List, Tuple, Type, TypeVar - - from public import public - --EMPTYBYTES = b'' --COMMASPACE = ', ' --CRLF = b'\r\n' --NLCRE = re.compile(br'\r\n|\r|\n') --log = logging.getLogger('mail.debug') -+from aiosmtpd.smtp import SMTP as SMTPServer -+from aiosmtpd.smtp import Envelope as SMTPEnvelope -+from aiosmtpd.smtp import Session as SMTPSession - -+T = TypeVar("T") - --def _format_peer(peer): -+EMPTYBYTES = b"" -+COMMASPACE = ", " -+CRLF = b"\r\n" -+NLCRE = re.compile(br"\r\n|\r|\n") -+log = logging.getLogger("mail.debug") -+ -+ -+def _format_peer(peer: str) -> str: - # This is a separate function mostly so the test suite can craft a - # reproducible output. -- return 'X-Peer: {!r}'.format(peer) -+ return "X-Peer: {!r}".format(peer) -+ -+ -+def message_from_bytes(s, *args, **kws): -+ return BytesParser(*args, **kws).parsebytes(s) -+ -+ -+def message_from_string(s, *args, **kws): -+ return Parser(*args, **kws).parsestr(s) - - - @public - class Debugging: -- def __init__(self, stream=None): -+ def __init__(self, stream: io.TextIOBase = None): - self.stream = sys.stdout if stream is None else stream - - @classmethod -- def from_cli(cls, parser, *args): -+ def from_cli(cls: Type[T], parser: ArgumentParser, *args) -> T: - error = False - stream = None - if len(args) == 0: - pass - elif len(args) > 1: - error = True -- elif args[0] == 'stdout': -+ elif args[0] == "stdout": - stream = sys.stdout -- elif args[0] == 'stderr': -+ elif args[0] == "stderr": - stream = sys.stderr - else: - error = True - if error: -- parser.error('Debugging usage: [stdout|stderr]') -+ parser.error("Debugging usage: [stdout|stderr]") - return cls(stream) - -- def _print_message_content(self, peer, data): -+ def _print_message_content(self, peer: str, data: AnyStr) -> None: - in_headers = True - for line in data.splitlines(): - # Dump the RFC 2822 headers first. - if in_headers and not line: - print(_format_peer(peer), file=self.stream) - in_headers = False -- if isinstance(data, bytes): -+ if isinstance(line, bytes): - # Avoid spurious 'str on bytes instance' warning. -- line = line.decode('utf-8', 'replace') -+ line = line.decode("utf-8", "replace") - print(line, file=self.stream) - -- async def handle_DATA(self, server, session, envelope): -- print('---------- MESSAGE FOLLOWS ----------', file=self.stream) -+ async def handle_DATA( -+ self, server: SMTPServer, session: SMTPSession, envelope: SMTPEnvelope -+ ) -> str: -+ print("---------- MESSAGE FOLLOWS ----------", file=self.stream) - # Yes, actually test for truthiness since it's possible for either the - # keywords to be missing, or for their values to be empty lists. - add_separator = False - if envelope.mail_options: -- print('mail options:', envelope.mail_options, file=self.stream) -+ print("mail options:", envelope.mail_options, file=self.stream) - add_separator = True - # rcpt_options are not currently support by the SMTP class. - rcpt_options = envelope.rcpt_options -- if any(rcpt_options): # pragma: nocover -- print('rcpt options:', rcpt_options, file=self.stream) -+ if any(rcpt_options): # pragma: nocover -+ print("rcpt options:", rcpt_options, file=self.stream) - add_separator = True - if add_separator: - print(file=self.stream) - self._print_message_content(session.peer, envelope.content) -- print('------------ END MESSAGE ------------', file=self.stream) -- return '250 OK' -+ print("------------ END MESSAGE ------------", file=self.stream) -+ return "250 OK" - - - @public - class Proxy: -- def __init__(self, remote_hostname, remote_port): -+ def __init__(self, remote_hostname: str, remote_port: int): - self._hostname = remote_hostname - self._port = remote_port - -- async def handle_DATA(self, server, session, envelope): -+ async def handle_DATA( -+ self, server: SMTPServer, session: SMTPSession, envelope: SMTPEnvelope -+ ) -> str: - if isinstance(envelope.content, str): - content = envelope.original_content - else: -@@ -107,15 +130,17 @@ class Proxy: - if NLCRE.match(line): - ending = line - break -- peer = session.peer[0].encode('ascii') -- lines.insert(_i, b'X-Peer: %s%s' % (peer, ending)) -+ peer = session.peer[0].encode("ascii") -+ lines.insert(_i, b"X-Peer: " + peer + ending) - data = EMPTYBYTES.join(lines) - refused = self._deliver(envelope.mail_from, envelope.rcpt_tos, data) - # TBD: what to do with refused addresses? -- log.info('we got some refusals: %s', refused) -- return '250 OK' -+ log.info("we got some refusals: %s", refused) -+ return "250 OK" - -- def _deliver(self, mail_from, rcpt_tos, data): -+ def _deliver( -+ self, mail_from: AnyStr, rcpt_tos: List[AnyStr], data: AnyStr -+ ) -> Dict[str, Tuple[int, bytes]]: - refused = {} - try: - s = smtplib.SMTP() -@@ -125,15 +150,15 @@ class Proxy: - finally: - s.quit() - except smtplib.SMTPRecipientsRefused as e: -- log.info('got SMTPRecipientsRefused') -+ log.info("got SMTPRecipientsRefused") - refused = e.recipients - except (OSError, smtplib.SMTPException) as e: -- log.exception('got %s', e.__class__) -+ log.exception("got %s", e.__class__) - # All recipients were refused. If the exception had an associated - # error code, use it. Otherwise, fake it with a non-triggering - # exception code. -- errcode = getattr(e, 'smtp_code', -1) -- errmsg = getattr(e, 'smtp_error', 'ignore') -+ errcode = getattr(e, "smtp_code", -1) -+ errmsg = getattr(e, "smtp_error", "ignore") - for r in rcpt_tos: - refused[r] = (errcode, errmsg) - return refused -@@ -142,75 +167,88 @@ class Proxy: - @public - class Sink: - @classmethod -- def from_cli(cls, parser, *args): -+ def from_cli(cls: Type[T], parser: ArgumentParser, *args) -> T: - if len(args) > 0: -- parser.error('Sink handler does not accept arguments') -+ parser.error("Sink handler does not accept arguments") - return cls() - - - @public - class Message(metaclass=ABCMeta): -- def __init__(self, message_class=None): -+ def __init__(self, message_class: Type[Em_Message] = None): - self.message_class = message_class - -- async def handle_DATA(self, server, session, envelope): -- envelope = self.prepare_message(session, envelope) -- self.handle_message(envelope) -- return '250 OK' -+ async def handle_DATA( -+ self, server: SMTPServer, session: SMTPSession, envelope: SMTPEnvelope -+ ) -> str: -+ message = self.prepare_message(session, envelope) -+ self.handle_message(message) -+ return "250 OK" - -- def prepare_message(self, session, envelope): -+ def prepare_message( -+ self, session: SMTPSession, envelope: SMTPEnvelope -+ ) -> Em_Message: - # If the server was created with decode_data True, then data will be a - # str, otherwise it will be bytes. - data = envelope.content -- if isinstance(data, bytes): -+ message: Em_Message -+ if isinstance(data, (bytes, bytearray)): - message = message_from_bytes(data, self.message_class) -- else: -- assert isinstance(data, str), ( -- 'Expected str or bytes, got {}'.format(type(data))) -+ elif isinstance(data, str): - message = message_from_string(data, self.message_class) -- message['X-Peer'] = str(session.peer) -- message['X-MailFrom'] = envelope.mail_from -- message['X-RcptTo'] = COMMASPACE.join(envelope.rcpt_tos) -+ else: -+ raise TypeError(f"Expected str or bytes, got {type(data)}") -+ assert isinstance(message, Em_Message) -+ message["X-Peer"] = str(session.peer) -+ message["X-MailFrom"] = envelope.mail_from -+ message["X-RcptTo"] = COMMASPACE.join(envelope.rcpt_tos) - return message - - @abstractmethod -- def handle_message(self, message): -+ def handle_message(self, message: Em_Message) -> None: - raise NotImplementedError - - - @public - class AsyncMessage(Message, metaclass=ABCMeta): -- def __init__(self, message_class=None, *, loop=None): -+ def __init__( -+ self, -+ message_class: Type[Em_Message] = None, -+ *, -+ loop: asyncio.AbstractEventLoop = None, -+ ): - super().__init__(message_class) - self.loop = loop or asyncio.get_event_loop() - -- async def handle_DATA(self, server, session, envelope): -+ async def handle_DATA( -+ self, server: SMTPServer, session: SMTPSession, envelope: SMTPEnvelope -+ ) -> str: - message = self.prepare_message(session, envelope) - await self.handle_message(message) -- return '250 OK' -+ return "250 OK" - - @abstractmethod -- async def handle_message(self, message): -+ async def handle_message(self, message: Em_Message) -> None: - raise NotImplementedError - - - @public - class Mailbox(Message): -- def __init__(self, mail_dir, message_class=None): -+ def __init__(self, mail_dir: os.PathLike, message_class: Type[Em_Message] = None): - self.mailbox = mailbox.Maildir(mail_dir) - self.mail_dir = mail_dir - super().__init__(message_class) - -- def handle_message(self, message): -+ def handle_message(self, message: Em_Message) -> None: - self.mailbox.add(message) - -- def reset(self): -+ def reset(self) -> None: - self.mailbox.clear() - - @classmethod -- def from_cli(cls, parser, *args): -+ def from_cli(cls: Type[T], parser: ArgumentParser, *args) -> T: - if len(args) < 1: -- parser.error('The directory for the maildir is required') -+ parser.error("The directory for the maildir is required") - elif len(args) > 1: -- parser.error('Too many arguments for Mailbox handler') -+ parser.error("Too many arguments for Mailbox handler") - return cls(args[0]) -diff --git a/aiosmtpd/lmtp.py b/aiosmtpd/lmtp.py -index 3f13af7..de68808 100644 ---- a/aiosmtpd/lmtp.py -+++ b/aiosmtpd/lmtp.py -@@ -11,14 +11,14 @@ class LMTP(SMTP): - show_smtp_greeting: bool = False - - @syntax('LHLO hostname') -- async def smtp_LHLO(self, arg): -+ async def smtp_LHLO(self, arg: str) -> None: - """The LMTP greeting, used instead of HELO/EHLO.""" - await super().smtp_EHLO(arg) - -- async def smtp_HELO(self, arg): -+ async def smtp_HELO(self, arg: str) -> None: - """HELO is not a valid LMTP command.""" - await self.push('500 Error: command "HELO" not recognized') - -- async def smtp_EHLO(self, arg): -+ async def smtp_EHLO(self, arg: str) -> None: - """EHLO is not a valid LMTP command.""" - await self.push('500 Error: command "EHLO" not recognized') -diff --git a/aiosmtpd/main.py b/aiosmtpd/main.py -index e978c60..2366ae4 100644 ---- a/aiosmtpd/main.py -+++ b/aiosmtpd/main.py -@@ -7,11 +7,12 @@ import os - import signal - import ssl - import sys --from argparse import ArgumentParser -+from argparse import ArgumentParser, Namespace - from contextlib import suppress - from functools import partial - from importlib import import_module - from pathlib import Path -+from typing import Optional, Sequence, Tuple - - from public import public - -@@ -167,7 +168,7 @@ def _parser() -> ArgumentParser: - return parser - - --def parseargs(args=None): -+def parseargs(args: Optional[Sequence[str]] = None) -> Tuple[ArgumentParser, Namespace]: - parser = _parser() - parsed = parser.parse_args(args) - # Find the handler class. -@@ -214,7 +215,7 @@ def parseargs(args=None): - - - @public --def main(args=None): -+def main(args: Optional[Sequence[str]] = None) -> None: - parser, args = parseargs(args=args) - - if args.setuid: # pragma: on-win32 -@@ -285,10 +286,8 @@ def main(args=None): - loop.add_signal_handler(signal.SIGINT, loop.stop) - - log.debug("Starting asyncio loop") -- try: -+ with suppress(KeyboardInterrupt): - loop.run_forever() -- except KeyboardInterrupt: -- pass - server_loop.close() - log.debug("Completed asyncio loop") - loop.run_until_complete(server_loop.wait_closed()) -diff --git a/aiosmtpd/proxy_protocol.py b/aiosmtpd/proxy_protocol.py -index 621098c..27d202a 100644 ---- a/aiosmtpd/proxy_protocol.py -+++ b/aiosmtpd/proxy_protocol.py -@@ -1,6 +1,7 @@ - # Copyright 2014-2021 The aiosmtpd Developers - # SPDX-License-Identifier: Apache-2.0 - -+import contextlib - import logging - import re - import struct -@@ -8,7 +9,7 @@ from collections import deque - from enum import IntEnum - from functools import partial - from ipaddress import IPv4Address, IPv6Address, ip_address --from typing import Any, AnyStr, Dict, Optional, Tuple, Union -+from typing import Any, AnyStr, ByteString, Dict, Optional, Tuple, Union - - import attr - from public import public -@@ -73,9 +74,10 @@ V2_PARSE_ADDR_FAMPRO = { - """Family & Proto combinations that need address parsing""" - - --__all__ = [ -+__all__ = ["struct", "partial", "IPv4Address", "IPv6Address"] -+__all__.extend( - k for k in globals().keys() if k.startswith("V1_") or k.startswith("V2_") --] + ["struct", "partial", "IPv4Address", "IPv6Address"] -+) - - - _NOT_FOUND = object() -@@ -144,10 +146,10 @@ class ProxyTLV(dict): - super().__init__(*args, **kwargs) - self.tlv_loc = _tlv_loc - -- def __getattr__(self, item): -+ def __getattr__(self, item: str) -> Any: - return self.get(item) - -- def __eq__(self, other): -+ def __eq__(self, other: Dict[str, Any]) -> bool: - return super().__eq__(other) - - def same_attribs(self, _raises: bool = False, **kwargs) -> bool: -@@ -175,7 +177,7 @@ class ProxyTLV(dict): - @classmethod - def parse( - cls, -- data: Union[bytes, bytearray], -+ data: ByteString, - partial_ok: bool = True, - strict: bool = False, - ) -> Tuple[Dict[str, Any], Dict[str, int]]: -@@ -189,7 +191,7 @@ class ProxyTLV(dict): - rslt: Dict[str, Any] = {} - tlv_loc: Dict[str, int] = {} - -- def _pars(chunk: Union[bytes, bytearray], *, offset: int): -+ def _pars(chunk: ByteString, *, offset: int) -> None: - i = 0 - while i < len(chunk): - typ = chunk[i] -@@ -228,7 +230,7 @@ class ProxyTLV(dict): - - @classmethod - def from_raw( -- cls, raw: Union[bytes, bytearray], strict: bool = False -+ cls, raw: ByteString, strict: bool = False - ) -> Optional["ProxyTLV"]: - """ - Parses raw bytes for TLV Vectors, decode them and giving them human-readable -@@ -275,7 +277,7 @@ class ProxyData: - dst_addr: Optional[EndpointAddress] = _anoinit(default=None) - src_port: Optional[int] = _anoinit(default=None) - dst_port: Optional[int] = _anoinit(default=None) -- rest: Union[bytes, bytearray] = _anoinit(default=b"") -+ rest: ByteString = _anoinit(default=b"") - """ - Rest of PROXY Protocol data following UNKNOWN (v1) or UNSPEC (v2), or containing - undecoded TLV (v2). If the latter, you can use the ProxyTLV class to parse the -@@ -302,12 +304,10 @@ class ProxyData: - return not (self.error or self.version is None or self.protocol is None) - - @property -- def tlv(self): -+ def tlv(self) -> Optional[ProxyTLV]: - if self._tlv is None: -- try: -+ with contextlib.suppress(MalformedTLV): - self._tlv = ProxyTLV.from_raw(self.rest) -- except MalformedTLV: -- pass - return self._tlv - - def with_error(self, error_msg: str, log_prefix: bool = True) -> "ProxyData": -@@ -340,7 +340,7 @@ class ProxyData: - return False - return True - -- def __bool__(self): -+ def __bool__(self) -> bool: - return self.valid - - -@@ -353,7 +353,7 @@ RE_PORT_NOLEADZERO = re.compile(r"^[1-9]\d{0,4}|0$") - # Reference: https://github.com/haproxy/haproxy/blob/v2.3.0/doc/proxy-protocol.txt - - --async def _get_v1(reader: AsyncReader, initial=b"") -> ProxyData: -+async def _get_v1(reader: AsyncReader, initial: ByteString = b"") -> ProxyData: - proxy_data = ProxyData(version=1) - proxy_data.whole_raw = bytearray(initial) - -@@ -437,7 +437,7 @@ async def _get_v1(reader: AsyncReader, initial=b"") -> ProxyData: - return proxy_data - - --async def _get_v2(reader: AsyncReader, initial=b"") -> ProxyData: -+async def _get_v2(reader: AsyncReader, initial: ByteString = b"") -> ProxyData: - proxy_data = ProxyData(version=2) - whole_raw = bytearray() - -diff --git a/aiosmtpd/qa/test_0packaging.py b/aiosmtpd/qa/test_0packaging.py -index 2240762..9dbb115 100644 ---- a/aiosmtpd/qa/test_0packaging.py -+++ b/aiosmtpd/qa/test_0packaging.py -@@ -2,8 +2,10 @@ - # SPDX-License-Identifier: Apache-2.0 - - """Test meta / packaging""" -+ - import re - import subprocess -+from datetime import datetime - from itertools import tee - from pathlib import Path - -@@ -15,6 +17,7 @@ from packaging import version - from aiosmtpd import __version__ - - RE_DUNDERVER = re.compile(r"__version__\s*?=\s*?(['\"])(?P[^'\"]+)\1\s*$") -+RE_VERHEADING = re.compile(r"(?P[0-9.]+)\s*\((?P[^)]+)\)") - - - @pytest.fixture -@@ -23,14 +26,16 @@ def aiosmtpd_version() -> version.Version: - - - class TestVersion: -- def test_pep440(self, aiosmtpd_version): -+ def test_pep440(self, aiosmtpd_version: version.Version): - """Ensure version number compliance to PEP-440""" - assert isinstance( - aiosmtpd_version, version.Version - ), "Version number must comply with PEP-440" - - # noinspection PyUnboundLocalVariable -- def test_ge_master(self, aiosmtpd_version, capsys): -+ def test_ge_master( -+ self, aiosmtpd_version: version.Version, capsys: pytest.CaptureFixture -+ ): - """Ensure version is monotonically increasing""" - reference = "master:aiosmtpd/__init__.py" - cmd = f"git show {reference}".split() -@@ -50,10 +55,11 @@ class TestVersion: - assert aiosmtpd_version >= master_ver, "Version number cannot be < master's" - - --class TestDocs: -- def test_NEWS_version(self, aiosmtpd_version): -- news_rst = next(Path("..").rglob("*/NEWS.rst")) -- with open(news_rst, "rt") as fin: -+class TestNews: -+ news_rst = list(Path("..").rglob("*/NEWS.rst"))[0] -+ -+ def test_NEWS_version(self, aiosmtpd_version: version.Version): -+ with self.news_rst.open("rt") as fin: - # pairwise() from https://docs.python.org/3/library/itertools.html - a, b = tee(fin) - next(b, None) -@@ -73,3 +79,23 @@ class TestDocs: - f"NEWS.rst is not updated: " - f"{newsver.base_version} < {aiosmtpd_version.base_version}" - ) -+ -+ def test_release_date(self, aiosmtpd_version: version.Version): -+ if aiosmtpd_version.pre is not None: -+ pytest.skip("Not a release version") -+ with self.news_rst.open("rt") as fin: -+ for ln in fin: -+ ln = ln.strip() -+ m = RE_VERHEADING.match(ln) -+ if not m: -+ continue -+ ver = version.Version(m.group("ver")) -+ if ver != aiosmtpd_version: -+ continue -+ try: -+ datetime.strptime(m.group("date"), "%Y-%m-%d") -+ except ValueError: -+ pytest.fail("Release version not dated correctly") -+ break -+ else: -+ pytest.fail("Release version has no NEWS fragment") -diff --git a/aiosmtpd/qa/test_1testsuite.py b/aiosmtpd/qa/test_1testsuite.py -index e61a71d..db20c61 100644 ---- a/aiosmtpd/qa/test_1testsuite.py -+++ b/aiosmtpd/qa/test_1testsuite.py -@@ -19,7 +19,7 @@ RE_ESC = re.compile(rb"(?P\d)\.\d+\.\d+\s") - - # noinspection PyUnresolvedReferences - @pytest.fixture(scope="module", autouse=True) --def exit_on_fail(request): -+def exit_on_fail(request: pytest.FixtureRequest): - # Behavior of this will be undefined if tests are running in parallel. - # But since parallel running is not practically possible (the ports will conflict), - # then I don't think that will be a problem. -@@ -65,7 +65,9 @@ class TestStatusCodes: - f"{key}: First digit of Enhanced Status Code different from " - f"first digit of Standard Status Code" - ) -- total_correct += 1 -+ # Can't use enumerate(); total_correct does not increase in lockstep with -+ # the loop (there are several "continue"s above) -+ total_correct += 1 # noqa: SIM113 - assert total_correct > 0 - - def test_commands(self): -diff --git a/aiosmtpd/smtp.py b/aiosmtpd/smtp.py -index 04a3497..b985b64 100644 ---- a/aiosmtpd/smtp.py -+++ b/aiosmtpd/smtp.py -@@ -24,7 +24,9 @@ from typing import ( - List, - NamedTuple, - Optional, -+ Sequence, - Tuple, -+ TypeVar, - Union, - ) - from warnings import warn -@@ -39,7 +41,7 @@ from aiosmtpd.proxy_protocol import ProxyData, get_proxy - # region #### Custom Data Types ####################################################### - - class _Missing: -- def __repr__(self): -+ def __repr__(self) -> str: - return "MISSING" - - -@@ -59,6 +61,9 @@ AuthenticatorType = Callable[["SMTP", "Session", "Envelope", str, Any], "AuthRes - AuthMechanismType = Callable[["SMTP", List[str]], Awaitable[Any]] - _TriStateType = Union[None, _Missing, bytes] - -+RT = TypeVar("RT") # "ReturnType" -+DecoratorType = Callable[[Callable[..., RT]], Callable[..., RT]] -+ - - # endregion - -@@ -149,7 +154,7 @@ class LoginPassword(NamedTuple): - - @public - class Session: -- def __init__(self, loop): -+ def __init__(self, loop: asyncio.AbstractEventLoop): - self.peer = None - self.ssl = None - self.host_name = None -@@ -172,7 +177,7 @@ class Session: - self.authenticated = None - - @property -- def login_data(self): -+ def login_data(self) -> Any: - """Legacy login_data, usually containing the username""" - log.warning( - "Session.login_data is deprecated and will be removed in version 2.0" -@@ -180,7 +185,7 @@ class Session: - return self._login_data - - @login_data.setter -- def login_data(self, value): -+ def login_data(self, value: Any) -> None: - log.warning( - "Session.login_data is deprecated and will be removed in version 2.0" - ) -@@ -189,7 +194,7 @@ class Session: - - @public - class Envelope: -- def __init__(self): -+ def __init__(self) -> None: - self.mail_from = None - self.mail_options = [] - self.smtp_utf8 = False -@@ -202,12 +207,14 @@ class Envelope: - # This is here to enable debugging output when the -E option is given to the - # unit test suite. In that case, this function is mocked to set the debug - # level on the loop (as if PYTHONASYNCIODEBUG=1 were set). --def make_loop(): -+def make_loop() -> asyncio.AbstractEventLoop: - return asyncio.get_event_loop() - - - @public --def syntax(text, extended=None, when: Optional[str] = None): -+def syntax( -+ text: str, extended: str = None, when: Optional[str] = None -+) -> DecoratorType: - """ - A @decorator that provides helptext for (E)SMTP HELP. - Applies for smtp_* methods only! -@@ -217,7 +224,7 @@ def syntax(text, extended=None, when: Optional[str] = None): - :param when: The name of the attribute of SMTP class to check; if the value - of the attribute is false-y then HELP will not be available for the command - """ -- def decorator(f): -+ def decorator(f: Callable[..., RT]) -> Callable[..., RT]: - f.__smtp_syntax__ = text - f.__smtp_syntax_extended__ = extended - f.__smtp_syntax_when__ = when -@@ -226,7 +233,7 @@ def syntax(text, extended=None, when: Optional[str] = None): - - - @public --def auth_mechanism(actual_name: str): -+def auth_mechanism(actual_name: str) -> DecoratorType: - """ - A @decorator to explicitly specifies the name of the AUTH mechanism implemented by - the function/method this decorates -@@ -234,9 +241,10 @@ def auth_mechanism(actual_name: str): - :param actual_name: Name of AUTH mechanism. Must consists of [A-Z0-9_-] only. - Will be converted to uppercase - """ -- def decorator(f): -+ def decorator(f: Callable[..., RT]) -> Callable[..., RT]: - f.__auth_mechanism_name__ = actual_name - return f -+ - actual_name = actual_name.upper() - if not VALID_AUTHMECH.match(actual_name): - raise ValueError(f"Invalid AUTH mechanism name: {actual_name}") -@@ -249,7 +257,7 @@ def login_always_fail( - return False - - --def is_int(o): -+def is_int(o: Any) -> bool: - return isinstance(o, int) - - -@@ -267,7 +275,7 @@ def sanitize(text: bytes) -> bytes: - - - @public --def sanitized_log(func: Callable, msg: AnyStr, *args, **kwargs): -+def sanitized_log(func: Callable[..., None], msg: AnyStr, *args, **kwargs) -> None: - """ - Sanitize args before passing to a logging function. - """ -@@ -305,24 +313,24 @@ class SMTP(asyncio.StreamReaderProtocol): - - def __init__( - self, -- handler, -+ handler: Any, - *, -- data_size_limit=DATA_SIZE_DEFAULT, -- enable_SMTPUTF8=False, -- decode_data=False, -- hostname=None, -- ident=None, -+ data_size_limit: int = DATA_SIZE_DEFAULT, -+ enable_SMTPUTF8: bool = False, -+ decode_data: bool = False, -+ hostname: str = None, -+ ident: str = None, - tls_context: Optional[ssl.SSLContext] = None, -- require_starttls=False, -- timeout=300, -- auth_required=False, -- auth_require_tls=True, -+ require_starttls: bool = False, -+ timeout: float = 300, -+ auth_required: bool = False, -+ auth_require_tls: bool = True, - auth_exclude_mechanism: Optional[Iterable[str]] = None, - auth_callback: AuthCallbackType = None, - command_call_limit: Union[int, Dict[str, int], None] = None, - authenticator: AuthenticatorType = None, - proxy_protocol_timeout: Optional[Union[int, float]] = None, -- loop=None -+ loop: asyncio.AbstractEventLoop = None - ): - self.__ident__ = ident or __ident__ - self.loop = loop if loop else make_loop() -@@ -343,7 +351,7 @@ class SMTP(asyncio.StreamReaderProtocol): - self.tls_context = tls_context - if tls_context: - if (tls_context.verify_mode -- not in {ssl.CERT_NONE, ssl.CERT_OPTIONAL}): -+ not in {ssl.CERT_NONE, ssl.CERT_OPTIONAL}): # noqa: DUO122 - log.warning("tls_context.verify_mode not in {CERT_NONE, " - "CERT_OPTIONAL}; this might cause client " - "connection problems") -@@ -452,13 +460,13 @@ class SMTP(asyncio.StreamReaderProtocol): - else: - raise TypeError("command_call_limit must be int or Dict[str, int]") - -- def _create_session(self): -+ def _create_session(self) -> Session: - return Session(self.loop) - -- def _create_envelope(self): -+ def _create_envelope(self) -> Envelope: - return Envelope() - -- async def _call_handler_hook(self, command, *args): -+ async def _call_handler_hook(self, command: str, *args) -> Any: - hook = self._handle_hooks.get(command) - if hook is None: - return MISSING -@@ -466,7 +474,7 @@ class SMTP(asyncio.StreamReaderProtocol): - return status - - @property -- def max_command_size_limit(self): -+ def max_command_size_limit(self) -> int: - try: - return max(self.command_size_limits.values()) - except ValueError: -@@ -484,7 +492,7 @@ class SMTP(asyncio.StreamReaderProtocol): - if closed.done() and not closed.cancelled(): - closed.exception() - -- def connection_made(self, transport): -+ def connection_made(self, transport: asyncio.transports.Transport) -> None: - # Reset state due to rfc3207 part 4.2. - self._set_rset_state() - self.session = self._create_session() -@@ -513,7 +521,7 @@ class SMTP(asyncio.StreamReaderProtocol): - self._handler_coroutine = self.loop.create_task( - self._handle_client()) - -- def connection_lost(self, error): -+ def connection_lost(self, error: Optional[Exception]) -> None: - log.info('%r connection lost', self.session.peer) - self._timeout_handle.cancel() - # If STARTTLS was issued, then our transport is the SSL protocol -@@ -527,7 +535,7 @@ class SMTP(asyncio.StreamReaderProtocol): - self._handler_coroutine.cancel() - self.transport = None - -- def eof_received(self): -+ def eof_received(self) -> bool: - log.info('%r EOF received', self.session.peer) - self._handler_coroutine.cancel() - if self.session.ssl is not None: -@@ -537,7 +545,7 @@ class SMTP(asyncio.StreamReaderProtocol): - return False - return super().eof_received() - -- def _reset_timeout(self, duration=None): -+ def _reset_timeout(self, duration: float = None) -> None: - if self._timeout_handle is not None: - self._timeout_handle.cancel() - self._timeout_handle = self.loop.call_later( -@@ -552,7 +560,9 @@ class SMTP(asyncio.StreamReaderProtocol): - # up state. - self.transport.close() - -- def _client_connected_cb(self, reader, writer): -+ def _client_connected_cb( -+ self, reader: asyncio.StreamReader, writer: asyncio.StreamWriter -+ ): - # This is redundant since we subclass StreamReaderProtocol, but I like - # the shorter names. - self._reader = reader -@@ -577,7 +587,7 @@ class SMTP(asyncio.StreamReaderProtocol): - log.debug("%r << %r", self.session.peer, response) - await self._writer.drain() - -- async def handle_exception(self, error): -+ async def handle_exception(self, error: Exception) -> str: - if hasattr(self.event_handler, 'handle_exception'): - status = await self.event_handler.handle_exception(error) - return status -@@ -678,9 +688,11 @@ class SMTP(asyncio.StreamReaderProtocol): - await self.push('500 Error: strict ASCII mode') - # Should we await self.handle_exception()? - continue -- max_sz = (self.command_size_limits[command] -- if self.session.extended_smtp -- else self.command_size_limit) -+ max_sz = ( -+ self.command_size_limits[command] -+ if self.session.extended_smtp -+ else self.command_size_limit -+ ) - if len(line) > max_sz: - await self.push('500 Command line too long') - continue -@@ -720,7 +732,8 @@ class SMTP(asyncio.StreamReaderProtocol): - self.transport.close() - continue - await self.push( -- '500 Error: command "%s" not recognized' % command) -+ f'500 Error: command "{command}" not recognized' -+ ) - continue - - # Received a valid command, reset the timer. -@@ -785,7 +798,7 @@ class SMTP(asyncio.StreamReaderProtocol): - - # SMTP and ESMTP commands - @syntax('HELO hostname') -- async def smtp_HELO(self, hostname): -+ async def smtp_HELO(self, hostname: str): - if not hostname: - await self.push('501 Syntax: HELO hostname') - return -@@ -798,7 +811,7 @@ class SMTP(asyncio.StreamReaderProtocol): - await self.push(status) - - @syntax('EHLO hostname') -- async def smtp_EHLO(self, hostname): -+ async def smtp_EHLO(self, hostname: str): - if not hostname: - await self.push('501 Syntax: EHLO hostname') - return -@@ -806,9 +819,9 @@ class SMTP(asyncio.StreamReaderProtocol): - response = [] - self._set_rset_state() - self.session.extended_smtp = True -- response.append('250-%s' % self.hostname) -+ response.append('250-' + self.hostname) - if self.data_size_limit: -- response.append('250-SIZE %s' % self.data_size_limit) -+ response.append(f'250-SIZE {self.data_size_limit}') - self.command_size_limits['MAIL'] += 26 - if not self._decode_data: - response.append('250-8BITMIME') -@@ -848,12 +861,12 @@ class SMTP(asyncio.StreamReaderProtocol): - await self.push(r) - - @syntax('NOOP [ignored]') -- async def smtp_NOOP(self, arg): -+ async def smtp_NOOP(self, arg: str): - status = await self._call_handler_hook('NOOP', arg) - await self.push('250 OK' if status is MISSING else status) - - @syntax('QUIT') -- async def smtp_QUIT(self, arg): -+ async def smtp_QUIT(self, arg: str): - if arg: - await self.push('501 Syntax: QUIT') - else: -@@ -863,7 +876,7 @@ class SMTP(asyncio.StreamReaderProtocol): - self.transport.close() - - @syntax('STARTTLS', when='tls_context') -- async def smtp_STARTTLS(self, arg): -+ async def smtp_STARTTLS(self, arg: str): - if arg: - await self.push('501 Syntax: STARTTLS') - return -@@ -1032,7 +1045,7 @@ class SMTP(asyncio.StreamReaderProtocol): - encode_to_b64=False, - ) - -- def _authenticate(self, mechanism, auth_data) -> AuthResult: -+ def _authenticate(self, mechanism: str, auth_data: Any) -> AuthResult: - if self._authenticator is not None: - # self.envelope is likely still empty, but we'll pass it anyways to - # make the invocation similar to the one in _call_handler_hook -@@ -1093,7 +1106,7 @@ class SMTP(asyncio.StreamReaderProtocol): - assert password is not None - return self._authenticate("PLAIN", LoginPassword(login, password)) - -- async def auth_LOGIN(self, _, args: List[str]): -+ async def auth_LOGIN(self, _, args: List[str]) -> AuthResult: - login: _TriStateType - if len(args) == 1: - # Client sent only "AUTH LOGIN" -@@ -1117,13 +1130,13 @@ class SMTP(asyncio.StreamReaderProtocol): - - return self._authenticate("LOGIN", LoginPassword(login, password)) - -- def _strip_command_keyword(self, keyword, arg): -+ def _strip_command_keyword(self, keyword: str, arg: str) -> Optional[str]: - keylen = len(keyword) - if arg[:keylen].upper() == keyword: - return arg[keylen:].strip() - return None - -- def _getaddr(self, arg) -> Tuple[Optional[str], Optional[str]]: -+ def _getaddr(self, arg: str) -> Tuple[Optional[str], Optional[str]]: - """ - Try to parse address given in SMTP command. - -@@ -1145,7 +1158,9 @@ class SMTP(asyncio.StreamReaderProtocol): - return None, None - return address, rest - -- def _getparams(self, params): -+ def _getparams( -+ self, params: Sequence[str] -+ ) -> Optional[Dict[str, Union[str, bool]]]: - # Return params as dictionary. Return None if not all parameters - # appear to be syntactically valid according to RFC 1869. - result = {} -@@ -1156,7 +1171,8 @@ class SMTP(asyncio.StreamReaderProtocol): - result[param] = value if eq else True - return result - -- def _syntax_available(self, method): -+ # noinspection PyUnresolvedReferences -+ def _syntax_available(self, method: Callable) -> bool: - if not hasattr(method, '__smtp_syntax__'): - return False - if method.__smtp_syntax_when__: -@@ -1193,7 +1209,7 @@ class SMTP(asyncio.StreamReaderProtocol): - if arg: - address, params = self._getaddr(arg) - if address is None: -- await self.push('502 Could not VRFY %s' % arg) -+ await self.push('502 Could not VRFY ' + arg) - else: - status = await self._call_handler_hook('VRFY', address) - await self.push( -@@ -1314,7 +1330,7 @@ class SMTP(asyncio.StreamReaderProtocol): - await self.push(status) - - @syntax('RSET') -- async def smtp_RSET(self, arg): -+ async def smtp_RSET(self, arg: str): - if arg: - await self.push('501 Syntax: RSET') - return -@@ -1458,5 +1474,5 @@ class SMTP(asyncio.StreamReaderProtocol): - await self.push('250 OK' if status is MISSING else status) - - # Commands that have not been implemented. -- async def smtp_EXPN(self, arg): -+ async def smtp_EXPN(self, arg: str): - await self.push('502 EXPN not implemented') -diff --git a/aiosmtpd/testing/helpers.py b/aiosmtpd/testing/helpers.py -index 7fa62a2..2328704 100644 ---- a/aiosmtpd/testing/helpers.py -+++ b/aiosmtpd/testing/helpers.py -@@ -12,7 +12,7 @@ import time - from smtplib import SMTP as SMTP_Client - from typing import List - --from aiosmtpd.smtp import Envelope -+from aiosmtpd.smtp import Envelope, Session, SMTP - - ASYNCIO_CATCHUP_DELAY = float(os.environ.get("ASYNCIO_CATCHUP_DELAY", 0.1)) - """ -@@ -52,12 +52,14 @@ class ReceivingHandler: - def __init__(self): - self.box = [] - -- async def handle_DATA(self, server, session, envelope): -+ async def handle_DATA( -+ self, server: SMTP, session: Session, envelope: Envelope -+ ) -> str: - self.box.append(envelope) - return "250 OK" - - --def catchup_delay(delay=ASYNCIO_CATCHUP_DELAY): -+def catchup_delay(delay: float = ASYNCIO_CATCHUP_DELAY): - """ - Sleep for awhile to give asyncio's event loop time to catch up. - """ -@@ -65,7 +67,7 @@ def catchup_delay(delay=ASYNCIO_CATCHUP_DELAY): - - - def send_recv( -- sock: socket.socket, data: bytes, end: bytes = b"\r\n", timeout=0.1 -+ sock: socket.socket, data: bytes, end: bytes = b"\r\n", timeout: float = 0.1 - ) -> bytes: - sock.send(data + end) - slist = [sock] -diff --git a/aiosmtpd/tests/conftest.py b/aiosmtpd/tests/conftest.py -index d0a6cd3..859d5ef 100644 ---- a/aiosmtpd/tests/conftest.py -+++ b/aiosmtpd/tests/conftest.py -@@ -8,10 +8,11 @@ import ssl - from contextlib import suppress - from functools import wraps - from smtplib import SMTP as SMTPClient --from typing import Generator, NamedTuple, Optional, Type -+from typing import Any, Callable, Generator, NamedTuple, Optional, Type, TypeVar - - import pytest - from pkg_resources import resource_filename -+from pytest_mock import MockFixture - - from aiosmtpd.controller import Controller - from aiosmtpd.handlers import Sink -@@ -50,6 +51,9 @@ class HostPort(NamedTuple): - port: int = 8025 - - -+RT = TypeVar("RT") # "ReturnType" -+ -+ - # endregion - - -@@ -79,15 +83,13 @@ SERVER_KEY = resource_filename("aiosmtpd.tests.certs", "server.key") - - # autouse=True and scope="session" automatically apply this fixture to ALL test cases - @pytest.fixture(autouse=True, scope="session") --def cache_fqdn(session_mocker): -+def cache_fqdn(session_mocker: MockFixture): - """ - This fixture "caches" the socket.getfqdn() call. VERY necessary to prevent - situations where quick repeated getfqdn() causes extreme slowdown. Probably due to - the DNS server thinking it was an attack or something. - """ - session_mocker.patch("socket.getfqdn", return_value=Global.FQDN) -- # -- yield - - - # endregion -@@ -97,7 +99,7 @@ def cache_fqdn(session_mocker): - - - @pytest.fixture --def get_controller(request): -+def get_controller(request: pytest.FixtureRequest) -> Callable[..., Controller]: - """ - Provides a function that will return an instance of a controller. - -@@ -122,7 +124,7 @@ def get_controller(request): - markerdata = {} - - def getter( -- handler, -+ handler: Any, - class_: Optional[Type[Controller]] = None, - **server_kwargs, - ) -> Controller: -@@ -154,7 +156,7 @@ def get_controller(request): - - - @pytest.fixture --def get_handler(request): -+def get_handler(request: pytest.FixtureRequest) -> Callable: - """ - Provides a function that will return an instance of - a :ref:`handler class `. -@@ -179,7 +181,7 @@ def get_handler(request): - else: - markerdata = {} - -- def getter(*args, **kwargs): -+ def getter(*args, **kwargs) -> Any: - if marker: - class_ = markerdata.pop("class_", default_class) - # *args overrides args_ in handler_data() -@@ -209,18 +211,22 @@ def temp_event_loop() -> Generator[asyncio.AbstractEventLoop, None, None]: - - - @pytest.fixture --def autostop_loop(temp_event_loop) -> Generator[asyncio.AbstractEventLoop, None, None]: -+def autostop_loop( -+ temp_event_loop: asyncio.AbstractEventLoop, -+) -> asyncio.AbstractEventLoop: - # Create a new event loop, and arrange for that loop to end almost - # immediately. This will allow the calls to main() in these tests to - # also exit almost immediately. Otherwise, the foreground test - # process will hang. - temp_event_loop.call_later(AUTOSTOP_DELAY, temp_event_loop.stop) - # -- yield temp_event_loop -+ return temp_event_loop - - - @pytest.fixture --def plain_controller(get_handler, get_controller) -> Generator[Controller, None, None]: -+def plain_controller( -+ get_handler: Callable, get_controller: Callable -+) -> Generator[Controller, None, None]: - """ - Returns a Controller that, by default, gets invoked with no optional args. - Hence the moniker "plain". -@@ -246,7 +252,7 @@ def plain_controller(get_handler, get_controller) -> Generator[Controller, None, - - @pytest.fixture - def nodecode_controller( -- get_handler, get_controller -+ get_handler: Callable, get_controller: Callable - ) -> Generator[Controller, None, None]: - """ - Same as :fixture:`plain_controller`, -@@ -268,7 +274,7 @@ def nodecode_controller( - - @pytest.fixture - def decoding_controller( -- get_handler, get_controller -+ get_handler: Callable, get_controller: Callable - ) -> Generator[Controller, None, None]: - handler = get_handler() - controller = get_controller(handler, decode_data=True) -@@ -285,7 +291,7 @@ def decoding_controller( - - - @pytest.fixture --def client(request) -> Generator[SMTPClient, None, None]: -+def client(request: pytest.FixtureRequest) -> Generator[SMTPClient, None, None]: - """ - Generic SMTP Client, - will connect to the ``host:port`` defined in ``Global.SrvAddr`` -@@ -302,7 +308,7 @@ def client(request) -> Generator[SMTPClient, None, None]: - - - @pytest.fixture --def ssl_context_server() -> Generator[ssl.SSLContext, None, None]: -+def ssl_context_server() -> ssl.SSLContext: - """ - Provides a server-side SSL Context - """ -@@ -310,11 +316,11 @@ def ssl_context_server() -> Generator[ssl.SSLContext, None, None]: - context.check_hostname = False - context.load_cert_chain(SERVER_CRT, SERVER_KEY) - # -- yield context -+ return context - - - @pytest.fixture --def ssl_context_client() -> Generator[ssl.SSLContext, None, None]: -+def ssl_context_client() -> ssl.SSLContext: - """ - Provides a client-side SSL Context - """ -@@ -322,14 +328,14 @@ def ssl_context_client() -> Generator[ssl.SSLContext, None, None]: - context.check_hostname = False - context.load_verify_locations(SERVER_CRT) - # -- yield context -+ return context - - - # Please keep the scope as "module"; setting it as "function" (the default) somehow - # causes the 'hidden' exception to be detected when the loop starts over in the next - # test case, defeating the silencing. - @pytest.fixture(scope="module") --def silence_event_loop_closed(): -+def silence_event_loop_closed() -> bool: - """ - Mostly used to suppress "unhandled exception" error due to - ``_ProactorBasePipeTransport`` raising an exception when doing ``__del__`` -@@ -341,9 +347,9 @@ def silence_event_loop_closed(): - return True - - # From: https://github.com/aio-libs/aiohttp/issues/4324#issuecomment-733884349 -- def silencer(func): -+ def silencer(func: Callable[..., RT]) -> Callable[..., RT]: - @wraps(func) -- def wrapper(self, *args, **kwargs): -+ def wrapper(self: Any, *args, **kwargs) -> RT: - try: - return func(self, *args, **kwargs) - except RuntimeError as e: -diff --git a/aiosmtpd/tests/test_handlers.py b/aiosmtpd/tests/test_handlers.py -index 51e06ce..35bd661 100644 ---- a/aiosmtpd/tests/test_handlers.py -+++ b/aiosmtpd/tests/test_handlers.py -@@ -3,6 +3,7 @@ - - import logging - import sys -+from email.message import Message as Em_Message - from io import StringIO - from mailbox import Maildir - from operator import itemgetter -@@ -10,14 +11,16 @@ from pathlib import Path - from smtplib import SMTPDataError, SMTPRecipientsRefused - from textwrap import dedent - from types import SimpleNamespace --from typing import AnyStr, Generator, Type, TypeVar, Union -+from typing import AnyStr, Callable, Generator, Type, TypeVar, Union - - import pytest - - from aiosmtpd.controller import Controller - from aiosmtpd.handlers import AsyncMessage, Debugging, Mailbox, Proxy, Sink -+from aiosmtpd.handlers import Message as AbstractMessageHandler - from aiosmtpd.smtp import SMTP as Server - from aiosmtpd.smtp import Session as ServerSession -+from aiosmtpd.smtp import Envelope - from aiosmtpd.testing.statuscodes import SMTP_STATUS_CODES as S - from aiosmtpd.testing.statuscodes import StatusCode - -@@ -54,7 +57,7 @@ class FakeParser: - - message: AnyStr = None - -- def error(self, message): -+ def error(self, message: AnyStr): - self.message = message - raise SystemExit - -@@ -63,16 +66,23 @@ class DataHandler: - content: AnyStr = None - original_content: bytes = None - -- async def handle_DATA(self, server, session, envelope): -+ async def handle_DATA( -+ self, server: Server, session: ServerSession, envelope: Envelope -+ ) -> str: - self.content = envelope.content - self.original_content = envelope.original_content - return S.S250_OK.to_str() - - -+class MessageHandler(AbstractMessageHandler): -+ def handle_message(self, message: Em_Message) -> None: -+ pass -+ -+ - class AsyncMessageHandler(AsyncMessage): -- handled_message = None -+ handled_message: Em_Message = None - -- async def handle_message(self, message): -+ async def handle_message(self, message: Em_Message) -> None: - self.handled_message = message - - -@@ -209,14 +219,13 @@ def debugging_controller(get_controller) -> Generator[Controller, None, None]: - - - @pytest.fixture --def temp_maildir(tmp_path: Path) -> Generator[Path, None, None]: -- maildir_path = tmp_path / "maildir" -- yield maildir_path -+def temp_maildir(tmp_path: Path) -> Path: -+ return tmp_path / "maildir" - - - @pytest.fixture - def mailbox_controller( -- temp_maildir, get_controller -+ temp_maildir, get_controller - ) -> Generator[Controller, None, None]: - handler = Mailbox(temp_maildir) - controller = get_controller(handler) -@@ -229,7 +238,7 @@ def mailbox_controller( - - - @pytest.fixture --def with_fake_parser(): -+def with_fake_parser() -> Callable: - """ - Gets a function that will instantiate a handler_class using the class's - from_cli() @classmethod, using FakeParser as the parser. -@@ -250,7 +259,7 @@ def with_fake_parser(): - handler = SimpleNamespace(fparser=parser, exception=type(e)) - return handler - -- yield handler_initer -+ return handler_initer - - - @pytest.fixture -@@ -435,6 +444,43 @@ class TestDebugging: - - - class TestMessage: -+ @pytest.mark.parametrize( -+ "content", -+ [ -+ b"", -+ bytearray(), -+ "", -+ ], -+ ids=["bytes", "bytearray", "str"] -+ ) -+ def test_prepare_message(self, temp_event_loop, content): -+ sess_ = ServerSession(temp_event_loop) -+ enve_ = Envelope() -+ handler = MessageHandler() -+ enve_.content = content -+ msg = handler.prepare_message(sess_, enve_) -+ assert isinstance(msg, Em_Message) -+ assert msg.keys() == ['X-Peer', 'X-MailFrom', 'X-RcptTo'] -+ assert msg.get_payload() == "" -+ -+ @pytest.mark.parametrize( -+ ("content", "expectre"), -+ [ -+ (None, r"Expected str or bytes, got "), -+ ([], r"Expected str or bytes, got "), -+ ({}, r"Expected str or bytes, got "), -+ ((), r"Expected str or bytes, got "), -+ ], -+ ids=("None", "List", "Dict", "Tuple") -+ ) -+ def test_prepare_message_err(self, temp_event_loop, content, expectre): -+ sess_ = ServerSession(temp_event_loop) -+ enve_ = Envelope() -+ handler = MessageHandler() -+ enve_.content = content -+ with pytest.raises(TypeError, match=expectre): -+ _ = handler.prepare_message(sess_, enve_) -+ - @handler_data(class_=DataHandler) - def test_message(self, plain_controller, client): - handler = plain_controller.handler -@@ -585,11 +631,8 @@ class TestMailbox: - # Check the messages in the mailbox. - mailbox = Maildir(temp_maildir) - messages = sorted(mailbox, key=itemgetter("message-id")) -- assert list(message["message-id"] for message in messages) == [ -- "", -- "", -- "", -- ] -+ expect = ["", "", ""] -+ assert [message["message-id"] for message in messages] == expect - - def test_mailbox_reset(self, temp_maildir, mailbox_controller, client): - client.sendmail( -@@ -766,7 +809,6 @@ class TestProxyMocked: - def patch_smtp_oserror(self, mocker): - mock = mocker.patch("aiosmtpd.handlers.smtplib.SMTP") - mock().sendmail.side_effect = OSError -- yield - - def test_oserror( - self, caplog, patch_smtp_oserror, proxy_decoding_controller, client -@@ -804,13 +846,13 @@ class TestHooks: - - def test_hook_EHLO_deprecated_warning(self): - with pytest.warns( -- DeprecationWarning, -- match=( -- # Is a regex; escape regex special chars if necessary -- r"Use the 5-argument handle_EHLO\(\) hook instead of the " -- r"4-argument handle_EHLO\(\) hook; support for the 4-argument " -- r"handle_EHLO\(\) hook will be removed in version 2.0" -- ) -+ DeprecationWarning, -+ match=( -+ # Is a regex; escape regex special chars if necessary -+ r"Use the 5-argument handle_EHLO\(\) hook instead of the " -+ r"4-argument handle_EHLO\(\) hook; support for the 4-argument " -+ r"handle_EHLO\(\) hook will be removed in version 2.0" -+ ), - ): - _ = Server(EHLOHandlerDeprecated()) - -diff --git a/aiosmtpd/tests/test_main.py b/aiosmtpd/tests/test_main.py -index 36992f3..e6b3868 100644 ---- a/aiosmtpd/tests/test_main.py -+++ b/aiosmtpd/tests/test_main.py -@@ -7,11 +7,13 @@ import multiprocessing as MP - import os - import time - from contextlib import contextmanager -+from multiprocessing.synchronize import Event as MP_Event - from smtplib import SMTP as SMTPClient - from smtplib import SMTP_SSL - from typing import Generator - - import pytest -+from pytest_mock import MockFixture - - from aiosmtpd import __version__ - from aiosmtpd.handlers import Debugging -@@ -33,7 +35,7 @@ MAIL_LOG = logging.getLogger("mail.log") - - - class FromCliHandler: -- def __init__(self, called): -+ def __init__(self, called: bool): - self.called = called - - @classmethod -@@ -63,14 +65,12 @@ def nobody_uid() -> Generator[int, None, None]: - - - @pytest.fixture --def setuid(mocker): -+def setuid(mocker: MockFixture): - if not HAS_SETUID: - pytest.skip("setuid is unavailable") - mocker.patch("aiosmtpd.main.pwd", None) - mocker.patch("os.setuid", side_effect=PermissionError) - mocker.patch("aiosmtpd.main.partial", side_effect=RuntimeError) -- # -- yield - - - # endregion -@@ -78,7 +78,7 @@ def setuid(mocker): - # region ##### Helper Funcs ########################################################### - - --def watch_for_tls(ready_flag, retq: MP.Queue): -+def watch_for_tls(ready_flag: MP_Event, retq: MP.Queue): - has_tls = False - req_tls = False - ready_flag.set() -@@ -100,7 +100,7 @@ def watch_for_tls(ready_flag, retq: MP.Queue): - retq.put(req_tls) - - --def watch_for_smtps(ready_flag, retq: MP.Queue): -+def watch_for_smtps(ready_flag: MP_Event, retq: MP.Queue): - has_smtps = False - ready_flag.set() - start = time.monotonic() -@@ -276,7 +276,7 @@ class TestParseArgs: - ) - - @pytest.mark.parametrize( -- "args, exp_host, exp_port", -+ ("args", "exp_host", "exp_port"), - [ - ((), "localhost", 8025), - (("-l", "foo:25"), "foo", 25), -@@ -333,7 +333,7 @@ class TestParseArgs: - assert args.requiretls is False - - @pytest.mark.parametrize( -- "certfile, keyfile, expect", -+ ("certfile", "keyfile", "expect"), - [ - ("x", "x", "Cert file x not found"), - (SERVER_CRT, "x", "Key file x not found"), -diff --git a/aiosmtpd/tests/test_proxyprotocol.py b/aiosmtpd/tests/test_proxyprotocol.py -index bf7f939..ad9dc9a 100644 ---- a/aiosmtpd/tests/test_proxyprotocol.py -+++ b/aiosmtpd/tests/test_proxyprotocol.py -@@ -10,12 +10,12 @@ import socket - import struct - import time - from base64 import b64decode --from contextlib import contextmanager -+from contextlib import contextmanager, suppress - from functools import partial - from ipaddress import IPv4Address, IPv6Address - from smtplib import SMTP as SMTPClient - from smtplib import SMTPServerDisconnected --from typing import Any, Dict, List, Optional -+from typing import Any, Callable, Dict, List, Optional - - import pytest - from pytest_mock import MockFixture -@@ -35,6 +35,7 @@ from aiosmtpd.proxy_protocol import ( - ) - from aiosmtpd.smtp import SMTP as SMTPServer - from aiosmtpd.smtp import Session as SMTPSession -+from aiosmtpd.smtp import Envelope as SMTPEnvelope - from aiosmtpd.tests.conftest import Global, controller_data, handler_data - - DEFAULT_AUTOCANCEL = 0.1 -@@ -94,13 +95,19 @@ HANDSHAKES = { - - - class ProxyPeekerHandler(Sink): -- def __init__(self, retval=True): -+ def __init__(self, retval: bool = True): - self.called = False - self.sessions: List[SMTPSession] = [] - self.proxy_datas: List[ProxyData] = [] - self.retval = retval - -- async def handle_PROXY(self, server, session, envelope, proxy_data): -+ async def handle_PROXY( -+ self, -+ server: SMTPServer, -+ session: SMTPSession, -+ envelope: SMTPEnvelope, -+ proxy_data: ProxyData, -+ ) -> bool: - self.called = True - self.sessions.append(session) - self.proxy_datas.append(proxy_data) -@@ -113,7 +120,9 @@ def does_not_raise(): - - - @pytest.fixture --def setup_proxy_protocol(mocker: MockFixture, temp_event_loop): -+def setup_proxy_protocol( -+ mocker: MockFixture, temp_event_loop: asyncio.AbstractEventLoop -+) -> Callable: - proxy_timeout = 1.0 - responses = [] - transport = mocker.Mock() -@@ -129,16 +138,14 @@ def setup_proxy_protocol(mocker: MockFixture, temp_event_loop): - - def runner(stop_after: float = DEFAULT_AUTOCANCEL): - loop.call_later(stop_after, protocol._handler_coroutine.cancel) -- try: -+ with suppress(asyncio.CancelledError): - loop.run_until_complete(protocol._handler_coroutine) -- except asyncio.CancelledError: -- pass - - test_obj.protocol = protocol - test_obj.runner = runner - test_obj.transport = transport - -- yield getter -+ return getter - - - class _TestProxyProtocolCommon: -@@ -303,7 +310,7 @@ class TestProxyTLV: - (None, "wrongname"), - ], - ) -- def test_backmap(self, typename, typeint): -+ def test_backmap(self, typename: str, typeint: int): - assert ProxyTLV.name_to_num(typename) == typeint - - def test_parse_partial(self): -@@ -384,14 +391,23 @@ class TestModule: - return emit - - @parametrize("handshake", HANDSHAKES.values(), ids=HANDSHAKES.keys()) -- def test_get(self, caplog, temp_event_loop, handshake): -+ def test_get( -+ self, -+ caplog: pytest.LogCaptureFixture, -+ temp_event_loop: asyncio.AbstractEventLoop, -+ handshake: bytes, -+ ): - caplog.set_level(logging.DEBUG) - mock_reader = self.MockAsyncReader(handshake) - reslt = temp_event_loop.run_until_complete(get_proxy(mock_reader)) - assert isinstance(reslt, ProxyData) - assert reslt.valid - -- def test_get_cut_v1(self, caplog, temp_event_loop): -+ def test_get_cut_v1( -+ self, -+ caplog: pytest.LogCaptureFixture, -+ temp_event_loop: asyncio.AbstractEventLoop, -+ ): - caplog.set_level(logging.DEBUG) - mock_reader = self.MockAsyncReader(GOOD_V1_HANDSHAKE[0:20]) - reslt = temp_event_loop.run_until_complete(get_proxy(mock_reader)) -@@ -401,7 +417,11 @@ class TestModule: - expect = ("mail.debug", 30, "PROXY error: PROXYv1 malformed") - assert expect in caplog.record_tuples - -- def test_get_cut_v2(self, caplog, temp_event_loop): -+ def test_get_cut_v2( -+ self, -+ caplog: pytest.LogCaptureFixture, -+ temp_event_loop: asyncio.AbstractEventLoop, -+ ): - caplog.set_level(logging.DEBUG) - mock_reader = self.MockAsyncReader(TEST_V2_DATA1_EXACT[0:20]) - reslt = temp_event_loop.run_until_complete(get_proxy(mock_reader)) -@@ -412,7 +432,11 @@ class TestModule: - expect = ("mail.debug", 30, expect_msg) - assert expect in caplog.record_tuples - -- def test_get_invalid_sig(self, caplog, temp_event_loop): -+ def test_get_invalid_sig( -+ self, -+ caplog: pytest.LogCaptureFixture, -+ temp_event_loop: asyncio.AbstractEventLoop, -+ ): - caplog.set_level(logging.DEBUG) - mock_reader = self.MockAsyncReader(b"PROXI TCP4 1.2.3.4 5.6.7.8 9 10\r\n") - reslt = temp_event_loop.run_until_complete(get_proxy(mock_reader)) -@@ -451,7 +475,7 @@ class TestGetV1(_TestProxyProtocolCommon): - assert self.transport.close.called - - @parametrize("patt", PUBLIC_V1_PATTERNS.values(), ids=PUBLIC_V1_PATTERNS.keys()) -- def test_valid_patterns(self, setup_proxy_protocol, patt: bytes): -+ def test_valid_patterns(self, setup_proxy_protocol: Callable, patt: bytes): - if not patt.endswith(b"\r\n"): - patt += b"\r\n" - setup_proxy_protocol(self) -@@ -1004,7 +1028,7 @@ class TestWithController: - # Try resending the handshake. Should also fail (because connection has - # been closed by the server. - # noinspection PyTypeChecker -- with pytest.raises(OSError) as exc_info: -+ with pytest.raises(OSError) as exc_info: # noqa: PT011 - sock.send(handshake) - resp = sock.recv(4096) - if resp == b"": -@@ -1041,7 +1065,7 @@ class TestWithController: - # Try resending the handshake. Should also fail (because connection has - # been closed by the server. - # noinspection PyTypeChecker -- with pytest.raises(OSError) as exc_info: -+ with pytest.raises(OSError) as exc_info: # noqa: PT011 - sock.send(handshake) - resp = sock.recv(4096) - if resp == b"": -@@ -1094,8 +1118,7 @@ class TestHandlerAcceptReject: - sock.sendall(handshake) - resp = sock.recv(4096) - assert oper(resp, b"") -- with expect: -- with SMTPClient() as client: -- client.sock = sock -- code, mesg = client.ehlo("example.org") -- assert code == 250 -+ with expect, SMTPClient() as client: -+ client.sock = sock -+ code, mesg = client.ehlo("example.org") -+ assert code == 250 -diff --git a/aiosmtpd/tests/test_server.py b/aiosmtpd/tests/test_server.py -index 41225dc..5e27070 100644 ---- a/aiosmtpd/tests/test_server.py -+++ b/aiosmtpd/tests/test_server.py -@@ -10,6 +10,7 @@ import socket - import time - from contextlib import ExitStack - from functools import partial -+from threading import Event - from pathlib import Path - from smtplib import SMTP as SMTPClient, SMTPServerDisconnected - from tempfile import mkdtemp -@@ -40,7 +41,7 @@ class SlowStartController(Controller): - kwargs.setdefault("ready_timeout", 0.5) - super().__init__(*args, **kwargs) - -- def _run(self, ready_event): -+ def _run(self, ready_event: Event): - time.sleep(self.ready_timeout * 1.5) - super()._run(ready_event) - -@@ -88,7 +89,7 @@ def safe_socket_dir() -> Generator[Path, None, None]: - # - yield tmpdir - # -- plist = [p for p in tmpdir.rglob("*")] -+ plist = list(tmpdir.rglob("*")) - for p in reversed(plist): - if p.is_dir(): - p.rmdir() -@@ -97,7 +98,7 @@ def safe_socket_dir() -> Generator[Path, None, None]: - tmpdir.rmdir() - - --def assert_smtp_socket(controller: UnixSocketMixin): -+def assert_smtp_socket(controller: UnixSocketMixin) -> bool: - assert Path(controller.unix_socket).exists() - sockfile = controller.unix_socket - ssl_context = controller.ssl_context -@@ -134,6 +135,7 @@ def assert_smtp_socket(controller: UnixSocketMixin): - catchup_delay() - resp = sock.recv(1024) - assert resp.startswith(b"221") -+ return True - - - class TestServer: -@@ -207,8 +209,9 @@ class TestController: - contr2 = Controller( - Sink(), hostname=Global.SrvAddr.host, port=Global.SrvAddr.port - ) -+ expectedre = r"error while attempting to bind on address" - try: -- with pytest.raises(socket.error): -+ with pytest.raises(socket.error, match=expectedre): - contr2.start() - finally: - contr2.stop() -@@ -526,6 +529,7 @@ class TestUnthreaded: - assert temp_event_loop.is_closed() is False - - -+@pytest.mark.filterwarnings("ignore::pytest.PytestUnraisableExceptionWarning") - class TestFactory: - def test_normal_situation(self): - cont = Controller(Sink()) -@@ -537,8 +541,7 @@ class TestFactory: - finally: - cont.stop() - -- @pytest.mark.filterwarnings("ignore::pytest.PytestUnraisableExceptionWarning") -- def test_unknown_args_direct(self, silence_event_loop_closed): -+ def test_unknown_args_direct(self, silence_event_loop_closed: bool): - unknown = "this_is_an_unknown_kwarg" - cont = Controller(Sink(), ready_timeout=0.3, **{unknown: True}) - expectedre = r"__init__.. got an unexpected keyword argument '" + unknown + r"'" -@@ -553,8 +556,7 @@ class TestFactory: - @pytest.mark.filterwarnings( - "ignore:server_kwargs will be removed:DeprecationWarning" - ) -- @pytest.mark.filterwarnings("ignore::pytest.PytestUnraisableExceptionWarning") -- def test_unknown_args_inkwargs(self, silence_event_loop_closed): -+ def test_unknown_args_inkwargs(self, silence_event_loop_closed: bool): - unknown = "this_is_an_unknown_kwarg" - cont = Controller(Sink(), ready_timeout=0.3, server_kwargs={unknown: True}) - expectedre = r"__init__.. got an unexpected keyword argument '" + unknown + r"'" -@@ -565,8 +567,7 @@ class TestFactory: - finally: - cont.stop() - -- @pytest.mark.filterwarnings("ignore::pytest.PytestUnraisableExceptionWarning") -- def test_factory_none(self, mocker: MockFixture, silence_event_loop_closed): -+ def test_factory_none(self, mocker: MockFixture, silence_event_loop_closed: bool): - # Hypothetical situation where factory() did not raise an Exception - # but returned None instead - mocker.patch("aiosmtpd.controller.SMTP", return_value=None) -@@ -579,8 +580,9 @@ class TestFactory: - finally: - cont.stop() - -- @pytest.mark.filterwarnings("ignore::pytest.PytestUnraisableExceptionWarning") -- def test_noexc_smtpd_missing(self, mocker, silence_event_loop_closed): -+ def test_noexc_smtpd_missing( -+ self, mocker: MockFixture, silence_event_loop_closed: bool -+ ): - # Hypothetical situation where factory() failed but no - # Exception was generated. - cont = Controller(Sink()) -diff --git a/aiosmtpd/tests/test_smtp.py b/aiosmtpd/tests/test_smtp.py -index 6fd8bfb..0fb3a15 100644 ---- a/aiosmtpd/tests/test_smtp.py -+++ b/aiosmtpd/tests/test_smtp.py -@@ -9,6 +9,7 @@ import logging - import socket - import time - import warnings -+from asyncio.transports import Transport - from base64 import b64encode - from contextlib import suppress - from smtplib import ( -@@ -19,7 +20,7 @@ from smtplib import ( - SMTPServerDisconnected, - ) - from textwrap import dedent --from typing import Any, AnyStr, Callable, Generator, List, Tuple -+from typing import cast, Any, AnyStr, Callable, Generator, List, Tuple - - import pytest - from pytest_mock import MockFixture -@@ -62,10 +63,7 @@ MAIL_LOG.setLevel(logging.DEBUG) - - - def auth_callback(mechanism, login, password) -> bool: -- if login and login.decode() == "goodlogin": -- return True -- else: -- return False -+ return login and login.decode() == "goodlogin" - - - def assert_nopassleak(passwd: str, record_tuples: List[Tuple[str, int, str]]): -@@ -87,7 +85,7 @@ class UndescribableError(Exception): - class ErrorSMTP(Server): - exception_type = ValueError - -- async def smtp_HELO(self, hostname): -+ async def smtp_HELO(self, hostname: str): - raise self.exception_type("test") - - -@@ -136,8 +134,13 @@ class PeekerHandler: - return AuthResult(success=True, auth_data=login_data) - - async def handle_MAIL( -- self, server, session: SMTPSession, envelope, address, mail_options -- ): -+ self, -+ server: Server, -+ session: SMTPSession, -+ envelope: SMTPEnvelope, -+ address: str, -+ mail_options: dict, -+ ) -> str: - self.sess = session - return S.S250_OK.to_str() - -@@ -157,7 +160,7 @@ class PeekerHandler: - async def auth_DONT(self, server, args): - return MISSING - -- async def auth_WITH_UNDERSCORE(self, server: Server, args): -+ async def auth_WITH_UNDERSCORE(self, server: Server, args) -> str: - """ - Be careful when using this AUTH mechanism; log_client_response is set to - True, and this will raise some severe warnings. -@@ -180,7 +183,9 @@ class StoreEnvelopeOnVRFYHandler: - - envelope = None - -- async def handle_VRFY(self, server, session, envelope, addr): -+ async def handle_VRFY( -+ self, server: Server, session: SMTPSession, envelope: SMTPEnvelope, addr: str -+ ) -> str: - self.envelope = envelope - return S.S250_OK.to_str() - -@@ -189,10 +194,10 @@ class ErroringHandler: - error = None - custom_response = False - -- async def handle_DATA(self, server, session, envelope): -+ async def handle_DATA(self, server, session, envelope) -> str: - return "499 Could not accept the message" - -- async def handle_exception(self, error): -+ async def handle_exception(self, error) -> str: - self.error = error - if not self.custom_response: - return "500 ErroringHandler handling error" -@@ -215,7 +220,7 @@ class ErroringHandlerConnectionLost: - class ErroringErrorHandler: - error = None - -- async def handle_exception(self, error): -+ async def handle_exception(self, error: Exception): - self.error = error - raise ValueError("ErroringErrorHandler test") - -@@ -223,13 +228,19 @@ class ErroringErrorHandler: - class UndescribableErrorHandler: - error = None - -- async def handle_exception(self, error): -+ async def handle_exception(self, error: Exception): - self.error = error - raise UndescribableError() - - - class SleepingHeloHandler: -- async def handle_HELO(self, server, session, envelope, hostname): -+ async def handle_HELO( -+ self, -+ server: Server, -+ session: SMTPSession, -+ envelope: SMTPEnvelope, -+ hostname: str, -+ ) -> str: - await asyncio.sleep(0.01) - session.host_name = hostname - return "250 {}".format(server.hostname) -@@ -267,8 +278,7 @@ class CustomIdentController(Controller): - ident: bytes = b"Identifying SMTP v2112" - - def factory(self): -- server = Server(self.handler, ident=self.ident.decode()) -- return server -+ return Server(self.handler, ident=self.ident.decode()) - - - # endregion -@@ -278,18 +288,19 @@ class CustomIdentController(Controller): - - - @pytest.fixture --def transport_resp(mocker: MockFixture): -+def transport_resp(mocker: MockFixture) -> Tuple[Transport, list]: - responses = [] - mocked = mocker.Mock() - mocked.write = responses.append - # -- yield mocked, responses -+ return cast(Transport, mocked), responses - - - @pytest.fixture - def get_protocol( -- temp_event_loop, transport_resp --) -> Generator[Callable[..., Server], None, None]: -+ temp_event_loop: asyncio.AbstractEventLoop, -+ transport_resp: Any, -+) -> Callable[..., Server]: - transport, _ = transport_resp - - def getter(*args, **kwargs) -> Server: -@@ -297,14 +308,16 @@ def get_protocol( - proto.connection_made(transport) - return proto - -- yield getter -+ return getter - - - # region #### Fixtures: Controllers ################################################## - - - @pytest.fixture --def auth_peeker_controller(get_controller) -> Generator[Controller, None, None]: -+def auth_peeker_controller( -+ get_controller: Callable[..., Controller] -+) -> Generator[Controller, None, None]: - handler = PeekerHandler() - controller = get_controller( - handler, -@@ -324,7 +337,7 @@ def auth_peeker_controller(get_controller) -> Generator[Controller, None, None]: - - @pytest.fixture - def authenticator_peeker_controller( -- get_controller, -+ get_controller: Callable[..., Controller] - ) -> Generator[Controller, None, None]: - handler = PeekerHandler() - controller = get_controller( -@@ -345,7 +358,8 @@ def authenticator_peeker_controller( - - @pytest.fixture - def decoding_authnotls_controller( -- get_handler, get_controller -+ get_handler: Callable, -+ get_controller: Callable[..., Controller] - ) -> Generator[Controller, None, None]: - handler = get_handler() - controller = get_controller( -@@ -368,7 +382,7 @@ def decoding_authnotls_controller( - - - @pytest.fixture --def error_controller(get_handler) -> Generator[ErrorController, None, None]: -+def error_controller(get_handler: Callable) -> Generator[ErrorController, None, None]: - handler = get_handler() - controller = ErrorController(handler) - controller.start() -@@ -417,10 +431,8 @@ class TestProtocol: - ] - ) - ) -- try: -+ with suppress(asyncio.CancelledError): - temp_event_loop.run_until_complete(protocol._handler_coroutine) -- except asyncio.CancelledError: -- pass - _, responses = transport_resp - assert responses[5] == S.S250_OK.to_bytes() + b"\r\n" - assert len(handler.box) == 1 -@@ -441,10 +453,8 @@ class TestProtocol: - ] - ) - ) -- try: -+ with suppress(asyncio.CancelledError): - temp_event_loop.run_until_complete(protocol._handler_coroutine) -- except asyncio.CancelledError: -- pass - _, responses = transport_resp - assert responses[5] == S.S250_OK.to_bytes() + b"\r\n" - assert len(handler.box) == 1 -@@ -986,19 +996,19 @@ class TestAuthMechanisms(_CommonMethods): - @pytest.fixture - def do_auth_plain1( - self, client -- ) -> Generator[Callable[[str], Tuple[int, bytes]], None, None]: -+ ) -> Callable[[str], Tuple[int, bytes]]: - self._ehlo(client) - - def do(param: str) -> Tuple[int, bytes]: - return client.docmd("AUTH PLAIN " + param) - - do.client = client -- yield do -+ return do - - @pytest.fixture - def do_auth_login3( - self, client -- ) -> Generator[Callable[[str], Tuple[int, bytes]], None, None]: -+ ) -> Callable[[str], Tuple[int, bytes]]: - self._ehlo(client) - resp = client.docmd("AUTH LOGIN") - assert resp == S.S334_AUTH_USERNAME -@@ -1007,7 +1017,7 @@ class TestAuthMechanisms(_CommonMethods): - return client.docmd(param) - - do.client = client -- yield do -+ return do - - def test_ehlo(self, client): - code, mesg = client.ehlo("example.com") -@@ -1119,11 +1129,11 @@ class TestAuthMechanisms(_CommonMethods): - assert_nopassleak(PW, caplog.record_tuples) - - @pytest.fixture -- def client_auth_plain2(self, client) -> Generator[SMTPClient, None, None]: -+ def client_auth_plain2(self, client) -> SMTPClient: - self._ehlo(client) - resp = client.docmd("AUTH PLAIN") - assert resp == S.S334_AUTH_EMPTYPROMPT -- yield client -+ return client - - def test_plain2_good_credentials( - self, caplog, auth_peeker_controller, client_auth_plain2 -@@ -1965,7 +1975,8 @@ class TestAuthArgs: - ], - ) - def test_authmechname_decorator_badname(self, name): -- with pytest.raises(ValueError): -+ expectre = r"Invalid AUTH mechanism name" -+ with pytest.raises(ValueError, match=expectre): - auth_mechanism(name) - - -diff --git a/aiosmtpd/tests/test_starttls.py b/aiosmtpd/tests/test_starttls.py -index 6bb2cbd..5e0a180 100644 ---- a/aiosmtpd/tests/test_starttls.py -+++ b/aiosmtpd/tests/test_starttls.py -@@ -12,6 +12,7 @@ import pytest - from aiosmtpd.controller import Controller - from aiosmtpd.handlers import Sink - from aiosmtpd.smtp import SMTP as Server -+from aiosmtpd.smtp import Envelope - from aiosmtpd.smtp import Session as Sess_ - from aiosmtpd.smtp import TLSSetupException - from aiosmtpd.testing.helpers import ReceivingHandler, catchup_delay -@@ -31,14 +32,18 @@ class EOFingHandler: - ssl_existed = None - result = None - -- async def handle_NOOP(self, server: Server, session: Sess_, envelope, arg): -+ async def handle_NOOP( -+ self, server: Server, session: Sess_, envelope: Envelope, arg: str -+ ) -> str: - self.ssl_existed = session.ssl is not None - self.result = server.eof_received() - return "250 OK" - - - class HandshakeFailingHandler: -- def handle_STARTTLS(self, server, session, envelope): -+ def handle_STARTTLS( -+ self, server: Server, session: Sess_, envelope: Envelope -+ ) -> bool: - return False - - -@@ -198,7 +203,7 @@ class TestStartTLS: - class ExceptionCaptureHandler: - error = None - -- async def handle_exception(self, error): -+ async def handle_exception(self, error: Exception) -> str: - self.error = error - return "500 ExceptionCaptureHandler handling error" - -@@ -354,7 +359,7 @@ class TestRequireTLSAUTH: - class TestTLSContext: - def test_verify_mode_nochange(self, ssl_context_server): - context = ssl_context_server -- for mode in (ssl.CERT_NONE, ssl.CERT_OPTIONAL): -+ for mode in (ssl.CERT_NONE, ssl.CERT_OPTIONAL): # noqa: DUO122 - context.verify_mode = mode - _ = Server(Sink(), tls_context=context) - assert context.verify_mode == mode -@@ -370,10 +375,10 @@ class TestTLSContext: - - def test_nocertreq_chkhost_warn(self, caplog, ssl_context_server): - context = ssl_context_server -- context.verify_mode = ssl.CERT_OPTIONAL -+ context.verify_mode = ssl.CERT_OPTIONAL # noqa: DUO122 - context.check_hostname = True - _ = Server(Sink(), tls_context=context) -- assert context.verify_mode == ssl.CERT_OPTIONAL -+ assert context.verify_mode == ssl.CERT_OPTIONAL # noqa: DUO122 - logmsg = caplog.record_tuples[0][-1] - assert "tls_context.check_hostname == True" in logmsg - assert "might cause client connection problems" in logmsg -diff --git a/housekeep.py b/housekeep.py -index 88dddd5..92b8cb6 100644 ---- a/housekeep.py -+++ b/housekeep.py -@@ -69,7 +69,8 @@ TERM_WIDTH, TERM_HEIGHT = shutil.get_terminal_size() - def deldir(targ: Path, verbose: bool = True): - if not targ.exists(): - return -- for i, pp in enumerate(reversed(sorted(targ.rglob("*"))), start=1): -+ rev_items = sorted(targ.rglob("*"), reverse=True) -+ for i, pp in enumerate(rev_items, start=1): - if pp.is_symlink(): - pp.unlink() - elif pp.is_file(): -diff --git a/setup.cfg b/setup.cfg -index 7cfbf7f..6638b75 100644 ---- a/setup.cfg -+++ b/setup.cfg -@@ -66,4 +66,54 @@ source-dir = aiosmtpd/docs - [flake8] - jobs = 1 - max-line-length = 88 --ignore = E123, E133, W503, W504, W293, E203 -+# "E,F,W,C90" are flake8 defaults -+# For others, take a gander at tox.ini to see which prefix provided by who -+select = E,F,W,C90,C4,MOD,JS,PIE,PT,SIM,ECE,C801,DUO,TAE,ANN,YTT,N400 -+ignore = -+ # black conflicts with E123 & E133 -+ E123 -+ E133 -+ # W503 conflicts with PEP8... -+ W503 -+ # W293 is a bit too noisy. Many files have been edited using editors that do not remove spaces from blank lines. -+ W293 -+ # Sometimes spaces around colons improve readability -+ E203 -+ # Sometimes we prefer the func()-based creation, not literal, for readability -+ C408 -+ # Sometimes we need to catch Exception broadly -+ PIE786 -+ # We don't really care about pytest.fixture vs pytest.fixture() -+ PT001 -+ # Good idea, but too many changes. Remove this in the future, and create separate PR -+ PT004 -+ # Sometimes exception needs to be explicitly raised in special circumstances, needing additional lines of code -+ PT012 -+ # I still can't grok the need to annotate "self" or "cls" ... -+ ANN101 -+ ANN102 -+ # I don't think forcing annotation for *args and **kwargs is a wise idea... -+ ANN002 -+ ANN003 -+ # We have too many "if..elif..else: raise" structures that does not convert well to "error-first" design -+ SIM106 -+per-file-ignores = -+ aiosmtpd/tests/test_*:ANN001 -+ aiosmtpd/tests/test_proxyprotocol.py:DUO102 -+ aiosmtpd/docs/_exts/autoprogramm.py:C801 -+# flake8-coding -+no-accept-encodings = True -+# flake8-copyright -+copyright-check = True -+# The number below was determined empirically by bisecting from 100 until no copyright-unnecessary files appear -+copyright-min-file-size = 44 -+copyright-author = The aiosmtpd Developers -+# flake8-annotations-complexity -+max-annotations-complexity = 4 -+# flake8-annotations-coverage -+min-coverage-percents = 12 -+# flake8-annotations -+mypy-init-return = True -+suppress-none-returning = True -+suppress-dummy-args = True -+allow-untyped-defs = True -diff --git a/tox.ini b/tox.ini -index 17d246e..eb2f4f6 100644 ---- a/tox.ini -+++ b/tox.ini -@@ -10,11 +10,14 @@ envdir = - py37: {toxworkdir}/3.7 - py38: {toxworkdir}/3.8 - py39: {toxworkdir}/3.9 -+ py310: {toxworkdir}/3.10 - pypy3: {toxworkdir}/pypy3 - py: {toxworkdir}/py - commands = - python housekeep.py prep -- !diffcov: bandit -c bandit.yml -r aiosmtpd -+ # Bandit is not needed on diffcov, and seems to be incompatible with 310 -+ # So, run only if "not (310 or diffcov)" ==> "(not 310) and (not diffcov)" -+ !py310-!diffcov: bandit -c bandit.yml -r aiosmtpd - nocov: pytest --verbose -p no:cov --tb=short {posargs} - cov: pytest --cov --cov-report=xml --cov-report=html --cov-report=term --tb=short {posargs} - diffcov: diff-cover _dump/coverage-{env:INTERP}.xml --html-report htmlcov/diffcov-{env:INTERP}.html -@@ -24,6 +27,7 @@ commands = - #sitepackages = True - usedevelop = True - deps = -+ # do NOT make these conditional, that way we can reuse same envdir for nocov+cov+diffcov - bandit - colorama - coverage[toml] -@@ -43,6 +47,7 @@ setenv = - py37: INTERP=py37 - py38: INTERP=py38 - py39: INTERP=py39 -+ py310: INTERP=py310 - pypy3: INTERP=pypy3 - py: INTERP=py - passenv = -@@ -51,18 +56,62 @@ passenv = - CI - GITHUB* - -+[flake8_plugins] -+# This is a pseudo-section that feeds into [testenv:qa] and GA -+# Snippets of letters above these plugins are tests that need to be "select"-ed in flake8 config (in -+# setup.cfg) to activate the respective plugins. If no snippet is given, that means the plugin is -+# always active. -+deps = -+ flake8-bugbear -+ flake8-builtins -+ flake8-coding -+ # C4 -+ flake8-comprehensions -+ # JS -+ flake8-multiline-containers -+ # PIE -+ flake8-pie -+ # MOD -+ flake8-printf-formatting -+ # PT -+ flake8-pytest-style -+ # SIM -+ flake8-simplify -+ # Cognitive Complexity looks like a good idea, but to fix the complaints... it will be an epic effort. -+ # So we disable it for now and reenable when we're ready, probably just before 2.0 -+ # # CCR -+ # flake8-cognitive-complexity -+ # ECE -+ flake8-expression-complexity -+ # C801 -+ flake8-copyright -+ # DUO -+ dlint -+ # TAE -+ flake8-annotations-complexity -+ # TAE -+ flake8-annotations-coverage -+ # ANN -+ flake8-annotations -+ # YTT -+ flake8-2020 -+ # N400 -+ flake8-broken-line -+ - [testenv:qa] - basepython = python3 - envdir = {toxworkdir}/qa - commands = - python housekeep.py prep -+ # The next line lists enabled plugins -+ python -m flake8 --version - python -m flake8 aiosmtpd setup.py housekeep.py release.py - check-manifest -v - pytest -v --tb=short aiosmtpd/qa - deps = - colorama - flake8 -- flake8-bugbear -+ {[flake8_plugins]deps} - pytest - check-manifest - -@@ -79,11 +128,13 @@ deps: - # - .github/workflows/unit-testing-and-coverage.yml - # - aiosmtpd/docs/RTD-requirements.txt - colorama -- pytest - sphinx - sphinx-autofixture - sphinx_rtd_theme - pickle5 ; python_version < '3.8' -+ # The below used as deps, need to be installed so autofixture work properly -+ pytest -+ pytest-mock - - [testenv:static] - basepython = python3 --- -2.32.0 - diff --git a/0003-URGENT-Fix-RTD-docs-gen.patch b/0003-URGENT-Fix-RTD-docs-gen.patch deleted file mode 100644 index 53c6009..0000000 --- a/0003-URGENT-Fix-RTD-docs-gen.patch +++ /dev/null @@ -1,24 +0,0 @@ -From b50563035ebf72502e25488367b46fccce5d6991 Mon Sep 17 00:00:00 2001 -From: Pandu E POLUAN -Date: Wed, 24 Mar 2021 11:03:53 +0700 -Subject: [PATCH 3/4] URGENT: Fix RTD docs gen - ---- - aiosmtpd/docs/RTD-requirements.txt | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/aiosmtpd/docs/RTD-requirements.txt b/aiosmtpd/docs/RTD-requirements.txt -index 42c1f7b..cfdaa48 100644 ---- a/aiosmtpd/docs/RTD-requirements.txt -+++ b/aiosmtpd/docs/RTD-requirements.txt -@@ -4,6 +4,7 @@ sphinx-autofixture - sphinx_rtd_theme - # Required by Sphinx.autodoc - pytest>=6.0 -+pytest-mock - - # aiosmtpd deps - atpublic --- -2.32.0 - diff --git a/0004-Make-Sphinx-RTD-deps-SSOT.patch b/0004-Make-Sphinx-RTD-deps-SSOT.patch deleted file mode 100644 index 72966bc..0000000 --- a/0004-Make-Sphinx-RTD-deps-SSOT.patch +++ /dev/null @@ -1,120 +0,0 @@ -From 215b854447e2567bbc5e3665d9a648d7b1fa2c82 Mon Sep 17 00:00:00 2001 -From: Pandu POLUAN -Date: Wed, 24 Mar 2021 12:14:03 +0700 -Subject: [PATCH 4/4] Make Sphinx/RTD deps SSOT - -Previously we can accidentally forgot to sync between tox.ini, GA yml, -and RTD-requirements.txt. - -Now tox.ini and GA yml actually refers to RTD-requirements.txt, so we -have achieved SSOT (Single Source Of Truth) for Sphinx/RTD deps. ---- - .github/workflows/unit-testing-and-coverage.yml | 7 +++++-- - aiosmtpd/docs/RTD-requirements.txt | 11 +++++++---- - aiosmtpd/docs/conf.py | 7 ++++--- - tox.ini | 11 +---------- - 4 files changed, 17 insertions(+), 19 deletions(-) - -diff --git a/.github/workflows/unit-testing-and-coverage.yml b/.github/workflows/unit-testing-and-coverage.yml -index ebc2248..eb8daa1 100644 ---- a/.github/workflows/unit-testing-and-coverage.yml -+++ b/.github/workflows/unit-testing-and-coverage.yml -@@ -37,6 +37,8 @@ jobs: - run: | - python -m pip install --upgrade pip setuptools wheel - python setup.py develop -+ # Common deps -+ pip install colorama - - name: "flake8 Style Checking" - shell: bash - # language=bash -@@ -48,12 +50,13 @@ jobs: - "config.read('tox.ini');" - "print(config['flake8_plugins']['deps']);" - ) -- pip install colorama flake8 $(python -c "${grab_f8_plugins[*]}") -+ pip install flake8 $(python -c "${grab_f8_plugins[*]}") - python -m flake8 aiosmtpd setup.py housekeep.py release.py - - name: "Docs Checking" - # language=bash - run: | -- pip install colorama pytest pytest-mock sphinx sphinx-autofixture sphinx_rtd_theme -+ # Prepare sphinx and the deps for sphinx extensions -+ pip install -r aiosmtpd/docs/RTD-requirements.txt - sphinx-build --color -b doctest -d build/.doctree aiosmtpd/docs build/doctest - sphinx-build --color -b html -d build/.doctree aiosmtpd/docs build/html - sphinx-build --color -b man -d build/.doctree aiosmtpd/docs build/man -diff --git a/aiosmtpd/docs/RTD-requirements.txt b/aiosmtpd/docs/RTD-requirements.txt -index cfdaa48..e26dc75 100644 ---- a/aiosmtpd/docs/RTD-requirements.txt -+++ b/aiosmtpd/docs/RTD-requirements.txt -@@ -1,11 +1,14 @@ --# Sphinx deps --sphinx>=2.1 -+### Sphinx deps -+pickle5 ; python_version < '3.8' -+# Sync the ver limit below with conf.py -+sphinx>=3.2 - sphinx-autofixture - sphinx_rtd_theme --# Required by Sphinx.autodoc -+ -+### Required by Sphinx.autodoc - pytest>=6.0 - pytest-mock - --# aiosmtpd deps -+### aiosmtpd deps - atpublic - attrs -diff --git a/aiosmtpd/docs/conf.py b/aiosmtpd/docs/conf.py -index d3273f1..689e4a7 100644 ---- a/aiosmtpd/docs/conf.py -+++ b/aiosmtpd/docs/conf.py -@@ -50,6 +50,8 @@ syspath_insert(repo_root / "aiosmtpd") - # :classmethod: needs Sphinx>=2.1 - # :noindex: needs Sphinx>=3.2 - needs_sphinx = "3.2" -+# If you change the above, don't forget to change the version limit in -+# `RTD-requirements.txt` - - # Add any Sphinx extension module names here, as strings. They can be - # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -@@ -62,9 +64,8 @@ extensions = [ - "autoprogramm", - "sphinx_rtd_theme" - ] --# IMPORTANT: If you edit this, also edit the following: --# - aiosmtpd/docs/RTD-requirements.txt --# - tox.ini -+# IMPORTANT: If you edit the above list, check if you need to edit the deps list -+# in `RTD-requirements.txt` - - # Add any paths that contain templates here, relative to this directory. - templates_path = ["_templates"] -diff --git a/tox.ini b/tox.ini -index eb2f4f6..e5ac6a3 100644 ---- a/tox.ini -+++ b/tox.ini -@@ -124,17 +124,8 @@ commands = - sphinx-build --color -b html -d build/.doctree aiosmtpd/docs build/html - sphinx-build --color -b man -d build/.doctree aiosmtpd/docs build/man - deps: -- # IMPORTANT: If you edit this, also edit the files: -- # - .github/workflows/unit-testing-and-coverage.yml -- # - aiosmtpd/docs/RTD-requirements.txt - colorama -- sphinx -- sphinx-autofixture -- sphinx_rtd_theme -- pickle5 ; python_version < '3.8' -- # The below used as deps, need to be installed so autofixture work properly -- pytest -- pytest-mock -+ -raiosmtpd/docs/RTD-requirements.txt - - [testenv:static] - basepython = python3 --- -2.32.0 - diff --git a/1.4.2.tar.gz b/1.4.2.tar.gz deleted file mode 100644 index 65d42fbc7e3abdb0d5bc007867a4f81232aa27e8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 139929 zcmV)8K*qlxiwFP!000001MFPub{jX6&hLH-n4XDjncWmAiL#Yw5=D|7?b?<`l*T6~ zkFn3QFR-t$RR#2gq-e>G;+&jOClSd8P$(4Y@)a&g z_*H)tssRuCW5ENFesTBD8a&-@mpFk!RE8!Mt8&SYz%p~y|%I0 z?eg_!L$M{c+I(%`{N6m@KX>ryiV&k=>zRyYio14{loV;`(I!0Y<{u% zn{YGt{EOTF-28hZnT_+o-Ri+7%>PEWdq4l5<5@EQ$7e5J_D>G}dUnt|?VldJI)1r( zdhn@Q@$vKD0S(x=pa0MBeAN6Wc^LLn@h%rS>t`ZLLY@gP3U27b;J=M!^WW)ib?4`Q zv)zI6&mn++@%jJyf$Orhh`(8;l($OLxhe)!J%LzCxUUN$12U(AeCas_(0{^Y&)+cyPFCuN-L5wW&<(i z6AAnvPf*HoEz+W+qdW^`44uSN7ORX8LQyoxs}>>-s8y}26M;G#FsXGeSe!=#ky@G+ z7f6*VXr>YoL-h;?eksEcdSR*1DxARE!IVWJ9m#kE6{NP@e?y%S$umtPS;G&N#%dR0 zda2StH<-@-G2@yw_Mk|>3*fo&TwdYVOfjBkD&m>+c^FO^jP(NF9uia4X!gd!zX+wy z9LHrpvbXFI8Ns^HsjmV7!(f*J*uG3AAEmK!iOT-h+ zK)5Jl5knQ>=Oo0KnhsSMs!JRmRFtWTF`dxc4r5lkaMC%*^(QbkXwAWK2>lh~LC{J? zq)=Hji-j+==INA1$CzQ^rHu0{_ULSo$63zWPrbE`CbPdfYxHY3^~aC5+4;}ObiLbz zKU?_cDgJr(i~Dn|d^Ks}e}Nnh;q#X!d&irgwZ1+t`*|bdKwWC~XsgNEYad0fMx^(W zwY{}jc0ZD}WD13~qHDQ*o(l0@Z=XGCcf1ZT-0|A*7hHI~Gx%6K{EF1xbOcie&9K!? z(lSlWWA~#}a37|aN$gBQuhV4GMM|NCG6{eS=Sp9K;CtN`Je3>;K^0D8+_$n5)kP{daZKVVZigr})9 zne7Op0$A6SVh09dsx2lWoua*>0}$c?Gd-@ZI?fvm`92^3KB6d{fT2o+27%NVfpegf zq#P{RpX-{A9gCXt$vC?FcJ+zKZ^G-bb&{QmJ!(3}13~eDv~c_cbd> zB``T*&f_PA{m!&?WDG%@2TTo7^f-r{!Jsd|hr*x}rH#*2gmmn@kT-*YzY#0ouQG_k zSgrw^7}uVp3Pc%^x3cmCcZ3cdh}VUE$*11^8sQ)0S>pdcG1I&L`Gowh-QBqN|DWTz z&;Rc8zx({}KL5MV|L*g@TKoqmbuk3t>$}(q`uO$#c6Y1OxnKYP49|`8pF^l{F$jQ} zxS**n_ymComN$*U+x78b{MTOVf^N*=zm1K1{P$U&m`7r}a*%BAu;DypHup7djXWII zLl8F+O~ym5in0L@;4eh-6!Sy?1Sbc(`>zhruRD&45d=I01OPBZ8mtjWn*AqG+4 zUjbmGP%p{#c$*yWAmy?w83=%O0r+HG(wOJ+_(T&&RTlJna`uYHIS*SZb^{TC4Z_R9K>Lu2L(l%$ zNcznf@L8ZRq%|;daDqvT0&RVB%WPXtIU~r2R(g0eWnIq{6nPpXGNLwDXf1 z(173ZKEeY-Jk4Y6!o;(jFpx_ijY>dRNlidj^9aIXZh*KP;2{KYqZ@_L7(#epmz%)b z@@<1}C!Kj(J-`SMk&ma@SjEfQ(+s!?)v0JOip$&OFBImw_mmN;2Y`xIK1zqELImH(WX0ec7fOt?d-4VHa*F|?s>juo5AN&!n zYp}oWnvvJs0l4`v+-5Ul{s>t-moW#8C8FTQ!2bzo45`ex$jP8l3|_0&3Y=IUBFN5) zZv98UZ(Uly&vw|O9~&$9&)dh3yw%5lZ@2#5X(e9;E3=I;S=_0jYriicfcE=fm5o|O z$di8jk^Sk#;pz8h-}O%pp0fu#n5ya)9&^?$6T8{lw_hQfajhkdOF%@m$fR`HS^)$i zi@~f77c6iIB(qBt3K$l)ON>-JGio%aEAvi+rpE=7ki%I6wsqY}Wkc_Ht$em2)Ppjc379~M5`f5R z=N*Ur>0(*UQ3RP9Y6lta@ZZb^r(S4!XU}OX&0One;J?k8x zP2Eq_csQmOVvdauAiCPz+Wl02F2vqWbhVKVI1Z#NGC!H?+i$q~z}&R-T(fK(m=)^6 zTNO+!M!Q?FH5U(Polw-l{6|EFPmfE#VLYitlOiUNcFrBOfNJ*ZE8-v}kQcfnH6)NQP*-MI6r5_4mP212o%XO)Pl3^hHV;gSgm?mGw4`eY zj(L*EaN0zFd5O!hO3}`XEY1+H6`#kDY5P1}F&iU=#S}W?l_ZZqpaGu(A>0V3Z4X+9 zok)!<7DO~g7#f+y-@=o4UO__+x0iUEogKCUgIr->ep!nJ__iLLR%ZO(a<_U1>p$15 z|H)AdIPMN;7tam*ziXSFt@-ue&GpXx`rqexR{!Y?Wb7n7&9qb4gd;{H?P!&!KIAqg zrE&t?7o3QA;&|3aivSn092*E+YBb?#Yt>ox;D;;Yp@Of;)Th7reZVhFA^Ziod!v8A z7p)vGQ&*0+-|P1>&^^a1IVrz+tKO>P#bDPm&<^6wR^M`lFKIK=10Ut|`_LhW_|xyV z9Lz4!cAS1N1t%qa{04^GD#uD~%J8{LKke3+N4cr}0Y&t4&Z3udgrIe|KZ+-u^$s^YB)WQ!S0T5K*Uq ziWR~rfH}Qar^f&aQ?Li;mc*R*?7i7%Vxja!tOdO2!+*!q<3sj0V_3yclP0{!HZOL~ zb_0C1vCy`A`Qr2y9({waDWE6_%IF`cklKBZ$3AfBuIMKZ!xOWtuL}}@i1sKmf+mjR zdGtC5!~i{QL$Y(VyM|GD8)9~}P37}LkP&zgs5;IvNWxkz8I3$WmLd$aCsoVttl8?V z;`Cpuj$pSz7e^wiXqZMgw#5dmL8t~6Ft%PE?j5}D9S{*70)^vL{e&AWFHL`#IhvD~ z$UFS|T%|RMVp1Nj&Q^K$v%n5vD(;?7+36wm6q9^-y zt!iNe<;ZJ9kfw-RX6>Z)4XNRd`BgDLdmyG)>C>!3n`hnV^e|7S*h?~<5&g9sE^Se> zdvcm4fvD5HnrZ!J7EreKMmwc>1wDm;$W;syC zv_(cK)xOktj9c6Nd|+M>CGw-iuu0TV^-Ijds^!=52!?r*$W6 za@R~7s>K4zH8L-kJ{_mn>E{->kO~oy!Nk5e(f{gn7Z1H>%2%OoI$B0D#I;z6ei>d9 zpab%#tq?%sfTsaK0dUyqbValG#%z-5`@Y?hZ9*P}b8Zh}+I?Sxp};22&n>JvKeq}^ zrn2sJpLmXA&(#(y5Q3c-;r)9Ri3CJ{-lt{}?!aK)l}6-@Jc2U)#p*YEJ(}Wj7{GZF zav!Jo{JeO3er~9jzbmRl#W;EL59=)}oR+Cfxs>Dd+75M`Tu8loMoP-e0CFDOe^xp z57oE0j&;1XCi^!$vzAU-XU!h}y6!=P27A7|y!1GAL$Si9$hzfV!_$M4S3S1-dY|nb zz1}~>rKui!essdldIwE*a&UZdw12jTubWhB|FCy@a`@dDz99l_fS6*4rvwmmdXD9$ zVMo+pdW;)Rk>KV!1MX{>CH`_V%^V8MwP<1-Od+6~1LT&Jy%JYmn88hl0J}8%qP^nG zc)N^N&rIx*czMR;4)c7ebb&EnCDT-n#u-x-H1INHoFNe5IRx5N{)76nbgpYb*I1xa zNC4yV*u0fPjR7%&od1AGFE9a_KMc@DPE4)o+K1r+Z$^g2W~SNMry{(|NnO*eA{90X z!`mMrG2O(`;9GNQACX$Q>2E8VEh3_0Iy8$IbT=_i6TC%JNwu8tVvZV?N`r=?*(3Sb zG*y=(Z5GE;72-Sdy-BMew7&=SEEQ8k62ManF+eH0)qq=7c%jEI*2G<18b0lcL%*D8 z*Clf)QJa9uBMF?)^Z;H?%$3a{NE4!~kE9=MuKoEjE3lmrd_gGB2z%ljz%-?J1Hn)P zk^>Qg5PS(!IYYh1XEo(NsJy`*;T0tKmNp*OXC3}UnE>3vr68zN*AGiTTmiR|fEDl^ zL25z@PkLsIfTm?Z)q1qY&_MHw<~1!z@eTx@Eud0@x8~3TAZiIiBZRAq2{!qoxh;~> zt>X|7JNAw@Mbt36q+LYnkoMG?rS0+B2@_MHS=j$jj`Gyx^#nXC){h2=s25qs%VYEo zrXvr@K87hkq)6ZqU)+H#3>1W;OQep1r8lAdiN|J)c!*qcc7T?~+%WOHj6{P{#GD=G zNZ{3GtTHp;y7z*S7D+$Sv8QrGAh|g$Tn+n;N-q|i0BjtIV)g5XV+T^4O`_oxJd~LoT2+93pdy1J7`KC6k>pXWFUQg! z*X$b4VuL&9q1|;xEr-f@(b1?pgA{e3(&878urpRSjN&i@1T2Bqk4TUlI#VI(w>=YJ zmv?8UZ_%|DE@wDn$xSvdJ}W&`%wk37lHQYGQoJEwni`~{DNQ=cg@zH~X>)tu5d}Ap zF-ikZQm6||(Y;PJtY&?$cE9!78J}0@()w!sl>#hMR2vpc zK9JbVoRB&O7E~0Jl#va!g7Rg|H*5Nxp##T5K4Ia3?Oiyd4xfkz`qqw4D)1cjCXW(vmSj) zRAY{~=(;yHmy;1SP`I--%=BXrGr*&SO?9C+Yi?vl3u@9vx#9o8A=ebJsmF*GR4gKV zLmsb+GUoOImd=i~&_@`GPNbi!T!ZmOJiS2ImsUWhKu-dfV7R?HjB`YSy;c+HZuD!A zH)nNQ^%{#NJO`D_VHXy7BYLR|5dC8`*C`uwZLU58`V-P#{jT>@8KK4%(l`sTTVH{^ zP2@%FS~EZ6h&mp7fd~n^-7AM*fF#z-O`Np4dTm}(Gqbu^77*}QO+f7b*?ZT;Hm)OG z^!z<|iXJE#0^C6JD%pWWO=ya;xI>W~lCtCN_yA3yNp=LH5i}r*v7Oi1@3Eik)K^vO z)@Xp##ZLB&FcXVttX}t3tFB*xgixQEA>%6^p{)s+wQ&j)pV@vy`i6ts3~a+FAGLYq zi|j3bZ4(1Cxq=Lo-zCH8UHfv9(zlFww70ngq?Rvc73IW%N(3i*gU;9(`*@DhIdU$b zBs7bNZyF}F(d`rJvs|?WKT#gR7r}gv-O^&_d*@oLxXzij$O3J73v`lz=>8X2od&&@ zj;AhOv69N1QiR#?EkH*i465B+f52R=G%rM1JMJL{aj|R2Ih4 z0p)p>!DBLGM#jJkyhf%~j&sJ81(q&iHg* zPKf##;Uvw>-RB?tM$sgRmQ}?n%iR!1Vi|OPt^9)LkL+$+>b@{}Vdu1oTP%gS>tcA! z)B0PnrXWg%J#80dnq5g3lB)ziGm%pnyx}e^%O+3qqG-(&EzX@8mRXM*=2YSPD&R!HPBbi&kt_A2 z7@5JHF}?B(S0%Rtjwn{o?3JW24BJ4W`+4)(*+nQQgef5f+i`T7`bwVIq61jUR;EHk z2Q$Ol1oUVLm&Z#2wvif}5s~A41dfLO&FzgGO2Bf3FQ8;C-&R5s;Wyh#*=%>zn(bDsux(_jzGZSnf5+AY=_K66Bez*}xoZZsj+o0xw3_KGc60haH*YYHt(gAB3zS)z;SvsH| zl?UfFY#VeN0-@7GcRRLpceg+m5!nl_%P|wYMW^n#>DWY@P|=?>+-U0gDf`Kvmdv_TU@%dWo)epu@I(ee4g-hMrT*N5Q1(XrDuz;b)- z_@~Pw0Tm}@Zf1GCysC`o31qTlz%r)WbZO1Ja3=;qqZP_V0trG5CyC+5K>^UrmtOG03Sr8BrP zuiOndUw=Mn&ChaTcs);HrLsZAEM1mP3NsL}rjeIN=o>O4uDeTTHR;0yVq6Hj=>re@`Iq_&d_8#dKX~ z=piSeC9_}9Lil51c?#-{!5|$CW;cdy4R(wnEF%AzCyRKaX3>)nL`C@H?Yr9dS*4!_HcLjkTe;BqTCc&FN{u>MFjp4lhA ztmsY49h*xQ7Vj2_BEELc9wn|1O?%or*MT|1Q*aAguA9RsGu=mlTEJD5i@WJ<7^y;7*MTu4%KJz86fapr4BsyTltM><1EE2haE)-+iWyx8MLI~u zrh{YPEr~WH+=VDeX%?+WbVV{9Z~QwwAuN#@KsI0WuoE&#uab$Fh|02us`Z}`DKrd7 z5ep8A;iCsRQ_iWd+@5g<6R);0VPA|zBDsOy%yKl)dZm-MP|xdEAdt!)mcnM!njV{- z;>6U62{OIp@gxPU39fWrQo8u_8(5kdRs-lMMV|(!OJRi$4u31_XU%Cc>!!Cs#T6hk z^+n9Ci4dJ&f4z*pBmR@-<<1_0i5Cy+fVv=JIWoYj$ij=$g0Dez_R~zUnlm=xH z)h`Y8Ww5wS=(ULC*LTmNgR^?{_3qihnVH=04$fa5zdnz?+dVzqJvu+wKZ}k}eGB{X zi)i=g`{+*xN6(4f$;6oZZp<)0b|e|om4T-wbtj1Rq=}(ZcO>NURIxxbnJ2L{ndb-R zhx;v>^`rK|(TmfAqi^SSBrA^?I8tCxxwz2Lz zJAW}wVJ7zs$#kHIu@zGS7#Pv%!XT%W8VU`a8}%FN>WP@Yaf{o#8V2C9pv$xAVqa(S zBpc~sdUVy-7&Mlew@t4w>|rh&_A1W@@O<=ihi@2j0sfyY<_Tu#I3N{(Aj9VM;U#bg z4RgbnV1-i$XN;TlgZYq#(}Fe*_8}PbvLa6Fu*&pg@HS&3>7{yN&n>{VP<(d{);&C~WnqDs6uhTBj$X?)WR|4QzKtxhJsoF z<7IveNk~LVJ7GMZUd3*F?3^+hde#ujbE{c|mALvCgw&By?k{sX&WhqFy3-VS+dy@~ zkeRYeq0cz*a^87vF74b5(n}Ioo2DcMZ@UL)DPHjz^e%KrvDP36d{zG{xd12 z^k1NGtj53~sYw>uwj$keu^;mOkDuMJ|D`{r^DpcDiQBmE{BN(9@n4A|Y<)iezs1L% zeCL0F^Z%is$edui-OZ z!)LsPe>Pr&A7$(T2l&SXTW9S*)Ti19Tlj4N8$JUyEC6cItN@5ka8@pbVwfjLT+G7V zYZYJyJ;JQ%175v8J7)}t3(M!RDKdE5f9;;x8JLo5LM#45Zl)bB{`;-n-*3L4|2LaG zw#8%4=t4jJdjUZ59oE_p7j3=Dm%Zt<{jD(%taDlh3-Fy~=q}Cr(a*R{f9@J=0=0Zf zD83ITU;<1y5@9%y8~J*YkMdcewZqu*Ge6HK>Cc=~P`_U%)1SLBI#xK)cyQH!n`Kk2 z51L=*v)Lsd)|28|98bjYk=Ed=ngSP4{k}~YLKPwAj=LAz_aTB&%wIsTMZtfzTLeG7h zuv%G?BLs7Guyzb*zY(xSOdL{NJ1_|S`316y8TWh3`LtyLN}(TfC=wPyLOoC!I5a?b zu+kLY{}=Fr#4KHjm8O6ym#*|{lFf!d97ohWEHw6%4y<4XcvvG|F~orw9wsU5bg3nH zaY?kYCPXpVjH0kOhIWzbLfG*g;txAGs`3T!K?0{BhS;!yUG)8D%R)}3w3TbMn!*Qj z!mtwl0~Esyq`JCl{h=Hx#_Fmwlw@YRL(N+As2HsP{B?@j0;GW&cCU7cHmfyEaLzM6 zTdS*k(k8XXhlhyt-B$bsb>0M31nyYU9;`J{G8|tgwD%D47v&S$=FLv6wyFuYq6XD& zl8$YxH=`dmexx5wVy}(O=!Z=_I3A~?v)5<)(P5g50S+yXeK=M3RdQ{tdi6r>{4?tI zh&yZE*?1sbXXg}l5u_p%Zl#j&}`Mr;-pG@EcrSCKW8mj7-QEpw)jjiN(vxc#evB9?x-C_9C1eahOI_WPVCxvSS72g`fznsfl%bD2PT2wbAW5} z?MVAa0iY!&G~AK~8=CgXtYAJHv)Jp6vvIH2QIA<4#Ms{YCY!9rkKmA{lL-gB6$Q>< zulI^+*ik-xffTd*__Y%q<%YI_lOIGY5(Tl+>$Pgxl=F-s;)cVb*f!DYIc#Z~{|uBQ z2RZ+$rYT(w4t1#{d=t$vGc>K&+kO&n$LqabO}y8y6Qb{yI$+U2sMXn;F?EVr+UpwB znR`pRRd9V-%*@ey@EB+8m`887pR~8zw83jeavH!}cQ}`xxK`U`d+6r+#*_B?7wwJh zmJ?;|kss5xa~?w=RJh&gYMI?!(AFL%hCtUq29UFm4X+}a#5mWc8`n9okRKxH;3e>U zhV;WQ`yh@D>EZY|T+HaINFFL!31AexO}&o#2y1xQivR_tw*scQW3U?*!UwH_ukOD& zM#=^vkls?`ajuWKMaGn3K6aX1U8MszL(Dl{fXd+d<_Kr%KwtPz@8ZKgS7-(NVnCm= z5xg%zSYp0UK!Z4YmEu@M*XeL9F(WpUU=o?`L?RowG2nXn8kn=NB!@RupMxdk)K5db zCDr&go3LE&<;Uc+8x^@B8^2S4^(`RB170c-=EHLqN@i2-s82rt+Gn`iUb>cl>9bOjpW`lXPD2!uY&;h;XTiTO5op_E9fZv5`ID&b$ zDQ&r<{UL`dP*2ZNab62q7H`Yc)ISJB1uL%#aDVM}^??)4tO|D+SyP_|r`W^6V!@3{ zJnMD4Ak9M#jhpd>%H59&X21guF^Z1iPoOEtuktDLqAkX$x7!B@%5+27P)AAcis`xF zG%T{=us4HuXo;eyD2of`S*<34SiPQmrq>AaXpT6g?4WMAU5k0Iqu>y8_<)KdJ?;G- zdv*w@d@$2=OQ-|3>^%`CZx!QRm~GDTZknjsXs6-OWu-MRD`*Nc4-+MIxIwHtQn%-~ zO_$3379NaTA7a&zeFSk=x!|=BNxaSwZL0n-E$iLb>$TtYdTaDgJAIc;FEivU?bY%z z)4}pww%^r4QUf1mt)|dw`pFncn|4M(dy{&&OC(*vHHhva5{BZdxKueNa_dQ(Q?znZ zMU8KxDGPB@k6m#IRZ9o=)j`jSU;{MHrL&Od;C_0Oa?%5DU5!YJWU3}+P!l|_n1xv( z0cxa<{KFP+U1T9nMyjk-fPS>ZeE|nz)->~%E1Z@ZO{h8bSYky^z?uTqM&brQ0ptgH zD{jg?f^`%Tl~&@D&6g)|xX~|?ING&fTBcP~4Z@ed6R)&O34lx)3;_TzO=4-a6=G?X zb~LP`uy`r*nZh(OWDFgpkv&TEUQ-U9lUq!$Yc9pJK|V=E4Ily$i!Z&(WX6lr4YvT0 zo(#z74IRA!@&m|>l63l61Ap0@4+i`S7*JRP$aqPdK6i7+*2eg-1 zJaKzxHiBd1=;*AjW}~+`V*YP9Q6))xtGW}bHaM1Vb(I92G}`D;NyDCRZnW1o+nZbP z{gRkpe%WrfFa7OB+sTi{EflkZC3co-S65@Np-nV&z(j(HviKT`zbNSZEnPPpJrqj7 zC_jUi=T>sD@HjCpzH6up7k9xx0f`xjs!-X^b+A7z%^D^O3azxQf&PP*O?Q7jN#4?rdyLijb7bKEWPzbjP;*FDA=bM38H_yMRJkadd|Wfp zD08DCuT)bhR-N4K{paqQrZs}PLYoYbRpl8-C6n5}B|9&yuN<`pKu0)zmiE z5(dIbsxadv6&BzPTaahyU}QZNTP}kU^W7{JrK4gtQB0+P38w{G6>SgndaQ?IF&6qw z5w2zicUC&$rbE6XBgo$pW`~_{&r_nK3#LS#Db#E@vL*9eO8V(4x3f~wi1`hZj_K#5 z_q+fs_0hOjU!K1@3>jI~46d#c@q+|!Y2O*UoPb{LMm@&@ z1|tbg%?VkPV;N)cgc{g&}QS54yXv>WtVy9llSy5G?>K64azrC%w z_Bg5u2B*qfgLPMnMqjz-uJWAj|20hl!*+h$XYu-Gy#9x^z2hTAq&)g2z8O4{V(lQ! zbFH@T$*kWd6AoussJRy1_3qjCM|%gy-M!uOy_c^~y3h9ycfY4y@sDL6xk;YS`0fL1 zZ9F+7d}NrDTy!fzwoDb&9B(38dBu6&>2|4Un8P?9F}^?^+br6tMpeLSlw*nuq%@pF zYY~_YG(ayXvXSr<2P5%rAEXm&ci?NI$mn3G&w4r4ns6Rq!G^fHYT`6L6lIa7lk`W{ zN3QH>Hr7zn=jmlK8w%Cyt;ZW8AE-!Bh#`~VriM8kiMPpcmbx1nIsqF+S~i(3g*X;@ z1b2A_#GrS)G(Wc>9ZVIdJYec;C6#^DE0RmPGije9@#ZLCu`^M)UqZpG8kxR?rkAQ| zao_k<7H_h#5CjfQ_0F>mGhk*m0d&Tc3S49y+mc>ha^QoJ)&x2RfQZD;nA!3=SFM+;5h}!r`ZuiF!rfhyZ2sUDh^Yn@QJ}l5pmV!^*$Qe;;MOvcIWK zF>6b%)oNRD^g8Tq%hL;{QF*z1hK#p0`mr5Hd%W^At2Ep&;}p7+iLnzE!Y|ES6%Zj> zY)|pR+2*IZx^*D@c;-5lLRpc*BUxdOoKRaPLcj2c8B&&`$m;5OHWrdgw@Wbca`4s-EitRK^ZsmUnF#&OZGK=Wdk3JDW0X;Chc z{u`q&vOnH4RH=^!OC;D&5Kff0LfluU2?!S>4QpEg#@uv8hAfNbt1?BF2x~Su2Wkt{ z#$l#%jxp}jolcucq#oi7=yJJ&A#Rd#{FYK|z6J-m_lj7IF6op*K>?k5T-)c=^vrvs zr%H8+5wUNNh(ifglx+OW#ld@Gkt{qQAp@yi|>trG- z2y7#`I^5#k@bupW?QOuPot*9A-oUgAtJ5^P!>BLlsCwQmh*M?Z0;Wkim$R{9>F5wP zpq6aeW}O6Bz|l|wDgo+bI$|u*C%F61kbc$cfh1-S&JK3sVajn?wjC2)2MW@W)!W_n<#^x6=wh%B96@*vRZ zwaH~4DRQ|Tb{7ol#}iYT?6UVv%wtpkg!S?xQ?YgXdq~};u&dsBB?fvJ=S%1{0$0KZ zH$sI=jlk7$z7h6M^cuqR)Tx_@71V-|a&A-tE#U_~`dt3MFTPm+jQ{Xke14Vl zuZLZwAoDeyOh)!gUYNg%Vrc%HUPB;;gROax-K0uQF8YRs?0&uXDxD@RdR8z%-Azh@ z+Ca)_yef%HruhE5Y|38TQUIRQ-mfS0RemV){+o1a8+p+^INCpd(u&TG_x{v9J3rmu zebrKfT$frIrHYewofO?{{PsyzE&2_3x5=9n->OPsl#DrA=nq|eQbWv!(8TI4zCJqm zb4|Tj4*03YjYN;4@g%vrNjgzJYLD`1`!*YGZE{um9&u(zFdz!*@7La*nNF?-UVjG_ucb@SNq4W&pT?W-H9G!C)WO`?e>RB zQA7tPPr3(ZGNX@Z%fdN{ZP~mxuwE1;A`+t|$+ zYQCb~2yOfDIxnV;X4HNb(V;VqoTiuN&!}Cc+?Y*@_iSsI(PjQ>uTQXSCfVy27g#&WSJ% zUCt(mIgRa4x;N?@n_tB1^nV+Yh|5wXeAwn?$Xlb5ZZ-{Rb8q2;CowX-H5&C!XQSSV z)|*YQTL+hj1e`GBpTyLl`2^aD$_TNn<{%IBY_6;-lkm^b6*8;rm1a z!U`Tm-@yQw&xQk7A=$#L9-naKLca>}Ld|$02YE1cI_^@H^Fyy3z7#&@2xWL`^LCad zC7K`Jk_n@G(iH0|Wh3a?U19_-K=ejvbN2=9A))OJL-x<6wE8!v#1y2H6OA?2BUZ0V zPfodO0zlh^(Keslb;UkCA$pY|?j@ZG7^Q>&i3bzARZCzAs?j&;4a9#K^jRj_nE=;@ zFUPhM>T(2;Mu<$KNQaj#b~g&h!2yH!im$O$hNEf=uw}c^jBPc+3RKNV15NC3JFTFw z1UVTlB^`A87dz-w+^zT}eAQOz9yh%qR=lsnop6_0jMvMd&gS(oE$-Y!{58${IdgmI zV9$yg4dUbyF0i9aUTLv=A#jKKX^B4*T#~ua(|e3Fp3|u(Mz z9(VGiVW3<=nwLrLm9{KYSeChJ??GwX4!jyHM;z~i`3dUj%8!+$Wp1mAcZG6s2&a8< z-#oK#%m5Cf&(03_ zD_HU0UXNJOe0^} zW9Jq?F7zkwzlw^8Ezn*}HI%{}r$~g>xZaw3>p60eihs*@B3*@Ln)BPjn`D~Q(wxO( z+F7NkZ7y7-cs52hv_`3troT?*W3{wHKh#aRI##^&u6Ky{Z)PCN&fN-V(r@7$57-uQ z)Ro{~nDD!3;`RB9FEO>}lbK)B!Bm~;hn#->lJ1?UBtJ1hz;wl|6sA&PlEi@$aL+6W z7hZjuEY(Fm@=daM3X62ARX6IT-qP_xXT3Ysa2}||qcn5{?ZS5mq3PUTO?bxXF0#Li zbgA@bO`(EVI{_ClbAREZyc;^u@X1#T2K`dc{j0vrOU?K1yGb%GJkCkHl#yNDTqlKz z)N!m7J@tDRh!S=(%@xUCYy&|#-iEelCBfy3Bx;WeVU=-q$2KIORHwnR&?E+SS5zES$M>4!TH0Hs+iLQ*6NM^1yAm-iWfun( zoCNj&-9qI?D(=3*Ry28g-w~Zxjouc+(%@ega&a)96Q7tZpV6wx`~ogGFS@p{xSddIWbg+@jog5xk7&E9e5R{Un- zD@t`SUeX9SDY-;~qxt{%w^FHd&E|c3eFuphxCQlars|R#gViQHCl|xq#7JWJ$>pUl z-%GVNxEQ)q8BF|ON|{&D%JAaltplZN7f=ojj|$+-H!BKbpCMQ++@9WMiu=R7NXx%H zV2{SP2{Cv4_Mp+MdcU$}yM;s13zn&AnM^8W@F&gOeyyl3YK4SYU7%0!T$n)Bde~<9 z+Mw1;!lt=IWa90tRu-&U%b=hLqz#FUR%L_$h7jAa%$To3 z{4QZok6X?K!wV<=;)<WJHPhjR8*B2QY!u8r>vhxe5j)FUII)aOB2h#p{c%gvc_aEm;hpDew}NJ>m$OTcMYq=2PY(1QoZB*my8|x&S_kC-l}hvlvGx z=(Fau)Uf4f%59$VzRxvJpPhdR;0iBMR=b;TO3JE52_|Z#Emfju4>@naS>tU6NC=b1 z%u(P6pSzDeb02fwN}7;+NoK`tEg){*wtkMhS4H+Vooj4~yjvyfz8<|9A(0nk_%C3ubJZAoHQqbh>A_LO24x1H}roBRhg|*+wSe@`m5l z?8521XT$ieeKl=wJ-NT}bNcRj;Dl=2lJo=@lY7sT4a0HaSK>73)D9a>pH0)rg2lEg z{MpV6y2R6Yw#^nmJXx8CGh3#_$0@i$1rHapzFHIFzhwx#j0?Bx;!PT`RDaFc8E?_= zzJ;OuTfod$l$z&2=L>}b=Az%LfAZ}tWdoFFbgH&R{gW+EA7pxYsGS4iUk72U^vjp) zn~y)nctcfGI^rxa>V&qOf2t{Gsl9b>Zq4k3Pl6fQ3BI*TXC~%g9d+om+h6szV2(MO)4X#{>?yLtJEL@p7MgiJNSo*>RfT#5uimTOEG-DevJ=ci ziG!ly?AY;@R-_p2lt)-?^j@yF^tIVQ>xQ;X9rfl}(@}a$OyMw@jX305YJ|}|8H)oR zXKbbeVyiSK1$X@AYAPrnI_^Pm`y!(Bs+V|YtLz?7~GUWTsaKl{HKA( zjk!Af9fcbX=}f25O^p1%vJRmQ@k^SP-I7q_^i9mVKeIC$bDp1#hTU`S z2sK;KZ#5T~Dm+3s$C6gJT7ECaPU*__Y80h*5NreZ?Ec%v#`@-V)4JBY9%b*&_?-t_ zdu0(HexvxKFERW6UirV`Qk>D?b;i6)gI!p~6b%>PAAkJ6@(!f_|Lfm;Zs;Q~^@@G-}4~X-p3IhLt`0pp{Uwn@L{w+RB*B=-n+0`hYq#xDBees{P zJ4)-nNiS@Ej{o`%K3xWV`R`5z|NDNHp8r>L(E}FiBimSh{x=?P&{;3Xe?H#+eExrn z&!fmJGHb&Xe=Y!2sy(XJ9!1~VtP3W>%PWoV{G4kic&st+9mm&V4gfSW<#5l3U zV4TP1`X*?7oWwBN9TKMu*z>ng&KQtMlaj>Y^;xV;_c9t}D8rN8^OrXHr`R(WjO=QX zTtJm$;Zl+9Nmhk+6eB4$YqV_HCD!p^#C;pOjTFl+pdHgqwsqax&pFTBI}-QC5Noo( zr#s2ED>#(wj@1R_$J*}UVXzme@PKxM*x^0P`IRL%~a|+qWYbiF^z) zt>jHb(z1v#*cqj^m*B6kiKKx5;U!5`)6TA-ppB8T$ABrh+eyT{nvDs z{r2_ITvvG|!r}eTv*V-rf_Akk$HZxqMXc07gK$zj^v+X{F_*`AP0 z`e?3NQ*cq)>H(n~%J?ywZzm-CC-(7F@$?*ceK#Q_ed*3ryQZL?3Z^BEbW>r z_g=lj%~$H1s|nqc+oQ5;da*3+mXulErLQ>YwV|*?!X@+Kb$E55Gq|!UyTW(b(vG0S zhjznVi|B;84i|1|zKQPL)+qHp9l{CaWdo*0^c`|zTq8+_a&qzP4AP zh3T(qAH$K0w{kFgCodg}lzHEQ)c=Mg;bOwne0lk#UOkwwyE^FdOJW(0~A%06@L%ntGA($ynM7D3b6k)f7p2n&lKp3f*(& z-)A^CZ-_WWZEE*-FOOgCuf=S_USpxcG-rq5zc?HrDPcwD-n%CKjphezTIJ+0SGRO# zP~st^kZY1{HAf2Z8_ozbRF(Y@zHw#WhTmMVQDvNd4e1DcWTB>=6)O8FCWeQ@F|YnClsV%# z#`u5Nc(wbdeQITIzB({5Z7Oc7HLsTD`sDeG`)9i5xbNR!jM{&Q>B_l3e7NnuCZA@+ zV)CpQD>K_mhsq-O0}h-MII4QWwo~fJO;UZ+Loiv|4Jz=EUii{XRX^x=oexMJi>8Dn zm-}V~g&xwSk|b0)Hz@FNG{6c|3n&17d&uekl+)r)MmPuMKFfjNZkA4iX*8(RyjD61 z2M?U&n#!1!qcrm8?;4@*taSWwV7Oqu9c^hYeUaemaXiWk#m>MzZNR@3_Y!6XO}+#02qRi+cO_d)VfR5x#+Ham-tWIe;ms|C zR#+Osy9I*eyZa=_cMlUCora=fhrUyx(daX(7Z)07umaXuy$~R^jhhllqRpX>V@O16j84fis!}RnV`LNAV$Vs zZzEnu&g~rertl{`hB-P=a{uQ84i4D;lW;Yo^AsU+Z zoVCbU)2 zYFrzoQ_feLF`!2_iM>pG> zPpUh*3nM_ybn8sfTyZRaJ~=)9^Y@WK#QeGInjp%F8Q+%_gK~&x@Hl_~!QLFJ2rmh$ z+dDjnIcUE#NiRE`SPQZqE2*DqR_kXymwT3(biYYnC2?g=|o%V8iQzR zMC0)KUJgkRV-FA{8J7HMKuc2w8yk4b(S6#$>krw$$W!R0WfX%X({02|yxIq&(Ubhk zoKF5Qr-IMZqEGL>%&4kSc>*FcYnt_(vsRj{=l8Dw{~m=QEC+z4E)*u0!^`D{utGSU zivAlM4E6jFBtW7MRN*dgJ4^~|>Z}jr&8cn$b5~#w*p_Dr!}fM7O0E)Q0V9n$OhQT`avWpu&l%v3$E5fH5a zkOX)G06X|V1d0YsBtE!$Ec5}cAKtPi?<*!%%o6!H`P+=-vLKedj^>diS0hI1b)@n2 zCbSvUcAZQHygzJM7(yRbyo^*N= zWYgV$d3fBD{IQaY(OmdRHc)&NOAc=G0pKWs<%CN~P!kFU5LVYP)Mh=?9OZocxOx9> z@MlVL_kz_(CLGJv>s^fV_U0FV*urE9#Q>}r=P1AAV?>+VLn2E?celwMaU%cJL1T}5 zmmlw0gAXAS!GKs&sM~khpfB#k#BR8dKKr*>EPZL5Ge*OM4;R*%WcX$3B^VrhN#X{Z zuihY%`YsL(Mk-zQvS&$lP(GJPj;crq!oPW#_Q<^)`I+k_qk>_Q*-Mb_s%*3p1(`<$ zc7c0&Fcsc!lG=BfHV2s+q#Yu1GT%-IJ4tz4E*po#Q2w}>V(i#janrxvH@7#K z^5M%E{*ygT6512KgVU#jYq^SUiSZcFiJcR0MZN954uds5yppgREWcuJHX=@9Ubjm=s zk%|oxuZMD&C-#r)^>(NM6(-Q!S2Wex)NG|GN30Dv^ouz$M&o|6-A+fKkbK-hO|2xA z73$nOfqJ`zK)S3ybs6R5>ZGaaOfLJK-u53JZ}*JEP^iejebSZMax1m*pp`l|kXAj; zjcNlIaa0XPY;ws+eaRbMw%Js;0lvu70aA~jAD)?DYO2zLOj1XoR?UhVjxz?wE|J=^ zn~Rj8XLY3th%eqvu(ACRy4o{T&t8QrXN@em0Hwk&3KQxs?Wz5*L z2>AjVwhjV7oB(KoZLCssb;o3bXU51PoK4r8aM=wrIFTdS!4Q~?kcdn;u18xo!Wjk{ zk~wI2qe!Q-@fy~*xQ1aw(Tix4p6{NX(|)5~8LaRrlCwv~uUcSoas1_XkU~1{O`}#% zGpAL|Hah&RXWQ1+pUce2oR8AE4at&uw_G-V$ z3UGa%d^jG<`X{qoBPkm~26Fr>?E98r&PXZ>aJml3GiBxBj!5i%OwAfJN2JsYx^ zs0=033Flu+m7L8o;@DWOMqa}y{SQcJ{v#ZyP z92_Qy>PIJsSPLq9op8Dw-2vd%x~tej_Ojw{vKg3pT?Hk>wyM?SAlvB!(*`85bGEOE z+zfTjfOVXMG#$61aZbIsptZb73b~#yurrt#W+n*4T;w?O&nNlVrY{O+;ISMn9ITBm zN$esXV*X$W(Z+IA_|MY+Ti)J3s0Bmtn9K`&d**MVzo(Pj%XuMyjkl5Bfz-{KiI%aYf@8GK zH0rz*7^p)7!`E)>4W|pxe#>S4?3{H=kFVK zJ{|fr+ODmC3H4M(9gcxnh3~+b+l-hpcd)_)Tmqnw*oZWlz)wR#cmYV1T>-uydIS2U zkfe{y5DHYZWBeHi3WK)gU}NAyu}Wjmx5(6Ai&oTw6Xp$)_i1JdsgpL+{_zXJIqs*~ zThS0#bV?F-iVVf;Ws$2gm^_MLVZUTK^gED4)sKLkWm$R8zId7ve{58Ra+mBecH&TR z{l#pDi<JFBBD_oh4btTd%Td2fNVJAIMbOhT^bg5xgPh3^32Nz>N zKw6|yq82B7w$H&VuV4?1(p!&`izvrO?2kn7r^!3MjAdzzBQ_fyiCU)QjawQUJuy#==ZV&zy?P>=)*Qc++sF%Ei2~fz^hpMiY*NGqh!na@C0u zy}}&nDyPli4tQ6Dofn4J=L9R_LMQAydlqRzgI=!$xzDqL$&PVVtedOiaeL!&p7b}o7d9)+*6xBEl&>;WapBbfI#*f2d3cmW5Gzb@kzDbRuMdu197jXs*)=j* zY>18`e@fB_Fq8!tN*5NFjrzmcAZ1$A-lrMOHQ|9d%RK4rHWoI8fp#ja>_rY8IP*uy z72(N&v38vEb~BFyLjfNhARdW>k0@sWES_I5&4clx2q5n!AOM9bCU3Gqn*r;H90fZ| z)EK?q2@G;hU@llmC{m4ReRu#O22RqeWHR79mNtXNaF*&99xyXAX%`kekRNk9Rb59y z4~%xqhBJ$Oz#}5g5kU5_JdW+L&`!Do!I?M{LreaeU!a3lT}Ny)y4bSBzZO}&k4fQ4 zb!DuVGK5H4K_VfwT9CjzK-p1Sm^jhAi|WoIVY6DO5H_#P78=_NZoJnkWhoN)T8OpM zFIA8>y@RUfGhlq@=hiY0>>mTsTZBb3 zO=Gd%0;$6OBWG4BC36kBIA7a+z znODu2dOZ~nyXqCfb+}vRwdOCzJTMKup5!B94Sn7bIzRt4!=X+!WZJWdAntc0X~aqT zgTf%T7p`1BzP80^bEqHRWKg|a+(m!V6v{-CzRibk^0%nqRW`zvt8TZtC29X_ozD$r z^AvH+OX6h1siUi`C|@Qrfs_7t>K;RpAQ0+Y6a%Fx_s-A4`x-lWdYkj|F1)Ub z7`Srn3QMucW>a_$Q=G?w$iYC>0BVYwDX}pARFPckH~DNdHIVos`$8>im=Psh%p~`r zGvpo^mWDAbgl~+{2K=Tc!VEhgiwZCe0j=yU$$kjd&XSC+$4wo7i9U&0&JaTNl-J$o z?g2*`RoE~feITUR;W|j2xJj?l&&6-);MRv(LaeAQ9$wmn%?nG}?)2sKKxIW$b=;lKy-V5U*bEayYvj##3aXArZw{2yYz-(OXS8A=zTY<9Rs8hKP!SSa6!w2 z(={@6O0Hk#7g=z>CO_dK~q6b zhe9~Jm?X4uWvpA?SgUP$PG=+}@|D~-G2KYWE)v{7N~8@ZF#!`Rvecj3r$m^~bI{~# zPBkn-t>AjF+Qk%6lQE3#oS!ooR8283bB1k^v1Dms)Kf`xiHo1_V~aeZ@(`=Wl7iNy z1G>0ceGR)4!49QrOhzO`c2q2+SV(U#7I$Dyyhe z+sS->zXC4czJ8$}mUS~-;EsjeP;MveiYUCSe?%hZP`cvLGR&sI*g4~GvEZJ6`}dV&BIf%e&<88qcv|Ud zsoXhD`I3=g`C#wo3kfGB5tXLcAu&`aE?Cbai-3f}mwy|uO?zo4sWPvdJbsaAt)7eb z9jw$P^;14FmahMNeNa-Xih55qK%gz0Sx^Z~Ku#VueM|wMP-ExWV$B8g@wSkgf)O`# zyNM3qaeHIEy|IYWAHc1HrhQ@*5dUnK|KPJU{^Rugd0WL7;RmPhJ|q_8KK#$kdHl~! zV1j;*|M>Mkk1XV0IxcDg*7j^?Gv3g@+wgq7%-*prSsryK(?J&~L22z#bSm3}c@wEA z#v8PKYU054Z0AY54!Ad~J?EATLs0|MQv7S3iT_TYrRU#sG5nY|?#KTv<3B?|v;Fz} z{|2As>z}@xegYJ5MtFWd{O>O|H@^6c|NR?$9pmnr!B^0)bFe_P$6yp98xGQcV@cN*ex8bH0an9IGfo{H zpIc?c?$P(rn@qN%5$sjDRne!f)K{MMB-aU?*+g%hle8eqV`S@;vp>;^^*FPiTcD7N?OT>D;%0}0zsERv7 zaRco{U!Og%)o@fLI0I7qIGGfw`Ho;T+GvIO?$FTeqr9lq_y`RYDN}<)BHkm%BCR!yrV~f{eR!pTZtCRBF^_0Yn zSzp_iQy-(Ym`7lTgUHB1m%G))BFm1~5l-(U&6@9|HuJ}7=@ zZ~Q2GCcBIfe_Gx*Z>}%4r`}vN&KDC7wHPF(Dvn4R0{MP)WcFVOf*;6;T9S(16@FeN82A7ZJ zHM21DS>?3!e4?aMXSJNpCzlSBr!VVDX?u9RSk#KnibnZ z>bsrtM)EpJCB1{btLotspK$pfw4f)OEx^G^=eo?H{2$Q|)RiCIN!N2uKWtP~>^7L? z<{T|Cd(-U6j-zN3NupUn%Xm%c_gLQUiiZVk@d25eTrDMZrLIaBCA6kH&I>h)bd6pe z^)+h`>0U+8*mHs&GpdNDYqniOVEO6(+1Zl*NOjr;p1pfI+EEjA(Z`9jO;g9~^=9<@ z=%>1xuj?J|n11_3?lVcoiRa46Mlxb5R!r5%#rMJwDEecI8wxw-_4tGPV(1QLtGuuc zZ)K!vzuy_sq zhGIH&3776l%GdPW7=!mp#RZ9~G{{b!^T*(g>EzB^iX5Ctx2vyo8(w|7bdvJ^fD1^z zd;9hy5w@=3A3kCmo!D-NMurtHMiy&Ec@&TDd_Ss}9HpFkwIPQ0jW6~~n%#tbskvjA z$r}<`{q!*GxC{R&c7n8ZT^ldTmUe6s_DZbu-gx8a7^QAAB>!b-2(LO4q`WE6*qA|P zLi1eCVrAp6hWSPLS#ejCALVmT=%4VeWY&#djgep{-0zp*M5v({|7qk>ME3HyQ61ciC*h|`g)%PJpU)|+9T#QrcHkxyVFY{dXW;{x7yVAKv zou1a`%Oc}X!`0lv%W=00HAA=C#CpJ4reB+T5%VNf7e8>_KXR|~xq@>We?d05iUv1bwtF-#uWnBk^k4^k&X4??^b@O2 zQV4`ZD{SlXmZ+vF*V}F%%66ieZrIyX={MIv?5m*b)<4pG{bYH*xImvH9Il^ z#Kd;>2vaXutkRanif6e2(BchI&L|xnr?`iIa`YL^(ba1ue3y>4ZaBOJKXdGCSNXz) zWr%QeXE5Y1C^5?A=Pvf{#W3%`Sx``9uZ6X+dSKzNxE>b#7--b)DPwhO^W}bV$$QyB zW>QScS$qAvsMRzH&wbx&`G`>DZl(E~jM=AdcQz77z(Kd`okOgssa!h_2akpTL|`J4DK%i-DuGc^}JrnFYT9!$N9LizNC^)c=K4@nv}UwRo|pBt`H&t>q~c9 z7kB$kb-U$P?om55=kGzi0;&`b<|8-Pw_sV_#ic@^@bbE^>m&_(ovvsNT>>{B=rDfp z-ubbzhovd4?4(>jm6MBBD>`Gcq0_Imii2!sac-$pc~j~mAA50uw`4#7J_@i&jev?& ztagcdc$FwrUsyvclK*a$6($<~Th^O(^N9{%Uei%Acu%G2G#;wZlz$efd_sjxsqH{k z)f?a&6sedHLkUV%#Qc1&^uVFaRlMWfxKKg82{E(R=M7 zOXw9>mCQ`Mvlp+c_li8bXOS=ReAqCDY`)%Lxp_mB4~J#i%2(my6To|~q8?`N?yn}C z()r3%>jn$cBqiQz!dzT+Z(4JY4VhUo6+7D*@Yc9gf> z{0F6N}&UU}$y%-3erj)!w(BiAHPAJwbzd67;P5hbZLf% z;K$(G|A>CT`#<>O>--pOQNNXq&X4YW9e_~Adfn>4g(6pKznSkbJEh93K|MCspiYN* z<#|pfY|uRkOUkoG{om@^s=c4UPDJ(ps5hfkSxCHBwt1TB{h4U^mxNd;f(0#`lJU5D zie$m(tlKv1FCE%VYfnMBc1#t1Y|F154oA$9v3PDI<^cxdmeVfof!_pbKR z=gXuh7g?||Djbwtx!}hIzd7kuRxWtQv%!Uyffi%-cQM?#>)%bK{6y3E)4FeziPV}= zvISLam+C3wrtQ(J|7C{Uj$hZd#3;$$%BS|6T9-S-Kk zj#cUyrJH(3c-lb)<*Cy#U5_`D^}44N0}91(m=3$pUU!S+652CxdR1j^CmB#b%7uRU z95V1pKFj@o1z7!KJ-|Q2|NHUg)@T3k-{AA0^|!#z{i67QHtvc4*xcGG=l|KDyz(8jr5p>NmTwp5Dk0H_7BG8@1_HqNjNH z3lfdLr6CROqU$Z~la?B$m-KS`v1wICl>MFB+Sq*j`_jwXRWGl9wRDh4|IHOc^CB5> zKIv$1Yr-IP|0YJ5WHene=n>Gn{gOPzlN8#av?aI$-b7y}H`(xxZrB&uBw<|Udh1m> z8s@D%X7-YzReyak8%<}?t9+E#TL&ZI0+VUds(+nL3qXP2MBk?L`Wf|Ai`9p-el|!f z%h;;#<+BO!2#(U*dh3P?(XjgI{6wy=yNSG}2@-5n>b&1=Df}&S+(I~ww+QcWe9bln348PJQO>ay;X*)fOsJ@Z$$Lg}9PAjS^l54ND zE0e2>#>VECBwp)(np}CJrGOaMR(w1#;}NWw6J~4&)WdX8>eWA+wEkc5S$h8i`}bGR z|F`jE>q$BOYvYS2>!0)g{T3f&)WR}%YSpRxc6Mr)wWkJ@u~hIk;O&?p9uCuoVN0eqRBiLh@WcSQefQ*`=7xP<#zHO4`3t)$nDR*m zU=7Y{LM$Pk5Vapoi&pLSI%hmSj(f5oTLu#o0h?%>X^hkEekK#iT3p`wv>v2slyO<;z_Wl zUCs^ON;xG%{+-6$p}Zwv&Vt>X37Fx?%;n*oxC z?^m~o$f_W4hk9PPe+Ch3%~epOI{A2Cj!-EpLj!q$CG!Id^wer!L|MP?}Mb!3d6IiNYwG1Wmw?gGU39eGK?ld46NtCRbzfO$}24)RMC! z8KW4-Xgn*f1>VqqN&_Au$4Scj%wiCtYEDWZxq3X$Rmmt(YMhsNnwvaR-m%pk7Bl`m z5G$jnXXQuF02?Shn}5lWib43Ief-P=?DD#GliVq~w@#kf*g$f$=L!pM4%I80z~&`G z^v|6uK3Zo2{+iO_vYpaxK0TwoR*6IcH`v>G9w1V^s$Dwv0!_TS%BO90RdKX zYEp?s*MO}U)3Q&y;x4LakZlO;^r=Y-UhVI_+&wxtd)4dJB$Y|8=RGrNjA+}mX)Ngk zsZu0pK@YJ#MK!*N@Q9&5!vRpA8m=c=DdQ$C-}a^4Cb6Wmv>a=vV@_+>YlffWG%F^* z3~&fFKFHsHvi*Gb z?B)I$BLeDhxk;WfRA{q}C{(Ulgl-qFcf00&+1zIW6z}?|I|Fv0i!?Ivt0tqVxl64TZiBEmKhk$v24R)wB(5FE!8X{hnux|G zLa3;4jZ>n8b%Hq6gh22eW9Wsc*0^fPs#+XR6tUwr$hvbpPDr{+Y!0ql&rsZq+RvhJ zDP2`LfPxFdF0H?L~x-LAd-4P-IQP;SG}%eaXV zoPQr*AhsXjGJaV9QE2w8n3*ga#F8@7qfhDOorceMzu%sBsLp_@Ri^1YAa7ueY<^I_ zLpV#SaOF1p9hdJ<(t+eI(mVZN6mA4}034M7Bs{b#7kA1FhiOuGF)4xBa*=wv_q<4RzI^$I73<}u3~<9srfd_Z+f&3ugm)Ly5E?~%3J>~ zh@Xt*(-FvFd=ns9HN=oq%^Oovr?LUI^f&lYO|7>D@T>>mZu#Q*^Tgm<8^EKv>Tv zK|f2{6E1j_aM<6#v>A3t#a$fpPIPLIY$-K87eWs^<>i;mH-;SEaxPiqxz%-5sA&WX z2Dn2+QA!lyL?{CFa-JYEd@d(L9Y{i3cbo!dLy}53^6kj9B)PR1{&dG=g@TxpM8e=P zrT*B6(okPwq~)=g~8B1b?f7chO^VzflDLj6<<#@oy= z&gMXcXaA7o%Fzk^0C}v(gC)|Wz9^iufoRi4yd?xq_aXFU6$DKh@ONTkwPlv6Wsvwm z!5D7Vr(dRFqKS5Gs3v_^S(c7$ba+D>Up2|sBjcb1^8rLUm zr|AS9*YDFGYW=y{?t1MS-V8Y|TAZmwLEt5+g@m&jKPOfL@k!_>#6RN*&RARy+wcb| z;vZgFp0o^F!3Ya9+%-@%m!uK;jXYqq8kmTdkOI*nena$+ARZ5GaozlsUgEciZ znbX8Nf~06?!mVHycxzpAS~%v>E})xCCE2?d4$j!sbNPY2sWhxp%`Vz_4F8>VY-5E0Moi|Od~ti$SpWrpO7n{@!__qn{q{~j6m`2~w)4{^9myQ8}$ zi(@m1Ury4rEjw)fij4ggurr^$l{<5OIN8Xil$cXS`e^_DaqGKO71qfc zT-wugtg!e<5j>^-C7fdd=MUHmP(%c&mm67}#x3^c#U0hO=|eQ{SB zCpjMYw(P>yl)sl$5*0ENUa6Vq;RR_D&(Tc0%x_cX(QkEtqnufTNj@|%_YLi0)8vcJ zFGW656A4Q@aqWa*&aoz}#v*EtWTR1flX2#XwFw08fn^d(d8tbii8b06Rb|bt!LEg9 z=QJ$FV!~X7#cmID?KFSLw>AL>^v|}q{%d`f+W+Zd`2^Fa0v|8MYt z>`%+Q!2Dk$y69zd6Zif1v-)!uK{|*;3dT9oxQcqYlpSg^8+m!3YD#hZRB|TeChMpG zGs~v;xmOuf%y60{Ugfu}xiz_ethi;<{1JuuURB*;O$_X*X z#$3)#?Wn-EGKIfP-sbSb4_2f`t31v7Ih3;b5bFb(Qf@5C)nSXP$Y^Ikx)s4x4Z-n> z*d~nG%;@i-2vcaV)HcCZ5$~W9B{iZNKOzV^0%} zYh&gA`*B5n-P~M91p6R+%hF3>)|r_{Q#}Txr8lCl?^3@_TwR*Tm-Y-Gin1$gJv3iC z23{qyajAudH3V2aX=SBQiwbtlFuO3elol&9M#K!TprtmIOma-uXzRWSR|{8oHZ@mv zd#^O*5E-WVnD&PnY5WrjlQUb5F48dl<#a(FT@vPUqq(ky*{_-1yvUhx)MLR6N?vDU@w`!Mw{e9SMXMr;sIa-J&CK8-2NAcX)_xs@pDnhCp7K95O13|+ zV^4cXDv_4V0%`DfelhS3HtV zdKnPSvbQ1$%c&(M!L3-@oO8u3eaCV2R$R0*(w3ArgD`eT)!YRs0uE{YB`HSz;b zq5WZjqJ~JuZEmz1eEL|>@Xnrh%tW1O`~zXJ7t5ScsuXFBJu`#6*THEQ`|>D<29ent z-_NyRYdO+4axP_OtC5s97V$IiDu6LRwd^!XA6I zwnVeB8F-?jq&=xg6kVddTF6ck)0`mtE3)&N*G%amWIbD&K2*C>6Vy3Q3xVv7EMj@~ z6dgtbx#XL^Z5IzZl59H5BUJ;@v#39tAUuUG1|#MKhHR_K_4T;p)F6IE&BD4o_4{^V7ik%2`*HC$>BLh_9a`#(p+6G}a{WHOl9y>A!bJ z@oR1MUg-yQ!MSu=IP)V3AzG8k&jSB@y5Nja6C z0~_zTSz(~tb$PnGsH#`Bnh@p~K=EVt6brI!v^O_`XKWFrgs$Vuea`L5)Kc@jHgeIO z%hh}c^7Rz|eI^cS)_3ZVi#J1O>(XdaHNkYj>sOD6O<6jm%VBb5?>bo7By){)Rl8?I zc%!Y?A+?OrP=XfVPrlEj_vyx$PyX<%`t0J+*UI(-$d&V?!R=^co)KOQbhpR+3^IgB zHd)DR3Xg9G(J3TXJu$5BmF|{*nC*h5VqBHoA#4~uvA|8`pn^nBiUk8P<_FWgJ#$2+ z>IFRtwy$-f@NO#WCdZaa`oSJwIIeo9&RED=a6 zCmq=7qygO~laZ&JnOl{**ktP7Xgy4saXy|6*$dv7OMSm38@v)a8qnPOJs99_V?DmH z-iIA=M{af1Io2ZA5^D+6{2y(`>#M8x+x@Cms>#;3*{0>zSQ$>bK)--{!rpflw*A#5GcMO}UTrxkD>#w=`cjww>xlId1$eV7Q zt3!!~t3ixU$^s;lzo?&1_>xK)Z=DE=-2MeFCcMOT!bZ&m{PEW2Mla;)>}pgH!5don zE_jr1U&Hb2;dkkEJ{-tVOi>>glnI<0#8E)*O?w5t+C4aoUYs7kD#sjE^(;iu)y`Ru z>-XrQrNfDJh=%@Ft~)ek2(9MYv3ASANw1~yJ_d^<*(!BpBS&UDYyB|0V1LIL{vc?h zl6g@cYtEzL?7fy?j-4raj%iIsHcsY8SRq{>7^gG1V-Hd_)oWGmPO##+Q8^%sHyjgb zyMonVTp;mfsOYufE4{wIK7Y~vGLl9IkwLy^0UJ39aIemdcaq#{O&51IWUDmQ7SywH z&iTE6_LRToxDx-e(pt^5+xDybqd~8wnOQO?lm2+xo#yX%#N?=tr+0jqmd}hkaBfZl zGLeQ}0x~hDdnf17`LUauCB6R;BJn;WU~W*xU|px+2Gh^REO`IgG=o(yMy&1FESoR_ z#A3yX^U2lP)*8J$AxUvfIpemu9OLWh&G0`g(N6bF0}51>PX?xXzqJG^OR`9 zKU-7&U-NUH{pa!{bARKr-2St?rv#ApLqbljgt8&9H* z&CbS`oyVITOT6;2EDx1D^yL~?O6RCPVP>`rRLQ0)#QR) z7bE&4H;K)(G!oAg^SsLs?(1Sr*f#H#MzgjkNmf|3LFuNMJ-Bq4unN|rY1Sf%Zd1%= z-eOo~deY<-0%tK2n~U9UEo_CsKo$4qaVB+{#8I4CIyStm+o~+x4LM*}83d{=JX@eL zEp`tv8K#npg6jlGLGp$n-rs zs01mPYNfhuXPXOuiPoaJAwzY1!M((PaBlkg1K(`&Mwp~mnB#Uk`bN#z;mNIzZd?4R zDP1u3Yt}6m(HS4hXFD75X1qy7#8{yLzojyp@dirZXbsYLv^sJ7C zk-8g9qLg(z+|P$q@UCdFep#StW7sqA)ccNV@eT$NBrGSN1Ff_nVb?2~Y?%tjt1C?? z4LrYJs)bG(G0$FICXrv=dy_3&@?F7T{a^LuRs2Fvkw!iI1@VgcW%dq{Y37#@t~Mxb zNo2kDBPhbFljGC#-J|o4K}Sgknb==jqDay2sS8=|(0ftTjzSLU^!$0-_g0Um@1|OC zn!lqlXZ~7Yqv{o4Ie!unh8$BPOBE6bHqR*eh-zE1&jU+-=+Xl;%A1{AH3zZU%0#OPQ(|0$B9l}2)X_>s-uHS<%c6`u_O-c7>+Cui z@N#}_lDOH7>_}c$2QSk8$y~It{bQ8h61}`jlgTfw=qKsUFLvIHh8d%@V}h6 zxnM;@0wXFMHAU3n3y9vM>VDR`er6Tm&$J!jP5*Pt!a9gbTRlhQcH%k;W9!n%qq;=p zX&S~V>P>GaP;cjMS6l6N9S^Zj9641|ci-yPUAMrF>a*(kP5LFPNRdjkrrqUif40h+ znV#^e&fPE>UCp4qkkmWk{19?m7lz8k(P?@q>Y(7-q^cyFxkVxnuo`;TR8OO~EzuT9 zM`rOn=O!a%qb^w)Z1kUrFeP_CccL`IY`4^N6E#_9YbKkwPA_J}R3E zh(S641(A2??5xn2eKE1&QTOu3mNTB0aw2qOM87XtB@I(TY--}ysJ7pK9sPdLihlq7 zO3i;>|NZyv-`})g0?8YBoVyBcIsld3T(ST9J}z|5~U32a-H0Gd+q`#JX-j z2q&Z;CP3Y^EyN2~_}VJNs9$AM{$rKoP5GB7DgJmxI}DXL`Zh_=&JA-+3=`dT4W2eR zc!+LGCU0irPSgWpWUq-{f}`Sz91cC6iwT>-spOgr+sItwl(mX0jpmB;^x6g7%FI`Z!#t7zhIBnBqcRgP<8E!>sIJBA4m zuE~-J(<2RPlv8gL-_rfW`PQj^y1a1X(GyOehIQmucnjO`W7(c|2H&LV*jP@P($@tH z!{}=3tlTD6Wqe&2mE=6R=4!gO8aqRDXCqC9q+hzM*Xz)rVgGgnkQfNf#Q&(5jC*36W$3NQ(Gbmx7{!&AKz*>$5!f=PI_rA|@elYhz$}kU#QC@;)1i@Y%y%EFqvIRxZ3692-rF_6i-ghMqT0^wl!K!R0AFj|=PZy$JXLTfcSG#6+a*;f7aRHWZ~KkcWdab^vU& zU+!V-H7HW%=mE@q(2n8ne+;Ohz2Lxo(5O^Oa}b|V(XG8F7C^ET@{ z1PtCiMQmU@P>H&)fp>_$qiZC;C4%2qm1)$7>F*}}$}vq(-fcXAbiK9tZVSBkm@cMa zK|Ji_%1xYU(p#N-ccJ!P*f`4^$OTzkr|Gn4$`)lhv~ZKU`<%#q7Wf$$n&7w8VzCj( zznM+YZHNO>Nz@%+8fSS4Dhdk5LQ14^Px_Sya`&295XZ^Ib5WXvNq&)w+#WHRi?62% z11B`^KeU*SA~oExofgX^yO288Na=p8CNN?S3l6@5A*`&x*JR}|0fzi|pw3jC74|%% z8Mqm9Tmb98QjWDtIr5t0p#-}fD0=zus)ScyX940k-JovyZH<%X;F#XGis%ir4uhS}(i^(JSzPQ*qzO$^v$ zeiatQyFG5ZQWkYob-uo*)+pKda#_}SB%ZJ$Owc7APp}Q%^@aLM%^4l+d{d3RX0&G& zNyw}B5$*UIskx@;hB_uG@GMOxG~Is6IVQ5^6bi>EZgXt%;$>oIm`9%9#8XV(vuK)J zMJ&5c)OR79YUB%RGK6qZUxodNZs_2l5!Et5;q&_RPz*m3BgN{AY?RS?S2mNmmdV@F z&dX^ig$#vtBE|-&?1Q~Gj84U5munmiURnk&7q*uS<) z!-gKTOWkKYtJdU#o#`yz8bWp2kQw!m^B$F+yv= z6gO7n*zuzkFc2%rwtQ*E`pOD_NAZQ4)ulfBdl- z>)Ke>+gdyts@!h5-4aj3@6q#s>GprQPWo@4&8BD4F!FQ$_-Pqq_!vEsFU)+86Jai8 zL?z}JVwCBM6Eryd%pjLeJ>R>03>5ca1YLq?J~(h{GG$&6%uN3}8Bf_?-n0lhz(p!= z2)2gvrD~OHg|eNj0l*&PTf|k!L=>;k8%rt$$#VW-QYB1S3#*(>hCy}D?czfp$BID? z&KckCLH9X{k0UW*fUi$F|Y2int?$s0ZA-e&+soV<> znDq1X9ovWA|1Nk4IW)C@BtbOP5QLG)NJOp7WU)&thDe1gkeJ$3TCSpn*4^I_Mfboh z-2AgLfvhND3FYz{u~j8Ol%JdT(i#^1vahm&n8{%>O7oei*zA=LI_hR(KI*W$*GKc9PW+kf7xYT2m^NFL3AvI0aJgPWQg3(cj^T>ihA?0 zo4u~fSx$G~3!^@mGgs^Qs*TIKOqkhS6=|0lQG-arF`@uuVuYjvFRc@+ zZ3+*YVOfj`d*szLuK?Rq^L$uv^3yCCa-6OxFxf2%a>DHdRDWWPuL?0DaFuZ7s2L1+ zcoWjFvnwzf233IJm6E9&gTkc&!)c7Tt%68Bo7^#=>ug%Hz)vx)0YchndM=U+;MXQa zCO#9avyN8XavMk!nl71Ck7;7}$6BFTgWz0(G_T?%N!RH>a~rw!^sq9db{9@g4PVZN zH7pMaD;XPLR+$r7otGO;M2s8o)!%HdoY3q_1aW9zkN#JFHa3J>9byW zL)E+u6K7bN9QJ8{tRVWe+WFo| zTe)Sy-J9n;v7`oVVb9iY&Y~P!OoOXRK_P0ey`>|?;iK()z~Wj874JZB#}o^-*UQFT zplY82`4vK1}Kn4mM&3L=x5Vb%C#Vm;8}G0l2`)7x12qc>qI6))nW5cVsN zAFp#QjGt-)n-aJwfFE6%d)f3eHc?-(u)huMM|18C)6^z4b^Iq=18wMd*9_83x64{%ojwhL)IGGTGcBqmT<)e z{4T#FPM&?_i=7qq!dPj>tZoNuUo;l1tGaKmJd1uBj(%B*;TAk@G#B-E;W+jszk+(R zR1CvkRWoSV)y7lx)Edx505cWI7$;0g!{je~llFSy`SHP~gtU4jsmJ$!jqiVva#duj$L+t^OBCaUo zYoe`RDT+2L*t0@XQc3urUd|+d!lZ`_gSms-B%2zCyz>1%1>R#{@vsMXaqVmCo2A-8 zsmP@v-GE*OR}}*Kl_L?bmVr7)f|5GMtwTHbZ8GWfb`Orx^7HQA@zMF|@!{eAY4`l# z)&BA8^B%T&Hpxe<&wyX6;AjQ#s|j6qm#qDp(wcL3yV^b45(DEwq`Shc%}U{Oade$1 zU}p*FRFm_853|V}tQ}({ncaBbOK8*lu3Wy&H0aW7EnWk0Dx1+c z_cQfgrXV2b!LY-hX_N80T9zH$K9y&SCDyQbzf{8Kj zESZ#Yr$aK$Ab%^83L`VAk-~&IRWakOAPd$?K?lIUg_{%#z!NQ)kYBC2*Lk+x#&VaCoF#~t0xz(<42~1MO)S4ur_WEI4H++wumcnc& z3sRDZkYlnV)#g@(S7RpDrCUI--Pu$piJ$x=@gn2FoMxQ5p)3isYT|ltQgbgP((`n4 z%%^sadiG1tNtpR~8oGBqp-!5zeSGs9sG_18l(>wRa*0ZM%I)1tP|qjCQF4Bn#tl%* zAa?-(5E~H=LXN$ZxIYh9;MDGqQ#8zVKjfK)xJ|rhs4p0 zQWp;#K+Y<{wSk`XZ_9;i@3Uz6*l=h@1yV#;vt$B{O_BMX3TAPQvYQkj?>(;Z_ndNv zJ+9L%p|JeB2bh~gquI@cWSh6iw?dtTfu9U?7fuB+s&O(|P6Ww-XW|7<)Vg@1W*66s4%ir59y>*$Fg>DNbYpGwH5!=vU=c%hULTDG30r1jnydGum zqB90@T(0h@R(s%ed3%`xM7NC7dQ9_L5_wGjK8|N zdYTB?p?Nk5DOFjb8=I9k48PBl5J4E{U@4cqQs-htoMYkb*jZf-j}jDc@4AAy$veGM zydi>e*@>+CJj~ss!AIu-e|V`k?hntyOMnQM}4`F z7|yl9+7#M&aKh7UvIzw8jBYeWC!lF{83uGG`(&CHJ{b%-6qx-oTus5QZPkbaqRZH5 zJ!NJGjKV2SdgwE)|rt;9rr-!?YZH@Cx|e^~Eqi^y=Xg2WLkL@OADLQ;<4;J|163g%Mi zsOc16iS(R~RDIs-)&Da2%cwplH-7M(afi``#zh^_q2}}>(1n|lF>HMK!6SXlBi%(T z1`=I}hcORS6b-nQe~r-~?S?mkCm+648_`N>GhiT%1qV@B0alo&BWNVBW1x5I0D6!f zuuCZ&qu1vzzMR*#s|`jHVCi+4TP3#C=otr439-%s6_=}r1qeV2<40}kxkMTbjZ2>H ztH1(vhupX(#agYLVvTd4IYw}msKDxiCVcx_O>@vkCUoA6%4I~(Y)D&KL1*lJY&&5c zma)G%40dk_4^-bhoLX1VXjzP|Sq91BxRgBWPoGG01C_2#BI>j_>Gd#gtlSvYswv4| z=rjt40_u% z3eo7yBxT0=P<3DI78crXIPA~{;x>NR==>O}vPA=pAEo)Tga5T3ZEZb%yuH1($xpug z`r!Q4!K;1#LiF&YRy%`e5XuB1Wm=IUeMcfnrWT;ZvSJ01aGQ!#$yONM#&;cY@&VNA zJcANIX&#(B=^mUdz==INR(~Y}qM1(T@M`(|aHs^I63H$^qW>sYw%$VICYh!z>gmmS zkrB~t8XQ2HpM#UPPe2^lkmM&h;1%}LyGw7&8P?@B4C!2If=7*}gT$l7Q1V}M_v=SAOlmz)OeTx8lzu!Om zS6qp?JnX?V3fR8M!p$DVM0+O)vQ#)#6~|!CXGxUhk4utEzrvh$I+#trHx_5XOmS)E z%RRT{W9f z)isn_f6}M8Ij;(Rwz>-P*|n&oMUcHfJJzweA0!QeS3>d|VA?Bz%)QVFrJcMzCbN-; z_idBow#-2>0E?saw#)T(*}2Bwqwfq51LJG9O>O~tX#rw9Pk7e|+N#*KoeX+G zUy!UpJL2~>+@BrQUC`}mnG5aTZFTn&Aj6xoK}vTz?M5>EN0>*Q89uM4}!wyPRo)3197={=P}?ke}9b&bp_oxNARo6Cy6{wi~2ZnTQa`gJjr zMBRQ4%3jagsKNe`B+(?(D%tY#K`P&Q*5iDJc8hXGbyQ5G%b<+Y$Z2*bch)&u*)-K| z+O#KZ17gBuvtt&ivss;;@1CBYA99N+tkPNGc$3}!6k!DyDe)W`J0HL&rLgy><~Ld? zr!J8Se&+x10#1p#*$h6_nL>p88}7g$yZL$CeLn|BjaO}+u`tt6Xu+Oukh5hhY0bN2 zB+MMj;%ca4pK6BejZjdpR^uHY0fHvzm#+z%ddy2bNi!E_py$0~oCf4lGO>nQ>?1u0 z8XABs9pnDn)bZNE>Z`@Oh3qwCPJ<*ePZ)nj`^y74IzEqzA>Ee)4ia+$0grq(HVvE1 zt*kIl>?97e8=AL?r}ImwIzY$_U==YJkj>EzE*4sG=M^`Y_0vFjm(D3Tl_+Xf{))KG zbOg$=qE!|-S0=hDNo=mGIL&jp{TVh1S@qz&!CaU2PnJ2aWc`5g*81Jk$++E0}d-@(x9qN*Ar6%1)$4=ptV{oEZ*xV}EIDjB z2RCo@#u;vu!P`FjyLU6w+S-Lx^_*Q!v!1Fk@M%s*;#b`j#WIPdcvIv#oyv9S=?>7P zbl}*cvLD)<_+pwqh2V6Px~7qqYD9cxel^PePBZ=Q^i^*EfodeK*=yFx)e&UcLX!*7 zb^z8OFQM{GF1xsuI_1;QOHML4BP~*pE2?SlIQEzf=%`_h#JkX!^z1`PJj3}Q9CaTg zDJ#6C#8defKx!h>KQmelwTIrOrV6+j_Ilc!)UqQ%9O*K$UC*@D&~?>X@Xuwi{lOg0mM~c}%ounx~F)#~G+r z8-=w7)_}0)hVtLd@C^%qzM!7KEMPwhQXa=~#mmrSy9wuJ#Y1bbCK^q%G{)D%elC$) zW_WLhL@^ze=_4L5B9AoL!1K;Wj!OB9#@Vg(if5x#X}h|gombcJ&Jh>YzI#_nsD=_h zl0I0YA$z;AcgZ}F*Rv+$Sj=&mWX6!#C)q%aQYKHWRfQ=cR8~s(>OyvOZh41^@MP!N z<;Zh>(`rq#P9Y;_J2P#VGih9#vr*t(slLb}Zy>Q-;rt<$ZmG`V#OW+5L>BdDPG1^~I`;CN$=XnIHPSgW#7E(9%-}JiT#tW4j)B?Sp zGkHDaWq553ht5h2(iqbyy;xE|mR;+rvZ}J6&a^+f1Xiob!eDt^uM(f+|7-5MZWV&W`(!HQ z*LckU?I%^1Q71mUKAY!oSG9-x`1x>-{or=p9qt-TNAYd;CL5=NEa4XMZ4JH?kDlA& z-Gh^EXrTIN;G3oRFXl4ⅅ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

0=q7d9R#9Kb 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 HEAz{;7ojRF&3HmcGcGn2 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≧5~Lm}&N2v1IrJIA}nhZqd( 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 diff --git a/284.patch b/284.patch deleted file mode 100644 index 89e8d7a..0000000 --- a/284.patch +++ /dev/null @@ -1,46 +0,0 @@ -From e302182240ea59f4cf65c7d4b128be29417f33a2 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= -Date: Thu, 23 Sep 2021 15:55:02 +0200 -Subject: [PATCH] Avoid SSLError: Cannot create a client socket with a - PROTOCOL_TLS_SERVER context - -When we build mailman3 in Fedora with Python 3.10.0rc2, -we see the following problem: - - Traceback (most recent call last): - File "/builddir/build/BUILD/mailman-3.3.4/src/mailman/testing/layers.py", line 297, in setUp - cls.smtpd.start() - File "/builddir/build/BUILD/mailman-3.3.4/src/mailman/testing/mta.py", line 177, in start - super().start() - File "/usr/lib/python3.10/site-packages/aiosmtpd/controller.py", line 288, in start - self._trigger_server() - File "/usr/lib/python3.10/site-packages/aiosmtpd/controller.py", line 481, in _trigger_server - InetMixin._trigger_server(self) - File "/usr/lib/python3.10/site-packages/aiosmtpd/controller.py", line 428, in _trigger_server - s = stk.enter_context(self.ssl_context.wrap_socket(s)) - File "/usr/lib64/python3.10/ssl.py", line 512, in wrap_socket - return self.sslsocket_class._create( - File "/usr/lib64/python3.10/ssl.py", line 1061, in _create - self._sslobj = self._context._wrap_socket( - ssl.SSLError: Cannot create a client socket with a PROTOCOL_TLS_SERVER context (_ssl.c:801) - -This makes the problem go away. - -Disclaimer: I have no idea what I'm doing here. ---- - aiosmtpd/controller.py | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/aiosmtpd/controller.py b/aiosmtpd/controller.py -index 79bdbd04..30fd4a11 100644 ---- a/aiosmtpd/controller.py -+++ b/aiosmtpd/controller.py -@@ -424,7 +424,7 @@ def _trigger_server(self): - hostname = self.hostname or self._localhost - with ExitStack() as stk: - s = stk.enter_context(create_connection((hostname, self.port), 1.0)) -- if self.ssl_context: -+ if self.ssl_context and self.ssl_context.protocol != ssl.PROTOCOL_TLS_SERVER: - s = stk.enter_context(self.ssl_context.wrap_socket(s)) - s.recv(1024) - diff --git a/CVE-2024-27305.patch b/CVE-2024-27305.patch deleted file mode 100644 index c4adcec..0000000 --- a/CVE-2024-27305.patch +++ /dev/null @@ -1,160 +0,0 @@ -From 24b6c79c8921cf1800e27ca144f4f37023982bbb Mon Sep 17 00:00:00 2001 -From: Login <84237895+The-Login@users.noreply.github.com> -Date: Sat, 2 Mar 2024 15:55:13 +0100 -Subject: [PATCH] Merge pull request from GHSA-pr2m-px7j-xg65 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Origin: https://github.com/aio-libs/aiosmtpd/commit/24b6c79c8921cf1800e27ca144f4f37023982bbb - -* SMTP Smuggling Fix - -Adapted adherence to RFC 5321 § 2.3.8 to fix SMTP smuggling issues (https://www.rfc-editor.org/rfc/rfc5321#section-2.3.8) - -* Apply suggestions from code review - -Co-authored-by: Sam Bull - -* Add files via upload - -* Update test_smtpsmuggling.py - ---------- - -Co-authored-by: Sam Bull ---- - aiosmtpd/smtp.py | 11 ++-- - aiosmtpd/tests/test_smtpsmuggling.py | 79 ++++++++++++++++++++++++++++ - 2 files changed, 85 insertions(+), 5 deletions(-) - create mode 100644 aiosmtpd/tests/test_smtpsmuggling.py - -diff --git a/aiosmtpd/smtp.py b/aiosmtpd/smtp.py -index 39e70d8b..00902c1e 100644 ---- a/aiosmtpd/smtp.py -+++ b/aiosmtpd/smtp.py -@@ -87,7 +87,7 @@ class _DataState(enum.Enum): - EMPTY_BARR = bytearray() - EMPTYBYTES = b'' - MISSING = _Missing() --NEWLINE = '\n' -+NEWLINE = '\r\n' - VALID_AUTHMECH = re.compile(r"[A-Z0-9_-]+\Z") - - # https://tools.ietf.org/html/rfc3207.html#page-3 -@@ -1427,9 +1427,10 @@ async def smtp_DATA(self, arg: str) -> None: - # Since eof_received cancels this coroutine, - # readuntil() can never raise asyncio.IncompleteReadError. - try: -- line: bytes = await self._reader.readuntil() -+ # https://datatracker.ietf.org/doc/html/rfc5321#section-2.3.8 -+ line: bytes = await self._reader.readuntil(b'\r\n') - log.debug('DATA readline: %s', line) -- assert line.endswith(b'\n') -+ assert line.endswith(b'\r\n') - except asyncio.CancelledError: - # The connection got reset during the DATA command. - log.info('Connection lost during DATA') -@@ -1446,7 +1447,7 @@ async def smtp_DATA(self, arg: str) -> None: - data *= 0 - # Drain the stream anyways - line = await self._reader.read(e.consumed) -- assert not line.endswith(b'\n') -+ assert not line.endswith(b'\r\n') - # A lone dot in a line signals the end of DATA. - if not line_fragments and line == b'.\r\n': - break -@@ -1458,7 +1459,7 @@ async def smtp_DATA(self, arg: str) -> None: - # Discard data immediately to prevent memory pressure - data *= 0 - line_fragments.append(line) -- if line.endswith(b'\n'): -+ if line.endswith(b'\r\n'): - # Record data only if state is "NOMINAL" - if state == _DataState.NOMINAL: - line = EMPTY_BARR.join(line_fragments) -diff --git a/aiosmtpd/tests/test_smtpsmuggling.py b/aiosmtpd/tests/test_smtpsmuggling.py -new file mode 100644 -index 00000000..b5d37851 ---- /dev/null -+++ b/aiosmtpd/tests/test_smtpsmuggling.py -@@ -0,0 +1,79 @@ -+# Copyright 2014-2021 The aiosmtpd Developers -+# SPDX-License-Identifier: Apache-2.0 -+ -+"""Test SMTP smuggling.""" -+ -+from email.mime.text import MIMEText -+from smtplib import SMTP, SMTP_SSL -+from typing import Generator, Union -+ -+import pytest -+import smtplib -+ -+from aiosmtpd.controller import Controller -+from aiosmtpd.testing.helpers import ReceivingHandler -+from aiosmtpd.testing.statuscodes import SMTP_STATUS_CODES as S -+ -+from aiosmtpd.smtp import SMTP as Server -+from aiosmtpd.smtp import Session as ServerSession -+from aiosmtpd.smtp import Envelope -+ -+from .conftest import Global, controller_data, handler_data -+ -+from aiosmtpd.testing.helpers import ( -+ ReceivingHandler -+) -+ -+def new_data(self, msg): -+ self.putcmd("data") -+ -+ (code, repl) = self.getreply() -+ if self.debuglevel > 0: -+ self._print_debug('data:', (code, repl)) -+ if code != 354: -+ raise SMTPDataError(code, repl) -+ else: -+ ##### Patching input encoding so we can send raw messages -+ #if isinstance(msg, str): -+ # msg = smtplib._fix_eols(msg).encode('ascii') -+ #q = smtplib._quote_periods(msg) -+ #if q[-2:] != smtplib.bCRLF: -+ # q = q + smtplib.bCRLF -+ #q = q + b"." + smtplib.bCRLF -+ q = msg -+ self.send(q) -+ (code, msg) = self.getreply() -+ if self.debuglevel > 0: -+ self._print_debug('data:', (code, msg)) -+ return (code, msg) -+ -+def return_unchanged(data): -+ return data -+ -+class TestSmuggling: -+ @handler_data(class_=ReceivingHandler) -+ def test_smtp_smuggling(self, plain_controller, client): -+ smtplib._fix_eols = return_unchanged -+ smtplib._quote_periods = return_unchanged -+ smtplib.SMTP.data = new_data -+ -+ handler = plain_controller.handler -+ sender = "sender@example.com" -+ recipients = ["rcpt1@example.com"] -+ resp = client.helo("example.com") -+ assert resp == S.S250_FQDN -+ # Trying SMTP smuggling with a fake \n.\r\n end-of-data sequence. -+ message_data = b"""\ -+From: Anne Person \r\n\ -+To: Bart Person \r\n\ -+Subject: A test\r\n\ -+Message-ID: \r\n\ -+\r\n\ -+Testing\ -+\n.\r\n\ -+NO SMUGGLING -+\r\n.\r\n\ -+""" -+ results = client.sendmail(sender, recipients, message_data) -+ client.quit() -+ assert b"NO SMUGGLING" in handler.box[0].content diff --git a/aiosmtpd-1.4.6.tar.gz b/aiosmtpd-1.4.6.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..6eeadfcc7d04d85fcd144d62eafb7a1a050dfe5e GIT binary patch literal 152775 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 z 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%0D8k=7Y7_qAydKn0Z$F9j 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 literal 0 HcmV?d00001 diff --git a/python-aiosmtpd.spec b/python-aiosmtpd.spec index 1bd6b96..3014f85 100644 --- a/python-aiosmtpd.spec +++ b/python-aiosmtpd.spec @@ -1,17 +1,11 @@ %global _empty_manifest_terminate_build 0 Name: python-aiosmtpd -Version: 1.4.2 -Release: 2 +Version: 1.4.6 +Release: 1 Summary: aiosmtpd - asyncio based SMTP server License: Apache 2.0 URL: https://github.com/aio-libs/aiosmtpd -Source0: https://github.com/aio-libs/aiosmtpd/archive/%{version}.tar.gz -Patch0001: 0001-Implement-Unthreaded-Controller-256.patch -Patch0002: 0002-Code-Hygiene-259.patch -Patch0003: 0003-URGENT-Fix-RTD-docs-gen.patch -Patch0004: 0004-Make-Sphinx-RTD-deps-SSOT.patch -Patch0005: %{url}/pull/284.patch -Patch0006: CVE-2024-27305.patch +Source0: %{url}/releases/download/v%{version}/aiosmtpd-%{version}.tar.gz BuildArch: noarch @@ -79,6 +73,10 @@ mv %{buildroot}/doclist.lst . %{_pkgdocdir} %changelog +* Wed May 29 2024 yaoxin - 1.4.6-1 +- Update to 1.4.6 (bsc#1224467, CVE-2024-34083): +- STARTTLS is now fully enforced if used. + * Wed Mar 13 2024 wangkai <13474090681@163.com> - 1.4.2-2 - Fix CVE-2024-27305 -- Gitee