Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 15 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
[project]
name = "with-argparse"
description = "A simple but handy Python library to generate a `argparse.ArgumentParser` object from a type-annotated method "
version = "1.0.5rc4"
description = "A simple but handy Python library to parse a type-annotated method as a CLI interface with support for dataclasses and attrs instances"
version = "1.0.6rc1"
license = {text = "Apache 2.0"}
readme = "README.md"

dependencies = ["typing-extensions>=4.15.0"]
requires-python = ">= 3.8"
dependencies = [
"attrs>=26.1.0",
"typing-extensions>=4.15.0",
]
requires-python = ">= 3.12"

authors = [
{ name = "Moritz Hennen", email = "mail@fleance.de" }
Expand All @@ -33,3 +36,11 @@ repository = "https://github.com/fleonce/with-argparse/"

[tool.setuptools]
packages = ["with_argparse"]

[tool.uv]
package = true

[dependency-groups]
dev = [
"mypy>=2.3.0",
]
8 changes: 4 additions & 4 deletions test/test_annotations.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ def wrapper(arg):
return arg

with self.assertRaisesRegex(
ValueError,
"Argument [a-z]+ must have a type annotation in order to be viable for argparse"
TypeError,
"Function .+ must be strongly typed, however has no no type annotation for field '[a-z]+'"
):
wrapper()

Expand All @@ -21,7 +21,7 @@ def func(*, arg):
return arg

with self.assertRaisesRegex(
ValueError,
"Argument [a-z]+ must have a type annotation in order to be viable for argparse"
TypeError,
"Function <function .+ must be strongly typed, however has no no type annotation for field '[a-z]+'"
):
func()
11 changes: 5 additions & 6 deletions test/test_argparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,8 @@ def func(inp: int | None):
with sys_args(inp=123):
self.assertEqual(123, func())

# @foreach(inp={'microsoft/deberta-v3-large'})
def test_arg(self):
@with_argparse
@with_argparse(strict=False)
def func(model: str, generative: bool = False, compare_to: int = 0, trust_remote_code: bool = False):
return model

Expand All @@ -57,7 +56,7 @@ def wrapper(a: Optional[int] = None):

def test_list_argparse(self):
@with_argparse
def wrapper(a: Set[int] = None):
def wrapper(a: set[int] | None = None):
return a

with sys_args():
Expand All @@ -73,7 +72,7 @@ def wrapper():
@foreach(default={0, None}, expect={42, 0})
def test_argparse_int(self, default: int | None, expect: int | None):
@with_argparse
def wrapper(value: int = default) -> int:
def wrapper(value: int | None = default) -> int | None:
return value

with sys_args(value=expect):
Expand Down Expand Up @@ -112,10 +111,10 @@ def func(arg: str) -> str:
func()

def test_duplicate_inputs(self):
@with_argparse
@with_argparse(strict=False)
def func(arg: str) -> str:
return arg

with sys_args(arg="456"):
with sys_args(arg="456"), self.assertRaises(SystemExit):
self.assertEqual(func(arg="123"), "456")
self.assertEqual(func("123"), "456")
49 changes: 49 additions & 0 deletions test/test_argparse2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
from with_argparse import with_attrs
import dataclasses
import unittest

import attrs

from tools import sys_args
from with_argparse import with_dataclass, partial_argparse, no_argparse


class ArgParseTestCase(unittest.TestCase):
def test_basic(self):
@dataclasses.dataclass
class A:
field1: int

@with_dataclass
def func(args: A):
return args.field1

with sys_args():
with self.assertRaises(SystemExit):
func()

with sys_args(field1="42"):
self.assertEqual(42, func())

def test_attrs(self):
@attrs.define
class A:
field1: int

@with_attrs(strict=False)
def func(args: A):
return args.field1

with sys_args():
with self.assertRaises(SystemExit):
func()

with sys_args(field1="42"):
self.assertEqual(42, func())

with sys_args(field1="42", test="test"), partial_argparse() as partial:
func()
self.assertEqual(["--test", "test"], partial.remainder)

with sys_args(), no_argparse():
self.assertEqual(42, func(A(42)))
60 changes: 0 additions & 60 deletions test/test_custom_parse.py

This file was deleted.

4 changes: 2 additions & 2 deletions test/test_dataclass.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class Test:
param: Literal['a', 'b']
items: list[str]

@with_dataclass(args=Test)
@with_dataclass
def func(args: Test):
return args.param

Expand All @@ -33,7 +33,7 @@ class A:
class B:
number: int

@with_dataclass(A, B)
@with_dataclass
def func(arg1: A, arg2: B):
return len(arg1.param) + arg2.number

Expand Down
28 changes: 0 additions & 28 deletions test/test_glob.py

This file was deleted.

15 changes: 9 additions & 6 deletions test/test_ignore.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import argparse
import logging
import unittest

Expand All @@ -11,14 +12,15 @@

class IgnoreTest(unittest.TestCase):
def test_ignore_single_param(self):
@with_argparse(ignore_keys={"arg"})
@with_argparse(strict=False)
def wrapper(arg: str) -> str:
return arg

self.assertEqual("abc", wrapper("abc"))
with sys_args():
self.assertEqual("abc", wrapper("abc"))

def test_ignore_multi_param(self):
@with_argparse(ignore_keys={"arg"})
@with_argparse(strict=False)
def wrapper(arg: str, inp: str) -> str:
return inp + arg

Expand All @@ -32,16 +34,17 @@ def wrapper(arg: str, inp: str) -> str:
self.assertEqual("42abc", wrapper("abc"))

def test_ignore_kwarg_multi_param(self):
@with_argparse(ignore_keys={"arg"})
@with_argparse(strict=False)
def wrapper(inp: str, arg: str) -> str:
return arg

with sys_args(inp="42"):
self.assertEqual("value", wrapper("value"))
with self.assertRaises(SystemExit):
self.assertEqual("value", wrapper("value"))
self.assertEqual("value", wrapper(arg="value"))

def test_kwonly_kwarg_multi_param(self):
@with_argparse(ignore_keys={"arg"})
@with_argparse(strict=False)
def wrapper(*, inp: str, arg: str) -> str:
return inp + arg

Expand Down
Loading
Loading