iris-devtester 1.10.2__tar.gz → 1.10.4__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 (242) hide show
  1. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/CLAUDE.md +2 -2
  2. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/CONSTITUTION.md +43 -11
  3. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/LICENSE +1 -1
  4. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/PKG-INFO +2 -2
  5. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/README.md +1 -1
  6. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/docs/TROUBLESHOOTING.md +4 -4
  7. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester/__init__.py +1 -1
  8. iris_devtester-1.10.4/iris_devtester/__main__.py +8 -0
  9. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester/config/defaults.py +2 -2
  10. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester/config/models.py +4 -3
  11. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester/connections/models.py +1 -1
  12. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester/containers/iris_container.py +47 -2
  13. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester/containers/wait_strategies.py +2 -2
  14. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester/fixtures/creator.py +2 -2
  15. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester/fixtures/loader.py +6 -2
  16. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester/integrations/langchain.py +2 -2
  17. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester/utils/dbapi_compat.py +27 -7
  18. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester/utils/enable_callin.py +4 -2
  19. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester/utils/password.py +5 -1
  20. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester/utils/test_connection.py +5 -3
  21. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester.egg-info/PKG-INFO +2 -2
  22. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester.egg-info/SOURCES.txt +1 -0
  23. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester.egg-info/entry_points.txt +1 -0
  24. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/pyproject.toml +2 -1
  25. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/conftest.py +1 -1
  26. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/contract/test_reset_verification_contract.py +3 -3
  27. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/contract/test_retry_logic_contract.py +7 -7
  28. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/integration/test_custom_user_remediation.py +2 -2
  29. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/integration/test_password_preconfig_integration.py +1 -1
  30. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/integration/test_password_reset_both_editions.py +4 -4
  31. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/integration/test_password_reset_macos.py +8 -8
  32. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/integration/test_password_reset_timing.py +6 -6
  33. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/integration/test_password_reset_validation.py +7 -7
  34. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/integration/test_proactive_password_reset.py +1 -1
  35. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/unit/test_connection_info.py +3 -3
  36. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/unit/test_iris_config.py +1 -1
  37. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/AGENTS.md +0 -0
  38. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/MANIFEST.in +0 -0
  39. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/SKILL.md +0 -0
  40. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/docs/GETTING_STARTED.md +0 -0
  41. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/docs/LANGCHAIN_INTEGRATION_QUICKSTART.md +0 -0
  42. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/docs/ROADMAP.md +0 -0
  43. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/docs/SQL_VS_OBJECTSCRIPT.md +0 -0
  44. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/docs/WHATS_NEW_v1.4.0.md +0 -0
  45. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/docs/archive/AGENTIC_SANDBOX_ENHANCEMENT_REPORT.md +0 -0
  46. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/docs/archive/IMPACT_ANALYSIS.md +0 -0
  47. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/docs/archive/IRIS_DEVTESTER_POSITIONING_REPORT.md +0 -0
  48. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/docs/archive/LANGCHAIN_INTEGRATION_STRATEGY.md +0 -0
  49. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/docs/archive/LANGCHAIN_INTEGRATION_TEST_RESULTS.md +0 -0
  50. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/docs/archive/PHASE_2_PLAN.md +0 -0
  51. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/docs/archive/RAG_TEMPLATES_ANALYSIS.md +0 -0
  52. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/docs/archive/README.md +0 -0
  53. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/docs/archive/STRATEGIC_ROADMAP_SUMMARY.md +0 -0
  54. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/docs/archive/feature-009-refactor-plan.md +0 -0
  55. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/docs/development/BUG_REPORT.md +0 -0
  56. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/docs/development/EXTRACTION_SUMMARY.md +0 -0
  57. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/docs/development/FEATURE_006_SUMMARY.md +0 -0
  58. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/docs/development/PHASE2_RESULTS.md +0 -0
  59. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/docs/development/PRE_PUBLISH_REVIEW.md +0 -0
  60. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/docs/development/PROGRESS.md +0 -0
  61. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/docs/development/PYPI_READINESS.md +0 -0
  62. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/docs/development/SESSION-INTEGRATION-TESTS.md +0 -0
  63. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/docs/development/SESSION-SUMMARY.md +0 -0
  64. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/docs/development/STATUS-002-PIVOTED.md +0 -0
  65. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/docs/development/STATUS-003-COMPLETE.md +0 -0
  66. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/docs/development/STATUS.md +0 -0
  67. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/docs/development/V1_COMPLETION_PLAN.md +0 -0
  68. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/docs/development/V1_RELEASE_SUMMARY.md +0 -0
  69. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/docs/features/WSGI-ASGI-SERVER-SETUP.md +0 -0
  70. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/docs/features/agent-skills.md +0 -0
  71. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/docs/features/dat-fixtures.md +0 -0
  72. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/docs/features/docker-compose.md +0 -0
  73. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/docs/features/performance-monitoring.md +0 -0
  74. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/docs/features/testcontainers.md +0 -0
  75. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/docs/learnings/api-contract-synchronization.md +0 -0
  76. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/docs/learnings/callin-service-requirement.md +0 -0
  77. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/docs/learnings/cpf-merge-and-container-restarts.md +0 -0
  78. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/docs/learnings/dat-fixtures-docker-exec-pattern.md +0 -0
  79. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/docs/learnings/dat-restore-database-isolation-problem.md +0 -0
  80. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/docs/learnings/dbapi-bulk-insert-performance-issue.md +0 -0
  81. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/docs/learnings/dbapi-objectscript-limitation.md +0 -0
  82. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/docs/learnings/dbapi-password-reset-limitation.md +0 -0
  83. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/docs/learnings/dbapi-private-module-myth.md +0 -0
  84. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/docs/learnings/docker-hub-image-naming.md +0 -0
  85. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/docs/learnings/embedded-python-considerations.md +0 -0
  86. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/docs/learnings/feature-002-pivot-summary.md +0 -0
  87. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/docs/learnings/integration-test-dbapi-limitation.md +0 -0
  88. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/docs/learnings/iris-backup-patterns.md +0 -0
  89. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/docs/learnings/iris-container-performance.md +0 -0
  90. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/docs/learnings/iris-container-readiness.md +0 -0
  91. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/docs/learnings/iris-docker-sdk-environment-variables.md +0 -0
  92. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/docs/learnings/iris-performance-monitoring-landscape.md +0 -0
  93. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/docs/learnings/iris-security-users-api.md +0 -0
  94. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/docs/learnings/password-reset-changeflag-fix.md +0 -0
  95. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/docs/learnings/rag-templates-production-patterns.md +0 -0
  96. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/docs/learnings/sql-task-manager-operations.md +0 -0
  97. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/docs/learnings/test-isolation-fix-summary.md +0 -0
  98. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/docs/learnings/test-isolation-investigation.md +0 -0
  99. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/docs/learnings/testcontainers-ryuk-lifecycle.md +0 -0
  100. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/examples/01_quickstart.py +0 -0
  101. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/examples/02_connection_management.py +0 -0
  102. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/examples/04_pytest_fixtures.py +0 -0
  103. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/examples/05_ci_cd.py +0 -0
  104. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/examples/08_auto_discovery.py +0 -0
  105. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/examples/09_enterprise.py +0 -0
  106. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/examples/10_docker_compose_integration.py +0 -0
  107. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/examples/langchain_integration_example.py +0 -0
  108. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester/cli/__init__.py +0 -0
  109. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester/cli/__main__.py +0 -0
  110. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester/cli/connection_commands.py +0 -0
  111. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester/cli/container.py +0 -0
  112. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester/cli/container_commands.py +0 -0
  113. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester/cli/fixture_commands.py +0 -0
  114. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester/config/__init__.py +0 -0
  115. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester/config/auto_discovery.py +0 -0
  116. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester/config/container_config.py +0 -0
  117. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester/config/container_state.py +0 -0
  118. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester/config/discovery.py +0 -0
  119. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester/config/presets.py +0 -0
  120. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester/config/yaml_loader.py +0 -0
  121. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester/connections/__init__.py +0 -0
  122. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester/connections/auto_discovery.py +0 -0
  123. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester/connections/connection.py +0 -0
  124. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester/connections/dbapi.py +0 -0
  125. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester/connections/jdbc.py +0 -0
  126. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester/connections/manager.py +0 -0
  127. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester/connections/retry.py +0 -0
  128. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester/containers/__init__.py +0 -0
  129. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester/containers/cpf_manager.py +0 -0
  130. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester/containers/models.py +0 -0
  131. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester/containers/monitor_utils.py +0 -0
  132. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester/containers/monitoring.py +0 -0
  133. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester/containers/performance.py +0 -0
  134. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester/containers/validation.py +0 -0
  135. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester/fixtures/__init__.py +0 -0
  136. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester/fixtures/manifest.py +0 -0
  137. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester/fixtures/obj_export.py +0 -0
  138. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester/fixtures/validator.py +0 -0
  139. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester/integrations/__init__.py +0 -0
  140. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester/ports/__init__.py +0 -0
  141. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester/ports/assignment.py +0 -0
  142. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester/ports/exceptions.py +0 -0
  143. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester/ports/registry.py +0 -0
  144. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester/testing/__init__.py +0 -0
  145. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester/testing/fixtures.py +0 -0
  146. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester/testing/helpers.py +0 -0
  147. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester/testing/models.py +0 -0
  148. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester/testing/schema_reset.py +0 -0
  149. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester/utils/__init__.py +0 -0
  150. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester/utils/container_port.py +0 -0
  151. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester/utils/container_status.py +0 -0
  152. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester/utils/health_checks.py +0 -0
  153. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester/utils/iris_container_adapter.py +0 -0
  154. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester/utils/progress.py +0 -0
  155. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester.egg-info/dependency_links.txt +0 -0
  156. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester.egg-info/requires.txt +0 -0
  157. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/iris_devtester.egg-info/top_level.txt +0 -0
  158. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/setup.cfg +0 -0
  159. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/__init__.py +0 -0
  160. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/contract/__init__.py +0 -0
  161. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/contract/cli/test_container_logs_contract.py +0 -0
  162. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/contract/cli/test_container_remove_contract.py +0 -0
  163. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/contract/cli/test_container_restart_contract.py +0 -0
  164. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/contract/cli/test_container_start_contract.py +0 -0
  165. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/contract/cli/test_container_status_contract.py +0 -0
  166. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/contract/cli/test_container_stop_contract.py +0 -0
  167. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/contract/cli/test_container_up_contract.py +0 -0
  168. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/contract/test_agent_skills.py +0 -0
  169. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/contract/test_cli_container_commands.py +0 -0
  170. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/contract/test_cli_fixture_commands.py +0 -0
  171. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/contract/test_connection_api.py +0 -0
  172. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/contract/test_container_api.py +0 -0
  173. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/contract/test_container_integration_contract.py +0 -0
  174. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/contract/test_container_status_api.py +0 -0
  175. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/contract/test_container_validation_api.py +0 -0
  176. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/contract/test_enable_callin_api.py +0 -0
  177. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/contract/test_fixture_creator_api.py +0 -0
  178. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/contract/test_fixture_loader_api.py +0 -0
  179. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/contract/test_fixture_validator_api.py +0 -0
  180. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/contract/test_iriscontainer_attach.py +0 -0
  181. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/contract/test_legacy_package_contract.py +0 -0
  182. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/contract/test_modern_package_contract.py +0 -0
  183. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/contract/test_monitoring_config_api.py +0 -0
  184. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/contract/test_package_detection.py +0 -0
  185. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/contract/test_port_registry_contract.py +0 -0
  186. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/contract/test_preconfig_contract.py +0 -0
  187. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/contract/test_resource_monitoring_api.py +0 -0
  188. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/contract/test_task_manager_api.py +0 -0
  189. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/contract/test_test_connection_api.py +0 -0
  190. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/contract/test_testing_fixtures_api.py +0 -0
  191. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/e2e/__init__.py +0 -0
  192. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/e2e/test_skill_workflow.py +0 -0
  193. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/integration/__init__.py +0 -0
  194. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/integration/conftest.py +0 -0
  195. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/integration/ports/__init__.py +0 -0
  196. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/integration/ports/test_manual_port_override.py +0 -0
  197. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/integration/ports/test_multi_project_isolation.py +0 -0
  198. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/integration/ports/test_port_exhaustion.py +0 -0
  199. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/integration/ports/test_port_persistence.py +0 -0
  200. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/integration/ports/test_stale_cleanup.py +0 -0
  201. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/integration/test_bug_fixes.py +0 -0
  202. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/integration/test_bug_fixes_011.py +0 -0
  203. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/integration/test_cli_container_integration.py +0 -0
  204. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/integration/test_connection_integration.py +0 -0
  205. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/integration/test_container_health_monitor.py +0 -0
  206. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/integration/test_container_status_integration.py +0 -0
  207. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/integration/test_container_validation.py +0 -0
  208. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/integration/test_cpf_merge.py +0 -0
  209. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/integration/test_cpf_presets.py +0 -0
  210. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/integration/test_cpf_security.py +0 -0
  211. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/integration/test_enable_callin_integration.py +0 -0
  212. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/integration/test_fixture_export_patterns.py +0 -0
  213. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/integration/test_fixture_performance.py +0 -0
  214. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/integration/test_fixture_refresh.py +0 -0
  215. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/integration/test_fixtures_integration.py +0 -0
  216. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/integration/test_iriscontainer_attach_integration.py +0 -0
  217. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/integration/test_monitor_utils_integration.py +0 -0
  218. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/integration/test_monitoring_integration.py +0 -0
  219. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/integration/test_password_reset_integration.py +0 -0
  220. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/integration/test_real_world_problems.py +0 -0
  221. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/integration/test_reliable_password_reset.py +0 -0
  222. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/integration/test_test_connection_integration.py +0 -0
  223. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/unit/__init__.py +0 -0
  224. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/unit/config/test_config_hierarchy.py +0 -0
  225. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/unit/config/test_container_config.py +0 -0
  226. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/unit/config/test_yaml_loader.py +0 -0
  227. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/unit/test_auto_discovery.py +0 -0
  228. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/unit/test_config_discovery.py +0 -0
  229. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/unit/test_connection_fallback.py +0 -0
  230. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/unit/test_cpf_manager.py +0 -0
  231. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/unit/test_iris_container.py +0 -0
  232. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/unit/test_manifest.py +0 -0
  233. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/unit/test_monitoring_policy.py +0 -0
  234. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/unit/test_password_preconfig.py +0 -0
  235. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/unit/test_password_preconfig_unit.py +0 -0
  236. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/unit/test_performance_metrics.py +0 -0
  237. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/unit/test_resource_thresholds.py +0 -0
  238. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/unit/test_retry.py +0 -0
  239. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/unit/test_schema_models.py +0 -0
  240. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/unit/test_validation_results.py +0 -0
  241. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/unit/test_wait_strategies.py +0 -0
  242. {iris_devtester-1.10.2 → iris_devtester-1.10.4}/tests/unit/utils/test_iris_container_adapter.py +0 -0
