Netdev List
 help / color / mirror / Atom feed
From: netdev-bot+sashiko@kernel.org
To: houminxi@gmail.com
Cc: netdev@vger.kernel.org, aconole@redhat.com, davem@davemloft.net,
	dev@openvswitch.org, echaudro@redhat.com, edumazet@google.com,
	i.maximets@ovn.org, kuba@kernel.org,
	linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org,
	pabeni@redhat.com, shuah@kernel.org, horms@kernel.org
Subject: Re: [PATCH 1/4] selftests: openvswitch: convert %-formatting to f-strings
Date: Wed, 09 Sep 2026 12:42:49 +0000	[thread overview]
Message-ID: <178895776955.219967.320136497327402821@kernel.org> (raw)
In-Reply-To: <20260905104026.3776396-2-houminxi@gmail.com>

Thank you for your contribution! Sashiko AI review found 2 potential
issue(s) to consider:

Critical: 0 · High: 0 · Medium: 0 (1) · Low: 2 (1)

- [Low] Commit message overstates what the patch achieves: it claims
  "Convert all 86 instances of %-formatting to f-strings to fix C0209…
- [Low] The f-string conversion replaces C0209 warnings with a batch of
  new over-long source lines (C0301 / PEP8 79-column, kernel 80-column…

Pre-existing issues:
- [Medium] In `OvsFlow.ovs_flow_msg.dpstr()`
  (tools/testing/selftests/net/openvswitch/ovs-dpctl.py:2556) the fifth…
- [Low] The `del-flows` branch of `main()` in
  tools/testing/selftests/net/openvswitch/ovs-dpctl.py detects a missing…

--

selftests: openvswitch: convert %-formatting to f-strings

This converts %-formatting (and a few str.format() call sites) in
tools/testing/selftests/net/openvswitch/ovs-dpctl.py over to f-strings in
order to silence pylint C0209.  It is described as a pure warning cleanup
with no behavior change.

[Severity: Low]
The commit message says:

  "Convert all 86 instances of %-formatting to f-strings to fix
   C0209 pylint warnings."

Is "all" accurate here?  One literal %-format survives this commit, in
ovsactions.dpstr():

    try:
        print_str += datum.dpstr(more)
    except:
        print_str += "{ATTR: %s not decoded}" % field[0]

C0209 fires exactly on a literal string used with the % operator, so
pylint still reports it for this file after this patch.  This one does get
converted later in the series (in "selftests: openvswitch: add missing
docstrings in ovs-dpctl.py"), so would it make sense to reword the message
here rather than claim the file is C0209-clean?

The message also only mentions %-formatting, while the diff additionally
rewrites str.format() call sites (the UFID string, the sample probability
and the used_time print).  Could the count and the "all %-formatting"
wording be adjusted to match what the diff actually touches?

> diff --git a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
> index 1615843c225e4..9cd0d8f0ab233 100644
> --- a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
> +++ b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py

[ ... ]

> @@ -413,14 +413,13 @@ class ovsactions(nla):
>          )
>  
>          def dpstr(self, more=False):
> -            args = "group=%d" % self.get_attr("OVS_PSAMPLE_ATTR_GROUP")
> +            args = f"group={int(self.get_attr('OVS_PSAMPLE_ATTR_GROUP'))}"
>  
>              cookie = self.get_attr("OVS_PSAMPLE_ATTR_COOKIE")
>              if cookie:
> -                args += ",cookie(%s)" % \
> -                        "".join(format(x, "02x") for x in cookie)
> +                args += f",cookie({''.join((format(x, '02x') for x in cookie))})"

[Severity: Low]
This conversion trades C0209 for C0301.  The cookie line in
ovsactions.psample.dpstr() was wrapped under 80 columns before via a line
continuation and is now over the limit.

The same happens in several other places touched by this patch, all of
which were within 79 columns before:

  - the NAT IP_MIN / IP_MAX prints in ovsactions.ovs_ct_attr.ovs_nat_attr.dpstr()
  - the emask print in ovsactions.ovs_ct_attr.dpstr()
  - the pid print in ovsactions.userspace.dpstr()
  - the three push_vlan() range-check messages in ovsactions.parse()
  - the tci / vid range-check messages in ovskey._parse_vlan_from_flowstr()
  - the encap() trailing-content message in ovskey._parse_encap_from_flowstr()
  - the port print in print_ovsdp_full()

The file goes from 5 to 16 lines longer than 79 columns.  Since the same
patch already uses intermediate locals elsewhere (val, pkts/nbytes,
mhit/mtotal), could those be used here too so no new long lines appear?

For reference, the later patch "selftests: openvswitch: suppress pylint
complexity warnings" concedes "10 remaining C0301 line-too-long warnings
(81-89 columns)" at the series tip, so these stay for the whole series.

>  
> -            return "psample(%s)" % args
> +            return f"psample({args})"

[ ... ]

> @@ -564,22 +557,18 @@ class ovsactions(nla):
>              if self.get_attr("OVS_CT_ATTR_FORCE_COMMIT") is not None:
>                  print_str += "force,"
>              if self.get_attr("OVS_CT_ATTR_EVENTMASK") is not None:
> -                print_str += "emask=0x%X," % self.get_attr(
> -                    "OVS_CT_ATTR_EVENTMASK"
> -                )
> +                print_str += f"emask=0x{self.get_attr('OVS_CT_ATTR_EVENTMASK'):X},"

[ ... ]

> @@ -767,32 +754,27 @@ class ovsactions(nla):
>                      if k == "vid":
>                          vid = int(v, 0)
>                          if vid < 0 or vid > 0xFFF:
>                              raise ValueError(
> -                                "push_vlan(): vid=%d out of "
> -                                "range (0-4095)" % vid)
> +                                f"push_vlan(): vid={int(vid)} out of range (0-4095)")
>                      elif k == "pcp":
>                          pcp = int(v, 0)
>                          if pcp < 0 or pcp > 7:
>                              raise ValueError(
> -                                "push_vlan(): pcp=%d out of "
> -                                "range (0-7)" % pcp)
> +                                f"push_vlan(): pcp={int(pcp)} out of range (0-7)")
>                      elif k == "tpid":
>                          tpid = int(v, 0)
>                          if tpid < 0 or tpid > 0xFFFF:
>                              raise ValueError(
> -                                "push_vlan(): tpid=0x%x out "
> -                                "of range (0-0xffff)" % tpid)
> +                                f"push_vlan(): tpid=0x{tpid:x} out of range (0-0xffff)")

