storepy 4.4.2__tar.gz → 4.4.3__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 (89) hide show
  1. {storepy-4.4.2/src/storepy.egg-info → storepy-4.4.3}/PKG-INFO +1 -1
  2. {storepy-4.4.2 → storepy-4.4.3}/pyproject.toml +1 -1
  3. {storepy-4.4.2 → storepy-4.4.3}/src/py_store/__init__.py +2 -0
  4. {storepy-4.4.2 → storepy-4.4.3}/src/py_store/crud/exec.py +9 -1
  5. {storepy-4.4.2 → storepy-4.4.3}/src/py_store/permission.py +15 -0
  6. {storepy-4.4.2 → storepy-4.4.3/src/storepy.egg-info}/PKG-INFO +1 -1
  7. {storepy-4.4.2 → storepy-4.4.3}/tests/test_require_context.py +6 -6
  8. {storepy-4.4.2 → storepy-4.4.3}/LICENSE +0 -0
  9. {storepy-4.4.2 → storepy-4.4.3}/README.md +0 -0
  10. {storepy-4.4.2 → storepy-4.4.3}/setup.cfg +0 -0
  11. {storepy-4.4.2 → storepy-4.4.3}/src/py_store/ask.py +0 -0
  12. {storepy-4.4.2 → storepy-4.4.3}/src/py_store/ask_knowledge.md +0 -0
  13. {storepy-4.4.2 → storepy-4.4.3}/src/py_store/bootstrap.py +0 -0
  14. {storepy-4.4.2 → storepy-4.4.3}/src/py_store/cache.py +0 -0
  15. {storepy-4.4.2 → storepy-4.4.3}/src/py_store/core.py +0 -0
  16. {storepy-4.4.2 → storepy-4.4.3}/src/py_store/crud/__init__.py +0 -0
  17. {storepy-4.4.2 → storepy-4.4.3}/src/py_store/crud/id.py +0 -0
  18. {storepy-4.4.2 → storepy-4.4.3}/src/py_store/crud/mutation.py +0 -0
  19. {storepy-4.4.2 → storepy-4.4.3}/src/py_store/crud/query.py +0 -0
  20. {storepy-4.4.2 → storepy-4.4.3}/src/py_store/crud/triggers.py +0 -0
  21. {storepy-4.4.2 → storepy-4.4.3}/src/py_store/crud/write.py +0 -0
  22. {storepy-4.4.2 → storepy-4.4.3}/src/py_store/datasource.py +0 -0
  23. {storepy-4.4.2 → storepy-4.4.3}/src/py_store/ddl.py +0 -0
  24. {storepy-4.4.2 → storepy-4.4.3}/src/py_store/executors/__init__.py +0 -0
  25. {storepy-4.4.2 → storepy-4.4.3}/src/py_store/executors/_values.py +0 -0
  26. {storepy-4.4.2 → storepy-4.4.3}/src/py_store/executors/mongo.py +0 -0
  27. {storepy-4.4.2 → storepy-4.4.3}/src/py_store/executors/mysql.py +0 -0
  28. {storepy-4.4.2 → storepy-4.4.3}/src/py_store/executors/postgres.py +0 -0
  29. {storepy-4.4.2 → storepy-4.4.3}/src/py_store/executors/sqlite.py +0 -0
  30. {storepy-4.4.2 → storepy-4.4.3}/src/py_store/feedback.py +0 -0
  31. {storepy-4.4.2 → storepy-4.4.3}/src/py_store/introspect/__init__.py +0 -0
  32. {storepy-4.4.2 → storepy-4.4.3}/src/py_store/introspect/mysql.py +0 -0
  33. {storepy-4.4.2 → storepy-4.4.3}/src/py_store/introspect/postgres.py +0 -0
  34. {storepy-4.4.2 → storepy-4.4.3}/src/py_store/introspect/sqlite.py +0 -0
  35. {storepy-4.4.2 → storepy-4.4.3}/src/py_store/llm.py +0 -0
  36. {storepy-4.4.2 → storepy-4.4.3}/src/py_store/load.py +0 -0
  37. {storepy-4.4.2 → storepy-4.4.3}/src/py_store/local/__init__.py +0 -0
  38. {storepy-4.4.2 → storepy-4.4.3}/src/py_store/local/handle.py +0 -0
  39. {storepy-4.4.2 → storepy-4.4.3}/src/py_store/local/store.py +0 -0
  40. {storepy-4.4.2 → storepy-4.4.3}/src/py_store/metadef.py +0 -0
  41. {storepy-4.4.2 → storepy-4.4.3}/src/py_store/naming.py +0 -0
  42. {storepy-4.4.2 → storepy-4.4.3}/src/py_store/resource/__init__.py +0 -0
  43. {storepy-4.4.2 → storepy-4.4.3}/src/py_store/resource/providers/__init__.py +0 -0
  44. {storepy-4.4.2 → storepy-4.4.3}/src/py_store/resource/providers/local.py +0 -0
  45. {storepy-4.4.2 → storepy-4.4.3}/src/py_store/resource/providers/s3.py +0 -0
  46. {storepy-4.4.2 → storepy-4.4.3}/src/py_store/scheduler/__init__.py +0 -0
  47. {storepy-4.4.2 → storepy-4.4.3}/src/py_store/schema.py +0 -0
  48. {storepy-4.4.2 → storepy-4.4.3}/src/py_store/scope.py +0 -0
  49. {storepy-4.4.2 → storepy-4.4.3}/src/py_store/secure.py +0 -0
  50. {storepy-4.4.2 → storepy-4.4.3}/src/py_store/sync.py +0 -0
  51. {storepy-4.4.2 → storepy-4.4.3}/src/py_store/workflow.py +0 -0
  52. {storepy-4.4.2 → storepy-4.4.3}/src/storepy.egg-info/SOURCES.txt +0 -0
  53. {storepy-4.4.2 → storepy-4.4.3}/src/storepy.egg-info/dependency_links.txt +0 -0
  54. {storepy-4.4.2 → storepy-4.4.3}/src/storepy.egg-info/requires.txt +0 -0
  55. {storepy-4.4.2 → storepy-4.4.3}/src/storepy.egg-info/top_level.txt +0 -0
  56. {storepy-4.4.2 → storepy-4.4.3}/tests/test_ask.py +0 -0
  57. {storepy-4.4.2 → storepy-4.4.3}/tests/test_cache.py +0 -0
  58. {storepy-4.4.2 → storepy-4.4.3}/tests/test_coverage_margin.py +0 -0
  59. {storepy-4.4.2 → storepy-4.4.3}/tests/test_federation_e2e.py +0 -0
  60. {storepy-4.4.2 → storepy-4.4.3}/tests/test_feedback_flush.py +0 -0
  61. {storepy-4.4.2 → storepy-4.4.3}/tests/test_fns_binding.py +0 -0
  62. {storepy-4.4.2 → storepy-4.4.3}/tests/test_host_contract.py +0 -0
  63. {storepy-4.4.2 → storepy-4.4.3}/tests/test_host_paths.py +0 -0
  64. {storepy-4.4.2 → storepy-4.4.3}/tests/test_load.py +0 -0
  65. {storepy-4.4.2 → storepy-4.4.3}/tests/test_local_store.py +0 -0
  66. {storepy-4.4.2 → storepy-4.4.3}/tests/test_metadef.py +0 -0
  67. {storepy-4.4.2 → storepy-4.4.3}/tests/test_migration.py +0 -0
  68. {storepy-4.4.2 → storepy-4.4.3}/tests/test_mongo_executor.py +0 -0
  69. {storepy-4.4.2 → storepy-4.4.3}/tests/test_mongo_session.py +0 -0
  70. {storepy-4.4.2 → storepy-4.4.3}/tests/test_multi_datasource.py +0 -0
  71. {storepy-4.4.2 → storepy-4.4.3}/tests/test_parity_deny.py +0 -0
  72. {storepy-4.4.2 → storepy-4.4.3}/tests/test_parity_local.py +0 -0
  73. {storepy-4.4.2 → storepy-4.4.3}/tests/test_parity_scope.py +0 -0
  74. {storepy-4.4.2 → storepy-4.4.3}/tests/test_policy_isolation.py +0 -0
  75. {storepy-4.4.2 → storepy-4.4.3}/tests/test_profile.py +0 -0
  76. {storepy-4.4.2 → storepy-4.4.3}/tests/test_py_store.py +0 -0
  77. {storepy-4.4.2 → storepy-4.4.3}/tests/test_raw_sql_and_ddl.py +0 -0
  78. {storepy-4.4.2 → storepy-4.4.3}/tests/test_rbac_host.py +0 -0
  79. {storepy-4.4.2 → storepy-4.4.3}/tests/test_real_backends_e2e.py +0 -0
  80. {storepy-4.4.2 → storepy-4.4.3}/tests/test_resource.py +0 -0
  81. {storepy-4.4.2 → storepy-4.4.3}/tests/test_resource_e2e.py +0 -0
  82. {storepy-4.4.2 → storepy-4.4.3}/tests/test_resource_units.py +0 -0
  83. {storepy-4.4.2 → storepy-4.4.3}/tests/test_scenario_course_platform.py +0 -0
  84. {storepy-4.4.2 → storepy-4.4.3}/tests/test_scenario_manager_transaction.py +0 -0
  85. {storepy-4.4.2 → storepy-4.4.3}/tests/test_scheduler.py +0 -0
  86. {storepy-4.4.2 → storepy-4.4.3}/tests/test_session.py +0 -0
  87. {storepy-4.4.2 → storepy-4.4.3}/tests/test_sql_commit_and_registry.py +0 -0
  88. {storepy-4.4.2 → storepy-4.4.3}/tests/test_triggers.py +0 -0
  89. {storepy-4.4.2 → storepy-4.4.3}/tests/test_workflow.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: storepy