@@ -1,4 +1,4 @@
1
- # CLAUDE.md - IRIS DevTools
1
+ # CLAUDE.md - iris-devtester
2
2
 
3
3
  **Purpose**: Provides Claude Code with project-specific context, patterns, and conventions.
4
4
 
@@ -11,7 +11,7 @@ This file provides guidance to Claude Code when working with this repository.
11
11
 
12
12
  ## Project Overview
13
13
 
14
- **IRIS DevTools** is a battle-tested Python package providing automatic, reliable infrastructure for InterSystems IRIS development. This is being extracted from production code in the `rag-templates` project.
14
+ **iris-devtester** is a battle-tested Python package providing automatic, reliable infrastructure for InterSystems IRIS development. This is being extracted from production code in the `rag-templates` project.
15
15
 
16
16
  ## Source Material
17
17
 
@@ -1,8 +1,8 @@
1
- # IRIS DevTools Constitution
1
+ # iris-devtester Constitution
2
2
 
3
- **Version**: 1.1.0
3
+ **Version**: 1.2.0
4
4
  **Status**: Foundational
5
- **Last Updated**: 2025-11-23
5
+ **Last Updated**: 2026-02-06
6
6
 
7
7
  ## Preamble
8
8
 
@@ -391,7 +391,38 @@ hasattr(iris, 'connect') # True in BOTH versions!
391
391
 
