Coder Social home page Coder Social logo

argparse_dataclass's People

Contributors

adsharma avatar asasine avatar frank113 avatar jayvdb avatar jcal-15 avatar lvdgraaff avatar mcobzarenco avatar mivade avatar pedro-avalos avatar rafi-cohen avatar svenwarnke avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

argparse_dataclass's Issues

Update Manifest

Description

When building on my local machine manifest_maker provides a warning that the MANIFEST.in file contains unknown commands. This warning is the result of MANIFEST not using include statements.

Related Issues

Proposed Solution

Update the MANIFEST.in file to use include statement to ensure the following files are included in the source distribution:

  • README.rst
  • LICENSE
  • tox.ini
  • requirements_dev.txt
  • Makefile

Steps to Reproduce

rm -rf sdist/ build/ ## ensure all prior build artifacts are removed
python setup.py sdist
running sdist
running egg_info
writing argparse_dataclass.egg-info/PKG-INFO
writing dependency_links to argparse_dataclass.egg-info/dependency_links.txt
writing top-level names to argparse_dataclass.egg-info/top_level.txt
reading manifest file 'argparse_dataclass.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
warning: manifest_maker: MANIFEST.in, line 1: unknown action 'README.rst'

warning: manifest_maker: MANIFEST.in, line 2: unknown action 'LICENSE'

warning: manifest_maker: MANIFEST.in, line 3: unknown action 'requirements_dev.txt'

warning: manifest_maker: MANIFEST.in, line 4: unknown action 'tox.ini'

adding license file 'LICENSE'
writing manifest file 'argparse_dataclass.egg-info/SOURCES.txt'
running check
creating argparse_dataclass-2.0.0
creating argparse_dataclass-2.0.0/argparse_dataclass.egg-info
copying files to argparse_dataclass-2.0.0...
copying LICENSE -> argparse_dataclass-2.0.0
copying MANIFEST.in -> argparse_dataclass-2.0.0
copying README.rst -> argparse_dataclass-2.0.0
copying argparse_dataclass.py -> argparse_dataclass-2.0.0
copying setup.py -> argparse_dataclass-2.0.0
copying argparse_dataclass.egg-info/PKG-INFO -> argparse_dataclass-2.0.0/argparse_dataclass.egg-info
copying argparse_dataclass.egg-info/SOURCES.txt -> argparse_dataclass-2.0.0/argparse_dataclass.egg-info
copying argparse_dataclass.egg-info/dependency_links.txt -> argparse_dataclass-2.0.0/argparse_dataclass.egg-info
copying argparse_dataclass.egg-info/top_level.txt -> argparse_dataclass-2.0.0/argparse_dataclass.egg-info
Writing argparse_dataclass-2.0.0/setup.cfg
creating dist
Creating tar archive
removing 'argparse_dataclass-2.0.0' (and everything under it)

System Information

  • MacOS Ventura 13.4
  • Python: 3.11.3

References

Add custom `dataclass` decorator

This is like the standard dataclass decorator but will also optionally (on by default) add a parse_args class method to the generated class. This would allow us to do shortcuts like:

@dataclass
class Parameters:
    x: int
    y: int

params = Parameters.parse_args()

Support Union types again

Consider the scenario, where an argument could have one of multiple types (see code below). Under version 0.2.1 this code worked. Now under 1.0.0 it breaks with "TypeError: Union types other than 'Optional' are not supported"

from dataclasses import dataclass, field
from typing import Union
from argparse_dataclass import ArgumentParser


def str_or_int(value: str) -> Union[str, int]:
    try:
        return int(value)
    except ValueError:
        return value


@dataclass
class Options:
    str_or_int: Union[str, int] = field(metadata=dict(type=str_or_int))


parser = ArgumentParser(Options)
print(parser.parse_args(["--str-or-int", "John"]))
print(parser.parse_args(["--str-or-int", "42"]))

