graphddb-runtime 0.5.1__tar.gz → 0.5.2__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.
Files changed (46) hide show
  1. {graphddb_runtime-0.5.1 → graphddb_runtime-0.5.2}/PKG-INFO +1 -1
  2. {graphddb_runtime-0.5.1 → graphddb_runtime-0.5.2}/graphddb_runtime.egg-info/PKG-INFO +1 -1
  3. {graphddb_runtime-0.5.1 → graphddb_runtime-0.5.2}/graphddb_runtime.egg-info/SOURCES.txt +2 -0
  4. {graphddb_runtime-0.5.1 → graphddb_runtime-0.5.2}/pyproject.toml +1 -1
  5. graphddb_runtime-0.5.2/tests/test_description_followups.py +65 -0
  6. graphddb_runtime-0.5.2/tests/test_description_jsdoc.py +99 -0
  7. {graphddb_runtime-0.5.1 → graphddb_runtime-0.5.2}/README.md +0 -0
  8. {graphddb_runtime-0.5.1 → graphddb_runtime-0.5.2}/graphddb_runtime/__init__.py +0 -0
  9. {graphddb_runtime-0.5.1 → graphddb_runtime-0.5.2}/graphddb_runtime/async_runtime.py +0 -0
  10. {graphddb_runtime-0.5.1 → graphddb_runtime-0.5.2}/graphddb_runtime/batch.py +0 -0
  11. {graphddb_runtime-0.5.1 → graphddb_runtime-0.5.2}/graphddb_runtime/concurrency.py +0 -0
  12. {graphddb_runtime-0.5.1 → graphddb_runtime-0.5.2}/graphddb_runtime/cursor.py +0 -0
  13. {graphddb_runtime-0.5.1 → graphddb_runtime-0.5.2}/graphddb_runtime/errors.py +0 -0
  14. {graphddb_runtime-0.5.1 → graphddb_runtime-0.5.2}/graphddb_runtime/filters.py +0 -0
  15. {graphddb_runtime-0.5.1 → graphddb_runtime-0.5.2}/graphddb_runtime/hydration.py +0 -0
  16. {graphddb_runtime-0.5.1 → graphddb_runtime-0.5.2}/graphddb_runtime/limits.py +0 -0
  17. {graphddb_runtime-0.5.1 → graphddb_runtime-0.5.2}/graphddb_runtime/middleware.py +0 -0
  18. {graphddb_runtime-0.5.1 → graphddb_runtime-0.5.2}/graphddb_runtime/per_key_cursor.py +0 -0
  19. {graphddb_runtime-0.5.1 → graphddb_runtime-0.5.2}/graphddb_runtime/relations.py +0 -0
  20. {graphddb_runtime-0.5.1 → graphddb_runtime-0.5.2}/graphddb_runtime/runtime.py +0 -0
  21. {graphddb_runtime-0.5.1 → graphddb_runtime-0.5.2}/graphddb_runtime/templates.py +0 -0
  22. {graphddb_runtime-0.5.1 → graphddb_runtime-0.5.2}/graphddb_runtime/transactions.py +0 -0
  23. {graphddb_runtime-0.5.1 → graphddb_runtime-0.5.2}/graphddb_runtime.egg-info/dependency_links.txt +0 -0
  24. {graphddb_runtime-0.5.1 → graphddb_runtime-0.5.2}/graphddb_runtime.egg-info/requires.txt +0 -0
  25. {graphddb_runtime-0.5.1 → graphddb_runtime-0.5.2}/graphddb_runtime.egg-info/top_level.txt +0 -0
  26. {graphddb_runtime-0.5.1 → graphddb_runtime-0.5.2}/setup.cfg +0 -0
  27. {graphddb_runtime-0.5.1 → graphddb_runtime-0.5.2}/tests/test_concurrency.py +0 -0
  28. {graphddb_runtime-0.5.1 → graphddb_runtime-0.5.2}/tests/test_contract_runtime.py +0 -0
  29. {graphddb_runtime-0.5.1 → graphddb_runtime-0.5.2}/tests/test_description.py +0 -0
  30. {graphddb_runtime-0.5.1 → graphddb_runtime-0.5.2}/tests/test_integration.py +0 -0
  31. {graphddb_runtime-0.5.1 → graphddb_runtime-0.5.2}/tests/test_integration_command.py +0 -0
  32. {graphddb_runtime-0.5.1 → graphddb_runtime-0.5.2}/tests/test_integration_compose.py +0 -0
  33. {graphddb_runtime-0.5.1 → graphddb_runtime-0.5.2}/tests/test_integration_contract.py +0 -0
  34. {graphddb_runtime-0.5.1 → graphddb_runtime-0.5.2}/tests/test_integration_edge_derive.py +0 -0
  35. {graphddb_runtime-0.5.1 → graphddb_runtime-0.5.2}/tests/test_integration_edge_write.py +0 -0
  36. {graphddb_runtime-0.5.1 → graphddb_runtime-0.5.2}/tests/test_integration_events.py +0 -0
  37. {graphddb_runtime-0.5.1 → graphddb_runtime-0.5.2}/tests/test_integration_maintain.py +0 -0
  38. {graphddb_runtime-0.5.1 → graphddb_runtime-0.5.2}/tests/test_integration_middleware.py +0 -0
  39. {graphddb_runtime-0.5.1 → graphddb_runtime-0.5.2}/tests/test_integration_referential.py +0 -0
  40. {graphddb_runtime-0.5.1 → graphddb_runtime-0.5.2}/tests/test_integration_relations.py +0 -0
  41. {graphddb_runtime-0.5.1 → graphddb_runtime-0.5.2}/tests/test_integration_unique.py +0 -0
  42. {graphddb_runtime-0.5.1 → graphddb_runtime-0.5.2}/tests/test_maintain.py +0 -0
  43. {graphddb_runtime-0.5.1 → graphddb_runtime-0.5.2}/tests/test_middleware.py +0 -0
  44. {graphddb_runtime-0.5.1 → graphddb_runtime-0.5.2}/tests/test_relations.py +0 -0
  45. {graphddb_runtime-0.5.1 → graphddb_runtime-0.5.2}/tests/test_ttl.py +0 -0
  46. {graphddb_runtime-0.5.1 → graphddb_runtime-0.5.2}/tests/test_unit.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: graphddb-runtime