392
392
  **Reference**: See hipporag2-pipeline CONSTITUTION.md Principle 9 for detailed empirical testing results.
393
393
 
394
- ### 9. DOCUMENT THE BLIND ALLEYS
394
+ ### 9. SQLITE-LEVEL ERGONOMICS (THE NORTH STAR)
395
+
396
+ **The Principle**: IRIS setup and connectivity should be invisible. A developer should go from "nothing" to "connected" with zero manual configuration.
397
+
398
+ **Why It Matters**:
399
+ - SQLite is the benchmark for "zero-friction" development
400
+ - Infrastructure setup is a major barrier to IRIS adoption
401
+ - Developer "flow" is interrupted by infrastructure management
402
+ - If a user has to think about ports, passwords, or container lifecycles, we have more work to do.
403
+
404
+ **Implementation Requirements**:
405
+ - ✅ `get_connection()` with zero-config auto-discovery
406
+ - ✅ Automatic container lifecycle management (transparent to the user)
407
+ - ✅ Standardized default credentials (`_SYSTEM`/`SYS`)
408
+ - ✅ Proactive remediation of all connectivity hurdles (service enablement, password reset)
409
+ - ✅ Silent infrastructure: infrastructure "noise" (logs, status) is hidden unless an error occurs
410
+
411
+ **Forbidden**:
412
+ - ❌ Requiring manual Docker commands for basic connectivity
413
+ - ❌ Mandatory configuration files for local dev
414
+ - ❌ Exposing infrastructure complexity in the primary API
415
+
416
+ **Example**:
417
+ ```python
418
+ # THE NORTH STAR EXPERIENCE
419
+ from iris_devtester import IRISContainer
420
+
421
+ # One line to everything: startup, auth, service enablement, connection
422
+ conn = IRISContainer.community().get_connection()
423
+ ```
424
+
425
+ ### 10. DOCUMENT THE BLIND ALLEYS
395
426
 
