omlish 0.0.0.dev43__py3-none-any.whl → 0.0.0.dev44__py3-none-any.whl

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.
omlish/__about__.py CHANGED
@@ -1,5 +1,5 @@
1
- __version__ = '0.0.0.dev43'
2
- __revision__ = '00082c22c620ab906955cc479d2d861116e82c45'
1
+ __version__ = '0.0.0.dev44'
2
+ __revision__ = '4ae588446d9d45931798e750e17556da7cbef79c'
3
3
 
4
4
 
5
5
  #
omlish/argparse.py CHANGED
@@ -16,6 +16,9 @@ from . import check
16
16
  T = ta.TypeVar('T')
17
17
 
18
18
 
19
+ ##
20
+
21
+
19
22
  SUPPRESS = argparse.SUPPRESS
20
23
 
21
24
  OPTIONAL = argparse.OPTIONAL
@@ -45,6 +48,9 @@ Namespace = argparse.Namespace
45
48
  ArgumentParser = argparse.ArgumentParser
46
49
 
47
50
 
51
+ ##
52
+
53
+
48
54
  @dc.dataclass(eq=False)
49
55
  class Arg:
50
56
  args: ta.Sequence[ta.Any]
@@ -61,6 +67,9 @@ def arg(*args, **kwargs) -> Arg:
61
67
  return Arg(args, kwargs)
62
68
 
63
69
 
70
+ #
71
+
72
+
64
73
  CommandFn = ta.Callable[[], None]
65
74
 
66
75
 
@@ -70,6 +79,7 @@ class Command:
70
79
  fn: CommandFn
71
80
  args: ta.Sequence[Arg] = ()
72
81
  parent: ta.Optional['Command'] = None
82
+ accepts_unknown: bool = False
73
83
 
74
84
  def __post_init__(self) -> None:
75
85
  check.isinstance(self.name, str)
@@ -79,6 +89,7 @@ class Command:
79
89
  check.callable(self.fn)
80
90
  check.arg(all(isinstance(a, Arg) for a in self.args))
81
91
  check.isinstance(self.parent, (Command, None))
92
+ check.isinstance(self.accepts_unknown, bool)
82
93
 
83
94
  functools.update_wrapper(self, self.fn)
84
95
 
@@ -95,6 +106,7 @@ def command(
95
106
  *args: Arg,
96
107
  name: str | None = None,
97
108
  parent: Command | None = None,
109
+ accepts_unknown: bool = False,
98
110
  ) -> ta.Any: # ta.Callable[[CommandFn], Command]: # FIXME
99
111
  for arg in args:
100
112
  check.isinstance(arg, Arg)
@@ -107,11 +119,15 @@ def command(
107
119
  fn,
108
120
  args,
109
121
  parent=parent,
122
+ accepts_unknown=accepts_unknown,
110
123
  )
111
124
 
112
125
  return inner
113
126
 
114
127
 
128
+ ##
129
+
130
+
115
131
  def get_arg_ann_kwargs(ann: ta.Any) -> ta.Mapping[str, ta.Any]:
116
132
  if ann is str:
117
133
  return {}
@@ -197,7 +213,8 @@ class Cli(metaclass=_CliMeta):
197
213
  super().__init__()
198
214
 
199
215
  self._argv = argv if argv is not None else sys.argv[1:]
200
- self._args = self.get_parser().parse_args(self._argv)
216
+
217
+ self._args, self._unknown_args = self.get_parser().parse_known_args(self._argv)
201
218
 
202
219
  _parser: ta.ClassVar[ArgumentParser]
203
220
 
@@ -213,12 +230,25 @@ class Cli(metaclass=_CliMeta):
213
230
  def args(self) -> Namespace:
214
231
  return self._args
215
232
 
233
+ @property
234
+ def unknown_args(self) -> ta.Sequence[str]:
235
+ return self._unknown_args
236
+
216
237
  def _run_cmd(self, cmd: Command) -> None:
217
238
  cmd.__get__(self, type(self))()
218
239
 
219
240
  def __call__(self) -> None:
220
241
  cmd = getattr(self.args, '_cmd', None)
