Skip to main content

Simple class-based argument parsing for python scripts

Project description

argsclass

Simple class-based argument parsing for python scripts

Class Inspection

The inspect_class function allows you to convert a class definition into a list of ArgSpec objects. This enables you to define your command-line arguments using class attributes with type hints and descriptors.

Basic Usage

from argsclass import inspect_class, positional

class Args:
    flag: bool                    # Boolean attributes become flags
    option: str = "default"       # Attributes with defaults become options
    Name: str = positional(help_text="foo")  # Use descriptors for positional args

specs = inspect_class(Args)
# Returns: [FlagArgSpec("flag"), OptionArgSpec("option"), PositionalArgSpec("Name")]

Type Inference

The inspector automatically infers argument types from type hints:

  • boolFlagArgSpec (boolean flags)
  • str, int, floatOptionArgSpec or PositionalArgSpec (depending on descriptor)
  • Attributes with default values → OptionArgSpec
  • Attributes with positional() descriptor → PositionalArgSpec

Descriptors

Use descriptors to create specific argument types:

from argsclass import positional, option, flag

class Args:
    # Positional argument
    filename = positional(help_text="Input file", arg_type=str)
    
    # Option with choices
    format = option(help_text="Output format", choices=["json", "xml"], default="json")
    
    # Flag with aliases
    verbose = flag(help_text="Verbose output", aliases={"v"})

Complete Example

from argsclass import inspect_class, positional, option, flag

class MyArgs:
    # Boolean flag (inferred from type hint)
    verbose: bool
    
    # Option with default
    output: str = "output.txt"
    
    # Positional argument
    filename = positional(help_text="Input file", arg_type=str)
    
    # Option with choices and aliases
    format = option(help_text="Output format", choices=["json", "xml"], aliases={"f"})
    
    # Flag with aliases
    debug = flag(help_text="Enable debug mode", aliases={"d"})

# Convert to ArgSpec objects
specs = inspect_class(MyArgs)
for spec in specs:
    print(f"{spec.__class__.__name__}: {spec.name}")

## Argument Parsing

The `parse` function can parse command-line arguments using either a list of ArgSpec objects or a class definition.

### Parsing with Classes

```python
from argsclass import parse, positional, option, flag

class MyArgs:
    verbose: bool
    output: str = "output.txt"
    filename = positional(help_text="Input file")

# Parse directly from class
result = parse(MyArgs, ["script.py", "--verbose", "input.txt"])
print(result)  # {'verbose': True, 'output': 'output.txt', 'filename': 'input.txt'}

Parsing with ArgSpec Lists

from argsclass import parse, PositionalArgSpec, OptionArgSpec, FlagArgSpec

specs = [
    PositionalArgSpec(name="filename"),
    OptionArgSpec(name="output", aliases={"o"}),
    FlagArgSpec(name="verbose", aliases={"v"})
]

result = parse(specs, ["script.py", "input.txt", "-o", "output.txt", "-v"])
print(result)  # {'filename': 'input.txt', 'output': 'output.txt', 'verbose': True}

Ambiguity Protection

The parser includes built-in protection against ambiguous argument configurations that could lead to unpredictable parsing behavior.

Ambiguous Configurations

The following configurations are considered ambiguous and will raise an AmbiguityError:

  1. Multiple positional arguments with non-specific cardinality:

    class AmbiguousArgs:
        files1 = positional(cardinality=Cardinality.one_or_more())
        files2 = positional(cardinality=Cardinality.zero_or_more())
    
  2. Multiple option arguments with non-specific cardinality:

    class AmbiguousArgs:
        files1 = option(cardinality=Cardinality.one_or_more())
        files2 = option(cardinality=Cardinality.zero_or_more())
    

Note: Mixed positional and option arguments with non-specific cardinality are NOT ambiguous because they are parsed differently:

  • Options are parsed by name (e.g., --option value)
  • Positionals are parsed by position

This configuration is valid:

class ValidArgs:
    files = positional(cardinality=Cardinality.one_or_more())  # Parsed by position
    tags = option(cardinality=Cardinality.zero_or_more())      # Parsed by name

Note: The parsing order matters! Arguments are processed in the order they appear in the class definition. For mixed positional and option arguments, it's recommended to define options first, then positionals:

class RecommendedOrder:
    tags = option(cardinality=Cardinality.zero_or_more())      # Processed first
    files = positional(cardinality=Cardinality.one_or_more())  # Processed second

Resolving Ambiguities

To resolve ambiguities, consider these approaches:

  1. Use specific cardinalities:

    class ValidArgs:
        input_file = positional()  # Single value
        output_file = positional()  # Single value
        files = positional(cardinality=Cardinality.one_or_more())  # Only one with non-specific
    
  2. Reorder arguments (put non-specific cardinality last):

    class ValidArgs:
        input_file = positional()  # Specific first
        output_file = positional()  # Specific second
        extra_files = positional(cardinality=Cardinality.zero_or_more())  # Non-specific last
    
  3. Use different argument types (this is actually always valid):

    class ValidArgs:
        input_file = positional()  # Positional for required
        extra_files = option(cardinality=Cardinality.zero_or_more())  # Option for optional
    

Disabling Ambiguity Validation

If you need to disable ambiguity validation (not recommended), you can set validate_ambiguities=False:

result = parse(MyArgs, argv, validate_ambiguities=False)

Ambiguity Detection Functions

You can also manually check for ambiguities:

from argsclass import detect_ambiguities, is_ambiguous, get_ambiguity_resolution_suggestions

# Check if configuration is ambiguous
if is_ambiguous(MyArgs):
    warnings = detect_ambiguities(MyArgs)
    suggestions = get_ambiguity_resolution_suggestions(MyArgs)
    print("Ambiguities found:", warnings)
    print("Suggestions:", suggestions)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

argsclass-0.2.0.tar.gz (38.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

argsclass-0.2.0-py3-none-any.whl (18.2 kB view details)

Uploaded Python 3

File details

Details for the file argsclass-0.2.0.tar.gz.

File metadata

  • Download URL: argsclass-0.2.0.tar.gz
  • Upload date:
  • Size: 38.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for argsclass-0.2.0.tar.gz
Algorithm Hash digest
SHA256 8358f189b27eff2f33008d3c302f3d7ced4848af3a0b1a4d736f9b6d8ee53a37
MD5 a77d5f2fa82ad52c55a9d0d434d68a3b
BLAKE2b-256 799e216ecba42269870a07301ea189a143738c936a6604745b29a787ab82253a

See more details on using hashes here.

Provenance

The following attestation bundles were made for argsclass-0.2.0.tar.gz:

Publisher: pypi-publish.yml on dotle-git/argsclass

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file argsclass-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: argsclass-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 18.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for argsclass-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9d401a651a3d95de75f53b90acdbe45c6a7602da438eb77777d6e2e0c84c0484
MD5 2d4020341fc29a7899613fd37f2a7e21
BLAKE2b-256 992be721944c37f3c70dd84ade8db5e70870b2fa8aa62aa02b42adf5c44e0df6

See more details on using hashes here.

Provenance

The following attestation bundles were made for argsclass-0.2.0-py3-none-any.whl:

Publisher: pypi-publish.yml on dotle-git/argsclass

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page