396
427
  **The Principle**: Failed approaches must be documented to prevent repetition.
397
428
 
@@ -401,18 +432,13 @@ hasattr(iris, 'connect') # True in BOTH versions!
401
432
  - Context for design decisions is valuable
402
433
  - Prevents regression to worse solutions
403
434
 
404
- **Implementation Requirements**:
405
- - ✅ `docs/learnings/` directory for deep-dives
406
- - ✅ "Why not X?" sections in documentation
407
- - ✅ ADR (Architecture Decision Records) for major choices
408
- - ✅ Performance comparisons
409
- - ✅ Case studies from production
410
-
411
435
  **Documented Blind Alleys**:
412
436
  - **Why not JDBC-only?** → DBAPI is 3x faster, see benchmark
413
437
  - **Why not shared test databases?** → Data pollution, see case study
414
438
  - **Why not manual password resets?** → CI/CD breaks, see incident report
415
439
  - **Why not port 1972 hardcoded?** → Conflicts in parallel tests, see issue #42
440
+ - **Why not prefer `iris.connect()`?** → In `intersystems-irispython` 5.3.1+, `iris.connect` uses the `_elsdk_` driver which has a critical `SIGSEGV` bug with `FETCH FIRST N ROWS ONLY` syntax. Prefer `intersystems_iris.connect` (the stable `_IRISNative` path) instead.
441
+
416
442
 
417
443
  **Example Documentation**:
418
444
  ```markdown
@@ -471,6 +497,12 @@ Principles may be amended when:
471
497
 
472
498
  ## Version History
473
499
 
500
+ ### v1.2.0 (2026-02-06)
501
+ - Added Principle 9: SQLite-Level Ergonomics (The North Star)
502
+ - Renumbered Principle 9 "Document the Blind Alleys" → Principle 10
503
+ - Standardized on `_SYSTEM` as the default toolkit username
504
+ - Renamed project to `iris-devtester` consistently across documentation
505
+
474
506
  ### v1.1.0 (2025-11-23)
475
507
  - Added Principle 8: Use Official IRIS Python API (No Private Attributes)
476
508
  - Documents empirically tested fact that `_DBAPI` does NOT exist in intersystems-irispython v5.1.2 or v5.3.0
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2025 IRIS DevTools Contributors
3
+ Copyright (c) 2025-2026 iris-devtester Contributors
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: iris-devtester
3
- Version: 1.10.2
3
+ Version: 1.10.4
4
4
  Summary: Battle-tested InterSystems IRIS infrastructure utilities for Python development
5
5
  Author-email: InterSystems Community <community@intersystems.com>
6
6
  Maintainer-email: Thomas Dyar <thomas.dyar@intersystems.com>
@@ -183,7 +183,7 @@ with IRISContainer.community() \
183
183
  ```python
