Skip to content

Commit 970f7a6

Browse files
authored
Merge pull request #7 from mbdevpl/feature/code-quality
refactor core codebase for code quality (this also changes signatures of some public functions)
2 parents 9ea57d1 + 09fc809 commit 970f7a6

4 files changed

Lines changed: 62 additions & 76 deletions

File tree

argunparse/argument_unparser.py

Lines changed: 42 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,10 @@ def option_should_be_skipped(value: t.Any) -> bool:
1919
class ArgumentUnparser:
2020
"""For performing reverse operation to what argparse.ArgumentParser does."""
2121

22-
# pylint: disable = too-many-arguments
22+
# pylint: disable = too-many-arguments, too-many-positional-arguments
2323
def __init__(
2424
self, short_opt: str = '-', long_opt: str = '--', opt_value: str = '=',
2525
begin_delim: str = '"', end_delim: str = '"') -> None:
26-
2726
assert isinstance(short_opt, str)
2827
assert isinstance(long_opt, str)
2928
assert isinstance(opt_value, str)
@@ -46,78 +45,66 @@ def unparse_arg(self, arg: t.Any) -> str: # pylint: disable = no-self-use
4645
arg = '""'
4746
return arg
4847

49-
def unparse_args(self, arguments: t.Sequence[t.Any],
50-
*, to_list: bool = False) -> t.Union[str, t.List[str]]:
51-
"""Convert list to string of command-line args."""
48+
def unparse_args_to_list(self, arguments: t.Sequence[t.Any]) -> list[str]:
49+
"""Convert list of objects to a list of command-line args."""
5250
unparsed_list = []
5351
for arg in arguments:
5452
unparsed_list.append(self.unparse_arg(arg))
5553
_LOG.debug('%s: unparsed args to %s', self, unparsed_list)
56-
if to_list:
57-
return unparsed_list
58-
unparsed = ' '.join(unparsed_list)
54+
return unparsed_list
55+
56+
def unparse_args(self, arguments: t.Sequence[t.Any]) -> str:
57+
"""Convert list to string of command-line args."""
58+
unparsed = ' '.join(self.unparse_args_to_list(arguments))
5959
_LOG.debug('%s: converted unparsed args to string "%s"', self, unparsed)
6060
return unparsed
6161

62-
def unparse_option(self, key: str, value: t.Any,
63-
*, to_list: bool = False) -> t.Union[str, t.List[str]]:
64-
"""Convert a key-value pair into a string that can be used as a command-line option."""
62+
def unparse_option_to_list(self, key: str, value: t.Any) -> list[str]:
63+
"""Convert a key-value pair into a short list to be used as a command-line option."""
6564
if option_should_be_skipped(value):
66-
return [] if to_list else ''
65+
return []
6766
unparsed_key = f'{self._long_opt if len(key) > 1 else self._short_opt}{key}'
68-
if not treat_as_option_with_no_value(value):
69-
unparsed_value = self.unparse_arg(value)
70-
if to_list and (self._opt_value == ' ' or treat_as_option_with_no_value(value)):
71-
if treat_as_option_with_no_value(value):
72-
return [unparsed_key]
73-
return [unparsed_key, unparsed_value]
74-
if not treat_as_option_with_no_value(value):
75-
unparsed_option = f'{unparsed_key}{self._opt_value}{unparsed_value}'
76-
if to_list:
77-
return [unparsed_option]
7867
if treat_as_option_with_no_value(value):
79-
return unparsed_key
80-
return unparsed_option
68+
return [unparsed_key]
69+
unparsed_value = self.unparse_arg(value)
70+
if self._opt_value == ' ':
71+
return [unparsed_key, unparsed_value]
72+
return [f'{unparsed_key}{self._opt_value}{unparsed_value}']
8173

82-
def unparse_options(self, options: t.Mapping[str, t.Any],
83-
*, to_list: bool = False) -> t.Union[str, t.List[str]]:
84-
"""Convert dictionary to string of command-line args."""
74+
def unparse_option(self, key: str, value: t.Any) -> str:
75+
"""Convert a key-value pair into a string that can be used as a command-line option."""
76+
if option_should_be_skipped(value):
77+
return ''
78+
unparsed = ' '.join(self.unparse_option_to_list(key, value))
79+
return unparsed
80+
81+
def unparse_options_to_list(self, options: t.Mapping[str, t.Any]) -> list[str]:
82+
"""Convert dictionary to a list of command-line args."""
8583
unparsed_list: t.List[str] = []
8684
for key, value in options.items():
8785
if option_should_be_skipped(value):
8886
continue
89-
unparsed_option = self.unparse_option(key, value, to_list=to_list)
90-
if to_list:
91-
unparsed_list += unparsed_option
92-
else:
93-
assert isinstance(unparsed_option, str), type(unparsed_option)
94-
unparsed_list.append(unparsed_option)
87+
unparsed_list += self.unparse_option_to_list(key, value)
9588
_LOG.debug('%s: unparsed options to %s', self, unparsed_list)
96-
if to_list:
97-
return unparsed_list
98-
unparsed = ' '.join(unparsed_list)
89+
return unparsed_list
90+
91+
def unparse_options(self, options: t.Mapping[str, t.Any]) -> str:
92+
"""Convert dictionary to string of command-line args."""
93+
unparsed = ' '.join(self.unparse_options_to_list(options))
9994
_LOG.debug('%s: converted unparsed options to string "%s"', self, unparsed)
10095
return unparsed
10196

