Linux maintainer tooling and workflows
 help / color / mirror / Atom feed
From: Tamir Duberstein <tamird@kernel.org>
To: "Kernel.org Tools" <tools@kernel.org>
Cc: Konstantin Ryabitsev <konstantin@linuxfoundation.org>,
	 Tamir Duberstein <tamird@kernel.org>
Subject: [PATCH b4 v2 11/11] Enable pyright strict mode
Date: Sun, 19 Apr 2026 12:00:06 -0400	[thread overview]
Message-ID: <20260419-ruff-check-v2-11-089dfb264501@kernel.org> (raw)
In-Reply-To: <20260419-ruff-check-v2-0-089dfb264501@kernel.org>

This catches a few impossible type assertions.

Signed-off-by: Tamir Duberstein <tamird@kernel.org>
---
 misc/review-ci-example.py |  6 +++---
 pyproject.toml            | 15 +++++++++++++--
 src/b4/__init__.py        |  9 +++++----
 src/b4/ez.py              | 29 +++++++++++++++--------------
 src/b4/review/tracking.py | 16 +++++++++-------
 src/b4/ty.py              |  6 +++---
 6 files changed, 48 insertions(+), 33 deletions(-)

diff --git a/misc/review-ci-example.py b/misc/review-ci-example.py
index dee0a5d..b2170a7 100755
--- a/misc/review-ci-example.py
+++ b/misc/review-ci-example.py
@@ -43,7 +43,7 @@ import sys
 
 def main() -> None:
     msg = email.message_from_binary_file(sys.stdin.buffer)
-    subject = msg.get('subject', '(no subject)')  # noqa: F841
+    subject = msg.get('subject', '(no subject)')  # noqa: F841  # pyright: ignore[reportUnusedVariable]
     msgid = msg.get('message-id', '').strip('<> ')
 
     # Example: read tracking data for commit-based CI lookups
@@ -51,9 +51,9 @@ def main() -> None:
     if tracking_file:
         with open(tracking_file) as fp:
             tracking = json.load(fp)
-        branch_tips = tracking.get('series', {}).get('branch-tips', [])
+        branch_tips = tracking.get('series', {}).get('branch-tips', [])  # pyright: ignore[reportUnusedVariable]
     else:
-        branch_tips = []  # noqa: F841
+        branch_tips = []  # noqa: F841  # pyright: ignore[reportUnusedVariable]
 
     # Seed the RNG with the message-id so results are stable across
     # repeated runs of the same message (simulates cached CI results).
diff --git a/pyproject.toml b/pyproject.toml
index bde64bf..b905090 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -134,8 +134,19 @@ warn_unreachable = true
 # once we specify `exclude`, we're on our own. See
 # https://github.com/microsoft/pyright/issues/9057#issuecomment-2366938099.
 exclude = [".venv", "ezgb", "liblore", "patatt"]
-typeCheckingMode = "standard"
-reportUnusedImport = true
+typeCheckingMode = "strict"
+
+# Overly strict rules.
+reportConstantRedefinition = false
+reportUnknownArgumentType = false
+reportUnknownLambdaType = false
+reportUnknownMemberType = false
+reportUnknownVariableType = false
+
+# False positives caused by underscore-prefixed functions used across files.
+# Might be good to clean this up.
+reportPrivateUsage = false
+reportUnusedFunction = false
 
 [tool.ty.src]
 exclude = ["ezgb/", "liblore/", "patatt/"]
diff --git a/src/b4/__init__.py b/src/b4/__init__.py
index 739e1af..e3452b0 100644
--- a/src/b4/__init__.py
+++ b/src/b4/__init__.py
@@ -62,7 +62,7 @@ ConfigDictT = Dict[str, Union[str, List[str], None]]
 
 charset.add_charset('utf-8', None)
 # Policy we use for saving mail locally