3
- Version: 0.5.1
3
+ Version: 0.5.2
4
4
  Summary: Thin DynamoDB executor for GraphDDB-generated Python repositories (single-operation core, issue #44).
5
5
  License: MIT
6
6
  Requires-Python: >=3.9
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: graphddb-runtime
3
- Version: 0.5.1
3
+ Version: 0.5.2
4
4
  Summary: Thin DynamoDB executor for GraphDDB-generated Python repositories (single-operation core, issue #44).
5
5
  License: MIT
6
6
  Requires-Python: >=3.9
@@ -23,6 +23,8 @@ graphddb_runtime.egg-info/top_level.txt
23
23
  tests/test_concurrency.py
24
24
  tests/test_contract_runtime.py
25
25
  tests/test_description.py
26
+ tests/test_description_followups.py
27
+ tests/test_description_jsdoc.py
26
28
  tests/test_integration.py
27
29
  tests/test_integration_command.py
28
30
  tests/test_integration_compose.py
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "graphddb-runtime"
7
- version = "0.5.1"
7
+ version = "0.5.2"
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"
@@ -0,0 +1,65 @@
1
+ """Issue #166 (follow-up of #154): the description taken in on the relation and GSI
2
+ TS declaration sites is propagated into the generated artifacts the Python bridge
3
+ consumes — manifest.json (entity relations / gsis) and the generated Python source
4
+ (relation field comment, GSI query-method docstring). An undescribed relation / GSI
5
+ carries no `description` key (backward compatible). TS↔Python parity holds because
6
+ both read the SAME serialized string from the manifest.
7
+
8
+ The `@maintainedFrom` maintenance IR is deliberately kept OFF manifest.json /
9
+ operations.json / the generated Python (a maintenance-graph concern, not a manifest
10
+ one), so there is nothing to assert Python-side for that site; its description is a
11
+ metadata-layer capture verified in the TS suite
12
+ (__tests__/spec/description-relation-maintained-gsi.test.ts).
13
+ """
14
+
15
+ from __future__ import annotations
16
+
17
+ import ast
18
+ import json
19
+ import os
20
+
21
+ import conftest
22
+
23
+ REPOSITORIES_PATH = os.path.join(conftest.FIXTURES_DIR, "repositories.py")
24
+ TYPES_PATH = os.path.join(conftest.FIXTURES_DIR, "types.py")
25
+ # The multi fixture is the one whose queries actually SELECT relations, so it is where
26
+ # a relation's field comment surfaces in the generated types.py.
27
+ _MULTI_DIR = os.path.join(os.path.dirname(conftest.FIXTURES_DIR), "generated_multi")
28
+ MULTI_TYPES_PATH = os.path.join(_MULTI_DIR, "types.py")
29
+
30
+
31
+ def _manifest() -> dict:
32
+ with open(conftest.MANIFEST_PATH, encoding="utf-8") as fh:
33
+ return json.load(fh)
34
+
35
+
36
+ def test_manifest_carries_relation_description() -> None:
37
+ group = _manifest()["entities"]["GroupModel"]
38
+ assert (
39
+ group["relations"]["members"]["description"]
40
+ == "Memberships linking users into this group."
41
+ )
42
+ # A relation without a declared description carries no `description` key.
43
+ assert "description" not in group["relations"]["permissions"]
44
+
45
+
46
+ def test_manifest_carries_gsi_description() -> None:
47
+ user = _manifest()["entities"]["UserModel"]
48
+ gsi1 = next(g for g in user["gsis"] if g["indexName"] == "GSI1")
49
+ assert gsi1["description"] == "Look up a user by their unique email address."
50
+
51
+
52
+ def test_generated_python_carries_gsi_method_docstring() -> None:
53
+ with open(REPOSITORIES_PATH, encoding="utf-8") as fh:
54
+ repos_src = fh.read()
55
+ ast.parse(repos_src)
56
+ # The GSI description surfaces as the docstring of the query that reads GSI1.
57
+ assert '"""Look up a user by their unique email address."""' in repos_src
58
+
59
+
60
+ def test_generated_python_carries_relation_field_comment() -> None:
61
+ with open(MULTI_TYPES_PATH, encoding="utf-8") as fh:
62
+ types_src = fh.read()
63
+ ast.parse(types_src)
64
+ # The `members` relation's description surfaces as a trailing field comment.
65
+ assert "# Memberships linking users into this group." in types_src
@@ -0,0 +1,99 @@
1
+ """Issue #165: JSDoc doc-comments extracted via a TS compiler-API pass become the
2
+ DEFAULT `description` (an explicit `description` still wins). These JSDoc-sourced
3
+ strings must reach the SAME generated artifacts the Python bridge consumes —
4
+ manifest.json / operations.json and the generated Python source — proving TS↔Python
5
+ parity (both read the one serialized string from the generated SSoT).
6
+
7
+ The committed fixtures (python/tests/fixtures/{models,definitions}.ts) carry JSDoc at
8
+ sites left WITHOUT an explicit description by #154/#166 (UserModel entity + its
9
+ `name` field + `groups` relation, GroupMembershipModel's `GSI1`, and the `getUser`
10
+ query + its `userId` param), plus one PRECEDENCE control (GroupModel has both a JSDoc
11
+ and an explicit description — the explicit must win, the JSDoc must be absent).
12
+ Regenerate with `npm run gen:py:fixtures[:multi]`.
13
+ """
14
+
15
+ from __future__ import annotations
16
+
17
+ import ast
18
+ import json
19
+ import os
20
+
21
+ import conftest
22
+
23
+ REPOSITORIES_PATH = os.path.join(conftest.FIXTURES_DIR, "repositories.py")
24
+ TYPES_PATH = os.path.join(conftest.FIXTURES_DIR, "types.py")
25
+ OPERATIONS_PATH = os.path.join(conftest.FIXTURES_DIR, "operations.json")
26
+
27
+
28
+ def _manifest() -> dict:
29
+ with open(conftest.MANIFEST_PATH, encoding="utf-8") as fh:
30
+ return json.load(fh)
31
+
32
+
33
+ def _operations() -> dict:
34
+ with open(OPERATIONS_PATH, encoding="utf-8") as fh:
35
+ return json.load(fh)
36
+
37
+
38
+ def test_manifest_carries_jsdoc_model_description() -> None:
39
+ user = _manifest()["entities"]["UserModel"]
40
+ assert "JSDoc-as-default (model)" in user["description"]
41
+
42
+
43
+ def test_manifest_carries_jsdoc_field_description() -> None:
44
+ user = _manifest()["entities"]["UserModel"]
45
+ assert user["fields"]["name"]["description"] == (
46
+ "#165 JSDoc-as-default (field): the user's display name."
47
+ )
48
+
49
+
50
+ def test_manifest_carries_jsdoc_relation_description() -> None:
51
+ user = _manifest()["entities"]["UserModel"]
52
+ assert user["relations"]["groups"]["description"] == (
53
+ "#165 JSDoc-as-default (relation): the groups this user is a member of."
54
+ )
55
+
56
+
57
+ def test_manifest_carries_jsdoc_gsi_description() -> None:
58
+ membership = _manifest()["entities"]["GroupMembershipModel"]
59
+ gsi1 = next(g for g in membership["gsis"] if g["indexName"] == "GSI1")
60
+ assert gsi1["description"] == (
61
+ "#165 JSDoc-as-default (gsi): list a user's group memberships (reverse index)."
62
+ )
63
+
64
+
65
+ def test_operations_carry_jsdoc_query_and_param_description() -> None:
66
+ get_user = _operations()["queries"]["getUserDocumented"]
67
+ assert get_user["description"] == (
68
+ "#165 JSDoc-as-default (query): fetch a single user by id (JSDoc source)."
69
+ )
70
+ assert get_user["params"]["userId"]["description"] == (
71
+ "#165 JSDoc-as-default (param): the user id to fetch."
72
+ )
73
+
74
+
75
+ def test_generated_python_carries_jsdoc_query_docstring() -> None:
76
+ with open(REPOSITORIES_PATH, encoding="utf-8") as fh:
77
+ repos_src = fh.read()
78
+ ast.parse(repos_src)
79
+ assert (
80
+ '"""#165 JSDoc-as-default (query): fetch a single user by id (JSDoc source)."""'
81
+ in repos_src
82
+ )
83
+
84
+
85
+ def test_generated_python_carries_jsdoc_field_comment() -> None:
86
+ with open(TYPES_PATH, encoding="utf-8") as fh:
87
+ types_src = fh.read()
88
+ ast.parse(types_src)
89
+ assert "# #165 JSDoc-as-default (field): the user's display name." in types_src
90
+
91
+
92
+ def test_explicit_description_overrides_jsdoc() -> None:
93
+ """GroupModel carries BOTH a JSDoc and an explicit `@model({ description })` —
94
+ the explicit string must win and the JSDoc must be absent everywhere."""
95
+ manifest = _manifest()
96
+ group = manifest["entities"]["GroupModel"]
97
+ assert group["description"] == "A group that users belong to."
98
+ # The precedence-control JSDoc must not have leaked into the manifest.
99
+ assert "PRECEDENCE CONTROL" not in json.dumps(manifest)