Skip to main content

No project description provided

Project description

aparse

build pypi

Python argparse extension with support for typing.

Getting started

Install the library from pip:

$ pip install aparse

Extend a function with @add_argparse_arguments decorator to add arguments automatically:

import argparse
from aparse import add_argparse_arguments

@add_argparse_arguments()
def example(arg1: str, arg2: int = 5):
    pass

parser = argparse.ArgumentParser()
parser = example.add_argparse_arguments(parser)
args = parser.parse_args()

# Call example with args
example.from_argparse_arguments(args)

Extend a class with @add_argparse_arguments decorator to construct it automatically:

import argparse
from aparse import add_argparse_arguments

@add_argparse_arguments()
class Example:
    def __init__(self, arg1: str, arg2: int = 5):
        pass

parser = argparse.ArgumentParser()
parser = Example.add_argparse_arguments(parser)
args = parser.parse_args()

# Construct Example with args
instance = Example.from_argparse_arguments(args)

Advanced usage

Using class inheritance

Arguments are automatically added from all base classes if kwargs or args arguments are used in the constructor.

import argparse
from aparse import add_argparse_arguments

class Parent:
    def __init__(self, arg3: str = 'test'):
        pass

@add_argparse_arguments()
class Example(Parent):
    def __init__(arg1: str, arg2: int = 5, **kwargs):
        super().__init__(**kwargs)

parser = argparse.ArgumentParser()
parser = Example.add_argparse_arguments(parser)
args = parser.parse_args()

# Construct Example with args
instance = Example.from_argparse_arguments(args)

Using arguments with the same name

Arguments can be reused if they share the same name. If the types are same and none or only one of them has a default parameter the arguments are merged automatically. If both arguments have a different type or a different values, exception is raised by default. You can prevent this behavior by using soft_defaults=True when calling add_argparse_arguments.

import argparse
from aparse import add_argparse_arguments

@add_argparse_arguments()
def example1(arg1: str, arg2: int = 5):
    pass

@add_argparse_arguments()
def example2(arg1: str = 'test', arg2: int = 5):
    pass

parser = argparse.ArgumentParser()
parser = example1.add_argparse_arguments(parser)
parser = example2.add_argparse_arguments(parser)
args = parser.parse_args()

# Call example1 and example2 with args
example1.from_argparse_arguments(args)
example2.from_argparse_arguments(args)

Using prefixes

Prefixes can be used to separate otherwise incompatible parameters.

import argparse
from aparse import add_argparse_arguments

@add_argparse_arguments()
def example1(arg1: str, arg2: int = 3):
    pass

@add_argparse_arguments()
def example2(arg1: str = 'test', arg2: int = 5):
    pass

parser = argparse.ArgumentParser()
parser = example1.add_argparse_arguments(parser, prefix='ex1')
parser = example2.add_argparse_arguments(parser, prefix='ex2')
args = parser.parse_args()

# Call example1 and example2 with args
example1.from_argparse_arguments(args, _prefix='ex1')
example2.from_argparse_arguments(args, _prefix='ex2')

Getting raw argparse arguments

If you need access to the raw arguments, you can use aparse.ArgparseArguments, in which case, the argparse arguments are passed as a dictionary.

import argparse
from aparse import add_argparse_arguments, ArgparseArguments

@add_argparse_arguments()
def example(ArgparseArguments: args):
    pass

parser = argparse.ArgumentParser()
parser = example.add_argparse_arguments(parser)
args = parser.parse_args()

# Call example with args
example.from_argparse_arguments(args)

Using nested dataclasses as arguments

Dataclasses are expanded as other argparse arguments. You can even have nested dataclasses.

@dataclass
class D1:
    test: str

@add_argparse_arguments()
@dataclass
class D2:
    data1: D1
    test2: int

argparser = ArgumentParser()
D2.add_argparse_arguments(argparser)
args = argparser.parse_args(['--test2', '5', '--data1-test', 'ok'])
d2 = D2.from_argparse_arguments(args)

List arguments

Lists can be used as arguments. In that case, the values are separated by commas.

@add_argparse_arguments()
def test_fn(d: List[int], e: List[str]):
    return d, e

argparser = ArgumentParser()
test_fn.add_argparse_arguments(argparser)
args = argparser.parse_args(['--d', '2,3', '--e', 'te,st'])
d, e = test_fn.from_argparse_arguments(args)

Custom code to construct class from string

If needed, you can specify, how the argument's class instance is constructed from a string argument.

class CS:
    def __init__(self, a):
        self.a = a

    @staticmethod
    def from_str(str_val):
        return CS(f'ok-{str_val}')

@add_argparse_arguments()
def test_fn(d: CS):
    return d

argparser = ArgumentParser()
test_fn.add_argparse_arguments(argparser)
args = argparser.parse_args(['--d', 'test'])
d = test_fn.from_argparse_arguments(args)

Getting the parsed arguments

In order to obtain the parsed kwargs without calling your function, use the bind_argparse_arguments function.

@add_argparse_arguments()
def testfn(k: int = 1, m: float = 2.):
    return dict(k=k, m=m)

argparser = ArgumentParser()
argparser = testfn.add_argparse_arguments(argparser)
args = argparser.parse_args(['--k', '3'])
kwargs = testfn.bind_argparse_arguments(args)

Passing other arguments to from_argparse_arguments

By defaults, aparse forwards any arguments passed to the from_argparse_arguments function to the original function. If the name is the same as an already existing argparse argument, its value is replaced by the value passed to the from_argparse_arguments function.

@add_argparse_arguments()
def testfn(x, k: int = 1, m: float = 2.):
    return dict(k=k, m=m, x=x)

argparser = ArgumentParser()
argparser = testfn.add_argparse_arguments(argparser)
args = argparser.parse_args(['--k', '3'])
testfn.from_argparse_arguments(args, 'test', m=5)

Ignoring arguments

Arguments can be ignored as follows:

@add_argparse_arguments(ignore={'m'})
def testfn(k: int = 1, m: float = 2.):
    return dict(k=k, m=m)

argparser = ArgumentParser()
argparser = testfn.add_argparse_arguments(argparser)
args = argparser.parse_args(['--k', '3'])
testfn.from_argparse_arguments(args)

Extending aparse

You can extend the basic handling of the aparse library, e.g., to add your own types. Implement your own aparse.Handler and register it with aparse.register_handler decorator.

For example the following code is the handler used for parsing lists.

from aparse import Handler, register_handler

@register_handler
class SimpleListHandler(Handler):
    def _list_type(self, tp: Type):
        if getattr(tp, '__origin__', None) == list:
            tp = tp.__args__[0]
            if tp in (int, str, float):
                return tp
        return None

    def preprocess_argparse_parameter(self, parameter: Parameter) -> Type:
        if self._list_type(parameter.type) is not None:
            return True, dataclasses.replace(parameter, argument_type=str)
        return False, parameter

    def parse_value(self, parameter: Parameter, value: Any) -> Any:
        list_type = self._list_type(parameter.type)
        if list_type is not None and isinstance(value, str):
            return True, list(map(list_type, value.split(',')))
        return False, value

Registering callbacks before and after parse

This functionality is currently under construction.

Conditional parsing

This functionality is currently under construction.

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

aparse-0.0.3.tar.gz (10.9 kB view details)

Uploaded Source

Built Distribution

aparse-0.0.3-py3-none-any.whl (10.2 kB view details)

Uploaded Python 3

File details

Details for the file aparse-0.0.3.tar.gz.

File metadata

  • Download URL: aparse-0.0.3.tar.gz
  • Upload date:
  • Size: 10.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.2 importlib_metadata/4.8.1 pkginfo/1.7.1 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.62.2 CPython/3.9.6

File hashes

Hashes for aparse-0.0.3.tar.gz
Algorithm Hash digest
SHA256 fb6aaa82e5d99f2ec29e66f6b06ce919680efda071a87d020075961c542569e1
MD5 671396230ff550b7775ec70016fa5166
BLAKE2b-256 02d1ec99bcebfed2b82958ada218bffc831862712a54dbc3a451afed3be36e96

See more details on using hashes here.

File details

Details for the file aparse-0.0.3-py3-none-any.whl.

File metadata

  • Download URL: aparse-0.0.3-py3-none-any.whl
  • Upload date:
  • Size: 10.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.2 importlib_metadata/4.8.1 pkginfo/1.7.1 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.62.2 CPython/3.9.6

File hashes

Hashes for aparse-0.0.3-py3-none-any.whl
Algorithm Hash digest
SHA256 b271e2876c075c16c1c110294a843c7ea5176291442c827176d1205a7fb0d92a
MD5 5099bf4845165c8f496d6147601f7c26
BLAKE2b-256 8d41951ab82718ccf7e7af027d8a05eb61d3e1179dc44a0141deaa0869a8e4a5

See more details on using hashes here.

Supported by

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