From: John Kacur <jkacur@redhat.com>
To: linux-rt-users <linux-rt-users@vger.kernel.org>
Cc: Clark Williams <williams@redhat.com>,
Tomas Glozar <tglozar@redhat.com>, John Kacur <jkacur@redhat.com>,
Claude <noreply@anthropic.com>
Subject: [PATCH 09/12] rteval: Improve argparse implementation and remove manual sys.argv parsing
Date: Fri, 7 Nov 2025 13:26:32 -0500 [thread overview]
Message-ID: <20251107182645.19545-10-jkacur@redhat.com> (raw)
In-Reply-To: <20251107182645.19545-1-jkacur@redhat.com>
This commit modernizes the argument parsing by using argparse properly
and eliminating fragile manual sys.argv manipulation.
Key improvements:
1. Use nargs='+' for -Z/--summarize and -H/--raw-histogram options
- These now properly accept one or more XML files as arguments
- Removed complex manual argument splitting logic (lines 158-174)
- Help text now correctly shows: -Z XMLFILE [XMLFILE ...]
2. Use nargs='?' with const='' for -S/--source-download option
- Simplified handling of optional kernel version argument
- Removed manual sys.argv.count() checks (line 179)
- Default value provided when flag is present without argument
3. Use parse_known_args() for early argument detection
- Config file (-f) detection now uses proper argparse
- Logging flags (-v/-D/-q) detection now uses proper argparse
- Removed all manual sys.argv indexing and counting
4. Return cmd_opts instead of cmd_args from parse_options()
- File arguments now directly accessible via cmd_opts attributes
- Clearer separation between options and file arguments
5. Improved error handling
- argparse provides better error messages for malformed arguments
- Supports both -Z file1 file2 and --summarize=file1 formats
This eliminates 40+ lines of fragile manual parsing code and makes
the argument handling more robust and maintainable.
Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: John Kacur <jkacur@redhat.com>
---
rteval-cmd | 93 +++++++++++++++++++++++-------------------------------
1 file changed, 39 insertions(+), 54 deletions(-)
diff --git a/rteval-cmd b/rteval-cmd
index 8fd37b98b069..00873ce1196b 100755
--- a/rteval-cmd
+++ b/rteval-cmd
@@ -124,11 +124,11 @@ def parse_options(cfg, parser, cmdargs):
action='store_true', default=rtevcfg.debugging,
help=f'turn on debug prints (default: {rtevcfg.debugging})')
parser.add_argument("-Z", '--summarize', dest='rteval___summarize',
- action='store_true', default=False,
- help='summarize an already existing XML report')
+ nargs='+', default=None, metavar='XMLFILE',
+ help='summarize one or more already existing XML reports')
parser.add_argument("-H", '--raw-histogram', dest='rteval___rawhistogram',
- action='store_true', default=False,
- help='Generate raw histogram data for an already existing XML report')
+ nargs='+', default=None, metavar='XMLFILE',
+ help='Generate raw histogram data for one or more already existing XML reports')
parser.add_argument("-f", "--inifile", dest="rteval___inifile",
type=str, default=None, metavar="FILE",
help="initialization file for configuring loads and behavior")
@@ -144,43 +144,19 @@ def parse_options(cfg, parser, cmdargs):
parser.add_argument("-V", "--version", dest="rteval___version",
action='store_true', default=False,
help='print rteval version and exit')
- parser.add_argument("-S", "--source-download", nargs="*", dest="rteval___srcdownload",
- type=str, default=None, metavar="KERNEL_VERSION",
+ parser.add_argument("-S", "--source-download", nargs="?", dest="rteval___srcdownload",
+ type=str, default=None, const='', metavar="KERNEL_VERSION",
help='download a source kernel from kernel.org and exit')
parser.add_argument("--noload", dest="rteval___noload",
action="store_true", default=False,
help="only run the measurements (don't run loads)")
-
- if not cmdargs:
- cmdargs = ["--help"]
-
- # if -Z/--summarize is specified, add the files to be summarized to cmd_args, and add -Z to cmd_opts
- cmd_args = []
- if (sys.argv.count('-Z')+sys.argv.count('--summarize')) > 0:
- try:
- ind = cmdargs.index('-Z')
- except ValueError:
- ind = cmdargs.index('--summarize')
- cmd_args = cmdargs[ind+1:]
- cmdargs = cmdargs[:ind+1]
- # if -H/--raw-histogram is specified, add the files to be summarized to cmd_args, and add -H to cmd_opts
- elif (sys.argv.count('-H')+sys.argv.count('--raw-histogram')) > 0:
- try:
- ind = cmdargs.index('-H')
- except ValueError:
- ind = cmdargs.index('--raw-histogram')
- cmd_args = cmdargs[ind+1:]
- cmdargs = cmdargs[:ind+1]
-
cmd_opts = parser.parse_args(args=cmdargs)
# if no kernel version was provided for --source-download, set version to default
- if (sys.argv.count('-S')+sys.argv.count('--source-download')) > 0:
- if cmd_opts.rteval___srcdownload == []:
+ if cmd_opts.rteval___srcdownload is not None:
+ if cmd_opts.rteval___srcdownload == '':
cmd_opts.rteval___srcdownload = ModuleParameters()["source"]["default"].replace(".tar.xz", "")
- else:
- cmd_opts.rteval___srcdownload = cmd_opts.rteval___srcdownload[0]
if cmd_opts.rteval___version:
print(f"rteval version {RTEVAL_VERSION}")
@@ -205,7 +181,7 @@ def parse_options(cfg, parser, cmdargs):
# Update the config object with the parsed arguments
cfg.UpdateFromOptionParser(cmd_opts)
- return cmd_args
+ return cmd_opts
if __name__ == '__main__':
from rteval.sysinfo import dmi
@@ -225,13 +201,14 @@ if __name__ == '__main__':
# Before really parsing options, see if we have been given a config file in the args
# and load it - just so that default values are according to the config file
- try:
- cfgfile = sys.argv[sys.argv.index('-f')+1]
- config.Load(cfgfile)
- except IndexError:
- # Missing file argument
- raise RuntimeError('The -f option requires a file name to the configuration file')
- except ValueError:
+ # Use a minimal parser to extract just the -f option
+ config_parser = argparse.ArgumentParser(add_help=False)
+ config_parser.add_argument('-f', '--inifile', dest='inifile')
+ early_args, _ = config_parser.parse_known_args()
+
+ if early_args.inifile:
+ config.Load(early_args.inifile)
+ else:
# No configuration file given, load defaults
config.Load()
@@ -247,20 +224,29 @@ if __name__ == '__main__':
'sysstat' : 'module'})
# Prepare log levels before loading modules, not to have unwanted log messages
+ # Use a minimal parser to extract logging-related flags early
rtevcfg = config.GetSection('rteval')
- if (sys.argv.count('-v')+sys.argv.count('--verbose')) > 0:
+ log_parser = argparse.ArgumentParser(add_help=False)
+ log_parser.add_argument('-v', '--verbose', action='store_true')
+ log_parser.add_argument('-D', '--debug', action='store_true')
+ log_parser.add_argument('-q', '--quiet', action='store_true')
+ log_parser.add_argument('--idle-set', action='store_true')
+ early_args, _ = log_parser.parse_known_args()
+
+ if early_args.verbose:
rtevcfg.verbose = True
- if (sys.argv.count('-D')+sys.argv.count('--debug')) > 0:
+ if early_args.debug:
rtevcfg.debugging = True
- if (sys.argv.count('-q')+sys.argv.count('--quiet')) > 0:
+ if early_args.quiet:
rtevcfg.quiet = True
+
loglev = (not rtevcfg.quiet and (Log.ERR | Log.WARN)) \
| (rtevcfg.verbose and Log.INFO) \
| (rtevcfg.debugging and Log.DEBUG)
logger.SetLogVerbosity(loglev)
# check if cpupower is being used
- if sys.argv.count('--idle-set') > 0:
+ if early_args.idle_set:
rtevcfg.update({'usingCpupower': True})
# Load modules
@@ -271,7 +257,7 @@ if __name__ == '__main__':
parser = argparse.ArgumentParser()
loadmods.SetupModuleOptions(parser)
measuremods.SetupModuleOptions(parser)
- cmd_args = parse_options(config, parser, sys.argv[1:])
+ cmd_opts = parse_options(config, parser, sys.argv[1:])
if rtevcfg.noload:
if rtevcfg.onlyload:
@@ -371,16 +357,15 @@ if __name__ == '__main__':
logger.log(Log.DEBUG, f"workdir: {rtevcfg.workdir}")
# if --summarize was specified then just parse the XML, print it and exit
- if rtevcfg.summarize or rtevcfg.rawhistogram:
- if len(cmd_args) < 1:
- raise RuntimeError("Must specify at least one XML file with --summarize!")
-
- for x in cmd_args:
- if rtevcfg.summarize:
- summarize(x, rtevcfg.xslt_report)
- elif rtevcfg.rawhistogram:
- summarize(x, rtevcfg.xslt_histogram)
+ if cmd_opts.rteval___summarize:
+ for xmlfile in cmd_opts.rteval___summarize:
+ summarize(xmlfile, rtevcfg.xslt_report)
+ sys.exit(0)
+ # if --raw-histogram was specified then just parse the XML, print it and exit
+ if cmd_opts.rteval___rawhistogram:
+ for xmlfile in cmd_opts.rteval___rawhistogram:
+ summarize(xmlfile, rtevcfg.xslt_histogram)
sys.exit(0)
if os.getuid() != 0:
--
2.51.1
next prev parent reply other threads:[~2025-11-07 18:27 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-11-07 18:26 [PATCH 00/12] rteval updates John Kacur
2025-11-07 18:26 ` [PATCH 01/12] rteval: Fix spelling of 'occurrences' in measurement modules John Kacur
2025-11-07 18:26 ` [PATCH 02/12] rteval: Fix typo in comment John Kacur
2025-11-07 18:26 ` [PATCH 03/12] rteval: Remove unused function remove_offline John Kacur
2025-11-07 18:26 ` [PATCH 04/12] rteval: timerlat: Fix typo in log message John Kacur
2025-11-07 18:26 ` [PATCH 05/12] rteval: cyclictest: Fix typo in comment John Kacur
2025-11-07 18:26 ` [PATCH 06/12] rteval: rtevalConfig: Remove redundant 'is True' comparison John Kacur
2025-11-07 18:26 ` [PATCH 07/12] rteval: Clean up MANIFEST.in and fix newnet.py copyright header John Kacur
2025-11-07 18:26 ` [PATCH 08/12] rteval: Add pyproject.toml for modern Python packaging John Kacur
2025-11-07 18:26 ` John Kacur [this message]
2025-11-07 18:26 ` [PATCH 10/12] rteval: timerlat: Add dma_latency option with default value of 0 John Kacur
2025-11-07 18:26 ` [PATCH 11/12] rteval: Add --measurement-module command-line argument John Kacur
2025-11-07 18:26 ` [PATCH 12/12] rteval: Add unit tests for --measurement-module argument John Kacur
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=20251107182645.19545-10-jkacur@redhat.com \
--to=jkacur@redhat.com \
--cc=linux-rt-users@vger.kernel.org \
--cc=noreply@anthropic.com \
--cc=tglozar@redhat.com \
--cc=williams@redhat.com \
/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;
as well as URLs for NNTP newsgroup(s).