184
184
  IRISContainer(
185
185
  image="intersystemsdc/iris-community:latest", # Docker image
186
- username="SuperUser", # Default username
186
+ username="_SYSTEM", # Default username
187
187
  password="SYS", # Default password
188
188
  namespace="USER", # Default namespace
189
189
  name="my-container", # Container name (alternative to with_name)
@@ -119,7 +119,7 @@ with IRISContainer.community() \
119
119
  ```python
120
120
  IRISContainer(
121
121
  image="intersystemsdc/iris-community:latest", # Docker image
122
- username="SuperUser", # Default username
122
+ username="_SYSTEM", # Default username
123
123
  password="SYS", # Default password
124
124
  namespace="USER", # Default namespace
125
125
  name="my-container", # Container name (alternative to with_name)
@@ -1,6 +1,6 @@
1
1
  # Troubleshooting Guide
2
2
 
3
- This guide covers the most common issues you might encounter when using IRIS DevTools and how to resolve them.
3
+ This guide covers the most common issues you might encounter when using iris-devtester and how to resolve them.
4
4
 
5
5
  ## Top 5 Issues
6
6
 
@@ -43,10 +43,10 @@ sudo usermod -aG docker $USER
43
43
  ```
44
44
 
45
45
  **Diagnosis:**
46
- IRIS requires password change on first login, but IRIS DevTools should auto-remediate this. If you see this error, auto-remediation failed.
46
+ IRIS requires password change on first login, but iris-devtester should auto-remediate this. If you see this error, auto-remediation failed.
47
47
 
48
48
  **Solution:**
49
- IRIS DevTools automatically handles this, but if you encounter the error:
49
+ iris-devtester automatically handles this, but if you encounter the error:
50
50
 
51
51
  ```python
52
52
  # The library should automatically reset the password
@@ -314,4 +314,4 @@ docker info | grep -E "CPUs|Total Memory"
314
314
 
315
315
  ---
316
316
 
317
- **Remember**: IRIS DevTools is designed to handle most issues automatically. If you encounter consistent errors, please [report them](https://github.com/intersystems-community/iris-devtester/issues/new?template=bug_report.yml) so we can improve auto-remediation.
317
+ **Remember**: iris-devtester is designed to handle most issues automatically. If you encounter consistent errors, please [report them](https://github.com/intersystems-community/iris-devtester/issues/new?template=bug_report.yml) so we can improve auto-remediation.
@@ -26,7 +26,7 @@ LangChain Integration:
26
26
  ... # Build your RAG app...
27
27
  """
28
28
 
29
- __version__ = "1.10.1"
29
+ __version__ = "1.10.3"
30
30
  __author__ = "InterSystems Community"
31
31
  __license__ = "MIT"
32
32
 
@@ -0,0 +1,8 @@
1
+ """
2
+ Entry point for python -m iris_devtester.
3
+ """
4
+
5
+ from iris_devtester.cli import main
6
+
7
+ if __name__ == "__main__":
8
+ main()
@@ -20,8 +20,8 @@ DEFAULT_PORT = 1972
20
20
  DEFAULT_NAMESPACE = "USER"
21
21
  """Default IRIS namespace (USER is the default workspace)"""
22
22
 
23
- DEFAULT_USERNAME = "SuperUser"
24
- """Default IRIS username (SuperUser has full access)"""
23
+ DEFAULT_USERNAME = "_SYSTEM"
24
+ """Default IRIS username (_SYSTEM has full access)"""
25
25
 
26
26
  DEFAULT_PASSWORD = "SYS"
27
27
  """Default IRIS password (SYS is the default for containers)"""
@@ -1,5 +1,5 @@
1
1
  """
2
- Configuration models for IRIS DevTools.
2
+ Configuration models for iris-devtester.
3
3
 
4
4
  Provides IRISConfig dataclass for database connection configuration.
5
5
  """
@@ -20,11 +20,12 @@ class IRISConfig:
20
20
  host: Database host (default: "localhost")
21
21
  port: Database port (default: 1972)
22
22
  namespace: IRIS namespace (default: "USER")
23
- username: Database username (default: "SuperUser")
23
+ username: Database username (default: "_SYSTEM")
24
24
  password: Database password (default: "SYS")
25
25
  driver: Preferred driver type (default: "auto")
26
26
  connection_string: Optional override connection string
27
27
  timeout: Connection timeout in seconds (default: 30)
28
+ container_name: Optional name of the IRIS container (used for password reset)
28
29
 
29
30
  Raises:
30
31
  ValueError: If validation fails (invalid port, empty namespace, etc.)
@@ -46,7 +47,7 @@ class IRISConfig:
46
47
  host: str = "localhost"
47
48
  port: int = 1972
48
49
  namespace: str = "USER"
49
- username: str = "SuperUser"
50
+ username: str = "_SYSTEM"
50
51
  password: str = "SYS"
51
52
  driver: Literal["dbapi", "jdbc", "auto"] = "auto"
52
53
  connection_string: Optional[str] = None
@@ -34,7 +34,7 @@ class ConnectionInfo:
34
34
  ... host="localhost",
35
35
  ... port=1972,
36
36
  ... namespace="USER",
37
- ... username="SuperUser"
37
+ ... username="_SYSTEM"
38
38
  ... )
39
39
  >>> info.driver_type
40
40
  'dbapi'
@@ -66,7 +66,7 @@ class IRISContainer(IRISBase):
66
66
  def __init__(
67
67
  self,
68
68
  image: str = "intersystemsdc/iris-community:latest",
69
- username: str = "SuperUser",
69
+ username: str = "_SYSTEM",
70
70
  password: str = "SYS",
71
71
  namespace: str = "USER",
72
72
  **kwargs,
@@ -205,6 +205,51 @@ class IRISContainer(IRISBase):
205
205
  image = f"caretdev/iris-community-light:{tag}"
206
206
  return cls(image=image, **kwargs)
207
207
 
208
+ @classmethod
209
+ def attach(cls, container_name: str, **kwargs) -> "IRISContainer":
210
+ """
211
+ Attach to an existing IRIS container by name.
212
+
213
+ This allows using persistent containers (e.g. from docker-compose)
214
+ instead of starting a new one via testcontainers.
215
+
216
+ Args:
217
+ container_name: Name of the existing Docker container.
218
+ **kwargs: Additional configuration (username, password, namespace).
219
+
220
+ Returns:
221
+ An IRISContainer instance attached to the existing container.
222
+ """
223
+ instance = cls(image="", name=container_name, **kwargs)
224
+ instance._is_attached = True
225
+ instance._container_name = container_name
226
+
227
+ try:
228
+ import docker
229
+
230
+ client = docker.from_env()
231
+ container = client.containers.get(container_name)
232
+ instance._container = container
233
+
234
+ # If it's a mock container, we need to set these manually
235
+ if not HAS_TESTCONTAINERS:
236
+ instance.host = "localhost"
237
+ # Try to find port from container ports
238
+ ports = container.attrs.get("NetworkSettings", {}).get("Ports", {})
239
+ if "1972/tcp" in ports and ports["1972/tcp"]:
240
+ instance._mapped_port = int(ports["1972/tcp"][0]["HostPort"])
241
+ else:
242
+ # testcontainers will handle discovery via get_config()
243
+ instance.get_config()
244
+
245
+ except Exception as e:
246
+ logger.warning(f"Could not fully inspect container '{container_name}': {e}")
247
+ # Fallback to defaults
248
+ instance.host = instance.host or "localhost"
249
+ instance._mapped_port = instance._mapped_port or 1972
250
+
251
+ return instance
252
+
208
253
  def with_name(self, name: str) -> "IRISContainer":
209
254
  """Set the container name."""
210
255
  self._container_name = name
@@ -305,7 +350,7 @@ class IRISContainer(IRISBase):
305
350
  container_name = self.get_container_name()
306
351
  ns = namespace or self._namespace
307
352
 
308
- cmd = ["docker", "exec", "-i", container_name, "iris", "session", "IRIS", "-U", ns]
353
+ cmd = ["docker", "exec", "-u", "irisowner", "-i", container_name, "iris", "session", "IRIS", "-U", ns]
309
354
 
310
355
  result = subprocess.run(
311
356
  cmd, input=f"{script}\nHalt\n".encode("utf-8"), capture_output=True, timeout=30
@@ -120,7 +120,7 @@ class IRISReadyWaitStrategy:
120
120
  " docker logs <container_name>\n"
121
121
  "\n"
122
122
  " 2. Verify IRIS is starting:\n"
123
- " docker exec <container_name> iris list\n"
123
+ " docker exec -u irisowner <container_name> iris list\n"
124
124
  "\n"
125
125
  " 3. Increase timeout if needed:\n"
126
126
  f" IRISReadyWaitStrategy(timeout={timeout * 2})\n"
@@ -170,7 +170,7 @@ class IRISReadyWaitStrategy:
170
170
  """
171
171
  try:
172
172
  result = subprocess.run(
173
- ["docker", "exec", container_name, "iris", "list"],
173
+ ["docker", "exec", "-u", "irisowner", container_name, "iris", "list"],
174
174
  capture_output=True,
175
175
  text=True,
176
176
  timeout=5,
@@ -132,7 +132,7 @@ class FixtureCreator:
132
132
  Halt
133
133
  """
134
134
  result = subprocess.run(
135
- ["docker", "exec", "-i", container_name, "iris", "session", "IRIS", "-U", namespace],
135
+ ["docker", "exec", "-u", "irisowner", "-i", container_name, "iris", "session", "IRIS", "-U", namespace],
136
136
  input=export_classes_script.encode("utf-8"),
137
137
  capture_output=True,
138
138
  timeout=120,
@@ -156,7 +156,7 @@ class FixtureCreator:
156
156
  Halt
157
157
  """
158
158
  result = subprocess.run(
159
- ["docker", "exec", "-i", container_name, "iris", "session", "IRIS", "-U", namespace],
159
+ ["docker", "exec", "-u", "irisowner", "-i", container_name, "iris", "session", "IRIS", "-U", namespace],
160
160
  input=export_globals_script.encode("utf-8"),
161
161
  capture_output=True,
162
162
  timeout=120,
@@ -146,7 +146,7 @@ class FixtureLoader:
146
146
  Halt
147
147
  """
148
148
  result = subprocess.run(
149
- ["docker", "exec", "-i", container_name, "iris", "session", "IRIS", "-U", "%SYS"],
149
+ ["docker", "exec", "-u", "irisowner", "-i", container_name, "iris", "session", "IRIS", "-U", "%SYS"],
150
150
  input=create_ns_script.encode("utf-8"),
151
151
  capture_output=True,
152
152
  timeout=60,
@@ -168,6 +168,8 @@ class FixtureLoader:
168
168
  [
169
169
  "docker",
170
170
  "exec",
171
+ "-u",
172
+ "irisowner",
171
173
  "-i",
172
174
  container_name,
173
175
  "iris",
@@ -200,6 +202,8 @@ class FixtureLoader:
200
202
  [
201
203
  "docker",
202
204
  "exec",
205
+ "-u",
206
+ "irisowner",
203
207
  "-i",
204
208
  container_name,
205
209
  "iris",
@@ -236,7 +240,7 @@ class FixtureLoader:
236
240
  Write "SUCCESS" Halt
237
241
  """
238
242
  subprocess.run(
239
- ["docker", "exec", "-i", container_name, "iris", "session", "IRIS", "-U", "%SYS"],
243
+ ["docker", "exec", "-u", "irisowner", "-i", container_name, "iris", "session", "IRIS", "-U", "%SYS"],
240
244
  input=ensure_user_script.encode("utf-8"),
241
245
  capture_output=True,
242
246
  timeout=30,
@@ -166,7 +166,7 @@ class LangChainIRISContainer(IRISContainer):
166
166
  >>> with LangChainIRISContainer.community() as iris:
167
167
  ... conn_str = iris.get_connection_string()
168
168
  ... print(conn_str)
169
- iris://SuperUser:SYS@localhost:52773/USER
169
+ iris://_SYSTEM:SYS@localhost:52773/USER
170
170
  """
171
171
  # Ensure connection is ready (auto-remediation)
172
172
  _ = self.get_connection()
@@ -174,7 +174,7 @@ class LangChainIRISContainer(IRISContainer):
174
174
  # Get connection details
175
175
  host = self.get_container_host_ip()
176
176
  port = self.get_exposed_port(1972) # SuperServer port
177
- username = getattr(self, "username", "SuperUser")
177
+ username = getattr(self, "username", "_SYSTEM")
178
178
  password = getattr(self, "password", "SYS")
179
179
  namespace = getattr(self, "namespace", "USER")
180
180
 
@@ -135,19 +135,39 @@ def detect_dbapi_package() -> DBAPIPackageInfo:
135
135
  """
136
136
  start_time = time.perf_counter()
137
137
 
138
- # Try modern package first (priority per Principle #2)
139
- # CRITICAL: Use official iris.connect() API, NOT private _DBAPI attribute!
140
- # See CONSTITUTION.md Principle 8 for empirical evidence that _DBAPI does not exist.
138
+ # Try modern stable package first (intersystems_iris)
139
+ # This is preferred over the 'iris' module because 'iris.connect'
140
+ # in intersystems-irispython 5.3.1+ uses the _elsdk_ driver path
141
+ # which has known SIGSEGV bugs with FETCH FIRST N ROWS ONLY syntax.
142
+ try:
143
+ import intersystems_iris
144
+
145
+ if hasattr(intersystems_iris, "connect"):
146
+ # Validate version from metadata
147
+ pkg_version = importlib.metadata.version("intersystems-irispython")
148
+ validate_package_version("intersystems-irispython", pkg_version, "5.1.2")
149
+
150
+ elapsed_ms = (time.perf_counter() - start_time) * 1000
151
+ logger.info(f"Detected IRIS DBAPI package: intersystems-irispython v{pkg_version} (via intersystems_iris)")
152
+
153
+ return DBAPIPackageInfo(
154
+ package_name="intersystems-irispython",
155
+ import_path="intersystems_iris",
156
+ version=pkg_version,
157
+ connect_function=intersystems_iris.connect,
158
+ detection_time_ms=elapsed_ms,
159
+ )
160
+ except (ImportError, importlib.metadata.PackageNotFoundError):
161
+ logger.debug("intersystems_iris not available or metadata not found, trying iris")
162
+
163
+ # Fallback to 'iris' module (also part of intersystems-irispython)
141
164
  modern_available = False
142
165
  try:
143
- import os
144
- import sys
145
-
146
166
  import iris
147
167
 
148
168
  modern_available = True
149
169
  except ImportError as e:
150
- logger.debug(f"Modern package not available, trying legacy: {e}")
170
+ logger.debug(f"Modern 'iris' package not available, trying legacy: {e}")
151
171
 
152
172
  if modern_available:
153
173
  import os
@@ -110,6 +110,8 @@ def enable_callin_service(
110
110
  enable_cmd = [
111
111
  "docker",
112
112
  "exec",
113
+ "-u",
114
+ "irisowner",
113
115
  "-i",
114
116
  container_name,
115
117
  "bash",
@@ -160,13 +162,13 @@ def enable_callin_service(
160
162
  f" docker logs {container_name} | tail -20\n"
161
163
  "\n"
162
164
  " 2. Try manually enabling CallIn:\n"
163
- f" docker exec -it {container_name} iris session IRIS -U %SYS\n"
165
+ f" docker exec -u irisowner -it {container_name} iris session IRIS -U %SYS\n"
164
166
  ' Do ##class(Security.Services).Get("%Service_CallIn",.prop)\n'
165
167
  ' Set prop("Enabled")=1\n'
166
168
  ' Do ##class(Security.Services).Modify("%Service_CallIn",.prop)\n'
167
169
  "\n"
168
170
  " 3. Check IRIS license (Community vs Enterprise):\n"
169
- " docker exec {container_name} iris list\n"
171
+ " docker exec -u irisowner {container_name} iris list\n"
170
172
  "\n"
171
173
  "Documentation: See docs/learnings/callin-service-requirement.md\n",
172
174
  )
@@ -357,6 +357,8 @@ Halt
357
357
  cmd = [
358
358
  "docker",
359
359
  "exec",
360
+ "-u",
361
+ "irisowner",
360
362
  "-i",
361
363
  container_name,
362
364
  "iris",
@@ -569,6 +571,8 @@ Halt
569
571
  cmd = [
570
572
  "docker",
571
573
  "exec",
574
+ "-u",
575
+ "irisowner",
572
576
  container_name,
573
577
  "sh",
574
578
  "-c",
@@ -625,7 +629,7 @@ Halt
625
629
  f"Failed to unexpire passwords in {container_name}: {str(e)}\n"
626
630
  "\n"
627
631
  "Manual fix:\n"
628
- f" docker exec {container_name} bash -c 'echo \"do ##class(Security.Users)"
632
+ f" docker exec -u irisowner {container_name} bash -c 'echo \"do ##class(Security.Users)"
629
633
  f'.UnExpireUserPasswords(\\"*\\")" | iris session IRIS -U %SYS\'\n',
630
634
  )
631
635
 
@@ -90,6 +90,8 @@ def test_connection(
90
90
  test_cmd = [
91
91
  "docker",
92
92
  "exec",
93
+ "-u",
94
+ "irisowner",
93
95
  "-i",
94
96
  container_name,
95
97
  "bash",
@@ -126,10 +128,10 @@ def test_connection(
126
128
  "\n"
127
129
  "How to fix it:\n"
128
130
  " 1. List available namespaces:\n"
129
- f' docker exec {container_name} iris session IRIS -U %SYS """Do ^%GSIZE"""\n'
131
+ f' docker exec -u irisowner {container_name} iris session IRIS -U %SYS """Do ^%GSIZE"""\n'
130
132
  "\n"
131
133
  " 2. Create the namespace if needed:\n"
132
- f" docker exec {container_name} iris session IRIS -U %SYS\n"
134
+ f" docker exec -u irisowner {container_name} iris session IRIS -U %SYS\n"
133
135
  f' Do ##class(Config.Namespaces).Create("{namespace}")\n'
134
136
  "\n"
135
137
  " 3. Or use an existing namespace like 'USER' or '%SYS'\n",
@@ -151,7 +153,7 @@ def test_connection(
151
153
  " iris-devtester container enable-callin {container_name}\n"
152
154
  "\n"
153
155
  " 3. Test basic IRIS access:\n"
154
- f" docker exec -it {container_name} iris session IRIS -U %SYS\n",
156
+ f" docker exec -u irisowner -it {container_name} iris session IRIS -U %SYS\n",
155
157
  )
156
158
 
157
159
  except subprocess.TimeoutExpired:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: iris-devtester
3
- Version: 1.10.2
3
+ Version: 1.10.4
4
4
  Summary: Battle-tested InterSystems IRIS infrastructure utilities for Python development
5
5
  Author-email: InterSystems Community <community@intersystems.com>
6
6
  Maintainer-email: Thomas Dyar <thomas.dyar@intersystems.com>
@@ -183,7 +183,7 @@ with IRISContainer.community() \
183
183
  ```python
184
184
  IRISContainer(
185
185
  image="intersystemsdc/iris-community:latest", # Docker image
186
- username="SuperUser", # Default username
186
+ username="_SYSTEM", # Default username
187
187
  password="SYS", # Default password
188
188
  namespace="USER", # Default namespace
189
189
  name="my-container", # Container name (alternative to with_name)
@@ -76,6 +76,7 @@ examples/09_enterprise.py
76
76
  examples/10_docker_compose_integration.py
77
77
  examples/langchain_integration_example.py
78
78
  iris_devtester/__init__.py
79
+ iris_devtester/__main__.py
79
80
  iris_devtester.egg-info/PKG-INFO
80
81
  iris_devtester.egg-info/SOURCES.txt
81
82
  iris_devtester.egg-info/dependency_links.txt
@@ -1,2 +1,3 @@
1
1
  [console_scripts]
2
+ idt = iris_devtester.cli:main
2
3
  iris-devtester = iris_devtester.cli:main
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "iris-devtester"
7
- version = "1.10.2"
7
+ version = "1.10.4"
8
8
  description = "Battle-tested InterSystems IRIS infrastructure utilities for Python development"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
@@ -88,6 +88,7 @@ docs = [
88
88
 
89
89
  [project.scripts]
90
90
  iris-devtester = "iris_devtester.cli:main"
91
+ idt = "iris_devtester.cli:main"
91
92
 
92
93
  [project.urls]
93
94
  Homepage = "https://github.com/intersystems-community/iris-devtester"
@@ -132,7 +132,7 @@ def iris_db_both_editions(request):
132
132
  iris_container = IRISContainer.enterprise(
133
133
  license_key=license_key,
134
134
  image=enterprise_image,
135
- username="SuperUser",
135
+ username="_SYSTEM",
136
136
  password="SYS",
137
137
  )
138
138
 
@@ -32,7 +32,7 @@ class TestResetVerificationContract:
32
32
  new_pwd = "RealPassword123!"
33
33
  result = reset_password(
34
34
  container_name=container_name,
35
- username="SuperUser",
35
+ username="_SYSTEM",
36
36
  new_password=new_pwd,
37
37
  hostname=config.host,
38
38
  port=config.port,
@@ -47,7 +47,7 @@ class TestResetVerificationContract:
47
47
  hostname=config.host,
48
48
  port=config.port,
49
49
  namespace=config.namespace,
50
- username="SuperUser",
50
+ username="_SYSTEM",
51
51
  password=new_pwd,
52
52
  )
53
53
  cursor = conn.cursor()
@@ -69,7 +69,7 @@ class TestResetVerificationContract:
69
69
  # This will cause a REAL connection failure during verification
70
70
  result = reset_password(
71
71
  container_name=container_name,
72
- username="SuperUser",
72
+ username="_SYSTEM",
73
73
  new_password="ShouldNotWork",
74
74
  hostname=config.host,
75
75
  port=9999, # WRONG PORT