ArgumentBuilder Python 3.8+
π Overview
ArgumentBuilder is a fluent, chainable builder class designed to construct command-line argument lists reliably. It automatically flattens nested sequences, converts values to strings, skips empty or None entries, and supports both Unix (--flag) and Windows (/flag) argument styles. Perfect for building subprocess calls, CLI wrappers, or any OS-level command arguments.
- β Flattens lists/tuples recursively
- β
Ignores
Noneand empty strings - β
Dual style: Unix (
--flag) or Windows (/flag) - β Method chaining for elegant construction
- β
Type-safe: returns
List[str]on build
βοΈ Constructor
__init__(style: str = "unix")
Initializes a new ArgumentBuilder instance with the specified argument style.
- style β
str, optional. Determines flag prefix:"unix"β--(default),"windows"β/. - Returns β
ArgumentBuilderinstance.
builder = ArgumentBuilder()
# Windows style
win_builder = ArgumentBuilder(style="windows")
π§ Public Methods
add_arg(value: Any) -> ArgumentBuilder
Adds an argument to the internal list. Automatically flattens list or tuple structures, converts any value to string, strips whitespace, and skips None or empty strings after stripping. This method is chainable.
- value β Any type: string, number, boolean, list, tuple, etc.
Noneor empty values are ignored. - Returns β
self(fluent interface).
builder.add_arg("ls").add_arg(["-l", "-a"]).add_arg(None).add_arg("--color")
# Resulting args: ["ls", "-l", "-a", "--color"]
add_flag(name: str, value: Any = None) -> ArgumentBuilder
Adds a flag (option) with an optional value. The flag name is automatically cleaned (trims spaces, replaces spaces with underscores). The prefix depends on the style parameter (-- for Unix, / for Windows). If a value is provided, it is added as a separate argument after the flag.
- name β Flag name (e.g.,
"verbose","output file"β normalized to"output_file"). - value β Optional value associated with the flag. If not
None, appended as next argument. - Returns β
selffor chaining.
builder.add_flag("verbose").add_flag("output", "result.txt")
# Result: ["--verbose", "--output", "result.txt"]
win_builder = ArgumentBuilder(style="windows")
win_builder.add_flag("recursive", True)
# Result: ["/recursive", "True"]
build() -> List[str]
Finalizes the argument building process and returns the constructed list of string arguments. This method does not alter the builder state; you can continue adding arguments after calling build().
- Returns β
List[str]containing all accumulated, sanitized arguments.
print(args) # ['echo', '--message', 'hello']
π‘ Practical Usage Example
Below is a complete example demonstrating how ArgumentBuilder can be used to construct complex command-line invocations for different operating systems while handling nested data structures gracefully.
import subprocess
# Build arguments for a 'find' command (Unix style)
builder = ArgumentBuilder(style="unix")
builder.add_arg("find") \
.add_arg("/home/user") \
.add_flag("type", "f") \
.add_flag("name", "*.py") \
.add_arg(["-exec", "grep", "-l", "TODO", "{}", ";"])
cmd: List[str] = builder.build()
print("Generated command:", cmd)
# Output: ['find', '/home/user', '--type', 'f', '--name', '*.py', '-exec', 'grep', '-l', 'TODO', '{}', ';']
# Windows style with flags
win_builder = ArgumentBuilder(style="windows")
win_builder.add_arg("dir") \
.add_flag("sort", "name") \
.add_flag("reverse")
print(win_builder.build()) # ['dir', '/sort', 'name', '/reverse']
π The builder intelligently handles nested sequences and automatically strips empty strings, making it robust for dynamic argument generation.
π API Reference & Behavior
| Method | Parameters | Description | Return |
|---|---|---|---|
__init__ | style: str = "unix" | Constructor. Style 'unix' => '--flag', 'windows' => '/flag'. | ArgumentBuilder |
add_arg | value: Any | Adds argument flattening iterables, converting to string, ignoring None/empty. | self |
add_flag | name: str, value: Any = None | Adds a flag with optional value. Normalizes name (spacesβunderscores). | self |
build | None | Returns the built argument list as List[str]. | List[str] |
π§ Internal Logic Notes
- Flattening:
add_argrecursively expandslistortupleinstances. Each element is processed individually. - Empty & None Handling: If a value is
Noneor becomes an empty string afterstrip(), it is silently discarded. - Flag Normalization: The flag name is stripped of leading/trailing whitespace, and any internal spaces are replaced with underscores (e.g.,
"output file"β"output_file"). - Style Prefix: For Unix style, prefix
--is added. For Windows style,/is added. No prefix modification for regular arguments added viaadd_arg. - Chainable Design: All methods except
build()return the instance, enabling method chaining for concise code.
π Edge Cases & Advanced Behavior
Handling nested structures & mixed types
builder.add_arg(["git", "commit", ["-m", "Initial commit"]])
builder.add_flag("amend").add_arg(None).add_flag("no-verify")
print(builder.build())
# Output: ['git', 'commit', '-m', 'Initial commit', '--amend', '--no-verify']
β οΈ Note: Passing a boolean value like True or False will be stringified ("True" / "False"). If you need special handling, convert manually before adding.
Windows style with numeric values
win.add_arg("ping").add_flag("n", 5).add_arg("127.0.0.1")
print(win.build()) # ['ping', '/n', '5', '127.0.0.1']