3
- Version: 4.4.2
3
+ Version: 4.4.3
4
4
  Summary: Multi-backend data layer for Python asyncio (MongoDB, MySQL, SQLite, PostgreSQL, local disk): pure JSON schemas, GQL tree queries compiled to a single native query, GROUP BY/HAVING aggregation, computed columns, soft-delete and role-based access control
5
5
  Author-email: leo <coen_ddt@qq.com>
6
6
  License-Expression: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "storepy"
7
- version = "4.4.2"
7
+ version = "4.4.3"
8
8
  description = "Multi-backend data layer for Python asyncio (MongoDB, MySQL, SQLite, PostgreSQL, local disk): pure JSON schemas, GQL tree queries compiled to a single native query, GROUP BY/HAVING aggregation, computed columns, soft-delete and role-based access control"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -350,6 +350,8 @@ class Store:
350
350
  run_as_internal = staticmethod(permission.run_as_internal)
351
351
  # 自定义权限错误(实例可被 store.PermissionError 捕获)
352
352
  PermissionError = permission.PermissionError
353
+ # 上下文缺失错误(实例可被 store.NoContextError 捕获;fail-secure 下未注入 ctx)
354
+ NoContextError = permission.NoContextError
353
355
  # 原生 SQL 入口错误(实例可被 store.RawSqlError 捕获)
