preparse 0.1.0.dev4__tar.gz → 0.1.0.dev6__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {preparse-0.1.0.dev4/src/preparse.egg-info → preparse-0.1.0.dev6}/PKG-INFO +1 -1
- {preparse-0.1.0.dev4 → preparse-0.1.0.dev6}/pyproject.toml +1 -1
- preparse-0.1.0.dev6/src/preparse/_parsing/Item.py +33 -0
- preparse-0.1.0.dev6/src/preparse/_parsing/__init__.py +1 -0
- preparse-0.1.0.dev6/src/preparse/_parsing/deparse.py +36 -0
- preparse-0.1.0.dev6/src/preparse/_parsing/digest.py +73 -0
- preparse-0.1.0.dev6/src/preparse/_parsing/parse.py +143 -0
- preparse-0.1.0.dev6/src/preparse/_parsing/process.py +28 -0
- {preparse-0.1.0.dev4 → preparse-0.1.0.dev6}/src/preparse/core/PreParser.py +27 -7
- {preparse-0.1.0.dev4 → preparse-0.1.0.dev6}/src/preparse/core/enums.py +13 -6
- {preparse-0.1.0.dev4 → preparse-0.1.0.dev6}/src/preparse/core/warnings.py +11 -2
- preparse-0.1.0.dev6/src/preparse/tests/test_data_toml.py +35 -0
- {preparse-0.1.0.dev4 → preparse-0.1.0.dev6}/src/preparse/tests/test_warn_9001.py +1 -1
- {preparse-0.1.0.dev4 → preparse-0.1.0.dev6}/src/preparse/tests/test_warn_9002.py +1 -1
- {preparse-0.1.0.dev4 → preparse-0.1.0.dev6}/src/preparse/tests/test_warn_even_more.py +1 -1
- {preparse-0.1.0.dev4 → preparse-0.1.0.dev6}/src/preparse/tests/test_warn_more.py +1 -1
- {preparse-0.1.0.dev4 → preparse-0.1.0.dev6/src/preparse.egg-info}/PKG-INFO +1 -1
- {preparse-0.1.0.dev4 → preparse-0.1.0.dev6}/src/preparse.egg-info/SOURCES.txt +6 -16
- preparse-0.1.0.dev4/src/preparse/_parsing/Parsing.py +0 -198
- preparse-0.1.0.dev4/src/preparse/_parsing/__init__.py +0 -0
- preparse-0.1.0.dev4/src/preparse/tests/test_extra.py +0 -160213
- preparse-0.1.0.dev4/src/preparse/tests/test_extra_no_permutation.py +0 -160213
- preparse-0.1.0.dev4/src/preparse/tests/test_extra_posix.py +0 -159704
- preparse-0.1.0.dev4/src/preparse/tests/test_long_only.py +0 -48826
- preparse-0.1.0.dev4/src/preparse/tests/test_long_only_no_permutation.py +0 -48826
- preparse-0.1.0.dev4/src/preparse/tests/test_long_only_posix.py +0 -48805
- preparse-0.1.0.dev4/src/preparse/tests/test_max.py +0 -93
- preparse-0.1.0.dev4/src/preparse/tests/test_max_1.py +0 -51
- preparse-0.1.0.dev4/src/preparse/tests/test_min.py +0 -80
- preparse-0.1.0.dev4/src/preparse/tests/test_min_1.py +0 -103
- preparse-0.1.0.dev4/src/preparse/tests/test_min_2.py +0 -83
- preparse-0.1.0.dev4/src/preparse/tests/test_min_3.py +0 -73
- preparse-0.1.0.dev4/src/preparse/tests/test_parse.py +0 -48715
- preparse-0.1.0.dev4/src/preparse/tests/test_parse_no_permutation.py +0 -48715
- preparse-0.1.0.dev4/src/preparse/tests/test_parse_posix.py +0 -48540
- {preparse-0.1.0.dev4 → preparse-0.1.0.dev6}/LICENSE.txt +0 -0
- {preparse-0.1.0.dev4 → preparse-0.1.0.dev6}/MANIFEST.in +0 -0
- {preparse-0.1.0.dev4 → preparse-0.1.0.dev6}/README.rst +0 -0
- {preparse-0.1.0.dev4 → preparse-0.1.0.dev6}/setup.cfg +0 -0
- {preparse-0.1.0.dev4 → preparse-0.1.0.dev6}/src/preparse/__init__.py +0 -0
- {preparse-0.1.0.dev4 → preparse-0.1.0.dev6}/src/preparse/core/Click.py +0 -0
- {preparse-0.1.0.dev4 → preparse-0.1.0.dev6}/src/preparse/core/__init__.py +0 -0
- {preparse-0.1.0.dev4 → preparse-0.1.0.dev6}/src/preparse/tests/__init__.py +0 -0
- {preparse-0.1.0.dev4 → preparse-0.1.0.dev6}/src/preparse/tests/test_expit.py +0 -0
- {preparse-0.1.0.dev4 → preparse-0.1.0.dev6}/src/preparse/tests/test_features.py +0 -0
- {preparse-0.1.0.dev4 → preparse-0.1.0.dev6}/src/preparse/tests/test_warn_9005.py +0 -0
- {preparse-0.1.0.dev4 → preparse-0.1.0.dev6}/src/preparse/tests/test_warn_9006.py +0 -0
- {preparse-0.1.0.dev4 → preparse-0.1.0.dev6}/src/preparse/tests/test_warn_9007.py +0 -0
- {preparse-0.1.0.dev4 → preparse-0.1.0.dev6}/src/preparse.egg-info/dependency_links.txt +0 -0
- {preparse-0.1.0.dev4 → preparse-0.1.0.dev6}/src/preparse.egg-info/requires.txt +0 -0
- {preparse-0.1.0.dev4 → preparse-0.1.0.dev6}/src/preparse.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import dataclasses
|
|
2
|
+
import functools
|
|
3
|
+
from typing import *
|
|
4
|
+
|
|
5
|
+
from preparse.core.enums import *
|
|
6
|
+
from preparse.core.warnings import *
|
|
7
|
+
|
|
8
|
+
__all__ = ["Item"]
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@dataclasses.dataclass
|
|
12
|
+
class Item:
|
|
13
|
+
key: Optional[str] = None
|
|
14
|
+
remainder: bool | str = False
|
|
15
|
+
value: Optional[str] = None
|
|
16
|
+
|
|
17
|
+
def ishungry(self: Self) -> bool:
|
|
18
|
+
return self.remainder and (self.value is None)
|
|
19
|
+
|
|
20
|
+
def isoption(self: Self) -> bool:
|
|
21
|
+
return self.key is not None
|
|
22
|
+
|
|
23
|
+
def islong(self: Self) -> bool:
|
|
24
|
+
return self.isoption() and self.key.startswith("-")
|
|
25
|
+
|
|
26
|
+
def isgroup(self: Self) -> bool:
|
|
27
|
+
return self.isoption() and not self.key.startswith("-")
|
|
28
|
+
|
|
29
|
+
def isspecial(self: Self) -> bool:
|
|
30
|
+
return self.key is None and self.value is None
|
|
31
|
+
|
|
32
|
+
def ispositional(self: Self) -> bool:
|
|
33
|
+
return self.key is None and self.value is not None
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from preparse._parsing.process import *
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
from typing import *
|
|
2
|
+
|
|
3
|
+
from preparse._parsing.Item import *
|
|
4
|
+
|
|
5
|
+
if TYPE_CHECKING:
|
|
6
|
+
from preparse.core.PreParser import PreParser
|
|
7
|
+
__all__ = ["deparse"]
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def deparse(items: list[Item]) -> list[str]:
|
|
11
|
+
ans: str = list()
|
|
12
|
+
item: Item
|
|
13
|
+
for item in items:
|
|
14
|
+
ans += deparse_item(item)
|
|
15
|
+
return ans
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def deparse_item(item: Item) -> list[str]:
|
|
19
|
+
if item.isspecial():
|
|
20
|
+
return ["--"]
|
|
21
|
+
if item.ispositional():
|
|
22
|
+
return [item.value]
|
|
23
|
+
if item.isgroup():
|
|
24
|
+
if item.value is None:
|
|
25
|
+
return ["-" + item.key]
|
|
26
|
+
if item.remainder:
|
|
27
|
+
return ["-" + item.key + item.value]
|
|
28
|
+
else:
|
|
29
|
+
return ["-" + item.key, item.value]
|
|
30
|
+
else:
|
|
31
|
+
if item.value is None:
|
|
32
|
+
return [item.key]
|
|
33
|
+
if item.remainder:
|
|
34
|
+
return [item.key + "=" + item.value]
|
|
35
|
+
else:
|
|
36
|
+
return [item.key, item.value]
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
from typing import *
|
|
2
|
+
|
|
3
|
+
from preparse._parsing.Item import *
|
|
4
|
+
from preparse.core.enums import *
|
|
5
|
+
from preparse.core.warnings import *
|
|
6
|
+
|
|
7
|
+
if TYPE_CHECKING:
|
|
8
|
+
from preparse.core.PreParser import PreParser
|
|
9
|
+
|
|
10
|
+
__all__ = ["digest"]
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def digest(*, items: list[Item], parser: "PreParser") -> list[Item]:
|
|
14
|
+
items = list(digest_order(items=items, order=parser.order))
|
|
15
|
+
items = list(digest_group(items=items, group=parser.group))
|
|
16
|
+
return items
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def digest_group(*, items: list[Item], group: Group) -> list[Item]:
|
|
20
|
+
if group == Group.MINIMIZE:
|
|
21
|
+
return digest_group_minimize(items)
|
|
22
|
+
if group == Group.MAXIMIZE:
|
|
23
|
+
return digest_group_maximize(items)
|
|
24
|
+
return items
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def digest_group_minimize(items: list[Item]) -> list[Item]:
|
|
28
|
+
ans: list[Item] = list()
|
|
29
|
+
item: Item
|
|
30
|
+
for item in items:
|
|
31
|
+
ans += digest_group_minimize_split(item)
|
|
32
|
+
return ans
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def digest_group_minimize_split(item: Item) -> list[Item]:
|
|
36
|
+
if not item.isgroup():
|
|
37
|
+
return [item]
|
|
38
|
+
ans: list[Item] = list()
|
|
39
|
+
x: str
|
|
40
|
+
for x in item.key:
|
|
41
|
+
if x == "-":
|
|
42
|
+
ans[-1].key += "-"
|
|
43
|
+
else:
|
|
44
|
+
ans.append(Item(key=x))
|
|
45
|
+
item.key = ans[-1].key
|
|
46
|
+
ans[-1] = item
|
|
47
|
+
return ans
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def digest_group_maximize(items: list[Item]) -> list[Item]:
|
|
51
|
+
ans: list[Item] = [items.pop(0)]
|
|
52
|
+
item: Item
|
|
53
|
+
for item in items:
|
|
54
|
+
if item.isgroup() and ans[-1].isgroup() and ans[-1].value is None:
|
|
55
|
+
item.key = ans[-1].key + item.key
|
|
56
|
+
ans[-1] = item
|
|
57
|
+
else:
|
|
58
|
+
ans.append(item)
|
|
59
|
+
return ans
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def digest_order(*, items: list[Item], order: Order) -> list[Item]:
|
|
63
|
+
if order == Order.PERMUTE:
|
|
64
|
+
items.sort(key=digest_order_key)
|
|
65
|
+
return items
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def digest_order_key(item: Item):
|
|
69
|
+
if item.isoption():
|
|
70
|
+
return 0
|
|
71
|
+
if item.isspecial():
|
|
72
|
+
return 1
|
|
73
|
+
return 2
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
from typing import *
|
|
2
|
+
|
|
3
|
+
from preparse._parsing.Item import *
|
|
4
|
+
from preparse.core.enums import *
|
|
5
|
+
from preparse.core.warnings import *
|
|
6
|
+
|
|
7
|
+
if TYPE_CHECKING:
|
|
8
|
+
from preparse.core.PreParser import PreParser
|
|
9
|
+
__all__ = ["parse"]
|
|
10
|
+
|
|
11
|
+
PUOW = PreparseUnrecognizedOptionWarning
|
|
12
|
+
PAOW = PreparseAmbiguousOptionWarning
|
|
13
|
+
PUAW = PreparseUnallowedArgumentWarning
|
|
14
|
+
PIOW = PreparseInvalidOptionWarning
|
|
15
|
+
PLORAW = PreparseLongOptionRequiresArgumentWarning
|
|
16
|
+
PSORAW = PreparseShortOptionRequiresArgumentWarning
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def parse(*, args: list[str], parser: "PreParser") -> Generator[Any, Any, Any]:
|
|
20
|
+
broken: bool = False
|
|
21
|
+
last: Optional[Item] = None
|
|
22
|
+
for arg in args:
|
|
23
|
+
if broken:
|
|
24
|
+
# if we are in the positional-only part
|
|
25
|
+
yield Item(value=arg)
|
|
26
|
+
continue
|
|
27
|
+
if last is not None:
|
|
28
|
+
# if the last item hungers for a value
|
|
29
|
+
last.value = arg
|
|
30
|
+
last.remainder = False
|
|
31
|
+
yield last
|
|
32
|
+
last = None
|
|
33
|
+
continue
|
|
34
|
+
if arg == "--":
|
|
35
|
+
yield Item()
|
|
36
|
+
broken = True
|
|
37
|
+
continue
|
|
38
|
+
if arg == "-" or not arg.startswith("-"):
|
|
39
|
+
# if the arg is positional
|
|
40
|
+
yield Item(value=arg)
|
|
41
|
+
broken = parser.order == Order.POSIX
|
|
42
|
+
continue
|
|
43
|
+
if arg.startswith("--") or parser.islongonly:
|
|
44
|
+
last = parse_long(arg=arg, parser=parser)
|
|
45
|
+
else:
|
|
46
|
+
last = parse_group(arg=arg, parser=parser)
|
|
47
|
+
if not last.ishungry():
|
|
48
|
+
yield last
|
|
49
|
+
last = None
|
|
50
|
+
if last is None:
|
|
51
|
+
# if the last item is not starved
|
|
52
|
+
return
|
|
53
|
+
if isinstance(last.remainder, str):
|
|
54
|
+
warning: PLORAW = PLORAW(
|
|
55
|
+
prog=parser.prog,
|
|
56
|
+
option=last.remainder,
|
|
57
|
+
)
|
|
58
|
+
parser.warn(warning)
|
|
59
|
+
last.remainder = True
|
|
60
|
+
else:
|
|
61
|
+
warning: PSORAW = PSORAW(
|
|
62
|
+
prog=parser.prog,
|
|
63
|
+
option=last.key[-1],
|
|
64
|
+
)
|
|
65
|
+
parser.warn(warning)
|
|
66
|
+
yield last
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def parse_long(*, arg: str, parser: "PreParser") -> Item:
|
|
70
|
+
ans: Item = parse_long_init(arg)
|
|
71
|
+
full: str = parse_long_full(item=ans, parser=parser)
|
|
72
|
+
nargs: Nargs = parser.optdict.get(full, Nargs.NO_ARGUMENT)
|
|
73
|
+
if nargs == Nargs.NO_ARGUMENT and ans.remainder:
|
|
74
|
+
warning = PUAW(prog=parser.prog, option=full)
|
|
75
|
+
parser.warn(warning)
|
|
76
|
+
if nargs == Nargs.REQUIRED_ARGUMENT:
|
|
77
|
+
ans.remainder = True
|
|
78
|
+
if ans.remainder:
|
|
79
|
+
ans.remainder = full
|
|
80
|
+
if parser.abbr == Abbr.COMPLETE:
|
|
81
|
+
ans.key = full
|
|
82
|
+
return ans
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def parse_long_init(arg: str) -> Item:
|
|
86
|
+
if "=" not in arg:
|
|
87
|
+
return Item(key=arg)
|
|
88
|
+
ans: Item = Item(remainder=True)
|
|
89
|
+
ans.key, ans.value = arg.split("=", 1)
|
|
90
|
+
return ans
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def parse_long_full(*, item: Item, parser: "PreParser") -> str:
|
|
94
|
+
if item.key in parser.optdict.keys():
|
|
95
|
+
return item.key
|
|
96
|
+
if parser.abbr == Abbr.REJECT:
|
|
97
|
+
warning: PUOW = PUOW(prog=parser.prog, option=arg)
|
|
98
|
+
parser.warn(warning)
|
|
99
|
+
x: str
|
|
100
|
+
pos: list[str] = list()
|
|
101
|
+
for x in parser.optdict.keys():
|
|
102
|
+
if x.startswith(item.key):
|
|
103
|
+
pos.append(x)
|
|
104
|
+
if len(pos) == 1:
|
|
105
|
+
return pos[0]
|
|
106
|
+
arg: str = item.key
|
|
107
|
+
if item.remainder:
|
|
108
|
+
arg += "=" + item.value
|
|
109
|
+
if len(pos) == 0:
|
|
110
|
+
warning: PUOW = PUOW(prog=parser.prog, option=arg)
|
|
111
|
+
parser.warn(warning)
|
|
112
|
+
else:
|
|
113
|
+
warning: PAOW = PAOW(prog=parser.prog, option=arg, possibilities=pos)
|
|
114
|
+
parser.warn(warning)
|
|
115
|
+
return item.key
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def parse_group_letter(letter: str, *, parser: "PreParser") -> Nargs:
|
|
119
|
+
try:
|
|
120
|
+
return parser.optdict["-" + letter]
|
|
121
|
+
except KeyError:
|
|
122
|
+
warning: PIOW = PIOW(prog=parser.prog, option=letter)
|
|
123
|
+
parser.warn(warning)
|
|
124
|
+
return Nargs.NO_ARGUMENT
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def parse_group(*, arg: str, parser: "PreParser") -> Item:
|
|
128
|
+
ans: Item = Item(key="")
|
|
129
|
+
nargs: Nargs
|
|
130
|
+
for i, a in enumerate(arg):
|
|
131
|
+
if i == 0:
|
|
132
|
+
continue
|
|
133
|
+
ans.key += a
|
|
134
|
+
nargs = parse_group_letter(a, parser=parser)
|
|
135
|
+
if nargs == Nargs.NO_ARGUMENT:
|
|
136
|
+
continue
|
|
137
|
+
if nargs == Nargs.OPTIONAL_ARGUMENT or i < len(arg) - 1:
|
|
138
|
+
ans.remainder = True
|
|
139
|
+
ans.value = arg[i + 1 :]
|
|
140
|
+
else:
|
|
141
|
+
ans.remainder = nargs == Nargs.REQUIRED_ARGUMENT
|
|
142
|
+
return ans
|
|
143
|
+
return ans
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
from typing import *
|
|
3
|
+
|
|
4
|
+
from preparse._parsing.deparse import *
|
|
5
|
+
from preparse._parsing.digest import *
|
|
6
|
+
from preparse._parsing.Item import *
|
|
7
|
+
from preparse._parsing.parse import *
|
|
8
|
+
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
from preparse.core.PreParser import PreParser
|
|
11
|
+
|
|
12
|
+
__all__ = ["process"]
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def process(
|
|
16
|
+
*,
|
|
17
|
+
args: Optional[Iterable] = None,
|
|
18
|
+
parser: "PreParser",
|
|
19
|
+
) -> list[str]:
|
|
20
|
+
"This method parses args."
|
|
21
|
+
if args is None:
|
|
22
|
+
args = sys.argv[1:]
|
|
23
|
+
args = [str(a) for a in args]
|
|
24
|
+
parser = parser.copy()
|
|
25
|
+
items: list[Item] = list(parse(args=args, parser=parser))
|
|
26
|
+
items: list[Item] = list(digest(items=items, parser=parser))
|
|
27
|
+
ans: list[str] = list(deparse(items=items))
|
|
28
|
+
return ans
|
|
@@ -9,7 +9,7 @@ from datarepr import datarepr
|
|
|
9
9
|
from makeprop import makeprop
|
|
10
10
|
from tofunc import tofunc
|
|
11
11
|
|
|
12
|
-
from preparse._parsing
|
|
12
|
+
from preparse._parsing import *
|
|
13
13
|
from preparse.core.Click import *
|
|
14
14
|
from preparse.core.enums import *
|
|
15
15
|
|
|
@@ -21,6 +21,7 @@ class PreParser:
|
|
|
21
21
|
__slots__ = (
|
|
22
22
|
"_abbr",
|
|
23
23
|
"_group",
|
|
24
|
+
"_longonly",
|
|
24
25
|
"_optdict",
|
|
25
26
|
"_order",
|
|
26
27
|
"_prog",
|
|
@@ -33,6 +34,7 @@ class PreParser:
|
|
|
33
34
|
prog: Any = None,
|
|
34
35
|
abbr: Any = Abbr.COMPLETE,
|
|
35
36
|
group: Any = Group.MAINTAIN,
|
|
37
|
+
longonly: Any = Longonly.INFER,
|
|
36
38
|
order: Any = Order.PERMUTE,
|
|
37
39
|
warn: Callable = str,
|
|
38
40
|
) -> None:
|
|
@@ -42,6 +44,7 @@ class PreParser:
|
|
|
42
44
|
self.prog = prog
|
|
43
45
|
self.abbr = abbr
|
|
44
46
|
self.group = group
|
|
47
|
+
self.longonly = longonly
|
|
45
48
|
self.order = order
|
|
46
49
|
self.warn = warn
|
|
47
50
|
|
|
@@ -67,6 +70,28 @@ class PreParser:
|
|
|
67
70
|
"This property decides how to approach the grouping of short options."
|
|
68
71
|
return Group(value)
|
|
69
72
|
|
|
73
|
+
@property
|
|
74
|
+
def islongonly(self) -> bool:
|
|
75
|
+
if self.longonly != Longonly.INFER:
|
|
76
|
+
return bool(self.longonly)
|
|
77
|
+
# if a long option with a single hyphon exists
|
|
78
|
+
# then all options are treated as long options
|
|
79
|
+
# example: -foo
|
|
80
|
+
for k in self.optdict.keys():
|
|
81
|
+
if len(k) < 3:
|
|
82
|
+
continue
|
|
83
|
+
if k.startswith("--"):
|
|
84
|
+
continue
|
|
85
|
+
if not k.startswith("-"):
|
|
86
|
+
continue
|
|
87
|
+
return True
|
|
88
|
+
return False
|
|
89
|
+
|
|
90
|
+
@makeprop()
|
|
91
|
+
def longonly(self: Self, value: Any) -> Longonly:
|
|
92
|
+
"This property decides whether the parser treats all options as long."
|
|
93
|
+
return Longonly(value)
|
|
94
|
+
|
|
70
95
|
@makeprop()
|
|
71
96
|
def optdict(self: Self, value: Any) -> dict:
|
|
72
97
|
"This property gives a dictionary of options."
|
|
@@ -84,12 +109,7 @@ class PreParser:
|
|
|
84
109
|
args: Optional[Iterable] = None,
|
|
85
110
|
) -> list[str]:
|
|
86
111
|
"This method parses args."
|
|
87
|
-
|
|
88
|
-
args = sys.argv[1:]
|
|
89
|
-
return Parsing(
|
|
90
|
-
parser=self.copy(),
|
|
91
|
-
args=[str(a) for a in args],
|
|
92
|
-
).ans
|
|
112
|
+
return process(args=args, parser=self)
|
|
93
113
|
|
|
94
114
|
@makeprop()
|
|
95
115
|
def order(self: Self, value: Any) -> Order:
|
|
@@ -10,6 +10,7 @@ from typing import *
|
|
|
10
10
|
__all__ = [
|
|
11
11
|
"Abbr",
|
|
12
12
|
"Group",
|
|
13
|
+
"Longonly",
|
|
13
14
|
"Order",
|
|
14
15
|
"Nargs",
|
|
15
16
|
]
|
|
@@ -33,6 +34,18 @@ class Group(BaseEnum):
|
|
|
33
34
|
MAINTAIN = 2
|
|
34
35
|
|
|
35
36
|
|
|
37
|
+
class Longonly(BaseEnum):
|
|
38
|
+
NO = 0
|
|
39
|
+
YES = 1
|
|
40
|
+
INFER = 2
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class Nargs(BaseEnum):
|
|
44
|
+
NO_ARGUMENT = 0
|
|
45
|
+
REQUIRED_ARGUMENT = 1
|
|
46
|
+
OPTIONAL_ARGUMENT = 2
|
|
47
|
+
|
|
48
|
+
|
|
36
49
|
class Order(BaseEnum):
|
|
37
50
|
GIVEN = 0
|
|
38
51
|
POSIX = 1
|
|
@@ -49,9 +62,3 @@ class Order(BaseEnum):
|
|
|
49
62
|
@classmethod
|
|
50
63
|
def infer_permute(cls: type) -> Self:
|
|
51
64
|
return cls.POSIX if cls._infer() else cls.PERMUTE
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
class Nargs(BaseEnum):
|
|
55
|
-
NO_ARGUMENT = 0
|
|
56
|
-
REQUIRED_ARGUMENT = 1
|
|
57
|
-
OPTIONAL_ARGUMENT = 2
|
|
@@ -4,7 +4,8 @@ from typing import *
|
|
|
4
4
|
__all__ = [
|
|
5
5
|
"PreparseAmbiguousOptionWarning",
|
|
6
6
|
"PreparseInvalidOptionWarning",
|
|
7
|
-
"
|
|
7
|
+
"PreparseLongOptionRequiresArgumentWarning",
|
|
8
|
+
"PreparseShortOptionRequiresArgumentWarning",
|
|
8
9
|
"PreparseUnallowedArgumentWarning",
|
|
9
10
|
"PreparseUnrecognizedOptionWarning",
|
|
10
11
|
"PreparseWarning",
|
|
@@ -51,7 +52,15 @@ class PreparseInvalidOptionWarning(PreparseWarning):
|
|
|
51
52
|
return "invalid option -- %r" % self.option
|
|
52
53
|
|
|
53
54
|
|
|
54
|
-
class
|
|
55
|
+
class PreparseLongOptionRequiresArgumentWarning(PreparseWarning):
|
|
56
|
+
__slots__ = ("prog", "option")
|
|
57
|
+
|
|
58
|
+
def getmsg(self: Self) -> str:
|
|
59
|
+
"This method returns the core message."
|
|
60
|
+
return "option %r requires an argument" % self.option
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class PreparseShortOptionRequiresArgumentWarning(PreparseWarning):
|
|
55
64
|
__slots__ = ("prog", "option")
|
|
56
65
|
|
|
57
66
|
def getmsg(self: Self) -> str:
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import tomllib
|
|
2
|
+
import unittest
|
|
3
|
+
from importlib import resources
|
|
4
|
+
|
|
5
|
+
from preparse.core import *
|
|
6
|
+
|
|
7
|
+
# Read URL of the Real Python feed from config file
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class TestDataToml(unittest.TestCase):
|
|
11
|
+
|
|
12
|
+
def get_data(self):
|
|
13
|
+
text: str = resources.read_text("preparse.tests", "data.toml")
|
|
14
|
+
data: dict = tomllib.loads(text)
|
|
15
|
+
return data
|
|
16
|
+
|
|
17
|
+
def test_0(self):
|
|
18
|
+
data: dict = self.get_data()
|
|
19
|
+
data = data["data"]
|
|
20
|
+
for kwargs in data:
|
|
21
|
+
self.parse(**kwargs)
|
|
22
|
+
|
|
23
|
+
def parse(
|
|
24
|
+
self,
|
|
25
|
+
*,
|
|
26
|
+
query,
|
|
27
|
+
solution,
|
|
28
|
+
**kwargs,
|
|
29
|
+
):
|
|
30
|
+
parser = PreParser(**kwargs)
|
|
31
|
+
msg: str = "parser=%r, query=%r" % (parser, query)
|
|
32
|
+
answer = parser.parse_args(query)
|
|
33
|
+
superanswer = parser.parse_args(answer)
|
|
34
|
+
self.assertEqual(answer, superanswer, msg=msg)
|
|
35
|
+
self.assertEqual(answer, solution, msg=msg)
|
|
@@ -74,7 +74,7 @@ class TestPreParserWarnings(unittest.TestCase):
|
|
|
74
74
|
warnings_caught = self.parse_with_warning(optdict, query)
|
|
75
75
|
self.assertTrue(
|
|
76
76
|
any(
|
|
77
|
-
"option requires an argument
|
|
77
|
+
"option '--foo' requires an argument" in str(warning.message)
|
|
78
78
|
for warning in warnings_caught
|
|
79
79
|
)
|
|
80
80
|
)
|
|
@@ -98,7 +98,7 @@ class TestPreParserWarnings(unittest.TestCase):
|
|
|
98
98
|
warnings_caught = self.parse_with_warning(optdict, query)
|
|
99
99
|
self.assertTrue(
|
|
100
100
|
any(
|
|
101
|
-
"option requires an argument
|
|
101
|
+
"option '--foo' requires an argument" in str(warning.message)
|
|
102
102
|
for warning in warnings_caught
|
|
103
103
|
)
|
|
104
104
|
)
|
|
@@ -74,7 +74,7 @@ class TestPreParserWarnings(unittest.TestCase):
|
|
|
74
74
|
warnings_caught = self.parse_with_warning(optdict, query)
|
|
75
75
|
self.assertTrue(
|
|
76
76
|
any(
|
|
77
|
-
"option requires an argument
|
|
77
|
+
"option '--foo' requires an argument" in str(warning.message)
|
|
78
78
|
for warning in warnings_caught
|
|
79
79
|
)
|
|
80
80
|
)
|
|
@@ -62,7 +62,7 @@ class TestPreParserWarnings(unittest.TestCase):
|
|
|
62
62
|
warnings_caught = self.parse_with_warning(optdict, query)
|
|
63
63
|
self.assertTrue(
|
|
64
64
|
any(
|
|
65
|
-
"option requires an argument
|
|
65
|
+
"option '--foo' requires an argument" in str(warning.message)
|
|
66
66
|
for warning in warnings_caught
|
|
67
67
|
)
|
|
68
68
|
)
|
|
@@ -9,31 +9,21 @@ src/preparse.egg-info/SOURCES.txt
|
|
|
9
9
|
src/preparse.egg-info/dependency_links.txt
|
|
10
10
|
src/preparse.egg-info/requires.txt
|
|
11
11
|
src/preparse.egg-info/top_level.txt
|
|
12
|
-
src/preparse/_parsing/
|
|
12
|
+
src/preparse/_parsing/Item.py
|
|
13
13
|
src/preparse/_parsing/__init__.py
|
|
14
|
+
src/preparse/_parsing/deparse.py
|
|
15
|
+
src/preparse/_parsing/digest.py
|
|
16
|
+
src/preparse/_parsing/parse.py
|
|
17
|
+
src/preparse/_parsing/process.py
|
|
14
18
|
src/preparse/core/Click.py
|
|
15
19
|
src/preparse/core/PreParser.py
|
|
16
20
|
src/preparse/core/__init__.py
|
|
17
21
|
src/preparse/core/enums.py
|
|
18
22
|
src/preparse/core/warnings.py
|
|
19
23
|
src/preparse/tests/__init__.py
|
|
24
|
+
src/preparse/tests/test_data_toml.py
|
|
20
25
|
src/preparse/tests/test_expit.py
|
|
21
|
-
src/preparse/tests/test_extra.py
|
|
22
|
-
src/preparse/tests/test_extra_no_permutation.py
|
|
23
|
-
src/preparse/tests/test_extra_posix.py
|
|
24
26
|
src/preparse/tests/test_features.py
|
|
25
|
-
src/preparse/tests/test_long_only.py
|
|
26
|
-
src/preparse/tests/test_long_only_no_permutation.py
|
|
27
|
-
src/preparse/tests/test_long_only_posix.py
|
|
28
|
-
src/preparse/tests/test_max.py
|
|
29
|
-
src/preparse/tests/test_max_1.py
|
|
30
|
-
src/preparse/tests/test_min.py
|
|
31
|
-
src/preparse/tests/test_min_1.py
|
|
32
|
-
src/preparse/tests/test_min_2.py
|
|
33
|
-
src/preparse/tests/test_min_3.py
|
|
34
|
-
src/preparse/tests/test_parse.py
|
|
35
|
-
src/preparse/tests/test_parse_no_permutation.py
|
|
36
|
-
src/preparse/tests/test_parse_posix.py
|
|
37
27
|
src/preparse/tests/test_warn_9001.py
|
|
38
28
|
src/preparse/tests/test_warn_9002.py
|
|
39
29
|
src/preparse/tests/test_warn_9005.py
|