graphddb-runtime 0.7.7__tar.gz → 0.7.8__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.
- {graphddb_runtime-0.7.7 → graphddb_runtime-0.7.8}/PKG-INFO +1 -1
- {graphddb_runtime-0.7.7 → graphddb_runtime-0.7.8}/graphddb_runtime/transactions.py +18 -2
- {graphddb_runtime-0.7.7 → graphddb_runtime-0.7.8}/graphddb_runtime.egg-info/PKG-INFO +1 -1
- {graphddb_runtime-0.7.7 → graphddb_runtime-0.7.8}/pyproject.toml +1 -1
- {graphddb_runtime-0.7.7 → graphddb_runtime-0.7.8}/tests/test_unit.py +57 -0
- {graphddb_runtime-0.7.7 → graphddb_runtime-0.7.8}/README.md +0 -0
- {graphddb_runtime-0.7.7 → graphddb_runtime-0.7.8}/graphddb_runtime/__init__.py +0 -0
- {graphddb_runtime-0.7.7 → graphddb_runtime-0.7.8}/graphddb_runtime/async_runtime.py +0 -0
- {graphddb_runtime-0.7.7 → graphddb_runtime-0.7.8}/graphddb_runtime/batch.py +0 -0
- {graphddb_runtime-0.7.7 → graphddb_runtime-0.7.8}/graphddb_runtime/concurrency.py +0 -0
- {graphddb_runtime-0.7.7 → graphddb_runtime-0.7.8}/graphddb_runtime/cursor.py +0 -0
- {graphddb_runtime-0.7.7 → graphddb_runtime-0.7.8}/graphddb_runtime/errors.py +0 -0
- {graphddb_runtime-0.7.7 → graphddb_runtime-0.7.8}/graphddb_runtime/filters.py +0 -0
- {graphddb_runtime-0.7.7 → graphddb_runtime-0.7.8}/graphddb_runtime/hydration.py +0 -0
- {graphddb_runtime-0.7.7 → graphddb_runtime-0.7.8}/graphddb_runtime/limits.py +0 -0
- {graphddb_runtime-0.7.7 → graphddb_runtime-0.7.8}/graphddb_runtime/middleware.py +0 -0
- {graphddb_runtime-0.7.7 → graphddb_runtime-0.7.8}/graphddb_runtime/per_key_cursor.py +0 -0
- {graphddb_runtime-0.7.7 → graphddb_runtime-0.7.8}/graphddb_runtime/relations.py +0 -0
- {graphddb_runtime-0.7.7 → graphddb_runtime-0.7.8}/graphddb_runtime/runtime.py +0 -0
- {graphddb_runtime-0.7.7 → graphddb_runtime-0.7.8}/graphddb_runtime/templates.py +0 -0
- {graphddb_runtime-0.7.7 → graphddb_runtime-0.7.8}/graphddb_runtime.egg-info/SOURCES.txt +0 -0
- {graphddb_runtime-0.7.7 → graphddb_runtime-0.7.8}/graphddb_runtime.egg-info/dependency_links.txt +0 -0
- {graphddb_runtime-0.7.7 → graphddb_runtime-0.7.8}/graphddb_runtime.egg-info/requires.txt +0 -0
- {graphddb_runtime-0.7.7 → graphddb_runtime-0.7.8}/graphddb_runtime.egg-info/top_level.txt +0 -0
- {graphddb_runtime-0.7.7 → graphddb_runtime-0.7.8}/setup.cfg +0 -0
- {graphddb_runtime-0.7.7 → graphddb_runtime-0.7.8}/tests/test_concurrency.py +0 -0
- {graphddb_runtime-0.7.7 → graphddb_runtime-0.7.8}/tests/test_contract_runtime.py +0 -0
- {graphddb_runtime-0.7.7 → graphddb_runtime-0.7.8}/tests/test_crosslang_python_cells.py +0 -0
- {graphddb_runtime-0.7.7 → graphddb_runtime-0.7.8}/tests/test_description.py +0 -0
- {graphddb_runtime-0.7.7 → graphddb_runtime-0.7.8}/tests/test_description_followups.py +0 -0
- {graphddb_runtime-0.7.7 → graphddb_runtime-0.7.8}/tests/test_description_jsdoc.py +0 -0
- {graphddb_runtime-0.7.7 → graphddb_runtime-0.7.8}/tests/test_integration.py +0 -0
- {graphddb_runtime-0.7.7 → graphddb_runtime-0.7.8}/tests/test_integration_command.py +0 -0
- {graphddb_runtime-0.7.7 → graphddb_runtime-0.7.8}/tests/test_integration_compose.py +0 -0
- {graphddb_runtime-0.7.7 → graphddb_runtime-0.7.8}/tests/test_integration_contract.py +0 -0
- {graphddb_runtime-0.7.7 → graphddb_runtime-0.7.8}/tests/test_integration_edge_derive.py +0 -0
- {graphddb_runtime-0.7.7 → graphddb_runtime-0.7.8}/tests/test_integration_edge_write.py +0 -0
- {graphddb_runtime-0.7.7 → graphddb_runtime-0.7.8}/tests/test_integration_events.py +0 -0
- {graphddb_runtime-0.7.7 → graphddb_runtime-0.7.8}/tests/test_integration_maintain.py +0 -0
- {graphddb_runtime-0.7.7 → graphddb_runtime-0.7.8}/tests/test_integration_middleware.py +0 -0
- {graphddb_runtime-0.7.7 → graphddb_runtime-0.7.8}/tests/test_integration_referential.py +0 -0
- {graphddb_runtime-0.7.7 → graphddb_runtime-0.7.8}/tests/test_integration_relations.py +0 -0
- {graphddb_runtime-0.7.7 → graphddb_runtime-0.7.8}/tests/test_integration_unique.py +0 -0
- {graphddb_runtime-0.7.7 → graphddb_runtime-0.7.8}/tests/test_maintain.py +0 -0
- {graphddb_runtime-0.7.7 → graphddb_runtime-0.7.8}/tests/test_middleware.py +0 -0
- {graphddb_runtime-0.7.7 → graphddb_runtime-0.7.8}/tests/test_relations.py +0 -0
- {graphddb_runtime-0.7.7 → graphddb_runtime-0.7.8}/tests/test_spec_version_guard.py +0 -0
- {graphddb_runtime-0.7.7 → graphddb_runtime-0.7.8}/tests/test_ttl.py +0 -0
|
@@ -50,11 +50,27 @@ def _resolve_template(
|
|
|
50
50
|
|
|
51
51
|
|
|
52
52
|
def _resolve_value(
|
|
53
|
-
template:
|
|
53
|
+
template: Any,
|
|
54
54
|
params: Mapping[str, Any],
|
|
55
55
|
element: Optional[Mapping[str, Any]],
|
|
56
56
|
) -> Any:
|
|
57
|
-
"""Resolve a value
|
|
57
|
+
"""Resolve a value leaf, preserving its type (issue #245).
|
|
58
|
+
|
|
59
|
+
A non-string leaf (an ``int`` / ``bool`` typed literal, from the #245
|
|
60
|
+
serializer) passes through verbatim, so it lands in DynamoDB as ``N`` /
|
|
61
|
+
``BOOL``. A string leaf is a template: a whole placeholder keeps the bound
|
|
62
|
+
param's type; a composite / plain string resolves to a string.
|
|
63
|
+
|
|
64
|
+
Scope note (#245): only integer / boolean literals keep their type in this
|
|
65
|
+
runtime. A ``float`` literal (e.g. ``rate: 0.5``) passes through here but then
|
|
66
|
+
fails LOUD at serialize time — boto3's ``TypeSerializer`` raises
|
|
67
|
+
``TypeError: Float types are not supported`` (the same pre-existing constraint
|
|
68
|
+
that applies to ``float`` *params*), so a float is never silently corrupted.
|
|
69
|
+
Making floats round-trip requires a ``Decimal`` conversion pass — a broader
|
|
70
|
+
change deliberately OUT of #245 scope (a follow-up).
|
|
71
|
+
"""
|
|
72
|
+
if not isinstance(template, str):
|
|
73
|
+
return template
|
|
58
74
|
if _WHOLE_PLACEHOLDER_RE.match(template):
|
|
59
75
|
name = template[1:-1]
|
|
60
76
|
if name.startswith("item."):
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "graphddb-runtime"
|
|
7
|
-
version = "0.7.
|
|
7
|
+
version = "0.7.8"
|
|
8
8
|
description = "Thin DynamoDB executor for GraphDDB-generated Python repositories (single-operation core, issue #44)."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.9"
|
|
@@ -634,6 +634,63 @@ def test_transaction_exceeding_25_after_expansion_raises():
|
|
|
634
634
|
)
|
|
635
635
|
|
|
636
636
|
|
|
637
|
+
# ── issue #245: value-position literals keep their type (N / BOOL, not S) ─────
|
|
638
|
+
def test_resolve_value_passes_typed_literal_through():
|
|
639
|
+
"""A non-string leaf (number / boolean typed literal, #245) is returned
|
|
640
|
+
verbatim, while a string leaf is resolved as a template."""
|
|
641
|
+
from graphddb_runtime.transactions import _resolve_value
|
|
642
|
+
|
|
643
|
+
assert _resolve_value(0, {}, None) == 0
|
|
644
|
+
assert isinstance(_resolve_value(0, {}, None), int)
|
|
645
|
+
assert _resolve_value(True, {}, None) is True
|
|
646
|
+
# A whole-placeholder string still keeps the bound param's type.
|
|
647
|
+
assert _resolve_value("{v}", {"v": 42}, None) == 42
|
|
648
|
+
# A composite string resolves to a string.
|
|
649
|
+
assert _resolve_value("V#{v}", {"v": 42}, None) == "V#42"
|
|
650
|
+
|
|
651
|
+
|
|
652
|
+
def test_transaction_put_serializes_numeric_literal_as_N():
|
|
653
|
+
"""End-to-end through ``TransactionExpander._build_item``: a ``version: 0``
|
|
654
|
+
numeric literal in a put item is serialized as an ``N`` attribute (not ``"0"``
|
|
655
|
+
as an ``S``), the #245 regression the whole fix targets."""
|
|
656
|
+
from graphddb_runtime.transactions import TransactionExpander
|
|
657
|
+
|
|
658
|
+
rt = make_runtime(FakeClient())
|
|
659
|
+
# Register a chunk-like modeled entity (mirrors the TS ChunkModel).
|
|
660
|
+
rt._entities["ChunkModel"] = {
|
|
661
|
+
"table": "UserPermissions",
|
|
662
|
+
"physicalName": "UserPermissions",
|
|
663
|
+
"prefix": "CHUNK",
|
|
664
|
+
"fields": {
|
|
665
|
+
"id": {"type": "string"},
|
|
666
|
+
"version": {"type": "number"},
|
|
667
|
+
"active": {"type": "boolean"},
|
|
668
|
+
},
|
|
669
|
+
"key": {
|
|
670
|
+
"inputFields": ["id"],
|
|
671
|
+
"pkTemplate": "CHUNK#{id}",
|
|
672
|
+
"skTemplate": "META",
|
|
673
|
+
},
|
|
674
|
+
"gsis": [],
|
|
675
|
+
"relations": {},
|
|
676
|
+
}
|
|
677
|
+
expander = TransactionExpander(rt)
|
|
678
|
+
spec = {
|
|
679
|
+
"type": "Put",
|
|
680
|
+
"tableName": "UserPermissions",
|
|
681
|
+
"entity": "ChunkModel",
|
|
682
|
+
# The #245 serializer emits number / boolean literals verbatim (native JSON).
|
|
683
|
+
"item": {"id": "{id}", "version": 0, "active": True},
|
|
684
|
+
}
|
|
685
|
+
built = expander._build_item(spec, {"id": "c1"}, None)
|
|
686
|
+
item = built["Put"]["Item"]
|
|
687
|
+
# DynamoDB attribute-value form: N for the number, BOOL for the boolean, S for id.
|
|
688
|
+
assert item["version"] == {"N": "0"}
|
|
689
|
+
assert item["active"] == {"BOOL": True}
|
|
690
|
+
assert item["id"] == {"S": "c1"}
|
|
691
|
+
assert item["PK"] == {"S": "CHUNK#c1"}
|
|
692
|
+
|
|
693
|
+
|
|
637
694
|
def test_transaction_validates_array_param():
|
|
638
695
|
rt = make_runtime(FakeClient())
|
|
639
696
|
with pytest.raises(ParameterValidationError):
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{graphddb_runtime-0.7.7 → graphddb_runtime-0.7.8}/graphddb_runtime.egg-info/dependency_links.txt
RENAMED
|
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
|
|
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
|
|
File without changes
|