242
+
243
+ if self._unknown_args and not (cmd is not None and cmd.accepts_unknown):
244
+ msg = f'unrecognized arguments: {" ".join(self._unknown_args)}'
245
+ if (parser := self.get_parser()).exit_on_error: # type: ignore
246
+ parser.error(msg)
247
+ else:
248
+ raise ArgumentError(None, msg)
249
+
221
250
  if cmd is None:
222
251
  self.get_parser().print_help()
223
252
  return
253
+
224
254
  self._run_cmd(cmd)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: omlish
3
- Version: 0.0.0.dev43
3
+ Version: 0.0.0.dev44
4
4
  Summary: omlish
5
5
  Author: wrmsr
6
6
  License: BSD-3-Clause
@@ -1,7 +1,7 @@
1
1
  omlish/.manifests.json,sha256=FPSgLg_3QDVzKlNOuqV3dMqhja2KG_TUfKdGmHE8Eg4,803
2
- omlish/__about__.py,sha256=r89Z8V9DxpOVxM2o7M6f4JV4JEbBfeEO1OjjT6MpsLE,2919
2
+ omlish/__about__.py,sha256=owguWBeUOCE7cGZXQ6xPQm5f1kN_oXAs0aniHbRvjWw,2919
3
3
  omlish/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- omlish/argparse.py,sha256=QUUS6sv2ftfcmhDj4qU429mEE_lfWa0UN5yYpPG65B0,6265
4
+ omlish/argparse.py,sha256=Vr70_85EVLJLgEkRtwOr264tMRtqtlN7ncFfXRUk5aM,6914
5
5
  omlish/c3.py,sha256=4vogWgwPb8TbNS2KkZxpoWbwjj7MuHG2lQG-hdtkvjI,8062
6
6
  omlish/cached.py,sha256=UAizxlH4eMWHPzQtmItmyE6FEpFEUFzIkxaO2BHWZ5s,196
7
7
  omlish/check.py,sha256=fgWiBoHvqZlE8tjaxK7OMW4J8z3_rEGRENTka3EohbI,10378
@@ -328,9 +328,9 @@ omlish/text/delimit.py,sha256=ubPXcXQmtbOVrUsNh5gH1mDq5H-n1y2R4cPL5_DQf68,4928
328
328
  omlish/text/glyphsplit.py,sha256=Ug-dPRO7x-OrNNr8g1y6DotSZ2KH0S-VcOmUobwa4B0,3296
329
329
  omlish/text/indent.py,sha256=6Jj6TFY9unaPa4xPzrnZemJ-fHsV53IamP93XGjSUHs,1274
330
330
  omlish/text/parts.py,sha256=7vPF1aTZdvLVYJ4EwBZVzRSy8XB3YqPd7JwEnNGGAOo,6495
331
- omlish-0.0.0.dev43.dist-info/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
332
- omlish-0.0.0.dev43.dist-info/METADATA,sha256=uuX1PAEvidaoC9uBAqHDBXL1Td-VZiG_xC1MdX_GKKY,3817
333
- omlish-0.0.0.dev43.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
334
- omlish-0.0.0.dev43.dist-info/entry_points.txt,sha256=Lt84WvRZJskWCAS7xnQGZIeVWksprtUHj0llrvVmod8,35
335
- omlish-0.0.0.dev43.dist-info/top_level.txt,sha256=pePsKdLu7DvtUiecdYXJ78iO80uDNmBlqe-8hOzOmfs,7
336
- omlish-0.0.0.dev43.dist-info/RECORD,,
331
+ omlish-0.0.0.dev44.dist-info/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
332
+ omlish-0.0.0.dev44.dist-info/METADATA,sha256=99p3BI8OMHbt03pRswyTOiLqt26ie2k4Puv8zbS4zS4,3817
333
+ omlish-0.0.0.dev44.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
334
+ omlish-0.0.0.dev44.dist-info/entry_points.txt,sha256=Lt84WvRZJskWCAS7xnQGZIeVWksprtUHj0llrvVmod8,35
335
+ omlish-0.0.0.dev44.dist-info/top_level.txt,sha256=pePsKdLu7DvtUiecdYXJ78iO80uDNmBlqe-8hOzOmfs,7
336
+ omlish-0.0.0.dev44.dist-info/RECORD,,