engin 0.0.18__py3-none-any.whl → 0.0.20__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.
- engin/__init__.py +0 -4
- engin/_assembler.py +24 -17
- engin/_block.py +16 -4
- engin/_cli/_graph.py +2 -2
- engin/_dependency.py +41 -30
- engin/_type_utils.py +2 -2
- engin/{_exceptions.py → exceptions.py} +27 -1
- engin/{ext → extensions}/fastapi.py +1 -1
- {engin-0.0.18.dist-info → engin-0.0.20.dist-info}/METADATA +1 -1
- engin-0.0.20.dist-info/RECORD +25 -0
- engin-0.0.18.dist-info/RECORD +0 -25
- /engin/{ext → extensions}/__init__.py +0 -0
- /engin/{ext → extensions}/asgi.py +0 -0
- {engin-0.0.18.dist-info → engin-0.0.20.dist-info}/WHEEL +0 -0
- {engin-0.0.18.dist-info → engin-0.0.20.dist-info}/entry_points.txt +0 -0
- {engin-0.0.18.dist-info → engin-0.0.20.dist-info}/licenses/LICENSE +0 -0
engin/__init__.py
CHANGED
@@ -1,9 +1,7 @@
|
|
1
|
-
from engin import ext
|
2
1
|
from engin._assembler import Assembler
|
3
2
|
from engin._block import Block, invoke, provide
|
4
3
|
from engin._dependency import Entrypoint, Invoke, Provide, Supply
|
5
4
|
from engin._engin import Engin
|
6
|
-
from engin._exceptions import ProviderError
|
7
5
|
from engin._lifecycle import Lifecycle
|
8
6
|
from engin._option import Option
|
9
7
|
from engin._type_utils import TypeId
|
@@ -17,10 +15,8 @@ __all__ = [
|
|
17
15
|
"Lifecycle",
|
18
16
|
"Option",
|
19
17
|
"Provide",
|
20
|
-
"ProviderError",
|
21
18
|
"Supply",
|
22
19
|
"TypeId",
|
23
|
-
"ext",
|
24
20
|
"invoke",
|
25
21
|
"provide",
|
26
22
|
]
|
engin/_assembler.py
CHANGED
@@ -9,8 +9,8 @@ from types import TracebackType
|
|
9
9
|
from typing import Any, Generic, TypeVar, cast
|
10
10
|
|
11
11
|
from engin._dependency import Dependency, Provide, Supply
|
12
|
-
from engin._exceptions import NotInScopeError, ProviderError
|
13
12
|
from engin._type_utils import TypeId
|
13
|
+
from engin.exceptions import NotInScopeError, ProviderError
|
14
14
|
|
15
15
|
LOG = logging.getLogger("engin")
|
16
16
|
|
@@ -65,6 +65,7 @@ class Assembler:
|
|
65
65
|
self._multiproviders: dict[TypeId, list[Provide[list[Any]]]] = defaultdict(list)
|
66
66
|
self._assembled_outputs: dict[TypeId, Any] = {}
|
67
67
|
self._lock = asyncio.Lock()
|
68
|
+
self._graph_cache: dict[TypeId, set[Provide]] = defaultdict(set)
|
68
69
|
|
69
70
|
for provider in providers:
|
70
71
|
type_id = provider.return_type_id
|
@@ -179,8 +180,8 @@ class Assembler:
|
|
179
180
|
"""
|
180
181
|
Add a provider to the Assembler post-initialisation.
|
181
182
|
|
182
|
-
If this replaces an existing provider, this will clear
|
183
|
-
output
|
183
|
+
If this replaces an existing provider, this will clear all previously assembled
|
184
|
+
output. Note: multiproviders cannot be replaced, they are always appended.
|
184
185
|
|
185
186
|
Args:
|
186
187
|
provider: the Provide instance to add.
|
@@ -190,14 +191,13 @@ class Assembler:
|
|
190
191
|
"""
|
191
192
|
type_id = provider.return_type_id
|
192
193
|
if provider.is_multiprovider:
|
193
|
-
if type_id in self._assembled_outputs:
|
194
|
-
del self._assembled_outputs[type_id]
|
195
194
|
self._multiproviders[type_id].append(provider)
|
196
195
|
else:
|
197
|
-
if type_id in self._assembled_outputs:
|
198
|
-
del self._assembled_outputs[type_id]
|
199
196
|
self._providers[type_id] = provider
|
200
197
|
|
198
|
+
self._assembled_outputs.clear()
|
199
|
+
self._graph_cache.clear()
|
200
|
+
|
201
201
|
def scope(self, scope: str) -> "_ScopeContextManager":
|
202
202
|
return _ScopeContextManager(scope=scope, assembler=self)
|
203
203
|
|
@@ -206,13 +206,14 @@ class Assembler:
|
|
206
206
|
if provider.scope == scope:
|
207
207
|
self._assembled_outputs.pop(type_id, None)
|
208
208
|
|
209
|
-
def _resolve_providers(self, type_id: TypeId) ->
|
209
|
+
def _resolve_providers(self, type_id: TypeId, resolved: set[TypeId]) -> set[Provide]:
|
210
210
|
"""
|
211
211
|
Resolves the chain of providers required to satisfy the provider of a given type.
|
212
212
|
Ordering of the return value is very important!
|
213
|
-
|
214
|
-
# TODO: performance optimisation, do not recurse for already satisfied providers?
|
215
213
|
"""
|
214
|
+
if type_id in self._graph_cache:
|
215
|
+
return self._graph_cache[type_id]
|
216
|
+
|
216
217
|
if type_id.multi:
|
217
218
|
root_providers = self._multiproviders.get(type_id)
|
218
219
|
else:
|
@@ -230,22 +231,28 @@ class Assembler:
|
|
230
231
|
raise LookupError(msg)
|
231
232
|
|
232
233
|
# providers that must be satisfied to satisfy the root level providers
|
233
|
-
|
234
|
+
resolved_providers = {
|
234
235
|
child_provider
|
235
236
|
for root_provider in root_providers
|
236
237
|
for root_provider_param in root_provider.parameter_type_ids
|
237
|
-
for child_provider in self._resolve_providers(root_provider_param)
|
238
|
-
|
239
|
-
|
238
|
+
for child_provider in self._resolve_providers(root_provider_param, resolved)
|
239
|
+
if root_provider_param not in resolved
|
240
|
+
} | set(root_providers)
|
241
|
+
|
242
|
+
resolved.add(type_id)
|
243
|
+
self._graph_cache[type_id] = resolved_providers
|
244
|
+
|
245
|
+
return resolved_providers
|
240
246
|
|
241
247
|
async def _satisfy(self, target: TypeId) -> None:
|
242
|
-
for provider in self._resolve_providers(target):
|
248
|
+
for provider in self._resolve_providers(target, set()):
|
243
249
|
if (
|
244
250
|
not provider.is_multiprovider
|
245
251
|
and provider.return_type_id in self._assembled_outputs
|
246
252
|
):
|
247
253
|
continue
|
248
254
|
type_id = provider.return_type_id
|
255
|
+
|
249
256
|
bound_args = await self._bind_arguments(provider.signature)
|
250
257
|
try:
|
251
258
|
value = await provider(*bound_args.args, **bound_args.kwargs)
|
@@ -253,6 +260,7 @@ class Assembler:
|
|
253
260
|
raise ProviderError(
|
254
261
|
provider=provider, error_type=type(err), error_message=str(err)
|
255
262
|
) from err
|
263
|
+
|
256
264
|
if provider.is_multiprovider:
|
257
265
|
if type_id in self._assembled_outputs:
|
258
266
|
self._assembled_outputs[type_id].extend(value)
|
@@ -269,8 +277,7 @@ class Assembler:
|
|
269
277
|
args.append(object())
|
270
278
|
continue
|
271
279
|
param_key = TypeId.from_type(param.annotation)
|
272
|
-
|
273
|
-
if not has_dependency:
|
280
|
+
if param_key not in self._assembled_outputs:
|
274
281
|
await self._satisfy(param_key)
|
275
282
|
val = self._assembled_outputs[param_key]
|
276
283
|
if param.kind == param.POSITIONAL_ONLY:
|
engin/_block.py
CHANGED
@@ -5,6 +5,7 @@ from typing import TYPE_CHECKING, ClassVar
|
|
5
5
|
|
6
6
|
from engin._dependency import Dependency, Func, Invoke, Provide
|
7
7
|
from engin._option import Option
|
8
|
+
from engin.exceptions import InvalidBlockError
|
8
9
|
|
9
10
|
if TYPE_CHECKING:
|
10
11
|
from engin._engin import Engin
|
@@ -42,7 +43,7 @@ def invoke(func_: Func | None = None) -> Func | Callable[[Func], Func]:
|
|
42
43
|
return _inner(func_)
|
43
44
|
|
44
45
|
|
45
|
-
class Block
|
46
|
+
class Block:
|
46
47
|
"""
|
47
48
|
A Block is a collection of providers and invocations.
|
48
49
|
|
@@ -74,7 +75,7 @@ class Block(Option):
|
|
74
75
|
|
75
76
|
@classmethod
|
76
77
|
def apply(cls, engin: "Engin") -> None:
|
77
|
-
block_name = cls.name or
|
78
|
+
block_name = cls.name or cls.__name__
|
78
79
|
for option in chain(cls.options, cls._method_options()):
|
79
80
|
if isinstance(option, Dependency):
|
80
81
|
option._block_name = block_name
|
@@ -82,8 +83,19 @@ class Block(Option):
|
|
82
83
|
|
83
84
|
@classmethod
|
84
85
|
def _method_options(cls) -> Iterable[Provide | Invoke]:
|
85
|
-
for
|
86
|
+
for name, method in inspect.getmembers(cls, inspect.isfunction):
|
86
87
|
if option := getattr(method, "_opt", None):
|
87
88
|
if not isinstance(option, Provide | Invoke):
|
88
|
-
raise
|
89
|
+
raise InvalidBlockError(
|
90
|
+
block=cls,
|
91
|
+
reason="Block option is not an instance of Provide or Invoke",
|
92
|
+
)
|
89
93
|
yield option
|
94
|
+
else:
|
95
|
+
raise InvalidBlockError(
|
96
|
+
block=cls,
|
97
|
+
reason=(
|
98
|
+
f"Method '{name}' is not a Provider or Invocation, did you "
|
99
|
+
"forget to decorate it?"
|
100
|
+
),
|
101
|
+
)
|
engin/_cli/_graph.py
CHANGED
@@ -12,10 +12,10 @@ from rich import print
|
|
12
12
|
from engin import Entrypoint, Invoke, TypeId
|
13
13
|
from engin._cli._common import COMMON_HELP, get_engin_instance
|
14
14
|
from engin._dependency import Dependency, Provide, Supply
|
15
|
-
from engin.
|
15
|
+
from engin.extensions.asgi import ASGIEngin
|
16
16
|
|
17
17
|
try:
|
18
|
-
from engin.
|
18
|
+
from engin.extensions.fastapi import APIRouteDependency
|
19
19
|
except ImportError:
|
20
20
|
APIRouteDependency = None # type: ignore[assignment,misc]
|
21
21
|
|
engin/_dependency.py
CHANGED
@@ -33,7 +33,7 @@ class Dependency(ABC, Option, Generic[P, T]):
|
|
33
33
|
def __init__(self, func: Func[P, T]) -> None:
|
34
34
|
self._func = func
|
35
35
|
self._is_async = iscoroutinefunction(func)
|
36
|
-
self._signature = inspect.signature(self._func)
|
36
|
+
self._signature = inspect.signature(self._func, eval_str=True)
|
37
37
|
self._block_name: str | None = None
|
38
38
|
|
39
39
|
source_frame = get_first_external_frame()
|
@@ -154,68 +154,58 @@ class Entrypoint(Invoke):
|
|
154
154
|
class Provide(Dependency[Any, T]):
|
155
155
|
def __init__(
|
156
156
|
self,
|
157
|
-
|
157
|
+
factory: Func[P, T],
|
158
158
|
*,
|
159
159
|
scope: str | None = None,
|
160
160
|
as_type: type | None = None,
|
161
161
|
override: bool = False,
|
162
162
|
) -> None:
|
163
163
|
"""
|
164
|
-
Provide a type via a
|
164
|
+
Provide a type via a factory function.
|
165
165
|
|
166
166
|
Args:
|
167
|
-
|
167
|
+
factory: the factory function that returns the type.
|
168
168
|
scope: (optional) associate this provider with a specific scope.
|
169
169
|
as_type: (optional) allows you to explicitly specify the provided type, e.g.
|
170
170
|
to type erase a concrete type, or to provide a mock implementation.
|
171
171
|
override: (optional) allow this provider to override other providers for the
|
172
172
|
same type from the same package.
|
173
173
|
"""
|
174
|
-
super().__init__(func=
|
174
|
+
super().__init__(func=factory)
|
175
175
|
self._scope = scope
|
176
176
|
self._override = override
|
177
177
|
self._explicit_type = as_type
|
178
|
+
self._return_type = self._resolve_return_type()
|
179
|
+
self._return_type_id = TypeId.from_type(self._return_type)
|
178
180
|
|
179
181
|
if self._explicit_type is not None:
|
180
182
|
self._signature = self._signature.replace(return_annotation=self._explicit_type)
|
181
183
|
|
182
|
-
self._is_multi = typing.get_origin(self.
|
184
|
+
self._is_multi = typing.get_origin(self._return_type) is list
|
183
185
|
|
184
186
|
# Validate that the provider does to depend on its own output value, as this will
|
185
187
|
# cause a recursion error and is undefined behaviour wise.
|
186
188
|
if any(
|
187
|
-
self.
|
189
|
+
self._return_type == param.annotation
|
188
190
|
for param in self._signature.parameters.values()
|
189
191
|
):
|
190
192
|
raise ValueError("A provider cannot depend on its own return type")
|
191
193
|
|
192
194
|
# Validate that multiproviders only return a list of one type.
|
193
195
|
if self._is_multi:
|
194
|
-
args = typing.get_args(self.
|
196
|
+
args = typing.get_args(self._return_type)
|
195
197
|
if len(args) != 1:
|
196
198
|
raise ValueError(
|
197
|
-
f"A multiprovider must be of the form list[X], not '{self.
|
199
|
+
f"A multiprovider must be of the form list[X], not '{self._return_type}'"
|
198
200
|
)
|
199
201
|
|
200
202
|
@property
|
201
203
|
def return_type(self) -> type[T]:
|
202
|
-
|
203
|
-
return self._explicit_type
|
204
|
-
if isclass(self._func):
|
205
|
-
return_type = self._func # __init__ returns self
|
206
|
-
else:
|
207
|
-
try:
|
208
|
-
return_type = get_type_hints(self._func, include_extras=True)["return"]
|
209
|
-
except KeyError as err:
|
210
|
-
raise RuntimeError(
|
211
|
-
f"Dependency '{self.name}' requires a return typehint"
|
212
|
-
) from err
|
213
|
-
|
214
|
-
return return_type
|
204
|
+
return self._return_type
|
215
205
|
|
216
206
|
@property
|
217
207
|
def return_type_id(self) -> TypeId:
|
218
|
-
return
|
208
|
+
return self._return_type_id
|
219
209
|
|
220
210
|
@property
|
221
211
|
def is_multiprovider(self) -> bool:
|
@@ -241,9 +231,9 @@ class Provide(Dependency[Any, T]):
|
|
241
231
|
# overwriting a dependency from the same package must be explicit
|
242
232
|
if is_same_package and not self._override:
|
243
233
|
msg = (
|
244
|
-
f"
|
245
|
-
f"'{existing_provider.
|
246
|
-
"`override=True` for the overriding Provider"
|
234
|
+
f"{self} from '{self._source_frame}' is implicitly overriding "
|
235
|
+
f"{existing_provider} from '{existing_provider.source_module}', if this "
|
236
|
+
"is intentional specify `override=True` for the overriding Provider"
|
247
237
|
)
|
248
238
|
raise RuntimeError(msg)
|
249
239
|
|
@@ -253,7 +243,22 @@ class Provide(Dependency[Any, T]):
|
|
253
243
|
return hash(self.return_type_id)
|
254
244
|
|
255
245
|
def __str__(self) -> str:
|
256
|
-
return f"Provide({self.
|
246
|
+
return f"Provide(factory={self.func_name}, type={self._return_type_id})"
|
247
|
+
|
248
|
+
def _resolve_return_type(self) -> type[T]:
|
249
|
+
if self._explicit_type is not None:
|
250
|
+
return self._explicit_type
|
251
|
+
if isclass(self._func):
|
252
|
+
return_type = self._func # __init__ returns self
|
253
|
+
else:
|
254
|
+
try:
|
255
|
+
return_type = get_type_hints(self._func, include_extras=True)["return"]
|
256
|
+
except KeyError as err:
|
257
|
+
raise RuntimeError(
|
258
|
+
f"Dependency '{self.name}' requires a return typehint"
|
259
|
+
) from err
|
260
|
+
|
261
|
+
return return_type
|
257
262
|
|
258
263
|
|
259
264
|
class Supply(Provide, Generic[T]):
|
@@ -274,10 +279,16 @@ class Supply(Provide, Generic[T]):
|
|
274
279
|
same type from the same package.
|
275
280
|
"""
|
276
281
|
self._value = value
|
277
|
-
super().__init__(
|
282
|
+
super().__init__(factory=self._get_val, as_type=as_type, override=override)
|
278
283
|
|
279
284
|
@property
|
280
|
-
def
|
285
|
+
def name(self) -> str:
|
286
|
+
if self._block_name:
|
287
|
+
return f"{self._block_name}.supply"
|
288
|
+
else:
|
289
|
+
return f"{self._source_frame}.supply"
|
290
|
+
|
291
|
+
def _resolve_return_type(self) -> type[T]:
|
281
292
|
if self._explicit_type is not None:
|
282
293
|
return self._explicit_type
|
283
294
|
if isinstance(self._value, list):
|
@@ -288,4 +299,4 @@ class Supply(Provide, Generic[T]):
|
|
288
299
|
return self._value
|
289
300
|
|
290
301
|
def __str__(self) -> str:
|
291
|
-
return f"Supply({self.return_type_id})"
|
302
|
+
return f"Supply(value={self._value}, type={self.return_type_id})"
|
engin/_type_utils.py
CHANGED
@@ -33,8 +33,8 @@ class TypeId:
|
|
33
33
|
return TypeId(type=type_, multi=False)
|
34
34
|
|
35
35
|
def __str__(self) -> str:
|
36
|
-
module = self.type
|
37
|
-
out = f"{module}." if module not in _implict_modules else ""
|
36
|
+
module = getattr(self.type, "__module__", None)
|
37
|
+
out = f"{module}." if module and module not in _implict_modules else ""
|
38
38
|
out += _args_to_str(self.type)
|
39
39
|
if self.multi:
|
40
40
|
out += "[]"
|
@@ -1,7 +1,10 @@
|
|
1
|
-
from typing import Any
|
1
|
+
from typing import TYPE_CHECKING, Any
|
2
2
|
|
3
3
|
from engin._dependency import Provide
|
4
4
|
|
5
|
+
if TYPE_CHECKING:
|
6
|
+
from engin._block import Block
|
7
|
+
|
5
8
|
|
6
9
|
class EnginError(Exception):
|
7
10
|
"""
|
@@ -15,6 +18,20 @@ class AssemblerError(EnginError):
|
|
15
18
|
"""
|
16
19
|
|
17
20
|
|
21
|
+
class InvalidBlockError(EnginError):
|
22
|
+
"""
|
23
|
+
Raised when an invalid block is instantiated.
|
24
|
+
"""
|
25
|
+
|
26
|
+
def __init__(self, block: "type[Block]", reason: str) -> None:
|
27
|
+
self.block = block
|
28
|
+
self.block_name = block.name or block.__name__
|
29
|
+
self.message = f"block '{self.block_name}' is invalid, reason: '{reason}'"
|
30
|
+
|
31
|
+
def __str__(self) -> str:
|
32
|
+
return self.message
|
33
|
+
|
34
|
+
|
18
35
|
class ProviderError(AssemblerError):
|
19
36
|
"""
|
20
37
|
Raised when a Provider errors during Assembly.
|
@@ -52,3 +69,12 @@ class NotInScopeError(AssemblerError):
|
|
52
69
|
|
53
70
|
def __str__(self) -> str:
|
54
71
|
return self.message
|
72
|
+
|
73
|
+
|
74
|
+
__all__ = [
|
75
|
+
"AssemblerError",
|
76
|
+
"EnginError",
|
77
|
+
"InvalidBlockError",
|
78
|
+
"NotInScopeError",
|
79
|
+
"ProviderError",
|
80
|
+
]
|
@@ -10,7 +10,7 @@ from engin import Assembler, Engin, Entrypoint, Invoke, Option
|
|
10
10
|
from engin._dependency import Dependency, Supply, _noop
|
11
11
|
from engin._graph import DependencyGrapher, Node
|
12
12
|
from engin._type_utils import TypeId
|
13
|
-
from engin.
|
13
|
+
from engin.extensions.asgi import ASGIEngin
|
14
14
|
|
15
15
|
try:
|
16
16
|
from fastapi import APIRouter, FastAPI
|
@@ -0,0 +1,25 @@
|
|
1
|
+
engin/__init__.py,sha256=A8TE_ci7idoR683535YoBrWZbYTgXXS-q7Y2y51nZ5M,486
|
2
|
+
engin/_assembler.py,sha256=-ENSrXPMWacionIYrTSQO7th9DDBOPyAT8ybPbBRtQw,11318
|
3
|
+
engin/_block.py,sha256=IacP4PoJKRhSQCbQSdoyCtmu362a4vj6qoUQKyaJwzI,3062
|
4
|
+
engin/_dependency.py,sha256=xINk3sudxzsTmkUkNAKQwzBc0G0DfhpnrZli4z3ALBY,9459
|
5
|
+
engin/_engin.py,sha256=yIpZdeqvm8hv0RxOV0veFuvyu9xQ054JSaeuUWwHdOQ,7380
|
6
|
+
engin/_graph.py,sha256=y1g7Lm_Zy5GPEgRsggCKV5DDaDzcwUl8v3IZCK8jyGI,1631
|
7
|
+
engin/_introspect.py,sha256=VdREX6Lhhga5SnEP9G7mjHkgJR4mpqk_SMnmL2zTcqY,966
|
8
|
+
engin/_lifecycle.py,sha256=cSWe3euZkmpxmUPFvph2lsTtvuZbxttEfBL-RnOI7lo,5325
|
9
|
+
engin/_option.py,sha256=nZcdrehp1QwgxMUoIpsM0PJuu1q1pbXzhcVsetbsHpc,223
|
10
|
+
engin/_type_utils.py,sha256=H3Tl-kJr2wY2RhaTXP9GrMqa2RsXMijHbjHKe1AxGmc,2276
|
11
|
+
engin/exceptions.py,sha256=-VPwPReZb9YEIkrWMR9TW2K5HEwmHHgEO7QWH6wfV8c,1946
|
12
|
+
engin/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
13
|
+
engin/_cli/__init__.py,sha256=koD5WTkZXb8QQIiVU5bJiSR1wwPGb5rv2iwd-v-BA7A,564
|
14
|
+
engin/_cli/_common.py,sha256=zMYb1Bs1yUuR3qf3r6WuVozYzDwHJvTVthVbTQfTF9w,1261
|
15
|
+
engin/_cli/_graph.html,sha256=rR5dnDKoz7KtSff0ERCi2UKuoH_Z03MRYiXI_W03G5k,2430
|
16
|
+
engin/_cli/_graph.py,sha256=HMC91nWvTOr6_czPBNx1RU55Ib3qesJRCmbnL2DsdDk,4659
|
17
|
+
engin/_cli/_inspect.py,sha256=0jm25d4wcbXVNJkyaeECSKY-irsxd-EIYBH1GDW_Yjc,3163
|
18
|
+
engin/extensions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
19
|
+
engin/extensions/asgi.py,sha256=d5Z6gtMVWDZdAlvrTaMt987sKyiq__A0X4gJQ7IETmA,3247
|
20
|
+
engin/extensions/fastapi.py,sha256=e8F4L_nZ9dU9j8mb9lXKwJG6CTu5aIk4N5faRj4EyUA,6369
|
21
|
+
engin-0.0.20.dist-info/METADATA,sha256=KiKW4DvikfKJJNzoXh7oC4RMdr02W0PkhtxXB8DN6bo,2354
|
22
|
+
engin-0.0.20.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
23
|
+
engin-0.0.20.dist-info/entry_points.txt,sha256=sW247zZUMxm0b5UKYvPuqQQljYDtU-j2zK3cu7gHwM0,41
|
24
|
+
engin-0.0.20.dist-info/licenses/LICENSE,sha256=XHh5LPUPKZWTBqBv2xxN2RU7D59nHoiJGb5RIt8f45w,1070
|
25
|
+
engin-0.0.20.dist-info/RECORD,,
|
engin-0.0.18.dist-info/RECORD
DELETED
@@ -1,25 +0,0 @@
|
|
1
|
-
engin/__init__.py,sha256=rBTteMLAVKg4TJSaMElJUwz72BA_X7nBTREg-I-bWhA,584
|
2
|
-
engin/_assembler.py,sha256=saxYTjT67WR2HLJAFXyDsDeQmLGp1uyDboTDiKTaZ_s,11177
|
3
|
-
engin/_block.py,sha256=8ysWrmHkWpTm6bmSc6jZVoO0Ax5Svu1HwxpZwAtIF_o,2617
|
4
|
-
engin/_dependency.py,sha256=5x4_0QvHtqv6R_brKHRc-INKE4oMh1JU8-9RCmulp4Q,8976
|
5
|
-
engin/_engin.py,sha256=yIpZdeqvm8hv0RxOV0veFuvyu9xQ054JSaeuUWwHdOQ,7380
|
6
|
-
engin/_exceptions.py,sha256=UzMppJWDk_Hx3qWAypcPVLw9OYCibqiZjLYeTl22zaE,1355
|
7
|
-
engin/_graph.py,sha256=y1g7Lm_Zy5GPEgRsggCKV5DDaDzcwUl8v3IZCK8jyGI,1631
|
8
|
-
engin/_introspect.py,sha256=VdREX6Lhhga5SnEP9G7mjHkgJR4mpqk_SMnmL2zTcqY,966
|
9
|
-
engin/_lifecycle.py,sha256=cSWe3euZkmpxmUPFvph2lsTtvuZbxttEfBL-RnOI7lo,5325
|
10
|
-
engin/_option.py,sha256=nZcdrehp1QwgxMUoIpsM0PJuu1q1pbXzhcVsetbsHpc,223
|
11
|
-
engin/_type_utils.py,sha256=Pmm4m1_WdevT5KTe8tzY_BseNxPyhu_nKsLGgyNcPpo,2247
|
12
|
-
engin/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
13
|
-
engin/_cli/__init__.py,sha256=koD5WTkZXb8QQIiVU5bJiSR1wwPGb5rv2iwd-v-BA7A,564
|
14
|
-
engin/_cli/_common.py,sha256=zMYb1Bs1yUuR3qf3r6WuVozYzDwHJvTVthVbTQfTF9w,1261
|
15
|
-
engin/_cli/_graph.html,sha256=rR5dnDKoz7KtSff0ERCi2UKuoH_Z03MRYiXI_W03G5k,2430
|
16
|
-
engin/_cli/_graph.py,sha256=S0HKWb3PlC1ygYTdsFzEm-eYmrbHhOOMZ7nApOe7ac8,4645
|
17
|
-
engin/_cli/_inspect.py,sha256=0jm25d4wcbXVNJkyaeECSKY-irsxd-EIYBH1GDW_Yjc,3163
|
18
|
-
engin/ext/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
19
|
-
engin/ext/asgi.py,sha256=d5Z6gtMVWDZdAlvrTaMt987sKyiq__A0X4gJQ7IETmA,3247
|
20
|
-
engin/ext/fastapi.py,sha256=TGNf0LFLaTLMLlAycH7GgP_GcBld262v9xboGOwhvgE,6362
|
21
|
-
engin-0.0.18.dist-info/METADATA,sha256=4d8IsPLHnEekTIP5Qdy2LfNYHHZ-G0DLWcjB2RRQdSs,2354
|
22
|
-
engin-0.0.18.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
23
|
-
engin-0.0.18.dist-info/entry_points.txt,sha256=sW247zZUMxm0b5UKYvPuqQQljYDtU-j2zK3cu7gHwM0,41
|
24
|
-
engin-0.0.18.dist-info/licenses/LICENSE,sha256=XHh5LPUPKZWTBqBv2xxN2RU7D59nHoiJGb5RIt8f45w,1070
|
25
|
-
engin-0.0.18.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|