102-
def unparse_options_and_args(self, options: t.Mapping[str, t.Any], arguments: t.Sequence[t.Any],
103-
*, to_list: bool = False) -> t.Union[str, t.List[str]]:
97+
def unparse_options_and_args_to_list(
98+
self, options: t.Mapping[str, t.Any], arguments: t.Sequence[t.Any]) -> list[str]:
99+
"""Convert dictionary and list to a list of command-line args."""
100+
unparsed_options = [] if options is None else self.unparse_options_to_list(options)
101+
unparsed_args = [] if arguments is None else self.unparse_args_to_list(arguments)
102+
return unparsed_options + unparsed_args
103+
104+
def unparse_options_and_args(
105+
self, options: t.Mapping[str, t.Any], arguments: t.Sequence[t.Any]) -> str:
104106
"""Convert dictionary and list to string of command-line args."""
105-
if options is None:
106-
unparsed_options = [] if to_list else ''
107-
else:
108-
unparsed_options = self.unparse_options(options, to_list=to_list)
109-
if arguments is None:
110-
unparsed_args = [] if to_list else ''
111-
else:
112-
unparsed_args = self.unparse_args(arguments, to_list=to_list)
113-
if to_list:
114-
return unparsed_options + unparsed_args
115-
unparsed = []
116-
if unparsed_options:
117-
unparsed.append(unparsed_options)
118-
if unparsed_args:
119-
unparsed.append(unparsed_args)
120-
return ' '.join(unparsed)
107+
return ' '.join(self.unparse_options_and_args_to_list(options, arguments))
121108

122109
def unparse_to_list(self, *args, **kwargs) -> list:
123110
"""Unparse given args as command-line arguments and kwargs as command-line options.
@@ -126,7 +113,7 @@ def unparse_to_list(self, *args, **kwargs) -> list:
126113
127114
This process is a reverse of what built-in argparse module does with parse_args() method.
128115
"""
129-
return self.unparse_options_and_args(kwargs, args, to_list=True)
116+
return self.unparse_options_and_args_to_list(kwargs, args)
130117

