velocity-python 0.1.111__tar.gz → 0.1.113__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 (302) hide show
  1. {velocity_python-0.1.111/src/velocity_python.egg-info → velocity_python-0.1.113}/PKG-INFO +1 -1
  2. {velocity_python-0.1.111 → velocity_python-0.1.113}/pyproject.toml +1 -1
  3. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/__init__.py +1 -1
  4. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/aws/handlers/context.py +6 -1
  5. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/aws/mirror.py +7 -3
  6. velocity_python-0.1.113/src/velocity/db/core/lazy_engine.py +116 -0
  7. {velocity_python-0.1.111 → velocity_python-0.1.113/src/velocity_python.egg-info}/PKG-INFO +1 -1
  8. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity_python.egg-info/SOURCES.txt +2 -0
  9. velocity_python-0.1.113/tests/test_lazy_engine.py +179 -0
  10. {velocity_python-0.1.111 → velocity_python-0.1.113}/LICENSE +0 -0
  11. {velocity_python-0.1.111 → velocity_python-0.1.113}/README.md +0 -0
  12. {velocity_python-0.1.111 → velocity_python-0.1.113}/setup.cfg +0 -0
  13. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/aws/__init__.py +0 -0
  14. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/aws/amplify.py +0 -0
  15. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/aws/amplify_build.py +0 -0
  16. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/aws/assets/__init__.py +0 -0
  17. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/aws/assets/backfill.py +0 -0
  18. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/aws/assets/indexing.py +0 -0
  19. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/aws/assets/references.py +0 -0
  20. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/aws/assets/service.py +0 -0
  21. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/aws/assets/usage_index.py +0 -0
  22. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/aws/blobs.py +0 -0
  23. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/aws/capabilities/__init__.py +0 -0
  24. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/aws/capabilities/base.py +0 -0
  25. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/aws/capabilities/dispatch.py +0 -0
  26. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/aws/capabilities/infra.py +0 -0
  27. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/aws/capabilities/jobs.py +0 -0
  28. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/aws/capabilities/provisioning.py +0 -0
  29. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/aws/capabilities/retention.py +0 -0
  30. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/aws/capabilities/security.py +0 -0
  31. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/aws/capabilities/single_session.py +0 -0
  32. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/aws/deploy/__init__.py +0 -0
  33. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/aws/deploy/config.py +0 -0
  34. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/aws/deploy/operations.py +0 -0
  35. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/aws/deploy/policies.py +0 -0
  36. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/aws/deploy/reconcile.py +0 -0
  37. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/aws/deploy/targets.py +0 -0
  38. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/aws/dirty_pipeline.py +0 -0
  39. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/aws/email.py +0 -0
  40. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/aws/feature_flags.py +0 -0
  41. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/aws/handlers/__init__.py +0 -0
  42. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/aws/handlers/base_handler.py +0 -0
  43. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/aws/handlers/context_factory.py +0 -0
  44. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/aws/handlers/exceptions.py +0 -0
  45. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/aws/handlers/lambda_handler.py +0 -0
  46. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/aws/handlers/masquerade.py +0 -0
  47. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/aws/handlers/mixins/__init__.py +0 -0
  48. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/aws/handlers/mixins/data_service.py +0 -0
  49. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/aws/handlers/mixins/job_handler.py +0 -0
  50. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/aws/handlers/mixins/session_control.py +0 -0
  51. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/aws/handlers/mixins/web_handler.py +0 -0
  52. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/aws/handlers/perf.py +0 -0
  53. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/aws/handlers/response.py +0 -0
  54. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/aws/handlers/sqs_handler.py +0 -0
  55. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/aws/job_lifecycle.py +0 -0
  56. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/aws/job_results.py +0 -0
  57. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/aws/s3.py +0 -0
  58. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/aws/sms.py +0 -0
  59. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/aws/ssm_config.py +0 -0
  60. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/aws/tests/__init__.py +0 -0
  61. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/aws/tests/test_amplify_build_policy_size.py +0 -0
  62. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/aws/tests/test_amplify_build_shim.py +0 -0
  63. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/aws/tests/test_base_handler_error_response.py +0 -0
  64. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/aws/tests/test_deploy_policies.py +0 -0
  65. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/aws/tests/test_deploy_reconcile.py +0 -0
  66. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/aws/tests/test_email.py +0 -0
  67. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/aws/tests/test_lambda_handler_json_serialization.py +0 -0
  68. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/aws/tests/test_response.py +0 -0
  69. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/aws/tests/test_sms.py +0 -0
  70. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/cache.py +0 -0
  71. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/__init__.py +0 -0
  72. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/core/__init__.py +0 -0
  73. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/core/async_support.py +0 -0
  74. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/core/column.py +0 -0
  75. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/core/database.py +0 -0
  76. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/core/decorators.py +0 -0
  77. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/core/engine.py +0 -0
  78. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/core/jsonproxy.py +0 -0
  79. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/core/result.py +0 -0
  80. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/core/row.py +0 -0
  81. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/core/sequence.py +0 -0
  82. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/core/table.py +0 -0
  83. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/core/transaction.py +0 -0
  84. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/core/view.py +0 -0
  85. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/exceptions.py +0 -0
  86. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/maintenance.py +0 -0
  87. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/migrations.py +0 -0
  88. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/servers/__init__.py +0 -0
  89. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/servers/base/__init__.py +0 -0
  90. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/servers/base/initializer.py +0 -0
  91. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/servers/base/operators.py +0 -0
  92. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/servers/base/sql.py +0 -0
  93. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/servers/base/types.py +0 -0
  94. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/servers/mysql/__init__.py +0 -0
  95. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/servers/mysql/operators.py +0 -0
  96. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/servers/mysql/reserved.py +0 -0
  97. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/servers/mysql/sql.py +0 -0
  98. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/servers/mysql/types.py +0 -0
  99. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/servers/postgres/__init__.py +0 -0
  100. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/servers/postgres/operators.py +0 -0
  101. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/servers/postgres/reserved.py +0 -0
  102. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/servers/postgres/sql.py +0 -0
  103. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/servers/postgres/types.py +0 -0
  104. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/servers/sqlite/__init__.py +0 -0
  105. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/servers/sqlite/operators.py +0 -0
  106. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/servers/sqlite/reserved.py +0 -0
  107. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/servers/sqlite/sql.py +0 -0
  108. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/servers/sqlite/types.py +0 -0
  109. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/servers/sqlserver/__init__.py +0 -0
  110. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/servers/sqlserver/operators.py +0 -0
  111. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/servers/sqlserver/reserved.py +0 -0
  112. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/servers/sqlserver/sql.py +0 -0
  113. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/servers/sqlserver/types.py +0 -0
  114. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/servers/tablehelper.py +0 -0
  115. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/tests/__init__.py +0 -0
  116. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/tests/common_db_test.py +0 -0
  117. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/tests/postgres/__init__.py +0 -0
  118. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/tests/postgres/common.py +0 -0
  119. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/tests/postgres/conftest.py +0 -0
  120. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/tests/postgres/test_column.py +0 -0
  121. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/tests/postgres/test_connections.py +0 -0
  122. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/tests/postgres/test_database.py +0 -0
  123. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/tests/postgres/test_engine.py +0 -0
  124. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/tests/postgres/test_general_usage.py +0 -0
  125. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/tests/postgres/test_imports.py +0 -0
  126. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/tests/postgres/test_result.py +0 -0
  127. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/tests/postgres/test_row.py +0 -0
  128. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/tests/postgres/test_row_comprehensive.py +0 -0
  129. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/tests/postgres/test_schema_locking.py +0 -0
  130. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/tests/postgres/test_schema_locking_unit.py +0 -0
  131. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/tests/postgres/test_sequence.py +0 -0
  132. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/tests/postgres/test_sql_comprehensive.py +0 -0
  133. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/tests/postgres/test_table.py +0 -0
  134. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/tests/postgres/test_table_comprehensive.py +0 -0
  135. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/tests/postgres/test_transaction.py +0 -0
  136. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/tests/sql/__init__.py +0 -0
  137. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/tests/sql/common.py +0 -0
  138. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/tests/sql/test_postgres_select_advanced.py +0 -0
  139. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/tests/sql/test_postgres_select_variances.py +0 -0
  140. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/tests/test_cursor_rowcount_fix.py +0 -0
  141. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/tests/test_db_utils.py +0 -0
  142. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/tests/test_postgres.py +0 -0
  143. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/tests/test_postgres_unchanged.py +0 -0
  144. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/tests/test_process_error_robustness.py +0 -0
  145. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/tests/test_result_caching.py +0 -0
  146. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/tests/test_result_sql_aware.py +0 -0
  147. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/tests/test_row_get_missing_column.py +0 -0
  148. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/tests/test_schema_locking_initializers.py +0 -0
  149. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/tests/test_schema_locking_simple.py +0 -0
  150. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/tests/test_sql_builder.py +0 -0
  151. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/tests/test_tablehelper.py +0 -0
  152. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/tests/test_view_helper.py +0 -0
  153. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/db/utils.py +0 -0
  154. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/logging.py +0 -0
  155. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/misc/__init__.py +0 -0
  156. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/misc/conv/__init__.py +0 -0
  157. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/misc/conv/iconv.py +0 -0
  158. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/misc/conv/oconv.py +0 -0
  159. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/misc/db.py +0 -0
  160. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/misc/export.py +0 -0
  161. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/misc/format.py +0 -0
  162. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/misc/mail.py +0 -0
  163. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/misc/merge.py +0 -0
  164. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/misc/pdf.py +0 -0
  165. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/misc/tests/__init__.py +0 -0
  166. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/misc/tests/test_db.py +0 -0
  167. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/misc/tests/test_fix.py +0 -0
  168. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/misc/tests/test_format.py +0 -0
  169. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/misc/tests/test_iconv.py +0 -0
  170. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/misc/tests/test_mail_send.py +0 -0
  171. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/misc/tests/test_merge.py +0 -0
  172. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/misc/tests/test_oconv.py +0 -0
  173. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/misc/tests/test_original_error.py +0 -0
  174. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/misc/tests/test_timer.py +0 -0
  175. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/misc/timer.py +0 -0
  176. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/misc/tools.py +0 -0
  177. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/nosql/__init__.py +0 -0
  178. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/nosql/core/__init__.py +0 -0
  179. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/nosql/core/capabilities.py +0 -0
  180. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/nosql/core/store.py +0 -0
  181. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/nosql/core/where.py +0 -0
  182. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/nosql/exceptions.py +0 -0
  183. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/nosql/servers/__init__.py +0 -0
  184. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/nosql/servers/base/__init__.py +0 -0
  185. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/nosql/servers/cassandra/__init__.py +0 -0
  186. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/nosql/servers/cassandra/translation.py +0 -0
  187. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/nosql/servers/couchbase/__init__.py +0 -0
  188. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/nosql/servers/couchbase/translation.py +0 -0
  189. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/nosql/servers/dynamodb/__init__.py +0 -0
  190. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/nosql/servers/dynamodb/translation.py +0 -0
  191. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/nosql/servers/elasticsearch/__init__.py +0 -0
  192. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/nosql/servers/elasticsearch/translation.py +0 -0
  193. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/nosql/servers/memory/__init__.py +0 -0
  194. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/nosql/servers/mongodb/__init__.py +0 -0
  195. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/nosql/servers/mongodb/translation.py +0 -0
  196. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/nosql/servers/redis/__init__.py +0 -0
  197. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/payment/__init__.py +0 -0
  198. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/payment/authorizenet_adapter.py +0 -0
  199. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/payment/authorizenet_mirror.py +0 -0
  200. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/payment/base_adapter.py +0 -0
  201. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/payment/braintree_adapter.py +0 -0
  202. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/payment/braintree_mirror.py +0 -0
  203. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/payment/charge_rules.py +0 -0
  204. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/payment/stripe_adapter.py +0 -0
  205. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity/payment/stripe_mirror.py +0 -0
  206. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity_python.egg-info/dependency_links.txt +0 -0
  207. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity_python.egg-info/entry_points.txt +0 -0
  208. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity_python.egg-info/requires.txt +0 -0
  209. {velocity_python-0.1.111 → velocity_python-0.1.113}/src/velocity_python.egg-info/top_level.txt +0 -0
  210. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_access_error_403.py +0 -0
  211. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_activity_tracking_aborted_tx.py +0 -0
  212. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_amplify_build.py +0 -0
  213. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_asset_indexing.py +0 -0
  214. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_asset_references.py +0 -0
  215. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_assets_service.py +0 -0
  216. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_async_support.py +0 -0
  217. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_batch_operations.py +0 -0
  218. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_blob_store.py +0 -0
  219. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_capabilities.py +0 -0
  220. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_capability_catalog.py +0 -0
  221. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_cognito_user_cache.py +0 -0
  222. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_column_tx_arg.py +0 -0
  223. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_concurrency_safety.py +0 -0
  224. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_connection_pool.py +0 -0
  225. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_connection_resilience.py +0 -0
  226. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_context_flags_loader.py +0 -0
  227. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_context_job_descriptions.py +0 -0
  228. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_data_service_query_cap.py +0 -0
  229. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_data_service_renumber.py +0 -0
  230. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_data_service_save_as.py +0 -0
  231. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_db_credentials_ssm_cascade.py +0 -0
  232. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_db_maintenance.py +0 -0
  233. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_decorators.py +0 -0
  234. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_delete_hook_fk_blocked.py +0 -0
  235. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_dirty_pipeline_fast_path.py +0 -0
  236. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_email_processing.py +0 -0
  237. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_enqueue_send_failures.py +0 -0
  238. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_feature_flags.py +0 -0
  239. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_get_cognito_user_provider.py +0 -0
  240. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_http_handler_rollback.py +0 -0
  241. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_iconv_money_to_cents.py +0 -0
  242. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_identifier_injection_guard.py +0 -0
  243. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_job_handler.py +0 -0
  244. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_job_lifecycle.py +0 -0
  245. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_job_results.py +0 -0
  246. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_json_columns.py +0 -0
  247. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_jsonb_dict_adapter.py +0 -0
  248. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_lambda_handler.py +0 -0
  249. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_lambda_handler_auth.py +0 -0
  250. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_lambda_handler_masquerade.py +0 -0
  251. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_lambda_handler_user_cache.py +0 -0
  252. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_masquerade_grant.py +0 -0
  253. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_mirror.py +0 -0
  254. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_mixins_import.py +0 -0
  255. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_n_plus_one.py +0 -0
  256. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_nosql_dynamodb.py +0 -0
  257. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_nosql_memory.py +0 -0
  258. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_nosql_mongodb.py +0 -0
  259. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_nosql_redis.py +0 -0
  260. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_nosql_translation.py +0 -0
  261. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_nosql_where.py +0 -0
  262. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_observability.py +0 -0
  263. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_on_commit.py +0 -0
  264. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_payment_authorizenet_adapter.py +0 -0
  265. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_payment_braintree_adapter.py +0 -0
  266. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_payment_braintree_mirror.py +0 -0
  267. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_payment_mirror_empty_table.py +0 -0
  268. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_payment_profile_sorting.py +0 -0
  269. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_payment_stripe_adapter.py +0 -0
  270. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_pdf.py +0 -0
  271. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_prepared_statements.py +0 -0
  272. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_psycopg3_upgrade.py +0 -0
  273. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_query_cache.py +0 -0
  274. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_query_missing_table_unlocked.py +0 -0
  275. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_read_cache.py +0 -0
  276. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_response.py +0 -0
  277. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_restricted_direct_tables.py +0 -0
  278. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_retry_side_effect_guard.py +0 -0
  279. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_return_default_safety.py +0 -0
  280. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_row_batch_update.py +0 -0
  281. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_row_cache_staleness.py +0 -0
  282. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_schema_migrations.py +0 -0
  283. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_security_capability.py +0 -0
  284. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_security_hardening.py +0 -0
  285. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_server_cursor.py +0 -0
  286. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_session_control.py +0 -0
  287. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_single_autocommit_safety.py +0 -0
  288. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_single_session_capability.py +0 -0
  289. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_spreadsheet_functions.py +0 -0
  290. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_sqlite_backend.py +0 -0
  291. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_sqs_per_record_transactions.py +0 -0
  292. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_ssm_config.py +0 -0
  293. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_store_user_data.py +0 -0
  294. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_sys_modified_count_postgres_demo.py +0 -0
  295. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_table_alter.py +0 -0
  296. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_table_find_cache.py +0 -0
  297. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_table_purge.py +0 -0
  298. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_transaction_class_wrapping.py +0 -0
  299. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_transaction_commit_and_ownership.py +0 -0
  300. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_transaction_edge_cases.py +0 -0
  301. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_where_clause_validation.py +0 -0
  302. {velocity_python-0.1.111 → velocity_python-0.1.113}/tests/test_write_hook_create_flow.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: velocity-python