-emlpolicy = email.policy.EmailPolicy(
+emlpolicy: email.policy.EmailPolicy[EmailMessage] = email.policy.EmailPolicy(
     utf8=True, cte_type='8bit', max_line_length=None, message_factory=EmailMessage
 )
 
@@ -4399,7 +4399,9 @@ def git_range_to_patches(
         msg.set_charset('utf-8')
         # Clean From to remove any 7bit-safe encoding
         origfrom = LoreMessage.clean_header(msg.get('From'))
-        lsubject = LoreSubject(msg.get('Subject'), presubject=presubject)
+        lsubject = LoreSubject(
+            LoreMessage.clean_header(msg.get('Subject')), presubject=presubject
+        )
         lsubject.counter = counter + 1
         lsubject.expected = expected
         if revision is not None:
@@ -5820,8 +5822,7 @@ def get_git_bool(gitbool: str) -> bool:
 
 def mailbox_email_factory(fh: BinaryIO) -> EmailMessage:
     """Factory function to create EmailMessage objects"""
-    msg = email.parser.BytesParser(policy=emlpolicy, _class=EmailMessage).parse(fh)  # type: EmailMessage
-    return msg
+    return email.parser.BytesParser(policy=emlpolicy, _class=EmailMessage).parse(fh)
 
 
 def get_msgs_from_mailbox_or_maildir(mbmd: str) -> List[EmailMessage]:
diff --git a/src/b4/ez.py b/src/b4/ez.py
index be3d2fe..cd8a10c 100644
--- a/src/b4/ez.py
+++ b/src/b4/ez.py
@@ -2679,20 +2679,21 @@ def get_sent_tagname(
     tagbase: str, tagprefix: str, revstr: Union[str, int]
 ) -> Tuple[str, Optional[int]]:
     revision = None
-    if isinstance(revstr, int):
-        revision = revstr
-    elif isinstance(revstr, str):
-        try:
-            revision = int(revstr)
-        except ValueError:
-            matches = re.search(r'^v(\d+)$', revstr)
-            if not matches:
-                # assume we got a full tag name, so try to find the revision there
-                matches = re.search(r'v(\d+)$', revstr)
-                if matches:
-                    revision = int(matches.groups()[0])
-                return revstr.replace('refs/tags/', ''), revision
-            revision = int(matches.groups()[0])
+    match revstr:
+        case int():
+            revision = revstr
+        case str():
+            try:
+                revision = int(revstr)
+            except ValueError:
+                matches = re.search(r'^v(\d+)$', revstr)
+                if not matches:
+                    # assume we got a full tag name, so try to find the revision there
+                    matches = re.search(r'v(\d+)$', revstr)
+                    if matches:
+                        revision = int(matches.groups()[0])
+                    return revstr.replace('refs/tags/', ''), revision
+                revision = int(matches.groups()[0])
 
     if tagbase.startswith('b4/'):
         return f'{tagprefix}{tagbase[3:]}-v{revision}', revision
diff --git a/src/b4/review/tracking.py b/src/b4/review/tracking.py
index fb41bf0..1adb99a 100644
--- a/src/b4/review/tracking.py
+++ b/src/b4/review/tracking.py
@@ -1057,13 +1057,15 @@ def get_review_target_branches() -> list[str]:
     """Return all configured review-target-branch values."""
     config = b4.get_main_config()
     val = config.get('review-target-branch')
-    if val is None:
-        return []
-    if isinstance(val, list):
-        return [str(v) for v in val if v]
-    if isinstance(val, str) and val:
-        return [val]
-    return []
+    match val:
+        case None:
+            return []
+        case list():
+            return [v for v in val if v]
+        case str():
+            if val:
+                return [val]
+            return []
 
 
 def get_review_target_branch_default() -> Optional[str]:
diff --git a/src/b4/ty.py b/src/b4/ty.py
index ba7f646..4e096af 100644
--- a/src/b4/ty.py
+++ b/src/b4/ty.py
@@ -530,8 +530,8 @@ def send_messages(
 
         outgoing += 1
         if send_email:
-            if not fromaddr and isinstance(jsondata['myemail'], str):
-                fromaddr = jsondata['myemail']
+            if not fromaddr:
+                fromaddr = user_email
             logger.info(
                 '  Sending: %s', b4.LoreMessage.clean_header(msg.get('subject'))
             )
@@ -959,7 +959,7 @@ def get_branch_info(gitdir: Optional[str], branch: str) -> Dict[str, str]:
     BRANCH_INFO = dict()
 
     remotecfg = b4.get_config_from_git('branch\\.%s\\..*' % branch)
-    if remotecfg is None or 'remote' not in remotecfg:
+    if 'remote' not in remotecfg:
         # Did not find a matching branch entry, so look at remotes
         gitargs = ['remote', 'show']
         lines = b4.git_get_command_lines(gitdir, gitargs)

-- 
2.53.0


  parent reply	other threads:[~2026-04-19 16:00 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-04-19 15:59 [PATCH b4 v2 00/11] Enable stricter local checks Tamir Duberstein
2026-04-19 15:59 ` [PATCH b4 v2 01/11] Add CI script Tamir Duberstein
2026-04-19 15:59 ` [PATCH b4 v2 02/11] Add ruff checks to CI Tamir Duberstein
2026-04-19 15:59 ` [PATCH b4 v2 03/11] Import dependencies unconditionally Tamir Duberstein
2026-04-19 15:59 ` [PATCH b4 v2 04/11] Add ruff format check to CI Tamir Duberstein
2026-04-19 18:06   ` Tamir Duberstein
2026-04-19 16:00 ` [PATCH b4 v2 05/11] Fix tests under uv with complex git config Tamir Duberstein
2026-04-19 16:00 ` [PATCH b4 v2 06/11] Fix typings in misc/ Tamir Duberstein
2026-04-19 16:00 ` [PATCH b4 v2 07/11] Enable mypy unreachable warnings Tamir Duberstein
2026-04-19 16:00 ` [PATCH b4 v2 08/11] Enable and fix pyright diagnostics Tamir Duberstein
2026-04-19 16:00 ` [PATCH b4 v2 09/11] Avoid duplicate map lookups Tamir Duberstein
2026-04-19 16:00 ` [PATCH b4 v2 10/11] Add ty and configuration Tamir Duberstein
2026-04-19 16:00 ` Tamir Duberstein [this message]
2026-04-23  2:48 ` [PATCH b4 v2 00/11] Enable stricter local checks Konstantin Ryabitsev

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260419-ruff-check-v2-11-089dfb264501@kernel.org \
    --to=tamird@kernel.org \
    --cc=konstantin@linuxfoundation.org \
    --cc=tools@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox