mixinv2 0.3.0.post35.dev0__tar.gz → 0.3.0.post37.dev0__tar.gz
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-0.3.0.post35.dev0 → mixinv2-0.3.0.post37.dev0}/PKG-INFO +1 -1
- {mixinv2-0.3.0.post35.dev0 → mixinv2-0.3.0.post37.dev0}/docs/mixinv2-tutorial.rst +15 -15
- {mixinv2-0.3.0.post35.dev0 → mixinv2-0.3.0.post37.dev0}/docs/tutorial.rst +6 -6
- {mixinv2-0.3.0.post35.dev0 → mixinv2-0.3.0.post37.dev0}/.gitignore +0 -0
- {mixinv2-0.3.0.post35.dev0 → mixinv2-0.3.0.post37.dev0}/README.md +0 -0
- {mixinv2-0.3.0.post35.dev0 → mixinv2-0.3.0.post37.dev0}/docs/Makefile +0 -0
- {mixinv2-0.3.0.post35.dev0 → mixinv2-0.3.0.post37.dev0}/docs/_static/favicon.svg +0 -0
- {mixinv2-0.3.0.post35.dev0 → mixinv2-0.3.0.post37.dev0}/docs/_static/logo.svg +0 -0
- {mixinv2-0.3.0.post35.dev0 → mixinv2-0.3.0.post37.dev0}/docs/conf.py +0 -0
- {mixinv2-0.3.0.post35.dev0 → mixinv2-0.3.0.post37.dev0}/docs/index.rst +0 -0
- {mixinv2-0.3.0.post35.dev0 → mixinv2-0.3.0.post37.dev0}/docs/installation.rst +0 -0
- {mixinv2-0.3.0.post35.dev0 → mixinv2-0.3.0.post37.dev0}/docs/specification.md +0 -0
- {mixinv2-0.3.0.post35.dev0 → mixinv2-0.3.0.post37.dev0}/pyproject.toml +0 -0
- {mixinv2-0.3.0.post35.dev0 → mixinv2-0.3.0.post37.dev0}/src/mixinv2/__init__.py +0 -0
- {mixinv2-0.3.0.post35.dev0 → mixinv2-0.3.0.post37.dev0}/src/mixinv2/_config.py +0 -0
- {mixinv2-0.3.0.post35.dev0 → mixinv2-0.3.0.post37.dev0}/src/mixinv2/_core.py +0 -0
- {mixinv2-0.3.0.post35.dev0 → mixinv2-0.3.0.post37.dev0}/src/mixinv2/_interned_linked_list.py +0 -0
- {mixinv2-0.3.0.post35.dev0 → mixinv2-0.3.0.post37.dev0}/src/mixinv2/_mixin_directory.py +0 -0
- {mixinv2-0.3.0.post35.dev0 → mixinv2-0.3.0.post37.dev0}/src/mixinv2/_mixin_parser.py +0 -0
- {mixinv2-0.3.0.post35.dev0 → mixinv2-0.3.0.post37.dev0}/src/mixinv2/_runtime.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mixinv2
|
|
3
|
-
Version: 0.3.0.
|
|
3
|
+
Version: 0.3.0.post37.dev0
|
|
4
4
|
Summary: A dependency injection framework with pytest-fixture syntax, plus a configuration language for declarative programming
|
|
5
5
|
Project-URL: Repository, https://github.com/Atry/MIXINv2
|
|
6
6
|
Author-email: "Yang, Bo" <yang-bo@yang-bo.com>
|
|
@@ -125,7 +125,7 @@ Four new concepts:
|
|
|
125
125
|
lexical scoping.
|
|
126
126
|
|
|
127
127
|
|
|
128
|
-
``UserRepository.
|
|
128
|
+
``UserRepository.Request`` — ANF style, cross-scope references
|
|
129
129
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
130
130
|
|
|
131
131
|
.. literalinclude:: ../../mixinv2-examples/src/mixinv2_examples/app_mixin/Library.mixin.yaml
|
|
@@ -141,7 +141,7 @@ cost is verbosity; the benefit is that every intermediate value is inspectable
|
|
|
141
141
|
and independently composable.
|
|
142
142
|
|
|
143
143
|
**Cross-scope lexical reference:** ``connection: [connection]`` inside
|
|
144
|
-
``
|
|
144
|
+
``Request`` finds ``UserRepository.connection`` — the lexical scope chain
|
|
145
145
|
searches outward through parent, grandparent, etc. No import statement is
|
|
146
146
|
needed; the scope hierarchy *is* the namespace.
|
|
147
147
|
|
|
@@ -159,18 +159,18 @@ names are filled with concrete values.
|
|
|
159
159
|
:start-after: # [docs:http-handlers]
|
|
160
160
|
:end-before: # [/docs:http-handlers]
|
|
161
161
|
|
|
162
|
-
**Flat inheritance:** ``
|
|
162
|
+
**Flat inheritance:** ``Request`` inherits *two* FFI adapters in its
|
|
163
163
|
inheritance list (``- [FFI, ExtractUserId]``, ``- [FFI, HttpSendResponse]``). Their
|
|
164
|
-
``@extern`` and ``@resource`` fields all merge into ``
|
|
164
|
+
``@extern`` and ``@resource`` fields all merge into ``Request``'s own field
|
|
165
165
|
namespace. The last list item (the mapping starting with ``request: []``) defines
|
|
166
|
-
``
|
|
166
|
+
``Request``'s own fields.
|
|
167
167
|
|
|
168
168
|
**Lexical scoping across scope boundaries:** ``[user_count]`` inside
|
|
169
|
-
``
|
|
169
|
+
``Request`` searches outward and finds ``HttpHandlers.user_count``. At this
|
|
170
170
|
point ``user_count`` is just an extern ``[]`` — its actual value comes from
|
|
171
171
|
``UserRepository`` after deep merge (explained below).
|
|
172
172
|
|
|
173
|
-
**Qualified this:** ``[
|
|
173
|
+
**Qualified this:** ``[Request, ~, written]`` — instead of declaring
|
|
174
174
|
``written: []`` and writing ``response: [written]``, this navigates the runtime
|
|
175
175
|
composition graph to access the ``written`` property inherited from
|
|
176
176
|
``HttpSendResponse``. The advantage: if ``HttpSendResponse`` is accidentally not
|
|
@@ -227,21 +227,21 @@ separate instances — it is a single scope with all four merged together. The
|
|
|
227
227
|
last list item supplies concrete values for every ``[]`` extern.
|
|
228
228
|
|
|
229
229
|
**Deep merge:** Both ``UserRepository`` and ``HttpHandlers`` define a
|
|
230
|
-
``
|
|
231
|
-
single ``
|
|
230
|
+
``Request``. When composed inside ``memory_app``, these merge by name into a
|
|
231
|
+
single ``Request``. After merging:
|
|
232
232
|
|
|
233
|
-
- ``user_id`` (from ``HttpHandlers.
|
|
234
|
-
visible to ``UserRepository.
|
|
233
|
+
- ``user_id`` (from ``HttpHandlers.Request`` via ``ExtractUserId``) becomes
|
|
234
|
+
visible to ``UserRepository.Request``, which uses it to look up
|
|
235
235
|
``current_user``
|
|
236
|
-
- ``current_user_name`` (from ``UserRepository.
|
|
237
|
-
``HttpHandlers.
|
|
236
|
+
- ``current_user_name`` (from ``UserRepository.Request``) becomes visible to
|
|
237
|
+
``HttpHandlers.Request``, which uses it in ``_format``
|
|
238
238
|
|
|
239
239
|
Neither scope imports or references the other — deep merge makes their fields
|
|
240
240
|
mutual siblings automatically. This is the most powerful feature of MIXINv2: cross-cutting concerns compose without glue code.
|
|
241
241
|
|
|
242
242
|
**Config value scoping:** App-lifetime values (``database_path``, ``host``, ``port``)
|
|
243
243
|
live directly in ``memory_app``. Request-lifetime values (``user_query_sql``,
|
|
244
|
-
``path_separator``, ``response_template``) live in ``memory_app.
|
|
244
|
+
``path_separator``, ``response_template``) live in ``memory_app.Request`` — they
|
|
245
245
|
are only needed during request handling.
|
|
246
246
|
|
|
247
247
|
|
|
@@ -324,7 +324,7 @@ Evaluation
|
|
|
324
324
|
composed_app.user_count # 2
|
|
325
325
|
|
|
326
326
|
# Create a fresh request scope (per-request resources):
|
|
327
|
-
scope = composed_app.
|
|
327
|
+
scope = composed_app.Request(request=fake_request)
|
|
328
328
|
scope.current_user.name # "alice"
|
|
329
329
|
scope.response # sends HTTP response as side effect
|
|
330
330
|
|
|
@@ -101,9 +101,9 @@ So far all resources have had application lifetime: created once at startup and
|
|
|
101
101
|
reused for every request. Real applications also need per-request resources — values
|
|
102
102
|
that must be created fresh for each incoming request and discarded when it completes.
|
|
103
103
|
|
|
104
|
-
A nested ``@scope`` named ``
|
|
104
|
+
A nested ``@scope`` named ``Request`` serves as a per-request factory. The
|
|
105
105
|
framework injects it by name as a ``Callable``; calling
|
|
106
|
-
``
|
|
106
|
+
``Request(request=handler)`` returns a fresh instance.
|
|
107
107
|
|
|
108
108
|
The application below has four scopes, each owning only its own concern:
|
|
109
109
|
|
|
@@ -112,10 +112,10 @@ The application below has four scopes, each owning only its own concern:
|
|
|
112
112
|
- **HttpHandlers** — HTTP layer; owns per-request ``userId``, ``responseBody``, ``responseSent``
|
|
113
113
|
- **NetworkServer** — network layer; owns ``host``/``port``, creates the ``HTTPServer``
|
|
114
114
|
|
|
115
|
-
``UserRepository.
|
|
116
|
-
single ``
|
|
117
|
-
by ``HttpHandlers.
|
|
118
|
-
in the DB by ``UserRepository.
|
|
115
|
+
``UserRepository.Request`` and ``HttpHandlers.Request`` are composed into a
|
|
116
|
+
single ``Request`` by the union mount. ``userId`` (extracted from the HTTP path
|
|
117
|
+
by ``HttpHandlers.Request``) flows automatically into ``currentUser`` (looked up
|
|
118
|
+
in the DB by ``UserRepository.Request``) without any glue code.
|
|
119
119
|
|
|
120
120
|
``responseSent`` is an IO resource: it sends the HTTP response as a side effect and
|
|
121
121
|
returns ``None``. The handler body is a single attribute access — all logic lives in
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mixinv2-0.3.0.post35.dev0 → mixinv2-0.3.0.post37.dev0}/src/mixinv2/_interned_linked_list.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|