You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ponymail.apache.org by se...@apache.org on 2023/03/28 22:08:36 UTC

[incubator-ponymail-foal] branch master updated: mypy typing fixes

This is an automated email from the ASF dual-hosted git repository.

sebb pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-ponymail-foal.git


The following commit(s) were added to refs/heads/master by this push:
     new 218c4f5  mypy typing fixes
218c4f5 is described below

commit 218c4f5287860f15996d2bdcc30e2a31877b26ef
Author: Sebb <se...@apache.org>
AuthorDate: Tue Mar 28 23:08:26 2023 +0100

    mypy typing fixes
    
    [skip ci]
---
 server/endpoints/gravatar.py    |  5 +++--
 server/endpoints/plain.py       |  5 +++--
 server/endpoints/preferences.py |  4 ++--
 server/endpoints/thread.py      |  1 +
 server/plugins/database.py      |  4 ++--
 server/plugins/messages.py      | 10 +++++-----
 tools/archiver.py               |  2 +-
 tools/migrate.py                |  5 +++--
 tools/plugins/dkim_id.py        |  2 --
 tools/plugins/textlib.py        |  2 +-
 tools/setup.py                  | 21 ++++++++++++---------
 11 files changed, 33 insertions(+), 28 deletions(-)

diff --git a/server/endpoints/gravatar.py b/server/endpoints/gravatar.py
index d8311d7..c496ca7 100644
--- a/server/endpoints/gravatar.py
+++ b/server/endpoints/gravatar.py
@@ -71,6 +71,7 @@ async def fetch_gravatar(gid: str) -> None:
 
 
 async def gravatar_exists_in_db(session: plugins.session.SessionObject, gid: str) -> bool:
+    assert session.database is not None # make mypy happy
     res = await session.database.search(
         index=session.database.dbs.db_mbox,
         size=1,
@@ -81,7 +82,7 @@ async def gravatar_exists_in_db(session: plugins.session.SessionObject, gid: str
     return False
 
 
-async def process(server: plugins.server.BaseServer, session: dict, indata: dict) -> aiohttp.web.Response:
+async def process(server: plugins.server.BaseServer, session: plugins.session.SessionObject, indata: dict) -> aiohttp.web.Response:
     gid = indata.get("md5", "null")
     # Ensure md5 hash is valid
     is_valid_md5 = len(gid) == 32 and all(letter in string.hexdigits for letter in gid)
@@ -110,5 +111,5 @@ async def process(server: plugins.server.BaseServer, session: dict, indata: dict
     return aiohttp.web.Response(headers=headers, content_type="image/png", body=gravatar_default)
 
 
-def register(server: plugins.server.BaseServer):
+def register(_server: plugins.server.BaseServer):
     return plugins.server.Endpoint(process)
diff --git a/server/endpoints/plain.py b/server/endpoints/plain.py
index 88c1fd0..ef9348a 100644
--- a/server/endpoints/plain.py
+++ b/server/endpoints/plain.py
@@ -24,6 +24,7 @@
 import plugins.server
 import plugins.session
 import plugins.messages
+import plugins.defuzzer
 import aiohttp.web
 import html
 
@@ -59,7 +60,7 @@ async def process(
                 "@".join(email.get("list_raw", "").strip("<>").split(".", 1))
             )
             date = html.escape(email.get("date", ""))
-            author = html.escape(email.get("from"))
+            author = html.escape(email.get("from", ""))
             output += f"""Posted to <a href="/list.html?{listname}">{listname}</a> by {author} on {date} UTC<br/>"""
             title = html.escape(email.get("subject", ""))
             body = html.escape(email.get("body", ""))
@@ -69,7 +70,7 @@ async def process(
             output += f"""<h1>{email["subject"]}</h1><pre>{body}</pre><hr/>\n"""
             for tid, email in _pdocs.items():
                 body = html.escape(email.get("body", ""))
-                author = html.escape(email.get("from"))
+                author = html.escape(email.get("from", ""))
                 output += f"""<h2>{email["subject"]}</h2>\n<b>Posted by {author}.</b><hr/><pre>{body}</pre><hr/>\n"""
     # Show a list
     elif list_id:
diff --git a/server/endpoints/preferences.py b/server/endpoints/preferences.py
index 79a8e25..ad85702 100644
--- a/server/endpoints/preferences.py
+++ b/server/endpoints/preferences.py
@@ -31,12 +31,12 @@ async def process(
 ) -> typing.Union[dict, aiohttp.web.Response]:
 
     versions: dict = {
-        "foal": server.foal_version,
+        "foal": server.foal_version, # type: ignore [attr-defined]
     }
 
     # Require login for this info
     if session.credentials and session.credentials.authoritative:
-        versions["server"] = server.server_version
+        versions["server"] = server.server_version  # type: ignore [attr-defined]
         if session.credentials.admin:
             versions["elasticsearch_engine"] = server.engine_version
             versions["elasticsearch_library"] = server.library_version
diff --git a/server/endpoints/thread.py b/server/endpoints/thread.py
index 4e0d41a..98f2320 100644
--- a/server/endpoints/thread.py
+++ b/server/endpoints/thread.py
@@ -49,6 +49,7 @@ async def process(
     email["children"] = thread
     emails.append(email)
     for email in emails:
+        assert isinstance(email, dict) # ensure mypy is happy with next line; TODO improve?
         plugins.messages.trim_email(email, external=True)
     return {
         "thread": email,
diff --git a/server/plugins/database.py b/server/plugins/database.py
index ffe2d3c..75b66a5 100644
--- a/server/plugins/database.py
+++ b/server/plugins/database.py
@@ -113,13 +113,13 @@ class Database:
         return res
 
     async def scan(self,
-                   query: dict = None,
+                   query: typing.Optional[dict] = None,
                    scroll: str = "5m",
                    preserve_order: bool = False,
                    size: int = 1000,
                    request_timeout: int = 60,
                    clear_scroll: bool = True,
-                   scroll_kwargs: dict = None,
+                   scroll_kwargs: typing.Optional[dict] = None,
                    **kwargs) -> typing.AsyncIterator[typing.List[dict]]:
         
         scroll_kwargs = scroll_kwargs or {}
diff --git a/server/plugins/messages.py b/server/plugins/messages.py
index fcc0182..584df4d 100644
--- a/server/plugins/messages.py
+++ b/server/plugins/messages.py
@@ -164,7 +164,7 @@ async def find_parent(session, doc: typing.Dict[str, str]):
 async def fetch_children(session: plugins.session.SessionObject,
         pdoc: dict,
         counter: int = 0,
-        pdocs: dict = None,
+        pdocs: typing.Optional[dict] = None,
         short: bool = False) -> typing.Tuple[list,list,dict]:
     """
     Fetches all accessible child messages of a parent email
@@ -210,9 +210,9 @@ async def fetch_children(session: plugins.session.SessionObject,
 
 async def get_email(
     session: plugins.session.SessionObject,
-    permalink: str = None,
-    messageid: str = None,
-    listid: str = None,
+    permalink: typing.Optional[str] = None,
+    messageid: typing.Optional[str] = None,
+    listid: typing.Optional[str] = None,
 ) -> typing.Optional[dict]:
     """
     Returns a single matching mbox document or None
@@ -589,7 +589,7 @@ class ThreadConstructor:
         return self.threads, self.authors
 
     
-    def find_root_subject(self, root_email: typing.Dict[str, str], osubject: str = None) -> typing.Optional[dict]:
+    def find_root_subject(self, root_email: typing.Dict[str, str], osubject: typing.Optional[str] = None) -> typing.Optional[dict]:
         """Finds the discussion origin of an email, if present"""
         irt = root_email.get("in-reply-to",'')
         subject = root_email.get("subject",'')
diff --git a/tools/archiver.py b/tools/archiver.py
index 64d4301..2feb887 100755
--- a/tools/archiver.py
+++ b/tools/archiver.py
@@ -191,7 +191,7 @@ class Body:
     def __init__(self, part: email.message.Message):
         self.content_type = part.get_content_type()
         self.charsets = [part.get_content_charset()]  # Part's charset
-        parent_charset = part.get_charsets()[0]
+        parent_charset = part.get_charsets()[0] # type: ignore [index] # (awaiting typedef fix)
         if parent_charset and parent_charset != self.charsets[0]:
             self.charsets.append(
                 parent_charset
diff --git a/tools/migrate.py b/tools/migrate.py
index 1530169..9193d00 100644
--- a/tools/migrate.py
+++ b/tools/migrate.py
@@ -34,6 +34,7 @@ import hashlib
 import multiprocessing
 import time
 import sys
+import typing
 import archiver
 
 # Increment this number whenever breaking changes happen in the migration workflow:
@@ -47,7 +48,7 @@ MAX_PARALLEL_OPS = max(min(int((cores + 1) * 0.75), cores - 1), 1)
 class MultiDocProcessor:
     """MultiProcess document processor"""
 
-    def __init__(self, old_es_url: str, new_es_url: str, target: callable, num_processes: int = 8, graceful: bool = False):
+    def __init__(self, old_es_url: str, new_es_url: str, target: typing.Callable, num_processes: int = 8, graceful: bool = False):
         self.processes = []
         self.queues = []
         self.target = target
@@ -60,7 +61,7 @@ class MultiDocProcessor:
         self.queue_pointer = 0
         self.num_processes = num_processes
         for _ in range(0, num_processes):
-            q = multiprocessing.Queue()
+            q: multiprocessing.Queue = multiprocessing.Queue()
             p = multiprocessing.Process(
                 target=self.start,
                 args=(
diff --git a/tools/plugins/dkim_id.py b/tools/plugins/dkim_id.py
index 0fdc410..48a93f0 100644
--- a/tools/plugins/dkim_id.py
+++ b/tools/plugins/dkim_id.py
@@ -401,11 +401,9 @@ def main() -> None:
     from typing import BinaryIO
 
     if len(argv) == 2:
-        f: BinaryIO
         with open(argv[1], "rb") as f:
             print(dkim_id(f.read()))
     elif len(argv) == 3: # add lid
-        f: BinaryIO
         with open(argv[1], "rb") as f:
             print(dkim_id(f.read(), argv[2].encode('utf-8')))
     else:
diff --git a/tools/plugins/textlib.py b/tools/plugins/textlib.py
index 0c55d6a..d3e2e84 100644
--- a/tools/plugins/textlib.py
+++ b/tools/plugins/textlib.py
@@ -20,7 +20,7 @@
 import re
 import typing
 
-def normalize_lid(lid: str, strict: bool = False) -> str:
+def normalize_lid(lid: str, strict: bool = False) -> typing.Optional[str]:
     """ Ensures that a List ID is in standard form, i.e. <a.b.c.d> """
     # If of format "list name" <foo.bar.baz>
     # we crop away the description (#511)
diff --git a/tools/setup.py b/tools/setup.py
index 193711d..2cba11d 100755
--- a/tools/setup.py
+++ b/tools/setup.py
@@ -275,10 +275,11 @@ while genname == "":
         "2  FULL: Full message digest with MTA trail. Not recommended for clustered setups."
     )
     try:
-        gno = input("Please select a generator (1 or 2) [1]: ")
-        if not gno:
+        ans = input("Please select a generator (1 or 2) [1]: ")
+        if ans:
+            gno = int(ans)
+        else:
             gno = 1
-        gno = int(gno)
         if gno <= len(supported_generators) and supported_generators[gno - 1]:
             genname = supported_generators[gno - 1]
     except ValueError:
@@ -298,19 +299,21 @@ if genname == "dkim" and (nonce is None and not args.defaults and not args.devel
 
 while shards < 1:
     try:
-        shards = input("How many shards for the ElasticSearch index? [3]: ")
-        if not shards:
+        ans = input("How many shards for the ElasticSearch index? [3]: ")
+        if ans:
+            shards = int(ans)
+        else:
             shards = 3
-        shards = int(shards)
     except ValueError:
         pass
 
 while replicas < 0:
     try:
-        replicas = input("How many replicas for each shard? [1]: ")
-        if not replicas:
+        ans = input("How many replicas for each shard? [1]: ")
+        if ans:
+            replicas = int(ans)
+        else:
             replicas = 1
-        replicas = int(replicas)
     except ValueError:
         pass