Skip to content

Commit da7b4de

Browse files
committed
Replacing upper case types with lower case types for Python 3.9+
1 parent f3b0805 commit da7b4de

File tree

7 files changed

+52
-56
lines changed

7 files changed

+52
-56
lines changed

src/tap/tap.py

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from pprint import pformat
99
from shlex import quote, split
1010
from types import MethodType
11-
from typing import Any, Callable, Dict, List, Optional, Sequence, Set, Tuple, TypeVar, Union, get_type_hints
11+
from typing import Any, Callable, List, Optional, Sequence, Set, Tuple, TypeVar, Union, get_type_hints
1212
from typing_inspect import is_literal_type
1313

1414
from tap.utils import (
@@ -53,9 +53,9 @@ def __init__(
5353
*args,
5454
underscores_to_dashes: bool = False,
5555
explicit_bool: bool = False,
56-
config_files: Optional[List[PathLike]] = None,
56+
config_files: Optional[list[PathLike]] = None,
5757
**kwargs,
58-
):
58+
) -> None:
5959
"""Initializes the Tap instance.
6060
6161
:param args: Arguments passed to the super class ArgumentParser.
@@ -88,7 +88,7 @@ def __init__(
8888
self.argument_buffer = {}
8989

9090
# Create a place to put the subparsers
91-
self._subparser_buffer: List[Tuple[str, type, Dict[str, Any]]] = []
91+
self._subparser_buffer: list[tuple[str, type, dict[str, Any]]] = []
9292

9393
# Get class variables help strings from the comments
9494
self.class_variables = self._get_class_variables()
@@ -369,7 +369,7 @@ def configure(self) -> None:
369369
pass
370370

371371
@staticmethod
372-
def get_reproducibility_info(repo_path: Optional[PathLike] = None) -> Dict[str, str]:
372+
def get_reproducibility_info(repo_path: Optional[PathLike] = None) -> dict[str, str]:
373373
"""Gets a dictionary of reproducibility information.
374374
375375
Reproducibility information always includes:
@@ -405,7 +405,7 @@ def get_reproducibility_info(repo_path: Optional[PathLike] = None) -> Dict[str,
405405

406406
return reproducibility
407407

408-
def _log_all(self, repo_path: Optional[PathLike] = None) -> Dict[str, Any]:
408+
def _log_all(self, repo_path: Optional[PathLike] = None) -> dict[str, Any]:
409409
"""Gets all arguments along with reproducibility information.
410410
411411
:param repo_path: Path to the git repo to examine for reproducibility info.
@@ -418,7 +418,10 @@ def _log_all(self, repo_path: Optional[PathLike] = None) -> Dict[str, Any]:
418418
return arg_log
419419

420420
def parse_args(
421-
self: TapType, args: Optional[Sequence[str]] = None, known_only: bool = False, legacy_config_parsing=False
421+
self: TapType,
422+
args: Optional[Sequence[str]] = None,
423+
known_only: bool = False,
424+
legacy_config_parsing: bool = False,
422425
) -> TapType:
423426
"""Parses arguments, sets attributes of self equal to the parsed arguments, and processes arguments.
424427
@@ -483,7 +486,7 @@ def parse_args(
483486
return self
484487

485488
@classmethod
486-
def _get_from_self_and_super(cls, extract_func: Callable[[type], dict]) -> Union[Dict[str, Any], Dict]:
489+
def _get_from_self_and_super(cls, extract_func: Callable[[type], dict]) -> Union[dict[str, Any], dict]:
487490
"""Returns a dictionary mapping variable names to values.
488491
489492
Variables and values are extracted from classes using key starting
@@ -518,7 +521,7 @@ def _get_from_self_and_super(cls, extract_func: Callable[[type], dict]) -> Union
518521

519522
return dictionary
520523

521-
def _get_class_dict(self) -> Dict[str, Any]:
524+
def _get_class_dict(self) -> dict[str, Any]:
522525
"""Returns a dictionary mapping class variable names to values from the class dict."""
523526
class_dict = self._get_from_self_and_super(
524527
extract_func=lambda super_class: dict(getattr(super_class, "__dict__", dict()))
@@ -531,7 +534,7 @@ def _get_class_dict(self) -> Dict[str, Any]:
531534

532535
return class_dict
533536

534-
def _get_annotations(self) -> Dict[str, Any]:
537+
def _get_annotations(self) -> dict[str, Any]:
535538
"""Returns a dictionary mapping variable names to their type annotations."""
536539
return self._get_from_self_and_super(extract_func=lambda super_class: dict(get_type_hints(super_class)))
537540

@@ -559,15 +562,15 @@ def _get_class_variables(self) -> dict:
559562

560563
return class_variables
561564

562-
def _get_argument_names(self) -> Set[str]:
565+
def _get_argument_names(self) -> set[str]:
563566
"""Returns a list of variable names corresponding to the arguments."""
564567
return (
565568
{get_dest(*name_or_flags, **kwargs) for name_or_flags, kwargs in self.argument_buffer.values()}
566569
| set(self._get_class_dict().keys())
567570
| set(self._annotations.keys())
568571
) - {"help"}
569572

570-
def as_dict(self) -> Dict[str, Any]:
573+
def as_dict(self) -> dict[str, Any]:
571574
"""Returns the member variables corresponding to the parsed arguments.
572575
573576
Note: This does not include attributes set directly on an instance
@@ -596,7 +599,7 @@ def as_dict(self) -> Dict[str, Any]:
596599

597600
return stored_dict
598601

599-
def from_dict(self, args_dict: Dict[str, Any], skip_unsettable: bool = False) -> TapType:
602+
def from_dict(self, args_dict: dict[str, Any], skip_unsettable: bool = False) -> TapType:
600603
"""Loads arguments from a dictionary, ensuring all required arguments are set.
601604
602605
:param args_dict: A dictionary from argument names to the values of the arguments.
@@ -682,7 +685,7 @@ def load(
682685

683686
return self
684687

685-
def _load_from_config_files(self, config_files: Optional[List[str]]) -> List[str]:
688+
def _load_from_config_files(self, config_files: Optional[list[str]]) -> list[str]:
686689
"""Loads arguments from a list of configuration files containing command line arguments.
687690
688691
:param config_files: A list of paths to configuration files containing the command line arguments
@@ -708,7 +711,7 @@ def __str__(self) -> str:
708711
"""
709712
return pformat(self.as_dict())
710713

711-
def __deepcopy__(self, memo: Dict[int, Any] = None) -> TapType:
714+
def __deepcopy__(self, memo: dict[int, Any] = None) -> TapType:
712715
"""Deepcopy the Tap object."""
713716
copied = type(self).__new__(type(self))
714717

@@ -722,11 +725,11 @@ def __deepcopy__(self, memo: Dict[int, Any] = None) -> TapType:
722725

723726
return copied
724727

725-
def __getstate__(self) -> Dict[str, Any]:
728+
def __getstate__(self) -> dict[str, Any]:
726729
"""Gets the state of the object for pickling."""
727730
return self.as_dict()
728731

729-
def __setstate__(self, d: Dict[str, Any]) -> None:
732+
def __setstate__(self, d: dict[str, Any]) -> None:
730733
"""
731734
Initializes the object with the provided dictionary of arguments for unpickling.
732735

src/tap/tapify.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
import dataclasses
99
import inspect
10-
from typing import Any, Callable, Dict, List, Optional, Sequence, Type, TypeVar, Union
10+
from typing import Any, Callable, Optional, Sequence, Type, TypeVar, Union
1111

1212
from docstring_parser import Docstring, parse
1313
from packaging.version import Version
@@ -68,7 +68,7 @@ class _TapData:
6868
Data about a class' or function's arguments which are sufficient to inform a Tap class.
6969
"""
7070

71-
args_data: List[_ArgData]
71+
args_data: list[_ArgData]
7272
"List of data about each argument in the class or function"
7373

7474
has_kwargs: bool
@@ -79,7 +79,7 @@ class _TapData:
7979

8080

8181
def _is_pydantic_base_model(obj: Union[Type[Any], Any]) -> bool:
82-
if inspect.isclass(obj): # issublcass requires that obj is a class
82+
if inspect.isclass(obj): # issubclass requires that obj is a class
8383
return issubclass(obj, BaseModel)
8484
else:
8585
return isinstance(obj, BaseModel)
@@ -94,7 +94,7 @@ def _is_pydantic_dataclass(obj: Union[Type[Any], Any]) -> bool:
9494

9595

9696
def _tap_data_from_data_model(
97-
data_model: Any, func_kwargs: Dict[str, Any], param_to_description: Dict[str, str] = None
97+
data_model: Any, func_kwargs: dict[str, Any], param_to_description: dict[str, str] = None
9898
) -> _TapData:
9999
"""
100100
Currently only works when `data_model` is a:
@@ -153,7 +153,7 @@ def arg_data_from_pydantic(name: str, field: _PydanticField, annotation: Optiona
153153
# dataclass fields in a pydantic BaseModel. It's also possible to use (builtin) dataclass fields and pydantic Fields
154154
# in the same data model. Therefore, the type of the data model doesn't determine the type of each field. The
155155
# solution is to iterate through the fields and check each type.
156-
args_data: List[_ArgData] = []
156+
args_data: list[_ArgData] = []
157157
for name, field in name_to_field.items():
158158
if isinstance(field, dataclasses.Field):
159159
# Idiosyncrasy: if a pydantic Field is used in a pydantic dataclass, then field.default is a FieldInfo
@@ -177,7 +177,7 @@ def arg_data_from_pydantic(name: str, field: _PydanticField, annotation: Optiona
177177

178178

179179
def _tap_data_from_class_or_function(
180-
class_or_function: _ClassOrFunction, func_kwargs: Dict[str, Any], param_to_description: Dict[str, str]
180+
class_or_function: _ClassOrFunction, func_kwargs: dict[str, Any], param_to_description: dict[str, str]
181181
) -> _TapData:
182182
"""
183183
Extract data by inspecting the signature of `class_or_function`.
@@ -186,7 +186,7 @@ def _tap_data_from_class_or_function(
186186
----
187187
Deletes redundant keys from `func_kwargs`
188188
"""
189-
args_data: List[_ArgData] = []
189+
args_data: list[_ArgData] = []
190190
has_kwargs = False
191191
known_only = False
192192

@@ -240,7 +240,7 @@ def _docstring(class_or_function) -> Docstring:
240240
return parse(doc)
241241

242242

243-
def _tap_data(class_or_function: _ClassOrFunction, param_to_description: Dict[str, str], func_kwargs) -> _TapData:
243+
def _tap_data(class_or_function: _ClassOrFunction, param_to_description: dict[str, str], func_kwargs) -> _TapData:
244244
"""
245245
Controls how :class:`_TapData` is extracted from `class_or_function`.
246246
"""
@@ -298,7 +298,7 @@ def to_tap_class(class_or_function: _ClassOrFunction) -> Type[Tap]:
298298
def tapify(
299299
class_or_function: Union[Callable[[InputType], OutputType], Type[OutputType]],
300300
known_only: bool = False,
301-
command_line_args: Optional[List[str]] = None,
301+
command_line_args: Optional[list[str]] = None,
302302
explicit_bool: bool = False,
303303
description: Optional[str] = None,
304304
**func_kwargs,
@@ -339,7 +339,7 @@ def tapify(
339339

340340
# Prepare command line arguments for class_or_function, respecting positional-only args
341341
class_or_function_args: list[Any] = []
342-
class_or_function_kwargs: Dict[str, Any] = {}
342+
class_or_function_kwargs: dict[str, Any] = {}
343343
command_line_args_dict = command_line_args.as_dict()
344344
for arg_data in tap_data.args_data:
345345
arg_value = command_line_args_dict[arg_data.name]

src/tap/utils.py

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
from argparse import ArgumentParser, ArgumentTypeError
22
import ast
33
from base64 import b64encode, b64decode
4-
import copy
5-
from functools import wraps
64
import inspect
75
from io import StringIO
86
from json import JSONEncoder
@@ -16,15 +14,11 @@
1614
from typing import (
1715
Any,
1816
Callable,
19-
Dict,
2017
Generator,
2118
Iterable,
2219
Iterator,
23-
List,
2420
Literal,
2521
Optional,
26-
Set,
27-
Tuple,
2822
Union,
2923
)
3024
from typing_inspect import get_args as typing_inspect_get_args, get_origin as typing_inspect_get_origin
@@ -38,7 +32,7 @@
3832
PathLike = Union[str, os.PathLike]
3933

4034

41-
def check_output(command: List[str], suppress_stderr: bool = True, **kwargs) -> str:
35+
def check_output(command: list[str], suppress_stderr: bool = True, **kwargs) -> str:
4236
"""Runs subprocess.check_output and returns the result as a string.
4337
4438
:param command: A list of strings representing the command to run on the command line.
@@ -225,7 +219,7 @@ def get_class_column(tokens: Iterable[tokenize.TokenInfo]) -> int:
225219
raise ValueError("Could not find any class variables in the class.")
226220

227221

228-
def source_line_to_tokens(tokens: Iterable[tokenize.TokenInfo]) -> Dict[int, List[Dict[str, Union[str, int]]]]:
222+
def source_line_to_tokens(tokens: Iterable[tokenize.TokenInfo]) -> dict[int, list[dict[str, Union[str, int]]]]:
229223
"""Extract a map from each line number to list of mappings providing information about each token."""
230224
line_to_tokens = {}
231225
for token_type, token, (start_line, start_column), (end_line, end_column), line in tokens:
@@ -244,7 +238,7 @@ def source_line_to_tokens(tokens: Iterable[tokenize.TokenInfo]) -> Dict[int, Lis
244238
return line_to_tokens
245239

246240

247-
def get_subsequent_assign_lines(source_cls: str) -> Tuple[Set[int], Set[int]]:
241+
def get_subsequent_assign_lines(source_cls: str) -> tuple[set[int], set[int]]:
248242
"""For all multiline assign statements, get the line numbers after the first line in the assignment.
249243
250244
:param source_cls: The source code of the class.
@@ -301,7 +295,7 @@ def get_subsequent_assign_lines(source_cls: str) -> Tuple[Set[int], Set[int]]:
301295
return intermediate_assign_lines, final_assign_lines
302296

303297

304-
def get_class_variables(cls: type) -> Dict[str, Dict[str, str]]:
298+
def get_class_variables(cls: type) -> dict[str, dict[str, str]]:
305299
"""Returns a dictionary mapping class variables to their additional information (currently just comments)."""
306300
# Get the source code and tokens of the class
307301
source_cls = inspect.getsource(cls)
@@ -387,7 +381,7 @@ def get_class_variables(cls: type) -> Dict[str, Dict[str, str]]:
387381
return variable_to_comment
388382

389383

390-
def get_literals(literal: Literal, variable: str) -> Tuple[Callable[[str], Any], List[type]]:
384+
def get_literals(literal: Literal, variable: str) -> tuple[Callable[[str], Any], list[type]]:
391385
"""Extracts the values from a Literal type and ensures that the values are all primitive types."""
392386
literals = list(get_args(literal))
393387

@@ -424,7 +418,7 @@ def boolean_type(flag_value: str) -> bool:
424418
class TupleTypeEnforcer:
425419
"""The type argument to argparse for checking and applying types to Tuples."""
426420

427-
def __init__(self, types: List[type], loop: bool = False):
421+
def __init__(self, types: list[type], loop: bool = False):
428422
self.types = [boolean_type if t == bool else t for t in types]
429423
self.loop = loop
430424
self.index = 0
@@ -545,7 +539,7 @@ def as_python_object(dct: Any) -> Any:
545539

546540

547541
def enforce_reproducibility(
548-
saved_reproducibility_data: Optional[Dict[str, str]], current_reproducibility_data: Dict[str, str], path: PathLike
542+
saved_reproducibility_data: Optional[dict[str, str]], current_reproducibility_data: dict[str, str], path: PathLike
549543
) -> None:
550544
"""Checks if reproducibility has failed and raises the appropriate error.
551545
@@ -597,7 +591,7 @@ def get_origin(tp: Any) -> Any:
597591

598592

599593
# TODO: remove this once typing_inspect.get_args is fixed for Python 3.10 union types
600-
def get_args(tp: Any) -> Tuple[type, ...]:
594+
def get_args(tp: Any) -> tuple[type, ...]:
601595
"""Same as typing_inspect.get_args but fixes Python 3.10 union types."""
602596
if sys.version_info >= (3, 10) and isinstance(tp, UnionType):
603597
return tp.__args__

tests/test_actions.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import sys
21
from typing import List, Literal
32
import unittest
43
from unittest import TestCase

tests/test_integration.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ def write(self, msg):
2121
sys.stderr = DevNull()
2222

2323

24-
def stringify(arg_list: Iterable[Any]) -> List[str]:
24+
def stringify(arg_list: Iterable[Any]) -> list[str]:
2525
"""Converts an iterable of arguments of any type to a list of strings.
2626
2727
:param arg_list: An iterable of arguments of any type.

tests/test_tapify.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from dataclasses import dataclass
77
import io
88
import sys
9-
from typing import Dict, List, Optional, Tuple, Any
9+
from typing import List, Optional, Tuple, Any
1010
import unittest
1111
from unittest import TestCase
1212

@@ -237,21 +237,21 @@ def __eq__(self, other: str) -> bool:
237237
self.assertEqual(output, "1 simple 3.14 -0.3 True wee")
238238

239239
def test_tapify_complex_types(self):
240-
def concat(complexity: List[str], requires: Tuple[int, int], intelligence: Person) -> str:
240+
def concat(complexity: list[str], requires: tuple[int, int], intelligence: Person) -> str:
241241
return f'{" ".join(complexity)} {requires[0]} {requires[1]} {intelligence}'
242242

243-
def concat_with_positionals(complexity: List[str], /, requires: Tuple[int, int], intelligence: Person) -> str:
243+
def concat_with_positionals(complexity: list[str], /, requires: tuple[int, int], intelligence: Person) -> str:
244244
return f'{" ".join(complexity)} {requires[0]} {requires[1]} {intelligence}'
245245

246246
class Concat:
247-
def __init__(self, complexity: List[str], requires: Tuple[int, int], intelligence: Person):
247+
def __init__(self, complexity: list[str], requires: tuple[int, int], intelligence: Person):
248248
self.kwargs = {"complexity": complexity, "requires": requires, "intelligence": intelligence}
249249

250250
def __eq__(self, other: str) -> bool:
251251
return other == concat(**self.kwargs)
252252

253253
class ConcatWithPositionals:
254-
def __init__(self, complexity: List[str], /, requires: Tuple[int, int], intelligence: Person):
254+
def __init__(self, complexity: list[str], /, requires: tuple[int, int], intelligence: Person):
255255
self.kwargs = {"complexity": complexity, "requires": requires, "intelligence": intelligence}
256256

257257
def __eq__(self, other: str) -> bool:
@@ -1468,7 +1468,7 @@ def __eq__(self, other: str) -> bool:
14681468
pydantic_data_models = []
14691469

14701470
class Concat:
1471-
def __init__(self, a: int, b: int = 2, **kwargs: Dict[str, str]):
1471+
def __init__(self, a: int, b: int = 2, **kwargs: dict[str, str]):
14721472
"""Concatenate three numbers.
14731473
14741474
:param a: The first number.
@@ -1482,7 +1482,7 @@ def __eq__(self, other: str) -> bool:
14821482
return other == concat(self.a, self.b, **self.kwargs)
14831483

14841484
class ConcatWithPositionals:
1485-
def __init__(self, a: int, /, b: int = 2, **kwargs: Dict[str, str]):
1485+
def __init__(self, a: int, /, b: int = 2, **kwargs: dict[str, str]):
14861486
"""Concatenate three numbers.
14871487
14881488
:param a: The first number.

0 commit comments

Comments
 (0)