omlish 0.0.0.dev407__py3-none-any.whl → 0.0.0.dev409__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 +2 -2
- omlish/inject/lite.py +112 -0
- omlish/lang/__init__.py +1 -1
- omlish/lang/imports/conditional.py +1 -1
- omlish/lang/imports/lazy.py +1 -1
- omlish/lang/imports/proxyinit.py +229 -122
- omlish/lite/inject.py +1 -0
- omlish/manifests/loading.py +19 -33
- {omlish-0.0.0.dev407.dist-info → omlish-0.0.0.dev409.dist-info}/METADATA +1 -1
- {omlish-0.0.0.dev407.dist-info → omlish-0.0.0.dev409.dist-info}/RECORD +15 -14
- /omlish/lang/imports/{resolution.py → resolving.py} +0 -0
- {omlish-0.0.0.dev407.dist-info → omlish-0.0.0.dev409.dist-info}/WHEEL +0 -0
- {omlish-0.0.0.dev407.dist-info → omlish-0.0.0.dev409.dist-info}/entry_points.txt +0 -0
- {omlish-0.0.0.dev407.dist-info → omlish-0.0.0.dev409.dist-info}/licenses/LICENSE +0 -0
- {omlish-0.0.0.dev407.dist-info → omlish-0.0.0.dev409.dist-info}/top_level.txt +0 -0
omlish/__about__.py
CHANGED
omlish/inject/lite.py
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
"""
|
2
|
+
TODO:
|
3
|
+
- explicit blacklisted key element - blacklist lite Injector
|
4
|
+
"""
|
5
|
+
import dataclasses as dc
|
6
|
+
import typing as ta
|
7
|
+
|
8
|
+
from .. import check
|
9
|
+
from .. import reflect as rfl
|
10
|
+
from ..lite import inject as lij
|
11
|
+
from .bindings import Binding
|
12
|
+
from .elements import Elements
|
13
|
+
from .keys import Key
|
14
|
+
from .providers import ConstProvider
|
15
|
+
from .providers import CtorProvider
|
16
|
+
from .providers import FnProvider
|
17
|
+
from .providers import LinkProvider
|
18
|
+
from .providers import Provider
|
19
|
+
from .scopes import Singleton
|
20
|
+
from .types import Scope
|
21
|
+
from .types import Unscoped
|
22
|
+
|
23
|
+
|
24
|
+
##
|
25
|
+
|
26
|
+
|
27
|
+
@dc.dataclass(frozen=True)
|
28
|
+
class BoxedLiteProvider:
|
29
|
+
p: Provider
|
30
|
+
sc: Scope | None = None
|
31
|
+
|
32
|
+
|
33
|
+
##
|
34
|
+
|
35
|
+
|
36
|
+
@ta.overload
|
37
|
+
def convert_from_lite(o: lij.InjectorBindings) -> Elements:
|
38
|
+
...
|
39
|
+
|
40
|
+
|
41
|
+
@ta.overload
|
42
|
+
def convert_from_lite(o: lij.InjectorKey) -> Key:
|
43
|
+
...
|
44
|
+
|
45
|
+
|
46
|
+
@ta.overload
|
47
|
+
def convert_from_lite(o: lij.InjectorBinding) -> Binding:
|
48
|
+
...
|
49
|
+
|
50
|
+
|
51
|
+
@ta.overload
|
52
|
+
def convert_from_lite(o: lij.InjectorProvider) -> BoxedLiteProvider:
|
53
|
+
...
|
54
|
+
|
55
|
+
|
56
|
+
def convert_from_lite(o):
|
57
|
+
if isinstance(o, lij.InjectorBindings):
|
58
|
+
return Elements([
|
59
|
+
convert_from_lite(c)
|
60
|
+
for c in o.bindings()
|
61
|
+
])
|
62
|
+
|
63
|
+
elif isinstance(o, lij.InjectorKey):
|
64
|
+
check.not_equal(o.cls_, lij.InjectorKeyCls)
|
65
|
+
check.arg(not o.array)
|
66
|
+
return Key(rfl.type_(o.cls_), tag=o.tag)
|
67
|
+
|
68
|
+
elif isinstance(o, lij.InjectorBinding):
|
69
|
+
blp = convert_from_lite(o.provider)
|
70
|
+
return Binding(
|
71
|
+
convert_from_lite(o.key),
|
72
|
+
blp.p,
|
73
|
+
blp.sc if blp.sc is not None else Unscoped(),
|
74
|
+
)
|
75
|
+
|
76
|
+
elif isinstance(o, lij.InjectorProvider):
|
77
|
+
if isinstance(o, lij.FnInjectorProvider):
|
78
|
+
return BoxedLiteProvider(FnProvider(
|
79
|
+
o.fn,
|
80
|
+
))
|
81
|
+
|
82
|
+
elif isinstance(o, lij.CtorInjectorProvider):
|
83
|
+
return BoxedLiteProvider(CtorProvider(
|
84
|
+
o.cls_,
|
85
|
+
))
|
86
|
+
|
87
|
+
elif isinstance(o, lij.ConstInjectorProvider):
|
88
|
+
return BoxedLiteProvider(ConstProvider(
|
89
|
+
o.v,
|
90
|
+
))
|
91
|
+
|
92
|
+
elif isinstance(o, lij.SingletonInjectorProvider):
|
93
|
+
blp = convert_from_lite(o.p)
|
94
|
+
check.none(blp.sc)
|
95
|
+
return dc.replace(
|
96
|
+
blp,
|
97
|
+
sc=Singleton(),
|
98
|
+
)
|
99
|
+
|
100
|
+
elif isinstance(o, lij.LinkInjectorProvider):
|
101
|
+
return BoxedLiteProvider(LinkProvider(
|
102
|
+
convert_from_lite(o.k),
|
103
|
+
))
|
104
|
+
|
105
|
+
elif isinstance(o, lij.ScopedInjectorProvider):
|
106
|
+
raise NotImplementedError
|
107
|
+
|
108
|
+
else:
|
109
|
+
raise TypeError(o)
|
110
|
+
|
111
|
+
else:
|
112
|
+
raise TypeError(o)
|
omlish/lang/__init__.py
CHANGED
omlish/lang/imports/lazy.py
CHANGED
omlish/lang/imports/proxyinit.py
CHANGED
@@ -1,10 +1,3 @@
|
|
1
|
-
"""
|
2
|
-
TODO:
|
3
|
-
- auto_proxy_init can capture `import as` by scanning globals for sentinels
|
4
|
-
- replaces _AutoProxyInitCapture._attrs dict outright
|
5
|
-
- should raise on unbound or shadowed import - was probably imported for side-effects but will never get
|
6
|
-
proxy imported
|
7
|
-
"""
|
8
1
|
import builtins
|
9
2
|
import contextlib
|
10
3
|
import functools
|
@@ -18,12 +11,11 @@ from ..lazyglobals import LazyGlobals
|
|
18
11
|
##
|
19
12
|
|
20
13
|
|
21
|
-
class NamePackage(ta.NamedTuple):
|
22
|
-
name: str
|
23
|
-
package: str
|
24
|
-
|
25
|
-
|
26
14
|
class _ProxyInit:
|
15
|
+
class NamePackage(ta.NamedTuple):
|
16
|
+
name: str
|
17
|
+
package: str
|
18
|
+
|
27
19
|
class _Import(ta.NamedTuple):
|
28
20
|
pkg: str
|
29
21
|
attr: str | None
|
@@ -48,26 +40,16 @@ class _ProxyInit:
|
|
48
40
|
def add(
|
49
41
|
self,
|
50
42
|
package: str,
|
51
|
-
attrs: ta.Iterable[str |
|
43
|
+
attrs: ta.Iterable[tuple[str | None, str]],
|
52
44
|
) -> None:
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
whole_attr = package.split('.')[-1]
|
45
|
+
for imp_attr, as_attr in attrs:
|
46
|
+
if imp_attr is None:
|
47
|
+
self._imps_by_attr[as_attr] = self._Import(package, None)
|
48
|
+
self._lazy_globals.set_fn(as_attr, functools.partial(self.get, as_attr))
|
58
49
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
else:
|
63
|
-
for attr in attrs:
|
64
|
-
if isinstance(attr, tuple):
|
65
|
-
imp_attr, attr = attr
|
66
|
-
else:
|
67
|
-
imp_attr = attr
|
68
|
-
|
69
|
-
self._imps_by_attr[attr] = self._Import(package, imp_attr)
|
70
|
-
self._lazy_globals.set_fn(attr, functools.partial(self.get, attr))
|
50
|
+
else:
|
51
|
+
self._imps_by_attr[as_attr] = self._Import(package, imp_attr)
|
52
|
+
self._lazy_globals.set_fn(as_attr, functools.partial(self.get, as_attr))
|
71
53
|
|
72
54
|
def _import_module(self, name: str) -> ta.Any:
|
73
55
|
return importlib.import_module(name, package=self._name_package.package)
|
@@ -98,12 +80,38 @@ class _ProxyInit:
|
|
98
80
|
def proxy_init(
|
99
81
|
init_globals: ta.MutableMapping[str, ta.Any],
|
100
82
|
package: str,
|
101
|
-
attrs: ta.Iterable[str | tuple[str, str]] | None = None,
|
83
|
+
attrs: ta.Iterable[str | tuple[str | None, str | None] | None] | None = None,
|
102
84
|
) -> None:
|
103
85
|
if isinstance(attrs, str):
|
104
86
|
raise TypeError(attrs)
|
105
87
|
|
106
|
-
|
88
|
+
if attrs is None:
|
89
|
+
attrs = [None]
|
90
|
+
|
91
|
+
whole_attr = package.split('.')[-1]
|
92
|
+
al: list[tuple[str | None, str]] = []
|
93
|
+
for attr in attrs:
|
94
|
+
if attr is None:
|
95
|
+
al.append((None, whole_attr))
|
96
|
+
|
97
|
+
elif isinstance(attr, str):
|
98
|
+
al.append((attr, attr))
|
99
|
+
|
100
|
+
elif isinstance(attr, tuple):
|
101
|
+
imp_attr, as_attr = attr
|
102
|
+
if as_attr is None:
|
103
|
+
if imp_attr is None:
|
104
|
+
as_attr = whole_attr
|
105
|
+
else:
|
106
|
+
as_attr = imp_attr
|
107
|
+
al.append((imp_attr, as_attr))
|
108
|
+
|
109
|
+
else:
|
110
|
+
raise TypeError(attr)
|
111
|
+
|
112
|
+
#
|
113
|
+
|
114
|
+
init_name_package = _ProxyInit.NamePackage(
|
107
115
|
init_globals['__name__'],
|
108
116
|
init_globals['__package__'],
|
109
117
|
)
|
@@ -123,7 +131,7 @@ def proxy_init(
|
|
123
131
|
if pi.name_package != init_name_package:
|
124
132
|
raise Exception(f'Wrong init name: {pi.name_package=} != {init_name_package=}')
|
125
133
|
|
126
|
-
pi.add(package,
|
134
|
+
pi.add(package, al)
|
127
135
|
|
128
136
|
|
129
137
|
##
|
@@ -166,6 +174,15 @@ class AutoProxyInitErrors:
|
|
166
174
|
class UnproxiedImportForbiddenError(ImportError):
|
167
175
|
pass
|
168
176
|
|
177
|
+
class UnreferencedImportsError(AutoProxyInitError):
|
178
|
+
def __init__(self, unreferenced: ta.Mapping[str, ta.Sequence[str | None]]) -> None:
|
179
|
+
super().__init__()
|
180
|
+
|
181
|
+
self.unreferenced = unreferenced
|
182
|
+
|
183
|
+
def __repr__(self) -> str:
|
184
|
+
return f'{self.__class__.__qualname__}(unreferenced={self.unreferenced!r})'
|
185
|
+
|
169
186
|
|
170
187
|
class _AutoProxyInitCapture:
|
171
188
|
class ModuleSpec(ta.NamedTuple):
|
@@ -178,8 +195,22 @@ class _AutoProxyInitCapture:
|
|
178
195
|
def __repr__(self) -> str:
|
179
196
|
return repr(str(self))
|
180
197
|
|
198
|
+
def __init__(self) -> None:
|
199
|
+
super().__init__()
|
200
|
+
|
201
|
+
self._modules_by_spec: dict[_AutoProxyInitCapture.ModuleSpec, _AutoProxyInitCapture._Module] = {}
|
202
|
+
self._modules_by_module_obj: dict[types.ModuleType, _AutoProxyInitCapture._Module] = {}
|
203
|
+
|
204
|
+
self._attrs: dict[_AutoProxyInitCapture._ModuleAttr, tuple[_AutoProxyInitCapture._Module, str]] = {}
|
205
|
+
|
206
|
+
#
|
207
|
+
|
181
208
|
class _ModuleAttr:
|
182
|
-
def __init__(
|
209
|
+
def __init__(
|
210
|
+
self,
|
211
|
+
module: '_AutoProxyInitCapture._Module',
|
212
|
+
name: str,
|
213
|
+
) -> None:
|
183
214
|
super().__init__()
|
184
215
|
|
185
216
|
self.__module = module
|
@@ -189,24 +220,62 @@ class _AutoProxyInitCapture:
|
|
189
220
|
return f'<{self.__class__.__name__}: {f"{self.__module.spec}:{self.__name}"!r}>'
|
190
221
|
|
191
222
|
class _Module:
|
192
|
-
def __init__(
|
223
|
+
def __init__(
|
224
|
+
self,
|
225
|
+
spec: '_AutoProxyInitCapture.ModuleSpec',
|
226
|
+
*,
|
227
|
+
getattr_handler: ta.Callable[['_AutoProxyInitCapture._Module', str], ta.Any] | None = None,
|
228
|
+
) -> None:
|
193
229
|
super().__init__()
|
194
230
|
|
195
231
|
self.spec = spec
|
196
232
|
|
197
|
-
self.
|
233
|
+
self.module_obj = types.ModuleType(f'<{self.__class__.__qualname__}: {spec!r}>')
|
234
|
+
if getattr_handler is not None:
|
235
|
+
self.module_obj.__getattr__ = functools.partial(getattr_handler, self) # type: ignore[method-assign] # noqa
|
236
|
+
self.initial_module_dict = dict(self.module_obj.__dict__)
|
198
237
|
|
199
|
-
self.
|
238
|
+
self.contents: dict[str, _AutoProxyInitCapture._ModuleAttr | types.ModuleType] = {}
|
200
239
|
self.imported_whole = False
|
201
240
|
|
202
241
|
def __repr__(self) -> str:
|
203
242
|
return f'{self.__class__.__name__}({self.spec!r})'
|
204
243
|
|
205
|
-
def
|
206
|
-
|
244
|
+
def _get_or_make_module(self, spec: ModuleSpec) -> _Module:
|
245
|
+
try:
|
246
|
+
return self._modules_by_spec[spec]
|
247
|
+
except KeyError:
|
248
|
+
pass
|
207
249
|
|
208
|
-
|
209
|
-
|
250
|
+
module = self._Module(
|
251
|
+
spec,
|
252
|
+
getattr_handler=self._handle_module_getattr,
|
253
|
+
)
|
254
|
+
self._modules_by_spec[spec] = module
|
255
|
+
self._modules_by_module_obj[module.module_obj] = module
|
256
|
+
return module
|
257
|
+
|
258
|
+
def _handle_module_getattr(self, module: _Module, attr: str) -> ta.Any:
|
259
|
+
if attr in module.contents:
|
260
|
+
raise AutoProxyInitErrors.AttrError(str(module.spec), attr)
|
261
|
+
|
262
|
+
v: _AutoProxyInitCapture._ModuleAttr | types.ModuleType
|
263
|
+
if not module.spec.name:
|
264
|
+
if not module.spec.level:
|
265
|
+
raise AutoProxyInitError
|
266
|
+
cs = _AutoProxyInitCapture.ModuleSpec(attr, module.spec.level)
|
267
|
+
cm = self._get_or_make_module(cs)
|
268
|
+
cm.imported_whole = True
|
269
|
+
v = cm.module_obj
|
270
|
+
|
271
|
+
else:
|
272
|
+
ma = _AutoProxyInitCapture._ModuleAttr(module, attr)
|
273
|
+
self._attrs[ma] = (module, attr)
|
274
|
+
v = ma
|
275
|
+
|
276
|
+
module.contents[attr] = v
|
277
|
+
setattr(module.module_obj, attr, v)
|
278
|
+
return v
|
210
279
|
|
211
280
|
def _handle_import(
|
212
281
|
self,
|
@@ -218,23 +287,6 @@ class _AutoProxyInitCapture:
|
|
218
287
|
if module.spec.level or not module.spec.name:
|
219
288
|
raise AutoProxyInitError
|
220
289
|
|
221
|
-
attr = module.spec.name
|
222
|
-
|
223
|
-
try:
|
224
|
-
xma: ta.Any = self._attrs[attr]
|
225
|
-
except KeyError:
|
226
|
-
pass
|
227
|
-
|
228
|
-
else:
|
229
|
-
if (
|
230
|
-
xma is not self._attrs.get(attr) or
|
231
|
-
not module.imported_whole
|
232
|
-
):
|
233
|
-
raise AutoProxyInitErrors.AttrError(str(module.spec), attr)
|
234
|
-
|
235
|
-
return
|
236
|
-
|
237
|
-
self._attrs[attr] = module
|
238
290
|
module.imported_whole = True
|
239
291
|
|
240
292
|
else:
|
@@ -242,27 +294,23 @@ class _AutoProxyInitCapture:
|
|
242
294
|
if attr == '*':
|
243
295
|
raise AutoProxyInitErrors.ImportStarForbiddenError(str(module.spec), from_list)
|
244
296
|
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
297
|
+
x = getattr(module.module_obj, attr)
|
298
|
+
|
299
|
+
bad = False
|
300
|
+
if x is not module.contents.get(attr):
|
301
|
+
bad = True
|
302
|
+
if isinstance(x, _AutoProxyInitCapture._ModuleAttr):
|
303
|
+
if self._attrs[x] != (module, attr):
|
304
|
+
bad = True
|
305
|
+
elif isinstance(x, types.ModuleType):
|
306
|
+
if x not in self._modules_by_module_obj:
|
307
|
+
bad = True
|
250
308
|
else:
|
251
|
-
|
252
|
-
|
253
|
-
xma is not self._attrs.get(attr)
|
254
|
-
):
|
255
|
-
raise AutoProxyInitErrors.AttrError(str(module.spec), attr)
|
256
|
-
|
257
|
-
continue
|
258
|
-
|
259
|
-
if attr in self._attrs:
|
309
|
+
bad = True
|
310
|
+
if bad:
|
260
311
|
raise AutoProxyInitErrors.AttrError(str(module.spec), attr)
|
261
312
|
|
262
|
-
|
263
|
-
self._attrs[attr] = ma
|
264
|
-
module.attrs[attr] = ma
|
265
|
-
setattr(module.module, attr, ma)
|
313
|
+
#
|
266
314
|
|
267
315
|
_MOD_SELF_ATTR: ta.ClassVar[str] = '__auto_proxy_init_capture__'
|
268
316
|
|
@@ -281,18 +329,14 @@ class _AutoProxyInitCapture:
|
|
281
329
|
return None
|
282
330
|
|
283
331
|
spec = _AutoProxyInitCapture.ModuleSpec(name, level)
|
284
|
-
|
285
|
-
module = self._modules[spec]
|
286
|
-
except KeyError:
|
287
|
-
module = self._Module(spec)
|
288
|
-
self._modules[spec] = module
|
332
|
+
module = self._get_or_make_module(spec)
|
289
333
|
|
290
334
|
self._handle_import(
|
291
335
|
module,
|
292
336
|
from_list=from_list,
|
293
337
|
)
|
294
338
|
|
295
|
-
return module.
|
339
|
+
return module.module_obj
|
296
340
|
|
297
341
|
@contextlib.contextmanager
|
298
342
|
def hook_context(
|
@@ -353,54 +397,103 @@ class _AutoProxyInitCapture:
|
|
353
397
|
del init_globals[self._MOD_SELF_ATTR]
|
354
398
|
builtins.__import__ = old_import
|
355
399
|
|
356
|
-
|
400
|
+
#
|
401
|
+
|
402
|
+
def verify_state(
|
357
403
|
self,
|
358
404
|
init_globals: ta.MutableMapping[str, ta.Any], # noqa
|
359
405
|
) -> None:
|
360
|
-
for
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
raise AutoProxyInitErrors.AttrError(None, attr) from None
|
406
|
+
for m in self._modules_by_spec.values():
|
407
|
+
for a, o in m.module_obj.__dict__.items():
|
408
|
+
try:
|
409
|
+
i = m.initial_module_dict[a]
|
365
410
|
|
366
|
-
|
367
|
-
|
368
|
-
|
411
|
+
except KeyError:
|
412
|
+
if o is not m.contents[a]:
|
413
|
+
raise AutoProxyInitErrors.AttrError(str(m.spec), a) from None
|
369
414
|
|
370
|
-
|
371
|
-
|
372
|
-
|
415
|
+
else:
|
416
|
+
if o != i:
|
417
|
+
raise AutoProxyInitErrors.AttrError(str(m.spec), a)
|
373
418
|
|
374
|
-
|
375
|
-
raise TypeError(obj)
|
376
|
-
|
377
|
-
@property
|
378
|
-
def all_attrs(self) -> ta.AbstractSet[str]:
|
379
|
-
return self._attrs.keys()
|
419
|
+
#
|
380
420
|
|
381
421
|
class ProxyInit(ta.NamedTuple):
|
382
422
|
package: str
|
383
|
-
attrs: ta.Sequence[str
|
423
|
+
attrs: ta.Sequence[tuple[str | None, str]]
|
384
424
|
|
385
|
-
|
386
|
-
|
425
|
+
class BuiltProxyInits(ta.NamedTuple):
|
426
|
+
proxy_inits: ta.Sequence['_AutoProxyInitCapture.ProxyInit']
|
427
|
+
unreferenced: ta.Mapping[str, ta.Sequence[str | None]] | None
|
387
428
|
|
388
|
-
|
389
|
-
|
390
|
-
|
429
|
+
def build_proxy_inits(
|
430
|
+
self,
|
431
|
+
init_globals: ta.MutableMapping[str, ta.Any], # noqa
|
432
|
+
*,
|
433
|
+
collect_unreferenced: bool = False,
|
434
|
+
) -> BuiltProxyInits:
|
435
|
+
dct: dict[_AutoProxyInitCapture._Module, list[tuple[str | None, str]]] = {}
|
391
436
|
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
437
|
+
rem_whole_mods: set[_AutoProxyInitCapture._Module] = set()
|
438
|
+
rem_mod_attrs: set[_AutoProxyInitCapture._ModuleAttr] = set()
|
439
|
+
if collect_unreferenced:
|
440
|
+
rem_whole_mods.update([m for m in self._modules_by_spec.values() if m.imported_whole])
|
441
|
+
rem_mod_attrs.update(self._attrs)
|
397
442
|
|
398
|
-
|
443
|
+
for attr, obj in init_globals.items():
|
444
|
+
if isinstance(obj, _AutoProxyInitCapture._ModuleAttr):
|
445
|
+
try:
|
446
|
+
m, a = self._attrs[obj]
|
447
|
+
except KeyError:
|
448
|
+
raise AutoProxyInitErrors.AttrError(None, attr) from None
|
449
|
+
dct.setdefault(m, []).append((a, attr))
|
450
|
+
rem_mod_attrs.discard(obj)
|
399
451
|
|
400
|
-
|
401
|
-
|
452
|
+
elif isinstance(obj, _AutoProxyInitCapture._Module):
|
453
|
+
raise AutoProxyInitErrors.AttrError(None, attr) from None
|
402
454
|
|
403
|
-
|
455
|
+
elif isinstance(obj, types.ModuleType):
|
456
|
+
try:
|
457
|
+
m = self._modules_by_module_obj[obj]
|
458
|
+
except KeyError:
|
459
|
+
continue
|
460
|
+
if not m.imported_whole:
|
461
|
+
raise RuntimeError(f'AutoProxyInit module {m.spec!r} not imported_whole')
|
462
|
+
dct.setdefault(m, []).append((None, attr))
|
463
|
+
rem_whole_mods.discard(m)
|
464
|
+
|
465
|
+
lst: list[_AutoProxyInitCapture.ProxyInit] = []
|
466
|
+
for m, ts in dct.items():
|
467
|
+
if not m.spec.name:
|
468
|
+
if not m.spec.level:
|
469
|
+
raise AutoProxyInitError
|
470
|
+
for imp_attr, as_attr in ts:
|
471
|
+
if not imp_attr:
|
472
|
+
raise RuntimeError
|
473
|
+
lst.append(_AutoProxyInitCapture.ProxyInit(
|
474
|
+
'.' * m.spec.level + imp_attr,
|
475
|
+
[(None, as_attr)],
|
476
|
+
))
|
477
|
+
|
478
|
+
else:
|
479
|
+
lst.append(_AutoProxyInitCapture.ProxyInit(
|
480
|
+
str(m.spec),
|
481
|
+
ts,
|
482
|
+
))
|
483
|
+
|
484
|
+
unreferenced: dict[str, list[str | None]] | None = None
|
485
|
+
if collect_unreferenced and (rem_whole_mods or rem_mod_attrs):
|
486
|
+
unreferenced = {}
|
487
|
+
for m in rem_whole_mods:
|
488
|
+
unreferenced.setdefault(str(m.spec), []).append(None)
|
489
|
+
for ma in rem_mod_attrs:
|
490
|
+
m, a = self._attrs[ma]
|
491
|
+
unreferenced.setdefault(str(m.spec), []).append(a)
|
492
|
+
|
493
|
+
return _AutoProxyInitCapture.BuiltProxyInits(
|
494
|
+
lst,
|
495
|
+
unreferenced,
|
496
|
+
)
|
404
497
|
|
405
498
|
|
406
499
|
@contextlib.contextmanager
|
@@ -409,6 +502,9 @@ def auto_proxy_init(
|
|
409
502
|
*,
|
410
503
|
disable: bool = False,
|
411
504
|
eager: bool = False,
|
505
|
+
|
506
|
+
unreferenced_callback: ta.Callable[[ta.Mapping[str, ta.Sequence[str | None]]], None] | None = None,
|
507
|
+
raise_unreferenced: bool = False,
|
412
508
|
) -> ta.Iterator[None]:
|
413
509
|
"""
|
414
510
|
This is a bit extreme - use sparingly. It relies on an interpreter-global import lock, but much of the ecosystem
|
@@ -425,14 +521,23 @@ def auto_proxy_init(
|
|
425
521
|
with cap.hook_context(init_globals):
|
426
522
|
yield
|
427
523
|
|
428
|
-
cap.
|
524
|
+
cap.verify_state(init_globals)
|
429
525
|
|
430
|
-
|
526
|
+
blt = cap.build_proxy_inits(
|
527
|
+
init_globals,
|
528
|
+
collect_unreferenced=unreferenced_callback is not None or raise_unreferenced,
|
529
|
+
)
|
431
530
|
|
432
|
-
|
433
|
-
|
531
|
+
if blt.unreferenced:
|
532
|
+
if unreferenced_callback:
|
533
|
+
unreferenced_callback(blt.unreferenced)
|
534
|
+
if raise_unreferenced:
|
535
|
+
raise AutoProxyInitErrors.UnreferencedImportsError(blt.unreferenced)
|
536
|
+
|
537
|
+
for pi in blt.proxy_inits:
|
538
|
+
for _, a in pi.attrs:
|
539
|
+
del init_globals[a]
|
434
540
|
|
435
|
-
for pi in pis:
|
436
541
|
proxy_init(
|
437
542
|
init_globals,
|
438
543
|
pi.package,
|
@@ -441,5 +546,7 @@ def auto_proxy_init(
|
|
441
546
|
|
442
547
|
if eager:
|
443
548
|
lg = LazyGlobals.install(init_globals)
|
444
|
-
|
445
|
-
|
549
|
+
|
550
|
+
for pi in blt.proxy_inits:
|
551
|
+
for _, a in pi.attrs:
|
552
|
+
lg.get(a)
|
omlish/lite/inject.py
CHANGED
omlish/manifests/loading.py
CHANGED
@@ -209,6 +209,7 @@ class ManifestLoader:
|
|
209
209
|
@classmethod
|
210
210
|
def _discover_packages_uncached(cls) -> ta.Sequence[str]:
|
211
211
|
from importlib import metadata as importlib_metadata # noqa
|
212
|
+
|
212
213
|
return [
|
213
214
|
ep.value
|
214
215
|
for ep in importlib_metadata.entry_points(group=cls.ENTRY_POINT_GROUP)
|
@@ -262,35 +263,31 @@ class ManifestLoader:
|
|
262
263
|
|
263
264
|
##
|
264
265
|
|
265
|
-
|
266
|
-
|
267
|
-
def _do_initialize(self) -> None:
|
268
|
-
self._detected_packages = set()
|
266
|
+
def _detect_packages_uncached(self) -> ta.AbstractSet[str]:
|
267
|
+
ret: ta.Set[str] = set()
|
269
268
|
|
270
269
|
for r in self._config.package_scan_root_dirs or []:
|
271
|
-
|
270
|
+
ret.update(self._scan_package_root_dir_locked(r))
|
272
271
|
|
273
272
|
if self._config.discover_packages:
|
274
|
-
|
273
|
+
ret.update(dps := self.discover_packages())
|
275
274
|
if not dps:
|
276
275
|
for r in self._config.discover_packages_fallback_scan_root_dirs or []:
|
277
|
-
|
276
|
+
ret.update(self._scan_package_root_dir_locked(r))
|
278
277
|
|
279
|
-
|
278
|
+
return ret
|
280
279
|
|
281
|
-
|
282
|
-
if not self._has_initialized:
|
283
|
-
self._do_initialize()
|
284
|
-
self._has_initialized = True
|
280
|
+
_detected_packages: ta.Optional[ta.AbstractSet[str]] = None
|
285
281
|
|
286
|
-
def
|
287
|
-
|
288
|
-
|
282
|
+
def _detect_packages_locked(self) -> ta.AbstractSet[str]:
|
283
|
+
if self._detected_packages is None:
|
284
|
+
self._detected_packages = self._detect_packages_uncached()
|
289
285
|
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
286
|
+
return self._detected_packages
|
287
|
+
|
288
|
+
def detect_packages(self) -> ta.AbstractSet[str]:
|
289
|
+
with self._lock:
|
290
|
+
return self._detect_packages_locked()
|
294
291
|
|
295
292
|
##
|
296
293
|
|
@@ -429,6 +426,7 @@ class ManifestLoader:
|
|
429
426
|
return f.read()
|
430
427
|
|
431
428
|
from importlib import resources as importlib_resources # noqa
|
429
|
+
|
432
430
|
t = importlib_resources.files(package_name).joinpath(file_name)
|
433
431
|
if not t.is_file():
|
434
432
|
return None
|
@@ -497,7 +495,7 @@ class ManifestLoader:
|
|
497
495
|
|
498
496
|
##
|
499
497
|
|
500
|
-
def
|
498
|
+
def _load_locked(
|
501
499
|
self,
|
502
500
|
*,
|
503
501
|
packages: ta.Optional[ta.Collection[str]] = None,
|
@@ -511,7 +509,7 @@ class ManifestLoader:
|
|
511
509
|
class_keys = {self.get_class_key(cls) for cls in classes}
|
512
510
|
|
513
511
|
if packages is None:
|
514
|
-
packages = self.
|
512
|
+
packages = self._detect_packages_locked()
|
515
513
|
|
516
514
|
lst: ta.List[ManifestLoader.LoadedManifest] = []
|
517
515
|
for pn in packages:
|
@@ -527,18 +525,6 @@ class ManifestLoader:
|
|
527
525
|
|
528
526
|
return lst
|
529
527
|
|
530
|
-
def _load_locked(
|
531
|
-
self,
|
532
|
-
*,
|
533
|
-
packages: ta.Optional[ta.Collection[str]] = None,
|
534
|
-
classes: ta.Optional[ta.Collection[type]] = None,
|
535
|
-
) -> ta.Sequence[LoadedManifest]:
|
536
|
-
self._initialize_locked()
|
537
|
-
return self._load_initialized(
|
538
|
-
packages=packages,
|
539
|
-
classes=classes,
|
540
|
-
)
|
541
|
-
|
542
528
|
def load(
|
543
529
|
self,
|
544
530
|
*,
|
@@ -1,5 +1,5 @@
|
|
1
1
|
omlish/.manifests.json,sha256=FLw7xkPiSXuImZgqSP8BwrEib2R1doSzUPLUkc-QUIA,8410
|
2
|
-
omlish/__about__.py,sha256=
|
2
|
+
omlish/__about__.py,sha256=4QkSZDk0KGwNDUXL28RW4dosDTkKwvPxAM7iBzddM4g,3601
|
3
3
|
omlish/__init__.py,sha256=SsyiITTuK0v74XpKV8dqNaCmjOlan1JZKrHQv5rWKPA,253
|
4
4
|
omlish/c3.py,sha256=rer-TPOFDU6fYq_AWio_AmA-ckZ8JDY5shIzQ_yXfzA,8414
|
5
5
|
omlish/cached.py,sha256=MLap_p0rdGoDIMVhXVHm1tsbcWobJF0OanoodV03Ju8,542
|
@@ -370,6 +370,7 @@ omlish/inject/injector.py,sha256=fyvaRoJXo_oibx1_IiGkncP9oXnZSKtDm7-ULNKRXHE,107
|
|
370
370
|
omlish/inject/inspect.py,sha256=Uq4KMloGWF_YS2mgZbrx-JXhZQnYHHKJSr68i9yoBVc,597
|
371
371
|
omlish/inject/keys.py,sha256=7jnI2cw7cvLlzZAfe5SC50O3oPOpOB6iGZGTigyfQvs,682
|
372
372
|
omlish/inject/listeners.py,sha256=Ffaun2fVWAgAwKgLdgziJynG_jhAWaaPEsy-2I2Cmpw,599
|
373
|
+
omlish/inject/lite.py,sha256=AFOCj_SznDCPjkiVSKdFXL2hH1q2o4kaDnzkxRWDpsI,2615
|
373
374
|
omlish/inject/managed.py,sha256=-9aBm1vRPOjNz4kgOmpt8S2T55s727t9RiggFBH8maU,2096
|
374
375
|
omlish/inject/multis.py,sha256=Dn63jE8P5ahSKc1IDBdzzx6ByBCgVOth5t4frG9m4UA,3336
|
375
376
|
omlish/inject/origins.py,sha256=-qXa18rIIkNwBdTrvASRDjgPYnoY6n6OPC222jJDrXg,551
|
@@ -425,7 +426,7 @@ omlish/iterators/iterators.py,sha256=RxW35yQ5ed8vBQ22IqpDXFx-i5JiLQdp7-pkMZXhJJ8
|
|
425
426
|
omlish/iterators/recipes.py,sha256=wOwOZg-zWG9Zc3wcAxJFSe2rtavVBYwZOfG09qYEx_4,472
|
426
427
|
omlish/iterators/tools.py,sha256=M16LXrJhMdsz5ea2qH0vws30ZvhQuQSCVFSLpRf_gTg,2096
|
427
428
|
omlish/iterators/unique.py,sha256=BSE-eanva8byFCJi09Nt2zzTsVr8LnTqY1PIInGYRs0,1396
|
428
|
-
omlish/lang/__init__.py,sha256=
|
429
|
+
omlish/lang/__init__.py,sha256=7Xe1YcE2PPgx-NI-V9VTsvUl4qZD0RPANxuDv9ddRXg,7231
|
429
430
|
omlish/lang/attrs.py,sha256=zFiVuGVOq88x45464T_LxDa-ZEq_RD9zJLq2zeVEBDc,5105
|
430
431
|
omlish/lang/casing.py,sha256=cFUlbDdXLhwnWwcYx4qnM5c4zGX7hIRUfcjiZbxUD28,4636
|
431
432
|
omlish/lang/clsdct.py,sha256=HAGIvBSbCefzRjXriwYSBLO7QHKRv2UsE78jixOb-fA,1828
|
@@ -463,10 +464,10 @@ omlish/lang/classes/restrict.py,sha256=CUyvLpMYiQwTjpzo5sdG_lQxdeEIq2z2xSVNrsI9K
|
|
463
464
|
omlish/lang/classes/simple.py,sha256=9blmJdi4c15zyIEbNVjkA0ZTSImQbv4g0p2Il6knWAc,2539
|
464
465
|
omlish/lang/classes/virtual.py,sha256=z0MYQD9Q5MkX8DzF325wDB4J9XoYbsB09jZ1omC62To,3366
|
465
466
|
omlish/lang/imports/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
466
|
-
omlish/lang/imports/conditional.py,sha256=
|
467
|
-
omlish/lang/imports/lazy.py,sha256=
|
468
|
-
omlish/lang/imports/proxyinit.py,sha256=
|
469
|
-
omlish/lang/imports/
|
467
|
+
omlish/lang/imports/conditional.py,sha256=R-E47QD95mMonPImWlrde3rnJrFKCCkYz71c94W05sc,1006
|
468
|
+
omlish/lang/imports/lazy.py,sha256=Fhtb5tSAttff6G2pZdF8bh__GZlqJWHaMKtA8KubuX4,1479
|
469
|
+
omlish/lang/imports/proxyinit.py,sha256=ALpV9LahE8SQl6jNO92Mk4PcaQPce9Cv53K8AwnH5fQ,16749
|
470
|
+
omlish/lang/imports/resolving.py,sha256=DeRarn35Fryg5JhVhy8wbiC9lvr58AnllI9B_reswUE,2085
|
470
471
|
omlish/lang/imports/traversal.py,sha256=pbFQIa880NGjSfcLsno2vE_G41_CLwDHb-7gWg2J3BI,2855
|
471
472
|
omlish/lifecycles/__init__.py,sha256=1FjYceXs-4fc-S-C9zFYmc2axHs4znnQHcJVHdY7a6E,578
|
472
473
|
omlish/lifecycles/abstract.py,sha256=c9UY7oxzYZ_neh5DPE4yv5HfuDv7B4Mj_9Zo-B8KDSs,1114
|
@@ -484,7 +485,7 @@ omlish/lite/configs.py,sha256=4-1uVxo-aNV7vMKa7PVNhM610eejG1WepB42-Dw2xQI,914
|
|
484
485
|
omlish/lite/contextmanagers.py,sha256=QEqVxUtmr9aJJ_03A-YC4vVUy8jkiIDCYIGIOlXvn8U,5827
|
485
486
|
omlish/lite/dataclasses.py,sha256=aRSCZz1jN_UI-CWJhN0SJeKxa-79vXNUZ6YOMgG31SE,3610
|
486
487
|
omlish/lite/imports.py,sha256=GyEDKL-WuHtdOKIL-cc8aFd0-bHwZFDEjAB52ItabX0,1341
|
487
|
-
omlish/lite/inject.py,sha256=
|
488
|
+
omlish/lite/inject.py,sha256=SJt0KjvzMz3vBswYhVbiA0cQqxzZO7HmsGvdtjkwgg4,29022
|
488
489
|
omlish/lite/json.py,sha256=m0Ce9eqUZG23-H7-oOp8n1sf4fzno5vtK4AK_4Vc-Mg,706
|
489
490
|
omlish/lite/logs.py,sha256=CWFG0NKGhqNeEgryF5atN2gkPYbUdTINEw_s1phbINM,51
|
490
491
|
omlish/lite/marshal.py,sha256=K_wnZwfC8cftGILyE3RlmzQEYuZOfzkMLKey41zuwtM,20296
|
@@ -519,7 +520,7 @@ omlish/logs/utils.py,sha256=OkFWf1exmWImmT7BaSiIC7c0Fk9tAis-PRqo8H4ny3c,398
|
|
519
520
|
omlish/manifests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
520
521
|
omlish/manifests/base.py,sha256=Dt44a3qppWaxkoi3naFFMetxbxw14qnz2naTKK93GNU,915
|
521
522
|
omlish/manifests/globals.py,sha256=kVqQ-fT4kc7xWzLHoI731GviitFPv2v2yqw-p7t7Exs,2628
|
522
|
-
omlish/manifests/loading.py,sha256=
|
523
|
+
omlish/manifests/loading.py,sha256=Br1OyI23pis_FfYju9xoacms608lzB1Zh_IqdVw_7vg,17201
|
523
524
|
omlish/manifests/static.py,sha256=9BaPBLkuzxHmg5A-5k9BjjBFINCdmFOIu06dMFgCfz4,497
|
524
525
|
omlish/manifests/types.py,sha256=NeOGuIVrcbqjCDbQ3MnCxxHAgHnw0CkWJsBzo230PWE,453
|
525
526
|
omlish/marshal/.dataclasses.json,sha256=wXWUy_IR8AolAa2RQnqn_mo2QnmVcvUJmayIykdVl0I,22
|
@@ -908,9 +909,9 @@ omlish/typedvalues/marshal.py,sha256=AtBz7Jq-BfW8vwM7HSxSpR85JAXmxK2T0xDblmm1HI0
|
|
908
909
|
omlish/typedvalues/of_.py,sha256=UXkxSj504WI2UrFlqdZJbu2hyDwBhL7XVrc2qdR02GQ,1309
|
909
910
|
omlish/typedvalues/reflect.py,sha256=PAvKW6T4cW7u--iX80w3HWwZUS3SmIZ2_lQjT65uAyk,1026
|
910
911
|
omlish/typedvalues/values.py,sha256=ym46I-q2QJ_6l4UlERqv3yj87R-kp8nCKMRph0xQ3UA,1307
|
911
|
-
omlish-0.0.0.
|
912
|
-
omlish-0.0.0.
|
913
|
-
omlish-0.0.0.
|
914
|
-
omlish-0.0.0.
|
915
|
-
omlish-0.0.0.
|
916
|
-
omlish-0.0.0.
|
912
|
+
omlish-0.0.0.dev409.dist-info/licenses/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
|
913
|
+
omlish-0.0.0.dev409.dist-info/METADATA,sha256=fCzoIaINPTeVtCOvdUmzuUWQqKIGW40xgEmeKO4bIxg,18881
|
914
|
+
omlish-0.0.0.dev409.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
915
|
+
omlish-0.0.0.dev409.dist-info/entry_points.txt,sha256=Lt84WvRZJskWCAS7xnQGZIeVWksprtUHj0llrvVmod8,35
|
916
|
+
omlish-0.0.0.dev409.dist-info/top_level.txt,sha256=pePsKdLu7DvtUiecdYXJ78iO80uDNmBlqe-8hOzOmfs,7
|
917
|
+
omlish-0.0.0.dev409.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|