diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 09d87bd..7de3922 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -15,11 +15,11 @@ jobs: strategy: matrix: python: - - "3.8" - "3.9" - "3.10" - "3.11" - "3.12" + - "3.13" runs-on: ubuntu-latest steps: diff --git a/argparse_dataclass.py b/argparse_dataclass.py index 8ac550c..4a5baf3 100644 --- a/argparse_dataclass.py +++ b/argparse_dataclass.py @@ -225,18 +225,17 @@ """ import argparse +from argparse import BooleanOptionalAction from typing import ( TypeVar, Optional, Sequence, Type, Tuple, - List, get_origin, Literal, get_args, Union, - Dict, Any, Generic, ) @@ -249,54 +248,6 @@ ) from importlib.metadata import version -if hasattr(argparse, "BooleanOptionalAction"): - # BooleanOptionalAction was added in Python 3.9 - BooleanOptionalAction = argparse.BooleanOptionalAction -else: - # backport of argparse.BooleanOptionalAction. - class BooleanOptionalAction(argparse.Action): - def __init__( - self, - option_strings, - dest, - default=None, - type=None, - choices=None, - required=False, - help=None, - metavar=None, - ): - _option_strings = [] - for option_string in option_strings: - _option_strings.append(option_string) - - if option_string.startswith("--"): - option_string = "--no-" + option_string[2:] - _option_strings.append(option_string) - - if help is not None and default is not None: - help += f" (default: {default})" - - super().__init__( - option_strings=_option_strings, - dest=dest, - nargs=0, - default=default, - type=type, - choices=choices, - required=required, - help=help, - metavar=metavar, - ) - - def __call__(self, parser, namespace, values, option_string=None): - if option_string in self.option_strings: - setattr(namespace, self.dest, not option_string.startswith("--no-")) - - def format_usage(self): - return " | ".join(self.option_strings) - - # In Python 3.10, we can use types.NoneType NoneType = type(None) @@ -316,7 +267,7 @@ def parse_args(options_class: Type[OptionsType], args: ArgsType = None) -> Optio def parse_known_args( options_class: Type[OptionsType], args: ArgsType = None -) -> Tuple[OptionsType, List[str]]: +) -> Tuple[OptionsType, list[str]]: """Parse known arguments and return tuple containing dataclass type and list of remaining arguments. """ @@ -424,7 +375,7 @@ def _add_dataclass_options( parser.add_argument(*args, **kwargs) -def _get_kwargs(namespace: argparse.Namespace) -> Dict[str, Any]: +def _get_kwargs(namespace: argparse.Namespace) -> dict[str, Any]: """Converts a Namespace to a dictionary containing the items that to be used as keyword arguments to the Options class. """ @@ -511,7 +462,7 @@ def parse_args(self, args: ArgsType = None, namespace=None) -> OptionsType: def parse_known_args( self, args: ArgsType = None, namespace=None - ) -> Tuple[OptionsType, List[str]]: + ) -> Tuple[OptionsType, list[str]]: """Parse known arguments and return tuple containing dataclass type and list of remaining arguments. """ diff --git a/pyproject.toml b/pyproject.toml index 0b85010..f4bac66 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [project] name = "argparse_dataclass" version = "2.1.0" -requires-python = ">=3.8" +requires-python = ">=3.9" description = "Declarative CLIs with argparse and dataclasses" license = {file = "LICENSE"} authors = [ @@ -12,11 +12,11 @@ classifiers = [ "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] [project.urls] diff --git a/tests/test_argumentparser.py b/tests/test_argumentparser.py index 70482fe..f21dd6f 100644 --- a/tests/test_argumentparser.py +++ b/tests/test_argumentparser.py @@ -3,7 +3,7 @@ import datetime as dt from dataclasses import dataclass, field -from typing import List, Optional, Union, Literal +from typing import Optional, Union, Literal from argparse_dataclass import ArgumentParser @@ -76,7 +76,7 @@ def test_nargs(self): @dataclass class Args: name: str - friends: List[str] = field(metadata=dict(nargs=2)) + friends: list[str] = field(metadata=dict(nargs=2)) args = ["--name", "Sam", "--friends", "pippin", "Frodo"] params = ArgumentParser(Args).parse_args(args) @@ -87,7 +87,7 @@ def test_nargs_plus(self): @dataclass class Args: name: str - friends: List[str] = field(metadata=dict(nargs="+")) + friends: list[str] = field(metadata=dict(nargs="+")) args = ["--name", "Sam", "--friends", "pippin", "Frodo"] params = ArgumentParser(Args).parse_args(args) diff --git a/tests/test_functional.py b/tests/test_functional.py index 70ec48f..ec41f9f 100644 --- a/tests/test_functional.py +++ b/tests/test_functional.py @@ -3,7 +3,7 @@ import datetime as dt from dataclasses import dataclass, field -from typing import List, Optional, Union +from typing import Optional, Union from argparse_dataclass import parse_args, parse_known_args @@ -166,7 +166,7 @@ def test_nargs(self): @dataclass class Args: name: str - friends: List[str] = field(metadata=dict(nargs=2)) + friends: list[str] = field(metadata=dict(nargs=2)) args = ["--name", "Sam", "--friends", "pippin", "Frodo"] params = parse_args(Args, args) @@ -177,7 +177,7 @@ def test_nargs_plus(self): @dataclass class Args: name: str - friends: List[str] = field(metadata=dict(nargs="+")) + friends: list[str] = field(metadata=dict(nargs="+")) args = ["--name", "Sam", "--friends", "pippin", "Frodo"] params = parse_args(Args, args) diff --git a/tox.ini b/tox.ini index 2539be6..586e5cb 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ [tox] -envlist = py38, py39, py310, py311 +envlist = py39, py310, py311, py312, py313 # isolated_build = True [testenv]