I think this is a legitimate use case and by having the 'type' field in metadata the user can take up the burden of transforming those. We are currently using argparse-dataclass 0.2.1 with Union types so this change in behavior is preventing us from updating at the moment.

It would be great to have this support for Union because I would really like to update and get support for Optional types as well.

Is nested dataclass supported?

from argparse_dataclass import dataclass
from argparse_dataclass import ArgumentParser

@dataclass
class SubOption:
    a: int = 1
    b: int = 2

@dataclass
class Options:
    x: int = 42
    y: bool = False
    sub: SubOption = None

parser = ArgumentParser(Options)
x = parser.parse_args(['--sub', '1'])
print(x)

for example, how can I parse args to get a value for sub?

dataclass decorator not working as expected

Hi,

I seem to be running into a couple of issues when using the decorator that was recently added in #9:

  1. It does not work with optional keyword arguments:
from argparse_dataclass import dataclass

@dataclass(frozen=True)
class Opt:
    x: int = 42
    y: bool = False

Error: TypeError: cls must be a dataclass
It seems that cls here is actually real_dataclass.wrap.

  1. It does not behave like a regular dataclass:
from argparse_dataclass import dataclass

@dataclass
class Opt:
    x: int = 42
    y: bool = False

opt = Opt()
print(opt.x)

Error: AttributeError: 'Inner' object has no attribute 'x'
Looks like Opt was "replaced" with Inner, which is defined in argparse_dataclass.dataclass.

Needs explicit type in metadata for Optional[type] fields

The following class fails to parse:

@dataclass
class IndexOptsMinimal:
    index: Optional[int] = None

The following workaround is required:

@dataclass
class IndexOptsWorkaround:
    index: Optional[int] = field(metadata=dict(type=int), default=None)

Using optional arguments that are allowed to be None is such a common pattern that it deserves to supported implicitly.

Field metadata being passed on to parser needs documentation

If I create a dataclass like this:

@dataclass
class Options:
    option1:int = 3
    """This is option1. it should be between 1 and 4"""
    option2:str = ""
    """This is option2. it should contain a name"""

Will the docstrings appear in the help of the argparse?

Option to keep underscores in arguments names

Thank you for this library.

I would like to have an option that would allow to keep the underscores in the argument names instead of replacing them by minus signs. I can prepare a PR for that change if that is a feature you are happy to integrate.

Support Argument groups

Hi, it is possible to use argument groups in argparse?

This is useful when you want to group arguments together.
For example, you can group arguments by their functionality.

import argparse

parser = argparse.ArgumentParser()

group = parser.add_argument_group('Training options')
group.add_argument('--epochs', type=int, default=10, help='Number of epochs')
group.add_argument('--batch_size', type=int, default=32, help='Batch size')

group = parser.add_argument_group('Optimizer options')
group.add_argument('--lr', type=float, default=0.01, help='Learning rate')

args = parser.parse_args()
usage: train.py [-h] [--epochs EPOCHS] [--batch_size BATCH_SIZE] [--lr LR]
                                                                          
options:                                                                  
  -h, --help            show this help message and exit

Training options:
  --epochs EPOCHS       Number of epochs
  --batch_size BATCH_SIZE
                        Batch size

Optimizer options:
  --lr LR               Learning rate

Docs: https://docs.python.org/3/library/argparse.html#argument-groups

make _add_dataclass_options public

Hi,

I would like to be able to use _add_dataclass_options directly in some of my code in order to be able to continue using normal argparse.ArgumentParser instances and use a dataclass to define only a subset of my script arguments.
Would it be possible to expose _add_dataclass_options as a public function i.e. remove the initial underscore?

ValueError when using `from __future__ import annotations`

With the below script, I get an exception:

from __future__ import annotations
from argparse_dataclass import dataclass

@dataclass
class MyArgs:
    foo: int = 0
    bar: str = 'hello'
    baz: bool = False

def main():
    print(MyArgs.parse_args())

if __name__ == '__main__':
    main()