354
356
  RawSqlError = datasource.RawSqlError
355
357
  # 原生 Mongo 命令入口错误(实例可被 store.NativeCommandError 捕获)
@@ -19,7 +19,7 @@ from .. import datasource as _datasource
19
19
  from ..executors.mongo import exec_mongo as _exec_mongo
20
20
  from ..feedback import emit as _emit_feedback
21
21
  from ..naming import _to_logical, _to_mongo
22
- from ..permission import PermissionError, get_context
22
+ from ..permission import NoContextError, PermissionError, get_context
23
23
  from ..schema import get as _schema_get
24
24
 
25
25
  _PHASE1_IDS = re.compile(r'^\{\{phase1\.ids\}\}$')
@@ -35,6 +35,11 @@ _PERM_PREFIX = 'ERR_PERMISSION:'
35
35
  # 反馈事件 `profile_blocked`(自动反馈原则:允许拦截,禁止静默)。
36
36
  _PROFILE_PREFIX = 'ERR_TEXT2QUERY:'
37
37
 
38
+ # 上下文缺失识别:core fail-secure(require_context / secure_mode)下无 ctx 时统一携带
39
+ # `ERR_NO_CONTEXT:` 稳定前缀(见 core `command/mod.rs`),同上按前缀映射。命中即抛
40
+ # `NoContextError`(与 PermissionError 同档 403;前缀剥离)。
41
+ _NO_CONTEXT_PREFIX = 'ERR_NO_CONTEXT:'
42
+
38
43
  # 从 core 文案 `... [$feature](功能收缩)` 中提取门禁项名;无 `[..]` 时留白(None),
39
44
  # 不伪造 feature —— 缺值必须显式暴露(禁静默兜底)。
40
45
  _FEATURE_RE = re.compile(r'\[(.+?)\]')