3
- Version: 0.1.111
3
+ Version: 0.1.113
4
4
  Summary: A rapid application development library for interfacing with data storage
5
5
  Author-email: Velocity Team <info@codeclubs.org>
6
6
  License-Expression: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "velocity-python"
7
- version = "0.1.111"
7
+ version = "0.1.113"
8
8
  authors = [
9
9
  { name="Velocity Team", email="info@codeclubs.org" },
10
10
  ]
@@ -1,4 +1,4 @@
1
- __version__ = version = "0.1.111"
1
+ __version__ = version = "0.1.113"
2
2
 
3
3
  import importlib as _importlib
4
4
 
@@ -18,8 +18,13 @@ from velocity.aws.ssm_config import get_region as config_get_region
18
18
  from velocity.aws.ssm_config import get_stage as config_get_stage
19
19
  from velocity.logging import get_logger
20
20
  from velocity.cache import memo
21
+ from velocity.db.core.lazy_engine import LazyEngine
21
22
 
22
- engine = velocity.db.postgres.initialize()
23
+ # Built on first use, not at import: importing a handler must not demand DB
24
+ # configuration (see LazyEngine). ``@engine.transaction`` on Context below is
25
+ # honoured lazily — the first call of a ``tx``-taking method constructs the
26
+ # engine and dispatches through the real decorator.
27
+ engine = LazyEngine(velocity.db.postgres.initialize)
23
28
 