$ python3 targ.py
Traceback (most recent call last):
  File "/Users/ibadawi/targ.py", line 4, in <module>
    @dataclass
     ^^^^^^^^^
  File "/Users/ibadawi/Library/Python/3.11/lib/python/site-packages/argparse_dataclass.py", line 474, in dataclass
    return wrap(cls)
           ^^^^^^^^^
  File "/Users/ibadawi/Library/Python/3.11/lib/python/site-packages/argparse_dataclass.py", line 465, in wrap
    cls.parse_args = staticmethod(ArgumentParser(cls).parse_args)
                                  ^^^^^^^^^^^^^^^^^^^
  File "/Users/ibadawi/Library/Python/3.11/lib/python/site-packages/argparse_dataclass.py", line 423, in __init__
    _add_dataclass_options(options_class, self)
  File "/Users/ibadawi/Library/Python/3.11/lib/python/site-packages/argparse_dataclass.py", line 374, in _add_dataclass_options
    parser.add_argument(*args, **kwargs)
  File "/usr/local/Cellar/[email protected]/3.11.2_1/Frameworks/Python.framework/Versions/3.11/lib/python3.11/argparse.py", line 1448, in add_argument
    raise ValueError('%r is not callable' % (type_func,))
ValueError: 'int' is not callable

Removing from __future__ import annotations works fine and prints MyArgs(foo=0, bar='hello', baz=False) as expected.

It looks like the types as returned by dataclasses.fields() are just strings in this case. I'm not super familiar with writing code to process annotations but a workaround might be to use typing.get_type_hints() instead of dataclasses.fields() to get at the field types:

typing.get_type_hints(MyArgs):

{'bar': <class 'str'>, 'baz': <class 'bool'>, 'foo': <class 'int'>}

dataclasses.fields(MyArgs):

(Field(name='foo',type='int',default=0,default_factory=<dataclasses._MISSING_TYPE object at 0x10b1d5610>,init=True,repr=True,hash=None,compare=True,metadata=mappingproxy({}),kw_only=False,_field_type=_FIELD),
 Field(name='bar',type='str',default='hello',default_factory=<dataclasses._MISSING_TYPE object at 0x10b1d5610>,init=True,repr=True,hash=None,compare=True,metadata=mappingproxy({}),kw_only=False,_field_type=_FIELD),
 Field(name='baz',type='bool',default=False,default_factory=<dataclasses._MISSING_TYPE object at 0x10b1d5610>,init=True,repr=True,hash=None,compare=True,metadata=mappingproxy({}),kw_only=False,_field_type=_FIELD))

Default help formatter is not working

example code:
from dataclasses import dataclass, field
from argparse_dataclass import ArgumentParser
from argparse import ArgumentDefaultsHelpFormatter

@dataclass
class FineParams:
    batch_size: int = field(default=300) 

parser = ArgumentParser(GCPFineParams, formatter_class=ArgumentDefaultsHelpFormatter)
params: FineParams = parser.parse_args()

resulting non-defaults help printout.

diving into argparse code (argparse.py, ver 1.1, line 1861) shone that the ArgumentParser's _actions class members, batch_size action is stored as _StoreAction(option_strings=['--batch-size'], dest='batch_size', nargs=None, const=None, default=<dataclasses._MISSING_TYPE object at 0x7f8465889960>, type=<class 'int'>, choices=None, required=False, help=None, metavar=None)

Support positional arguments

Since I am in the happy position of building a school project and not being able to depend on click for command-line arguments, I decided to see if it was possible to combine dataclasses and argparse. Apparently your library (which I would have to rewrite anyway) doesn't make it possible to provide positional arguments. Would that be possible through another metadata flag?

Do you want to publish it in Pypi ?

I don't know if this is the right place to write, but I don't know where else write it, anyway....
Are you intending to publish the lib again on pypi? I found this library very useful and it could be worth!

Thanks in advance

Modernize packaging

We're still using setup.py but a pyproject.toml-based approach is the preferred way these days. See also build.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.