@@ -85,6 +90,7 @@ def _call(fn):
85
90
  """绑定层调用包装:
86
91
 
87
92
  - 权限类错误(``ERR_PERMISSION:`` 前缀)→ ``PermissionError``
93
+ - 上下文缺失(``ERR_NO_CONTEXT:`` 前缀)→ ``NoContextError``(同档 403)
88
94
  - 档位类错误(``ERR_TEXT2QUERY:`` 前缀)→ emit ``profile_blocked`` 反馈 + ``ProfileViolation``
89
95
 
90
96
  按前缀映射而非具体文案(core 文案可自由调整,映射不随文案漂移而静默失效)。
@@ -96,6 +102,8 @@ def _call(fn):
96
102
  msg = str(e)
97
103
  if msg.startswith(_PERM_PREFIX):
98
104
  raise PermissionError(msg[len(_PERM_PREFIX):]) from e
105
+ if msg.startswith(_NO_CONTEXT_PREFIX):
106
+ raise NoContextError(msg[len(_NO_CONTEXT_PREFIX):]) from e
99
107
  if msg.startswith(_PROFILE_PREFIX):
100
108
  detail = msg[len(_PROFILE_PREFIX):]
101
109
  m = _FEATURE_RE.search(detail)
@@ -184,3 +184,18 @@ class PermissionError(Exception):
184
184
  def __init__(self, message, status=403):
185
185
  super().__init__(message)
186
186
  self.status = status
187
+
188
+
189
+ class NoContextError(Exception):
190
+ """上下文缺失错误(fail-secure:require_context 开启 / secure_mode 下未注入 ctx)
191
+
192
+ 与 PermissionError 同属权限上下文类(403):core 抛 ``ERR_NO_CONTEXT:`` 稳定前缀
193
+ (见 core ``command/mod.rs``),由 ``crud.exec._call`` 归一为本类型(前缀已剥离)。
194
+ ``code`` 与 core machine code 对齐(``no_context``),供皮按枚举判定(禁按文案匹配)。
195
+ 对齐 nodejs-store ``NoContextError``。
196
+ """
197
+
198
+ def __init__(self, message, status=403):
199
+ super().__init__(message)
200
+ self.code = 'no_context'
201
+ self.status = status
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: storepy
3
- Version: 4.4.2
3
+ Version: 4.4.3
4
4
  Summary: Multi-backend data layer for Python asyncio (MongoDB, MySQL, SQLite, PostgreSQL, local disk): pure JSON schemas, GQL tree queries compiled to a single native query, GROUP BY/HAVING aggregation, computed columns, soft-delete and role-based access control
5
5
  Author-email: leo <coen_ddt@qq.com>
6
6
  License-Expression: MIT
@@ -123,13 +123,13 @@ def test_require_context_on_blocks_without_ctx():
123
123
  _mock([{'_id': '1', 'title': 'a'}])
124
124
  _sc.set_require_context(True)
125
125
  try:
126
- with pytest.raises(RuntimeError, match='ERR_NO_CONTEXT'):
126
+ with pytest.raises(perm.NoContextError):
127
127
  _run(_crud_mod.query('RcModel{title}'))
128
- with pytest.raises(RuntimeError, match='ERR_NO_CONTEXT'):
128
+ with pytest.raises(perm.NoContextError):
129
129
  _run(_crud_mod.insert('RcModel', {'title': 'x'}))
130
- with pytest.raises(RuntimeError, match='ERR_NO_CONTEXT'):
130
+ with pytest.raises(perm.NoContextError):
131
131
  _run(_crud_mod.update('RcModel', {'_id': '1'}, {'title': 'y'}))
132
- with pytest.raises(RuntimeError, match='ERR_NO_CONTEXT'):
132
+ with pytest.raises(perm.NoContextError):
133
133
  _run(_crud_mod.remove('RcModel', {'_id': '1'}))
134
134
  finally:
135
135
  _sc.set_require_context(False)
@@ -177,9 +177,9 @@ def test_secure_mode_flips_switches_blocks_ctxless():
177
177
  assert secure.is_secure() is True
178
178
  assert _sc.require_context() is True
179
179
  # 开关1 require_context:无 ctx 读写拒绝
180
- with pytest.raises(RuntimeError, match='ERR_NO_CONTEXT'):
180
+ with pytest.raises(perm.NoContextError):
181
181
  _run(_crud_mod.query('RcModel{title}'))
182
- with pytest.raises(RuntimeError, match='ERR_NO_CONTEXT'):
182
+ with pytest.raises(perm.NoContextError):
183
183
  _run(_crud_mod.insert('RcModel', {'title': 'x'}))
184
184
  # 开关3 meta closed:无 ctx 注册新定义拒绝
185
185
  with pytest.raises(RuntimeError, match='ERR_PERMISSION'):
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
File without changes
File without changes