24
29
 
25
30
  cognito_client = boto3.client("cognito-idp")
@@ -40,9 +40,13 @@ def alternate_engine(alternate_db: str | None = None):
40
40
  """Engine for the alternate database — same instance, other ``database``.
41
41
 
42
42
  Host/port/user/password are inherited from the running config, so no
43
- separate credentials are needed; only the database name changes (the
44
- ``DBAlternate`` config key by default). Cached per database name so
45
- repeated mirrors in one process reuse the connection.
43
+ separate credentials are needed; only the database name changes: the
44
+ ``DBAlternate`` config key, which the site factory's
45
+ ``provision-capabilities`` derives on every deploy-backend from the
46
+ sibling environment's ``DBDatabase`` (``/{Project}/{env}/DBAlternate`` =
47
+ the other stage's database) — nothing to declare by hand inside the
48
+ factory. Cached per database name so repeated mirrors in one process
49
+ reuse the connection.
46
50
  """
47
51
  from velocity.aws import ssm_config
48
52
  from velocity.db.servers import postgres
@@ -0,0 +1,116 @@
1
+ """A module-level engine that is built on first use, not at import.
2
+
3
+ ``velocity.aws.handlers.context`` used to run ``postgres.initialize()`` at
4
+ import, so merely importing a handler (or collecting a test that touches one)
5
+ demanded DB configuration — three unrelated test suites ended up stubbing DB
6
+ env vars just to import the package (IMPROVEMENT_BACKLOG, 2026-08-14).
7
+
8
+ ``LazyEngine`` is a drop-in stand-in for that module attribute:
9
+
10
+ * attribute access (``engine.schema_locked``, ``engine.transaction()``) builds
11
+ the real engine once, then delegates;
12
+ * ``@engine.transaction`` still works as a function, ``classmethod`` and class
13
+ decorator — decoration never builds the engine; the first *call* of a
14
+ decorated callable that declares ``tx`` does, and then dispatches through the
15
+ real ``Engine.transaction`` so retry/commit semantics are unchanged;
16
+ * callables that do not declare ``tx`` are returned untouched, exactly as the
17
+ real decorator would run them, so using them never needs configuration.
18
+
19
+ The configuration error a missing DB env produces therefore surfaces at first
20
+ use, with the same message, instead of at import.
21
+ """
22
+
23
+ from __future__ import annotations
24
+
25
+ import inspect
26
+ from functools import wraps
27
+ from typing import Any, Callable
28
+
29
+
30
+ class LazyEngine:
31
+ """Proxy that constructs ``factory()`` on first use and delegates to it."""
32
+
33
+ def __init__(self, factory: Callable[[], Any]):
34
+ self._factory = factory
35
+ self._engine = None
36
+
37
+ # ── construction ──────────────────────────────────────────────────────
38
+
39
+ def resolve(self):
40
+ """The real engine, built on the first call."""
41
+ if self._engine is None:
42
+ self._engine = self._factory()
43
+ return self._engine
44
+
45
+ @property
46
+ def initialized(self) -> bool:
47
+ """True once the real engine has been built."""
48
+ return self._engine is not None
49
+
50
+ def __getattr__(self, name: str):
51
+ # Only reached for names not found on the proxy itself.
52
+ return getattr(self.resolve(), name)
53
+
54
+ def __repr__(self) -> str:
55
+ state = repr(self._engine) if self._engine is not None else "uninitialized"
56
+ return f"LazyEngine({state})"
57
+
58
+ # ── @engine.transaction ───────────────────────────────────────────────
59
+
60
+ def transaction(self, func_or_cls=None):
61
+ """Mirror ``Engine.transaction``: no args → a Transaction on the real
62
+ engine; a function / classmethod / class → wrapped lazily."""
63
+ if func_or_cls is None:
64
+ return self.resolve().transaction()
65
+ if isinstance(func_or_cls, classmethod):
66
+ return classmethod(self._lazy_function(func_or_cls.__func__))
67
+ if inspect.isclass(func_or_cls):
68
+ return self._lazy_class(func_or_cls)
69
+ if inspect.isfunction(func_or_cls) or inspect.ismethod(func_or_cls):
70
+ return self._lazy_function(func_or_cls)
71
+ return self.resolve().transaction(func_or_cls)
72
+
73
+ def _lazy_function(self, func):
74
+ names = list(inspect.signature(func).parameters.keys())
75
+ if "_tx" in names:
76
+ # Same contract as Engine.transaction, enforced at decoration time.
77
+ raise NameError(
78
+ f"In function {func.__name__}, '_tx' is not allowed as a parameter."
79
+ )
80
+ if "tx" not in names:
81
+ # Engine.transaction would call such a function straight through;
82
+ # returning it untouched is the same behaviour with no engine needed.
83
+ return func
84
+
85
+ wrapped = None
86
+
87
+ @wraps(func)
88
+ def lazy(*args, **kwds):
89
+ nonlocal wrapped
90
+ if wrapped is None:
91
+ wrapped = self.resolve().transaction(func)
92
+ return wrapped(*args, **kwds)
93
+
94
+ return lazy
95
+
96
+ def _lazy_class(self, cls):
97
+ # Same shape as Engine.transaction's class branch: a subclass carrying
98
+ # wrapped copies of every public callable, descriptors preserved.
99
+ new_cls = type(cls.__name__, (cls,), {})
100
+ for attr_name in dir(cls):
101
+ if attr_name.startswith("__") and attr_name.endswith("__"):
102
+ continue
103
+ raw = inspect.getattr_static(cls, attr_name, None)
104
+ if isinstance(raw, staticmethod):
105
+ setattr(
106
+ new_cls, attr_name, staticmethod(self._lazy_function(raw.__func__))
107
+ )
108
+ elif isinstance(raw, classmethod):
109
+ setattr(
110
+ new_cls, attr_name, classmethod(self._lazy_function(raw.__func__))
111
+ )
112
+ else:
113
+ attr = getattr(cls, attr_name)
114
+ if callable(attr):
115
+ setattr(new_cls, attr_name, self._lazy_function(attr))
116
+ return new_cls
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: velocity-python
3
- Version: 0.1.111
3
+ Version: 0.1.113
4
4
  Summary: A rapid application development library for interfacing with data storage
