[PATCH 05/36] tuna: Add comprehensive docstrings to converter functions
John Kacur <[email protected]> Fri, 10 Jul 2026 10:14:43 -0400
| Newsgroups | org.kernel.vger.linux-rt-users |
|---|---|
| Message-ID | <[email protected]> |
Add detailed docstrings to all argparse converter functions to improve code documentation and maintainability: - threadstring_to_list(): Documents flexible input formats (PIDs, patterns, mixed), parameters, and the match_requested return value - irqstring_to_list(): Explains IRQ number and pattern matching - socketstring_to_list(): Documents socket-to-CPU expansion and validation behavior - pick_op(): Explains operation prefix extraction (+, -, or None) - get_loglevel(): Documents numeric (0-4) and string format conversion - get_policy_and_rtprio(): Explains POLICY:RTPRIO parsing Each docstring includes Args, Returns, and Notes sections with clear examples of accepted input formats. This completes task #3 from the argparse enhancements tracking document. Assisted-by: Claude:claude-sonnet-4-5 Signed-off-by: John Kacur <[email protected]> --- tuna-cmd.py | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++ tuna/tuna.py | 30 +++++++++++++ 2 files changed, 149 insertions(+) diff --git a/tuna-cmd.py b/tuna-cmd.py index 6cb0a679cc60..f1605896c33c 100755 --- a/tuna-cmd.py +++ b/tuna-cmd.py @@ -28,6 +28,28 @@ import shutil import tuna.cpupower as cpw def get_loglevel(level): + """Convert a logging level string to a Python logging level constant. + + Accepts either numeric (0-4) or string (DEBUG, INFO, WARNING, ERROR) formats. + Numeric values are multiplied by 10 to match Python logging constants. + + Args: + level: Logging level as string. Can be: + - Numeric: "0" (NOTSET), "1" (DEBUG), "2" (INFO), "3" (WARNING), "4" (ERROR) + - String: "DEBUG", "INFO", "WARNING", "ERROR" (case-insensitive) + + Returns: + Integer logging level constant compatible with Python's logging module. + - Numeric input: Returns level * 10 (e.g., "1" -> 10 for DEBUG) + - String input: Returns the uppercase string (e.g., "debug" -> "DEBUG") + + Raises: + ValueError: If level is "CRITICAL" (not supported by tuna) + + Note: + Python logging levels: 0=NOTSET, 10=DEBUG, 20=INFO, 30=WARNING, 40=ERROR, 50=CRITICAL + CRITICAL level is explicitly rejected as tuna does not support it. + """ if level.isdigit() and int(level) in range(0,5): # logging built-in module levels: # 0 - NOTSET @@ -541,6 +563,31 @@ def do_list_op(op, current_list, op_list): return list(set(op_list)) def threadstring_to_list(threadstr, ps=None): + """Convert a thread specifier string to a list of thread IDs. + + Accepts flexible input formats with comma and/or space separators. + Thread specifiers can be numeric PIDs or name patterns with wildcards. + + Args: + threadstr: String of thread specifiers. Can be: + - Numeric PIDs: "1", "1,2,3", "1, 2, 3", "1 2 3" + - Thread name patterns: "systemd*", "kworker/*" + - Mixed: "1,systemd*,100", "1 systemd* 100" + Patterns use shell-style wildcards (* and ?). + ps: Optional procfs.pidstats() object. If None, will be created + on demand when needed to resolve name patterns. + + Returns: + Tuple of (thread_list, match_requested) where: + - thread_list: List of integer PIDs that match the specifiers + - match_requested: Boolean indicating if any filtering was requested + (True if threadstr is non-empty, False otherwise) + + Note: + The match_requested flag is used by display functions to determine + whether to show only matched threads or all threads in the system. + Empty input returns ([], False) to indicate "show all threads". + """ match_requested = bool(threadstr) thread_list = [] if not threadstr: @@ -561,6 +608,30 @@ def threadstring_to_list(threadstr, ps=None): return thread_list, match_requested def irqstring_to_list(irqstr): + """Convert an IRQ specifier string to a list of IRQ numbers. + + Accepts flexible input formats with comma and/or space separators. + IRQ specifiers can be numeric IRQ numbers or IRQ user patterns with wildcards. + + Args: + irqstr: String of IRQ specifiers. Can be: + - Numeric IRQ numbers: "50", "50,51,52", "50, 51, 52", "50 51 52" + - IRQ user patterns: "eth0*", "nvme*" + - Mixed: "50,eth0*,100", "50 eth0* 100" + Patterns use shell-style wildcards (* and ?) matched against + IRQ user names from /proc/interrupts. + + Returns: + Tuple of (irq_list, match_requested) where: + - irq_list: List of integer IRQ numbers that match the specifiers + - match_requested: Boolean indicating if any filtering was requested + (True if irqstr is non-empty, False otherwise) + + Note: + The match_requested flag is used by display functions to determine + whether to show only matched IRQs or all IRQs in the system. + Empty input returns ([], False) to indicate "show all IRQs". + """ match_requested = bool(irqstr) irq_list = [] if not irqstr: @@ -578,6 +649,30 @@ def irqstring_to_list(irqstr): return irq_list, match_requested def socketstring_to_list(socketstr): + """Convert a CPU socket specifier string to a list of CPU numbers. + + Accepts flexible input formats with comma and/or space separators. + Socket specifiers are socket IDs that get expanded to all CPUs in those sockets. + + Args: + socketstr: String of socket specifiers. Can be: + - Single socket: "0" + - Multiple sockets: "0,1", "0, 1", "0 1" + Socket IDs must be valid socket numbers present in the system. + + Returns: + List of integer CPU numbers belonging to the specified sockets. + CPUs are returned in the order they appear in sysfs. + + Raises: + SystemExit: If any socket ID is invalid. Prints available sockets + and exits with code 2. + + Note: + This function queries sysfs to discover CPU topology and validate + socket IDs. Invalid socket IDs cause immediate program termination + with an error message showing valid options. + """ cpu_list = [] # Split by both comma and whitespace import re @@ -593,6 +688,30 @@ def socketstring_to_list(socketstr): return cpu_list def pick_op(argument): + """Extract an operation prefix from an argument string. + + Checks if the argument starts with a '+' or '-' operation prefix. + If present, returns the operation and the remaining string. + + Args: + argument: String to check for operation prefix. + + Returns: + Tuple of (operation, remaining_string) where: + - operation: '+' for addition, '-' for removal, None for replacement + - remaining_string: The argument with the operation prefix removed, + or the original argument if no prefix was found + + Examples: + >>> pick_op("+1,2,3") + ('+', '1,2,3') + >>> pick_op("-0,1") + ('-', '0,1') + >>> pick_op("1,2,3") + (None, '1,2,3') + >>> pick_op("") + (None, '') + """ if argument == "": return (None, argument) if argument[0] in ('+', '-'): diff --git a/tuna/tuna.py b/tuna/tuna.py index be3ca5017ef0..1cb538575b17 100755 --- a/tuna/tuna.py +++ b/tuna/tuna.py @@ -530,6 +530,36 @@ def get_irq_affinity_text(irqs, irq): return "" def get_policy_and_rtprio(parm): + """Parse a scheduling policy and priority from a POLICY:RTPRIO string. + + Accepts flexible input formats for specifying scheduler policy and real-time priority. + Can specify just a policy, just a priority, or both separated by a colon. + + Args: + parm: String specifying policy and/or priority. Can be: + - Policy only: "FIFO", "RR", "OTHER", "BATCH", "IDLE" + - Priority only: "50" (assumes current policy) + - Both: "FIFO:50", "RR:99" + Policy names are case-insensitive. + + Returns: + Tuple of (policy, rtprio) where: + - policy: Integer scheduling policy constant (e.g., SCHED_FIFO, SCHED_RR) + or None if only priority was specified + - rtprio: Integer real-time priority (1-99 for RT policies, 0 for others) + Defaults to 1 for RT policies if not specified + + Raises: + ValueError: If the policy name is invalid or cannot be parsed + + Examples: + >>> get_policy_and_rtprio("FIFO:50") + (SCHED_FIFO, 50) + >>> get_policy_and_rtprio("RR") + (SCHED_RR, 1) + >>> get_policy_and_rtprio("50") + (None, 50) + """ parms = parm.split(":") rtprio = 0 policy = None -- 2.54.0