[ ... ]

> @@ -2569,16 +2549,14 @@ class OvsFlow(GenericNetlinkSocket):
>              ufid = self.get_attr("OVS_FLOW_ATTR_UFID")
>              ufid_str = ""
>              if ufid is not None:
> -                ufid_str = (
> -                    "ufid:{:08x}-{:04x}-{:04x}-{:04x}-{:04x}{:08x}".format(
> -                        ufid[0],
> -                        ufid[1] >> 16,
> -                        ufid[1] & 0xFFFF,
> -                        ufid[2] >> 16,
> -                        ufid[2] & 0,
> -                        ufid[3],
> -                    )
> -                )
> +                u0 = ufid[0]
> +                u1h = ufid[1] >> 16
> +                u1l = ufid[1] & 0xFFFF
> +                u2h = ufid[2] >> 16
> +                u2l = ufid[2] & 0
                                ^^^

[Severity: Medium]
This isn't a bug introduced by this patch, but since the mask is being
lifted into a freshly written local, is the & 0 intentional?

Every sibling group in OvsFlow.ovs_flow_msg.dpstr() uses a real shift or
mask (ufid[1] >> 16, ufid[1] & 0xFFFF, ufid[2] >> 16), while u2l is
unconditionally zero, so the fifth group of the printed UFID always comes
out as 0000 and two flows differing only in the low half of ufid[2] print
an identical ufid: string under dump-flows -v.