5
5
  Author-email: Velocity Team <info@codeclubs.org>
6
6
  License-Expression: MIT
@@ -75,6 +75,7 @@ src/velocity/db/core/database.py
75
75
  src/velocity/db/core/decorators.py
76
76
  src/velocity/db/core/engine.py
77
77
  src/velocity/db/core/jsonproxy.py
78
+ src/velocity/db/core/lazy_engine.py
78
79
  src/velocity/db/core/result.py
79
80
  src/velocity/db/core/row.py
80
81
  src/velocity/db/core/sequence.py
@@ -245,6 +246,7 @@ tests/test_lambda_handler.py
245
246
  tests/test_lambda_handler_auth.py
246
247
  tests/test_lambda_handler_masquerade.py
247
248
  tests/test_lambda_handler_user_cache.py
249
+ tests/test_lazy_engine.py
248
250
  tests/test_masquerade_grant.py
249
251
  tests/test_mirror.py
250
252
  tests/test_mixins_import.py
@@ -0,0 +1,179 @@
1
+ """LazyEngine: the handler package imports without DB configuration, the
2
+ engine is built exactly once on first use, and @engine.transaction keeps the
3
+ real decorator's semantics (tx injected on call, static/class methods intact,
4
+ tx-less callables untouched)."""
5
+
6
+ import os
7
+ import subprocess
8
+ import sys
9
+
10
+ import pytest
11
+
12
+ import velocity
13
+ from velocity.db.core.lazy_engine import LazyEngine
14
+
15
+ SENTINEL_TX = object()
16
+
17
+
18
+ class FakeEngine:
19
+ """Stands in for Engine: transaction(func) injects SENTINEL_TX when the
20
+ caller passed no tx, transaction() returns a marker."""
21
+
22
+ schema_locked = "fake-flag"
23
+
24
+ def transaction(self, func_or_cls=None):
25
+ if func_or_cls is None:
26
+ return "TX"
27
+
28
+ def wrapper(*args, **kwds):
29
+ if "tx" not in kwds:
30
+ kwds["tx"] = SENTINEL_TX
31
+ return func_or_cls(*args, **kwds)
32
+
33
+ return wrapper
34
+
35
+
36
+ def make_lazy():
37
+ calls = []
38
+
39
+ def factory():
40
+ calls.append(1)
41
+ return FakeEngine()
42
+
43
+ return LazyEngine(factory), calls
44
+
45
+
46
+ def test_construction_and_decoration_do_not_build_the_engine():
47
+ lazy, calls = make_lazy()
48
+
49
+ @lazy.transaction
50
+ class Ctx:
51
+ def with_tx(self, tx=None, value=None):
52
+ return tx, value
53
+
54
+ def plain(self, value):
55
+ return value
56
+
57
+ @staticmethod
58
+ def static(tx=None):
59
+ return tx
60
+
61
+ @classmethod
62
+ def klass(cls, tx=None):
63
+ return cls, tx
64
+
65
+ assert calls == []
66
+ assert not lazy.initialized
67
+ assert Ctx.__name__ == "Ctx"
68
+
69
+
70
+ def test_first_tx_call_builds_once_and_injects_tx():
71
+ lazy, calls = make_lazy()
72
+
73
+ @lazy.transaction
74
+ class Ctx:
75
+ def with_tx(self, tx=None, value=None):
76
+ return tx, value
77
+
78
+ ctx = Ctx()
79
+ assert ctx.with_tx(value=1) == (SENTINEL_TX, 1)
80
+ assert ctx.with_tx(value=2) == (SENTINEL_TX, 2)
81
+ assert calls == [1]
82
+ assert lazy.initialized
83
+
84
+
85
+ def test_callables_without_tx_never_need_the_engine():
86
+ lazy, calls = make_lazy()
87
+
88
+ @lazy.transaction
89
+ class Ctx:
90
+ def plain(self, value):
91
+ return value * 2
92
+
93
+ assert Ctx().plain(21) == 42
94
+ assert calls == []
95
+
96
+
97
+ def test_static_and_class_methods_keep_their_nature():
98
+ lazy, _calls = make_lazy()
99
+
100
+ @lazy.transaction
101
+ class Ctx:
102
+ @staticmethod
103
+ def static(tx=None):
104
+ return tx
105
+
106
+ @classmethod
107
+ def klass(cls, tx=None):
108
+ return cls.__name__, tx
109
+
110
+ assert Ctx.static() is SENTINEL_TX
111
+ assert Ctx().static() is SENTINEL_TX
112
+ assert Ctx.klass() == ("Ctx", SENTINEL_TX)
113
+
114
+
115
+ def test_function_and_classmethod_decoration():
116
+ lazy, calls = make_lazy()
117
+
118
+ @lazy.transaction
119
+ def work(tx=None, n=0):
120
+ return tx, n
121
+
122
+ assert calls == []
123
+ assert work(n=3) == (SENTINEL_TX, 3)
124
+ assert calls == [1]
125
+
126
+
127
+ def test_tx_underscore_parameter_is_rejected_at_decoration_without_building():
128
+ lazy, calls = make_lazy()
129
+ with pytest.raises(NameError):
130
+
131
+ @lazy.transaction
132
+ def bad(_tx=None):
133
+ return _tx
134
+
135
+ assert calls == []
136
+
137
+
138
+ def test_attribute_access_and_bare_transaction_delegate():
139
+ lazy, calls = make_lazy()
140
+ assert lazy.schema_locked == "fake-flag"
141
+ assert lazy.transaction() == "TX"
142
+ assert calls == [1]
143
+ assert "LazyEngine(" in repr(lazy)
144
+
145
+
146
+ def _run_without_db_env(code: str) -> subprocess.CompletedProcess:
147
+ env = {k: v for k, v in os.environ.items() if not k.startswith("DB")}
148
+ src = os.path.dirname(os.path.dirname(os.path.abspath(velocity.__file__)))
149
+ env["PYTHONPATH"] = src + os.pathsep + env.get("PYTHONPATH", "")
150
+ return subprocess.run(
151
+ [sys.executable, "-c", code],
152
+ env=env,
153
+ capture_output=True,
154
+ text=True,
155
+ timeout=120,
156
+ )
157
+
158
+
159
+ def test_handlers_import_without_db_configuration():
160
+ result = _run_without_db_env(
161
+ "import velocity.aws.handlers.context as c\n"
162
+ "assert not c.engine.initialized, 'engine built at import'\n"
163
+ "print('imported')"
164
+ )
165
+ assert result.returncode == 0, result.stderr
166
+ assert "imported" in result.stdout
167
+
168
+
169
+ def test_missing_configuration_surfaces_on_first_use_not_import():
170
+ result = _run_without_db_env(
171
+ "import velocity.aws.handlers.context as c\n"
172
+ "try:\n"
173
+ " c.engine.transaction()\n"
174
+ "except Exception as e:\n"
175
+ " print('FIRST_USE:', type(e).__name__, e)\n"
176
+ )
177
+ assert result.returncode == 0, result.stderr
178
+ assert "FIRST_USE:" in result.stdout
179
+ assert "Missing required configuration keys" in result.stdout