131118
def unparse(self, *args, **kwargs) -> str:
132119
"""Unparse given args as command-line arguments and kwargs as command-line options.

requirements_test.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
-r requirements.txt
2-
boilerplates[logging,packaging_tests] ~= 1.2
2+
boilerplates[logging,packaging-tests] ~= 1.2

test/examples.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,14 @@
33
import collections
44
import itertools
55
import pathlib
6+
import typing as t
67

78
_UNPARSER_INIT_ARGS_EXAMPLES = [
89
('short_opt', {'-', '--', '_', '__'}),
910
('long_opt', {'-', '--', '_', '__'}),
1011
('opt_value', {'=', ' ', ''})]
1112

12-
OPTIONS = {
13+
OPTIONS: dict[str, dict[str, t.Any]] = {
1314
'-h': {'h': True}, '--verbosity=100': {'verbosity': 100},
1415
'--DEFINE=NDEBUG': {'DEFINE': 'NDEBUG'},
1516
'--long_flag': {'long_flag': True}, '-o=out_file.txt': {'o': 'out_file.txt'},
@@ -35,8 +36,6 @@
3536
('-123456790', -123456790), (str(2**16), 2**16), ('x', 'x'), ('y', 'y'), ('z', 'z'),
3637
(repr('hello world'), 'hello world')}
3738

38-
ARGUMENTS_SKIPPED = {}
39-
4039
ARGUMENTS_VARIANTS = [([ref1, ref2], [arg1, arg2])
4140
for ((ref1, arg1), (ref2, arg2)) in itertools.permutations(ARGUMENTS, 2)]
4241

test/test_argument_unparser.py

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -24,41 +24,41 @@ def test_option(self):
2424
for reference, option in OPTIONS.items():
2525
with self.subTest(option=option):
2626
key, value = list(*itertools.chain(option.items()))
27+
list_result = unparser.unparse_option_to_list(key, value)
28+
self.assertListEqual([reference], list_result)
2729
result = unparser.unparse_option(key, value)
2830
self.assertEqual(reference, result)
29-
list_result = unparser.unparse_option(key, value, to_list=True)
30-
self.assertListEqual([reference], list_result)
3131

3232
def test_option_skipped(self):
3333
unparser = ArgumentUnparser()
3434
for option in OPTIONS_SKIPPED.items():
3535
with self.subTest(option=option):
3636
key, value = option
37+
list_result = unparser.unparse_option_to_list(key, value)
38+
self.assertListEqual(list_result, [])
3739
result = unparser.unparse_option(key, value)
3840
self.assertEqual(result, '')
39-
list_result = unparser.unparse_option(key, value, to_list=True)
40-
self.assertListEqual(list_result, [])
4141

4242
def test_option_space(self):
4343
unparser = ArgumentUnparser(opt_value=' ')
4444
for reference, option in OPTIONS.items():
4545
with self.subTest(option=option):
4646
key, value = list(*itertools.chain(option.items()))
47+
list_result = unparser.unparse_option_to_list(key, value)
48+
self.assertListEqual(reference.split('='), list_result)
4749
result = unparser.unparse_option(key, value)
4850
self.assertEqual(reference.replace('=', ' '), result)
49-
list_result = unparser.unparse_option(key, value, to_list=True)
50-
self.assertListEqual(reference.split('='), list_result)
5151

5252
def test_options(self):
5353
_LOG.debug('testing %i option variants...',
5454
len(OPTIONS_VARIANTS) + len(OPTIONS_SKIPPED_VARIANTS))
5555
unparser = ArgumentUnparser()
5656
for reference, options in itertools.chain(OPTIONS_VARIANTS, OPTIONS_SKIPPED_VARIANTS):
5757
with self.subTest(options=options):
58+
list_result = unparser.unparse_options_to_list(options)
59+
self.assertListEqual(reference, list_result)
5860
result = unparser.unparse_options(options)
5961
self.assertEqual(' '.join(reference), result)
60-
list_result = unparser.unparse_options(options, to_list=True)
61-
self.assertListEqual(reference, list_result)
6262

6363
def test_options_space(self):
6464
_LOG.debug('testing %i option variants...',
@@ -68,7 +68,7 @@ def test_options_space(self):
6868
with self.subTest(options=options):
6969
result = unparser.unparse_options(options)
7070
self.assertEqual(' '.join(reference).replace('=', ' '), result)
71-
list_result = unparser.unparse_options(options, to_list=True)
71+
list_result = unparser.unparse_options_to_list(options)
7272
fixed_reference = list(itertools.chain.from_iterable(
7373
[_.split('=') if '=' in _ else [_] for _ in reference]))
7474
self.assertListEqual(fixed_reference, list_result)
@@ -84,30 +84,30 @@ def test_args(self):
8484
unparser = ArgumentUnparser()
8585
for reference, args in ARGUMENTS_VARIANTS:
8686
with self.subTest(args=args):
87+
list_result = unparser.unparse_args_to_list(args)
88+
self.assertListEqual(reference, list_result)
8789
result = unparser.unparse_args(args)
8890
self.assertEqual(' '.join(reference), result)
89-
list_result = unparser.unparse_args(args, to_list=True)
90-
self.assertListEqual(reference, list_result)
9191

9292
def test_options_and_args(self):
9393
unparser = ArgumentUnparser()
9494
for (reference_options, options), (reference_args, args) in OPTIONS_AND_ARGUMENTS_VARIANTS:
9595
with self.subTest(options=options, args=args):
96+
list_result = unparser.unparse_options_and_args_to_list(None, args)
97+
self.assertListEqual(reference_args, list_result)
9698
result = unparser.unparse_options_and_args(None, args)
9799
self.assertEqual(' '.join(reference_args), result)
98-
list_result = unparser.unparse_options_and_args(None, args, to_list=True)
99-
self.assertListEqual(reference_args, list_result)
100100

101+
list_result = unparser.unparse_options_and_args_to_list(options, None)
102+
self.assertListEqual(reference_options, list_result)
101103
result = unparser.unparse_options_and_args(options, None)
102104
self.assertEqual(' '.join(reference_options), result)
103-
list_result = unparser.unparse_options_and_args(options, None, to_list=True)
104-
self.assertListEqual(reference_options, list_result)
105105

106+
list_result = unparser.unparse_options_and_args_to_list(options, args)
107+
self.assertListEqual(reference_options + reference_args, list_result)
106108
result = unparser.unparse_options_and_args(options, args)
107109
self.assertEqual(
108110
' '.join(itertools.chain(reference_options, reference_args)), result)
109-
list_result = unparser.unparse_options_and_args(options, args, to_list=True)
110-
self.assertListEqual(reference_options + reference_args, list_result)
111111

112112
def test_unparse(self):
113113
unparser = ArgumentUnparser()

0 commit comments

Comments
 (0)