The packing side in OvsFlow.ovs_flow_msg.parse() drops the same bits:

    uuidRawObj[5] & (0xFF << 32) >> 32,

Since >> binds tighter than &, this is uuidRawObj[5] & 0xFF, so only bits
0-7 of the UUID node field reach word 2.

openvswitch.sh test_flow_set installs a UFID with a nonzero fifth group:

	local fwd_flow="ufid:00000001-0002-0003-0004-000500060007"

but only asserts on the dumped action, so nothing in-tree catches this.
Would it be worth using 0xFFFF here (as a separate patch) instead of
carrying & 0 forward?  It is still present at the series tip.

> +                u3 = ufid[3]
> +                ufid_str = (f"ufid:{u0:08x}-{u1h:04x}-{u1l:04x}"
> +                            f"-{u2h:04x}-{u2l:04x}{u3:08x}")

[ ... ]

> @@ -3115,7 +3088,7 @@ def main(argv):
>      elif hasattr(args, "flsbr"):
>          rep = ovsdp.info(args.flsbr, 0)
>          if rep is None:
> -            print("DP '%s' not found." % args.flsbr)
> +            print(f"DP '{args.flsbr}' not found.")
>          ovsflow.del_flows(rep["dpifindex"])

[Severity: Low]
This is a pre-existing issue and not introduced by this patch, but while
this branch is being touched: is the missing return 1 here deliberate?

OvsDatapath.info() turns an ENODEV netlink reply into None:

    except NetlinkError as ne:
        if ne.code == errno.ENODEV:
            reply = None

so del-flows against a nonexistent datapath prints the message and then
falls into rep["dpifindex"], raising TypeError: 'NoneType' object is not
subscriptable.  The adjacent addif / delif / dumpdp / add-flow / mod-flow
branches all return 1 after the same check.  It is unchanged at the series
tip.

>  
>      return 0

-- 
Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260905104026.3776396-1-houminxi%40gmail.com

  reply	other threads:[~2026-09-09 12:42 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-05 10:40 [PATCH net-next 0/4] selftests: openvswitch: pylint cleanup of ovs-dpctl.py Minxi Hou
2026-09-05 10:40 ` [PATCH 1/4] selftests: openvswitch: convert %-formatting to f-strings Minxi Hou
2026-09-09 12:42   ` netdev-bot+sashiko [this message]
2026-09-05 10:40 ` [PATCH 2/4] selftests: openvswitch: fix misc pylint warnings in ovs-dpctl.py Minxi Hou
2026-09-09 12:42   ` netdev-bot+sashiko
2026-09-05 10:40 ` [PATCH 3/4] selftests: openvswitch: add missing docstrings " Minxi Hou
2026-09-09 12:42   ` netdev-bot+sashiko
2026-09-05 10:40 ` [PATCH 4/4] selftests: openvswitch: suppress pylint complexity warnings Minxi Hou
2026-09-09 12:42   ` netdev-bot+sashiko
2026-09-06  8:55 ` [PATCH net-next 0/4] selftests: openvswitch: pylint cleanup of ovs-dpctl.py Minxi Hou
2026-09-08 17:04 ` [net-next,0/4] " Minxi Hou

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=178895776955.219967.320136497327402821@kernel.org \
    --to=netdev-bot+sashiko@kernel.org \
    --cc=aconole@redhat.com \
    --cc=davem@davemloft.net \
    --cc=dev@openvswitch.org \
    --cc=echaudro@redhat.com \
    --cc=edumazet@google.com \
    --cc=horms@kernel.org \
    --cc=houminxi@gmail.com \
    --cc=i.maximets@ovn.org \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=shuah@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