omlish 0.0.0.dev43__py3-none-any.whl → 0.0.0.dev45__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.dev45'
2
+ __revision__ = 'db777c425b0d53ee128b96fca75e6c6f4cd43654'
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)
@@ -220,8 +220,8 @@ class AccessForbiddenDescriptor:
220
220
  raise AccessForbiddenError(self._name)
221
221
 
222
222
 
223
- def access_forbidden(): # noqa
224
- return AccessForbiddenDescriptor()
223
+ def access_forbidden(name=None): # noqa
224
+ return AccessForbiddenDescriptor(name)
225
225
 
226
226
 
227
227
  ##
@@ -7,6 +7,7 @@ from .types import ( # noqa
7
7
  TYPES,
8
8
  Type,
9
9
  Union,
10
+ get_orig_bases,
10
11
  get_orig_class,
11
12
  get_params,
12
13
  is_type,
omlish/reflect/types.py CHANGED
@@ -61,6 +61,17 @@ _KNOWN_SPECIAL_TYPE_VARS = tuple(
61
61
  ##
62
62
 
63
63
 
64
+ _SIMPLE_GENERIC_ALIAS_TYPES: set[type] = set()
65
+
66
+
67
+ def is_simple_generic_alias_type(oty: type) -> bool:
68
+ return (
69
+ oty is _GenericAlias or
70
+ oty is ta.GenericAlias or # type: ignore # noqa
71
+ oty in _SIMPLE_GENERIC_ALIAS_TYPES
72
+ )
73
+
74
+
64
75
  def get_params(obj: ta.Any) -> tuple[ta.TypeVar, ...]:
65
76
  if isinstance(obj, type):
66
77
  if issubclass(obj, ta.Generic): # type: ignore
@@ -71,10 +82,7 @@ def get_params(obj: ta.Any) -> tuple[ta.TypeVar, ...]:
71
82
 
72
83
  oty = type(obj)
73
84
 
74
- if (
75
- oty is _GenericAlias or
76
- oty is ta.GenericAlias # type: ignore # noqa
77
- ):
85
+ if is_simple_generic_alias_type(oty):
78
86
  return obj.__dict__.get('__parameters__', ()) # noqa
79
87
 
80
88
  if oty is _CallableGenericAlias:
@@ -91,6 +99,10 @@ def is_union_type(cls: ta.Any) -> bool:
91
99
  return ta.get_origin(cls) in {ta.Union}
92
100
 
93
101
 
102
+ def get_orig_bases(obj: ta.Any) -> ta.Any:
103
+ return obj.__orig_bases__ # noqa
104
+
105
+
94
106
  def get_orig_class(obj: ta.Any) -> ta.Any:
95
107
  return obj.__orig_class__ # noqa
96
108
 
@@ -195,8 +207,7 @@ def is_type(obj: ta.Any) -> bool:
195
207
  isinstance(obj, ta.NewType) or # noqa
196
208
 
197
209
  (
198
- oty is _GenericAlias or
199
- oty is ta.GenericAlias or # type: ignore # noqa
210
+ is_simple_generic_alias_type(oty) or
200
211
  oty is _CallableGenericAlias
201
212
  ) or
202
213
 
@@ -222,8 +233,7 @@ def type_(obj: ta.Any) -> Type:
222
233
  return NewType(obj)
223
234
 
224
235
  if (
225
- oty is _GenericAlias or
226
- oty is ta.GenericAlias or # type: ignore # noqa
236
+ is_simple_generic_alias_type(oty) or
227
237
  oty is _CallableGenericAlias
228
238
  ):
229
239
  origin = ta.get_origin(obj)
omlish/specs/__init__.py CHANGED
@@ -1,9 +1,10 @@
1
1
  """
2
2
  TODO:
3
3
  - avro
4
+ - iceberg
4
5
  - jmespath
6
+ - jsonnet
5
7
  - jsonpatch
6
8
  - jsonpointer.py
7
- - openapi
8
9
  - protobuf
9
10
  """
@@ -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.dev45
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=ksJohON1-moGxasw7d_K1YOOVRTb4318HQNolEuZ3zo,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
@@ -174,7 +174,7 @@ omlish/lang/clsdct.py,sha256=AjtIWLlx2E6D5rC97zQ3Lwq2SOMkbg08pdO_AxpzEHI,1744
174
174
  omlish/lang/cmp.py,sha256=5vbzWWbqdzDmNKAGL19z6ZfUKe5Ci49e-Oegf9f4BsE,1346
175
175
  omlish/lang/contextmanagers.py,sha256=NEwaTLQMfhKawD5x_0HgI2RpeLXbMa5r9NqWqfDnUXI,10408
176
176
  omlish/lang/datetimes.py,sha256=ehI_DhQRM-bDxAavnp470XcekbbXc4Gdw9y1KpHDJT0,223
177
- omlish/lang/descriptors.py,sha256=OLM1qi14kY7PLGIJnvkd6CBEOzHgD9q8Cs2cB6Kzflk,6602
177
+ omlish/lang/descriptors.py,sha256=tszC_fMICqCz1cUXejJ4beWzt6DlIBulknJFRkSTZp4,6615
178
178
  omlish/lang/exceptions.py,sha256=qJBo3NU1mOWWm-NhQUHCY5feYXR3arZVyEHinLsmRH4,47
179
179
  omlish/lang/functions.py,sha256=kkPfcdocg-OmyN7skIqrFxNvqAv89Zc_kXKYAN8vw8g,3895
180
180
  omlish/lang/imports.py,sha256=04ugFC8NI5sbL7NH4V0r0q_nFsP_AMkHLz697CVkMtQ,6274
@@ -250,11 +250,11 @@ omlish/math/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
250
250
  omlish/math/bits.py,sha256=yip1l8agOYzT7bFyMGc0RR3XlnGCfHMpjw_SECLLh1I,3477
251
251
  omlish/math/floats.py,sha256=UimhOT7KRl8LXTzOI5cQWoX_9h6WNWe_3vcOuO7-h_8,327
252
252
  omlish/math/stats.py,sha256=MegzKVsmv2kra4jDWLOUgV0X7Ee2Tbl5u6ql1v4-dEY,10053
253
- omlish/reflect/__init__.py,sha256=iWDCNJNP4afPcv-MxZRJSIRQ4NRw6XYPyRHhBXb5YIA,667
253
+ omlish/reflect/__init__.py,sha256=8t2955chuWPzj8yiV7R_jlREAezSz6CVTJ0HKY58Vpk,687
254
254
  omlish/reflect/isinstance.py,sha256=x5T9S2634leinBT4hl3CZZkRttvdvvlxChkC_x9Qu2s,1176
255
255
  omlish/reflect/ops.py,sha256=RJ6jzrM4ieFsXzWyNXWV43O_WgzEaUvlHSc5N2ezW2A,2044
256
256
  omlish/reflect/subst.py,sha256=JM2RGv2-Rcex8wCqhmgvRG59zD242P9jM3O2QLjKWWo,3586
257
- omlish/reflect/types.py,sha256=R9AH5YnOvdZs6QhzJ6VmjvcvGibQEQi6YqK25f5VUxw,6862
257
+ omlish/reflect/types.py,sha256=Zkcp8nx_vFNH7pBZ5pU5P0wIgQCauj5Nic3BZb5cRik,7030
258
258
  omlish/secrets/__init__.py,sha256=VKB2IF9vz4h4RXcZxgXj36KXOLcGBzfqVnxPgPDWpmg,408
259
259
  omlish/secrets/crypto.py,sha256=6CsLy0UEqCrBK8Xx_3-iFF6SKtu2GlEqUQ8-MliY3tk,3709
260
260
  omlish/secrets/marshal.py,sha256=U9uSRTWzZmumfNZeh_dROwVdGrARsp155TylRbjilP8,2048
@@ -262,7 +262,7 @@ omlish/secrets/openssl.py,sha256=wxA_wIlxtuOUy71ABxAJgavh-UI_taOfm-A0dVlmSwM,621
262
262
  omlish/secrets/passwords.py,sha256=3r-vEK6Gp6aq4L5Csnd06QnrjO9xfzHJP-g_7I9W_ao,4101
263
263
  omlish/secrets/secrets.py,sha256=ClD7t_mkmWkseVk4ahLzYLuLXeTxiwwPiidYm42vLh4,6871
264
264
  omlish/secrets/subprocesses.py,sha256=EcnKlHHtnUMHGrBWXDfu8tv28wlgZx4P4GOiuPW9Vo8,1105
265
- omlish/specs/__init__.py,sha256=_CSPXx25uGhXkmqLs9CSdcWAkZaQnc3cJk3lb2dadgE,88
265
+ omlish/specs/__init__.py,sha256=R5X62_Iur9gg_gWLWJCgjSK_zec76g15agYPLNgwfGc,99
266
266
  omlish/specs/jsonrpc/__init__.py,sha256=E0EogYSKmbj1D-V57tBgPDTyVuD8HosHqVg0Vh1CVwM,416
267
267
  omlish/specs/jsonrpc/errors.py,sha256=-Zgmlo6bV6J8w5f8h9axQgLquIFBHDgIwcpufEH5NsE,707
268
268
  omlish/specs/jsonrpc/marshal.py,sha256=iXZNR7n0vfL_yiPFFYN-ZyGlzknNXExs2qC1HFChGPU,1913
@@ -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.dev45.dist-info/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
332
+ omlish-0.0.0.dev45.dist-info/METADATA,sha256=Wgmc5z7G_7Nqo7dCn6hUlxya_-xb7yRNAy9kFr16xC0,3817
333
+ omlish-0.0.0.dev45.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
334
+ omlish-0.0.0.dev45.dist-info/entry_points.txt,sha256=Lt84WvRZJskWCAS7xnQGZIeVWksprtUHj0llrvVmod8,35
335
+ omlish-0.0.0.dev45.dist-info/top_level.txt,sha256=pePsKdLu7DvtUiecdYXJ78iO80uDNmBlqe-8hOzOmfs,7
336
+ omlish-0.0.0.dev45.dist-info/RECORD,,