public inbox for tools@linux.kernel.org
 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 11/12] Enable pyright strict mode
Date: Tue, 07 Apr 2026 12:48:40 -0400	[thread overview]
Message-ID: <20260407-ruff-check-v1-11-c9568541ff67@kernel.org> (raw)
In-Reply-To: <20260407-ruff-check-v1-0-c9568541ff67@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        | 11 +++++++----
 src/b4/ez.py              | 29 +++++++++++++++--------------
 src/b4/review/tracking.py | 16 +++++++++-------
 src/b4/ty.py              |  6 +++---
 6 files changed, 50 insertions(+), 33 deletions(-)

diff --git a/misc/review-ci-example.py b/misc/review-ci-example.py
index cbac2ae..13a670e 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 25338e7..b89c4d9 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -125,8 +125,19 @@ strict = true
 warn_unreachable = true
 
 [tool.pyright]
-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.rules]
 all = "error"
diff --git a/src/b4/__init__.py b/src/b4/__init__.py
index c9b05d8..1711758 100644
--- a/src/b4/__init__.py
+++ b/src/b4/__init__.py
@@ -61,7 +61,9 @@ from email.message import EmailMessage, Message
 
 charset.add_charset('utf-8', None)
 # Policy we use for saving mail locally
-emlpolicy = email.policy.EmailPolicy(utf8=True, cte_type='8bit', max_line_length=None, message_factory=EmailMessage)
+emlpolicy: email.policy.EmailPolicy[EmailMessage] = email.policy.EmailPolicy(
+    utf8=True, cte_type='8bit', max_line_length=None, message_factory=EmailMessage
+)
 
 # Presence of these characters requires quoting of the name in the header
 # adapted from email._parseaddr
@@ -4086,7 +4088,9 @@ def git_range_to_patches(gitdir: Optional[str], start: str, end: str,
         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:
@@ -5378,8 +5382,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 9f55bc9..4e38c38 100644
--- a/src/b4/ez.py
+++ b/src/b4/ez.py
@@ -2346,20 +2346,21 @@ def cmd_send(cmdargs: argparse.Namespace) -> None:
 
 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 9c5d33f..16e62cb 100644
--- a/src/b4/review/tracking.py
+++ b/src/b4/review/tracking.py
@@ -933,13 +933,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 f88b53f..4ef9c33 100644
--- a/src/b4/ty.py
+++ b/src/b4/ty.py
@@ -469,8 +469,8 @@ def send_messages(listing: List[JsonDictT], branch: str, cmdargs: argparse.Names
 
         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')))
             b4.send_mail(smtp, [msg], fromaddr, dryrun=cmdargs.dryrun)
         else:
@@ -878,7 +878,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-07 16:48 UTC|newest]

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

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=20260407-ruff-check-v1-11-c9568541ff67@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