mixinv2 0.2.0.post28.dev0__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.
- mixinv2/__init__.py +100 -0
- mixinv2/_config.py +56 -0
- mixinv2/_core.py +2908 -0
- mixinv2/_interned_linked_list.py +147 -0
- mixinv2/_mixin_directory.py +150 -0
- mixinv2/_mixin_parser.py +487 -0
- mixinv2/_runtime.py +710 -0
- mixinv2-0.2.0.post28.dev0.dist-info/METADATA +16 -0
- mixinv2-0.2.0.post28.dev0.dist-info/RECORD +10 -0
- mixinv2-0.2.0.post28.dev0.dist-info/WHEEL +4 -0
mixinv2/__init__.py
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"""
|
|
2
|
+
MIXINv2: A dependency injection framework with pytest-fixture-like semantics.
|
|
3
|
+
|
|
4
|
+
Public API
|
|
5
|
+
==========
|
|
6
|
+
|
|
7
|
+
Decorators:
|
|
8
|
+
- :func:`scope`
|
|
9
|
+
- :func:`resource`
|
|
10
|
+
- :func:`patch`
|
|
11
|
+
- :func:`patch_many`
|
|
12
|
+
- :func:`merge`
|
|
13
|
+
- :func:`extern`
|
|
14
|
+
- :func:`public`
|
|
15
|
+
- :func:`eager`
|
|
16
|
+
- :func:`extend`
|
|
17
|
+
|
|
18
|
+
Runtime:
|
|
19
|
+
- :func:`evaluate`
|
|
20
|
+
|
|
21
|
+
Reference types (parameters to :func:`extend`):
|
|
22
|
+
- :class:`AbsoluteReference`
|
|
23
|
+
- :class:`RelativeReference`
|
|
24
|
+
- :class:`LexicalReference`
|
|
25
|
+
- :class:`QualifiedThisReference`
|
|
26
|
+
- :data:`ResourceReference`
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
from __future__ import annotations
|
|
30
|
+
|
|
31
|
+
from typing import TYPE_CHECKING
|
|
32
|
+
|
|
33
|
+
# Public API: decorators and evaluate
|
|
34
|
+
from mixinv2._core import eager as eager
|
|
35
|
+
from mixinv2._core import extend as extend
|
|
36
|
+
from mixinv2._core import extern as extern
|
|
37
|
+
from mixinv2._core import merge as merge
|
|
38
|
+
from mixinv2._core import patch as patch
|
|
39
|
+
from mixinv2._core import patch_many as patch_many
|
|
40
|
+
from mixinv2._core import public as public
|
|
41
|
+
from mixinv2._core import resource as resource
|
|
42
|
+
from mixinv2._core import scope as scope
|
|
43
|
+
from mixinv2._runtime import evaluate as evaluate
|
|
44
|
+
|
|
45
|
+
if TYPE_CHECKING:
|
|
46
|
+
from collections.abc import Hashable
|
|
47
|
+
from typing import Protocol, TypeAlias, final
|
|
48
|
+
|
|
49
|
+
@final
|
|
50
|
+
class AbsoluteReference(Protocol):
|
|
51
|
+
"""An absolute reference to a resource starting from the root scope."""
|
|
52
|
+
|
|
53
|
+
path: tuple[Hashable, ...]
|
|
54
|
+
|
|
55
|
+
def __init__(self, *, path: tuple[Hashable, ...]) -> None: ...
|
|
56
|
+
|
|
57
|
+
@final
|
|
58
|
+
class RelativeReference(Protocol):
|
|
59
|
+
"""A reference to a resource relative to the current lexical scope."""
|
|
60
|
+
|
|
61
|
+
de_bruijn_index: int
|
|
62
|
+
path: tuple[Hashable, ...]
|
|
63
|
+
|
|
64
|
+
def __init__(
|
|
65
|
+
self, *, de_bruijn_index: int, path: tuple[Hashable, ...]
|
|
66
|
+
) -> None: ...
|
|
67
|
+
|
|
68
|
+
@final
|
|
69
|
+
class LexicalReference(Protocol):
|
|
70
|
+
"""A lexical reference following the MIXINv2 spec resolution algorithm."""
|
|
71
|
+
|
|
72
|
+
path: tuple[Hashable, ...]
|
|
73
|
+
|
|
74
|
+
def __init__(self, *, path: tuple[Hashable, ...]) -> None: ...
|
|
75
|
+
|
|
76
|
+
@final
|
|
77
|
+
class QualifiedThisReference(Protocol):
|
|
78
|
+
"""A qualified this reference: [SelfName, ~, property, path]."""
|
|
79
|
+
|
|
80
|
+
self_name: str
|
|
81
|
+
path: tuple[str, ...]
|
|
82
|
+
|
|
83
|
+
def __init__(
|
|
84
|
+
self, *, self_name: str, path: tuple[str, ...]
|
|
85
|
+
) -> None: ...
|
|
86
|
+
|
|
87
|
+
ResourceReference: TypeAlias = (
|
|
88
|
+
AbsoluteReference
|
|
89
|
+
| RelativeReference
|
|
90
|
+
| LexicalReference
|
|
91
|
+
| QualifiedThisReference
|
|
92
|
+
)
|
|
93
|
+
else:
|
|
94
|
+
from mixinv2._core import AbsoluteReference as AbsoluteReference
|
|
95
|
+
from mixinv2._core import LexicalReference as LexicalReference
|
|
96
|
+
from mixinv2._core import (
|
|
97
|
+
QualifiedThisReference as QualifiedThisReference,
|
|
98
|
+
)
|
|
99
|
+
from mixinv2._core import RelativeReference as RelativeReference
|
|
100
|
+
from mixinv2._core import ResourceReference as ResourceReference
|
mixinv2/_config.py
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from enum import Enum, auto
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class InitializationTiming(Enum):
|
|
6
|
+
LAZY = auto()
|
|
7
|
+
"""
|
|
8
|
+
The resource is created when it is first accessed.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
POST_INIT = auto()
|
|
12
|
+
"""
|
|
13
|
+
The resource is created in ``Scope.__post_init__``.
|
|
14
|
+
"""
|
|
15
|
+
ENTER = auto()
|
|
16
|
+
"""
|
|
17
|
+
The resource is created in ``Scope.__enter__`` or ``Scope.__aenter__``, depending on whether the resource is async.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@dataclass(kw_only=True, frozen=True, slots=True, weakref_slot=True)
|
|
22
|
+
class Lifecycle:
|
|
23
|
+
is_weak_reference: bool
|
|
24
|
+
"""
|
|
25
|
+
Whether the resource is cached using a weak reference.
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
initialization: InitializationTiming
|
|
29
|
+
"""
|
|
30
|
+
When the resource is created.
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class LifecycleSentinel(Enum):
|
|
35
|
+
EPHEMERAL = auto()
|
|
36
|
+
"""
|
|
37
|
+
The resource is not cached, and is created every time it is accessed.
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@dataclass(kw_only=True, frozen=True, slots=True, weakref_slot=True)
|
|
42
|
+
class ResourceConfig:
|
|
43
|
+
lifecycle: Lifecycle | LifecycleSentinel
|
|
44
|
+
is_async: bool
|
|
45
|
+
"""
|
|
46
|
+
Whether the resource is async.
|
|
47
|
+
|
|
48
|
+
When lifecycle is not EPHEMERAL, the resource (possibly after ``async_enter_context``) is converted to a Future when is_async is True.
|
|
49
|
+
"""
|
|
50
|
+
|
|
51
|
+
is_contextmanager: bool
|
|
52
|
+
"""
|
|
53
|
+
Whether the resource is a context manager.
|
|
54
|
+
|
|
55
|
+
If True, the ``TResult`` is either a ``ContextManager`` or ``AsyncContextManager``, and should be registered with ``scope.exit_stack.enter_context``` or ``scope.exit_stack.async_enter_context`` depending on ``is_async``.
|
|
56
|
+
"""
|