iris-pex-embedded-python 4.0.1b6__tar.gz → 4.0.1b8__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 (147) hide show
  1. {iris_pex_embedded_python-4.0.1b6/src/iris_pex_embedded_python.egg-info → iris_pex_embedded_python-4.0.1b8}/PKG-INFO +2 -2
  2. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/README.md +1 -1
  3. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/docs/cookbooks/add-business-operation.md +2 -1
  4. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/docs/cookbooks/add-business-process.md +2 -3
  5. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/docs/cookbooks/add-polling-service.md +1 -1
  6. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/docs/cookbooks/hello-world-production.md +1 -1
  7. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/docs/cookbooks/production-settings-and-targets.md +3 -3
  8. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/docs/getting-started/first-steps.md +2 -2
  9. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/docs/getting-started/register-component.md +2 -2
  10. iris_pex_embedded_python-4.0.1b8/docs/index.md +68 -0
  11. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/docs/production-graph.md +17 -1
  12. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/docs/python-api.md +18 -3
  13. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/docs/settings.md +5 -5
  14. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/pyproject.toml +2 -1
  15. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/production/common.py +14 -1
  16. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/production/component.py +24 -2
  17. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/production/declarations.py +6 -4
  18. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/production/model.py +29 -7
  19. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/production/rendering.py +5 -6
  20. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/production/types.py +2 -2
  21. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/production/validation.py +70 -4
  22. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8/src/iris_pex_embedded_python.egg-info}/PKG-INFO +2 -2
  23. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iris_pex_embedded_python.egg-info/SOURCES.txt +1 -0
  24. iris_pex_embedded_python-4.0.1b8/src/iris_pex_embedded_python.egg-info/dependency_links.txt +1 -0
  25. iris_pex_embedded_python-4.0.1b6/docs/index.md +0 -58
  26. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/AGENTS.md +0 -0
  27. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/LICENSE +0 -0
  28. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/MANIFEST.in +0 -0
  29. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/docs/agents-template.md +0 -0
  30. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/docs/ai-coding.md +0 -0
  31. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/docs/benchmarks.md +0 -0
  32. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/docs/changelog.md +0 -0
  33. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/docs/code-of-conduct.md +0 -0
  34. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/docs/command-line.md +0 -0
  35. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/docs/component-interaction.md +0 -0
  36. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/docs/contributing.md +0 -0
  37. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/docs/cookbooks/code-index.md +0 -0
  38. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/docs/cookbooks/fhir-submission-python-client.md +0 -0
  39. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/docs/cookbooks/hl7v2-native-input.md +0 -0
  40. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/docs/cookbooks/hl7v2-to-fhir-with-fhir-converter.md +0 -0
  41. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/docs/cookbooks/index.md +0 -0
  42. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/docs/cookbooks/remote-migration.md +0 -0
  43. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/docs/credits.md +0 -0
  44. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/docs/debug.md +0 -0
  45. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/docs/dtl.md +0 -0
  46. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/docs/example.md +0 -0
  47. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/docs/getting-started/installation.md +0 -0
  48. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/docs/healthcare-ai-coding.md +0 -0
  49. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/docs/logging.md +0 -0
  50. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/docs/prod-settings.md +0 -0
  51. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/docs/production-change-workflow.md +0 -0
  52. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/docs/rest-api.md +0 -0
  53. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/docs/useful-links.md +0 -0
  54. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/docs/venv.md +0 -0
  55. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/docs/wrapper.md +0 -0
  56. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/mkdocs.yml +0 -0
  57. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/setup.cfg +0 -0
  58. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/__init__.py +0 -0
  59. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/__main__.py +0 -0
  60. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/cli/__init__.py +0 -0
  61. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/cli/formatting.py +0 -0
  62. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/cli/main.py +0 -0
  63. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/cli/parser.py +0 -0
  64. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/cli/types.py +0 -0
  65. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/cls/IOP/BusinessOperation.cls +0 -0
  66. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/cls/IOP/BusinessProcess.cls +0 -0
  67. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/cls/IOP/BusinessService.cls +0 -0
  68. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/cls/IOP/Common.cls +0 -0
  69. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/cls/IOP/Director.cls +0 -0
  70. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/cls/IOP/Duplex/Operation.cls +0 -0
  71. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/cls/IOP/Duplex/Process.cls +0 -0
  72. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/cls/IOP/Duplex/Service.cls +0 -0
  73. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/cls/IOP/Generator/Message/Ack.cls +0 -0
  74. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/cls/IOP/Generator/Message/Poll.cls +0 -0
  75. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/cls/IOP/Generator/Message/Start.cls +0 -0
  76. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/cls/IOP/Generator/Message/StartPickle.cls +0 -0
  77. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/cls/IOP/Generator/Message/Stop.cls +0 -0
  78. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/cls/IOP/InboundAdapter.cls +0 -0
  79. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/cls/IOP/Message/JSONSchema.cls +0 -0
  80. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/cls/IOP/Message.cls +0 -0
  81. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/cls/IOP/OutboundAdapter.cls +0 -0
  82. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/cls/IOP/PickleMessage.cls +0 -0
  83. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/cls/IOP/PrivateSession/Duplex.cls +0 -0
  84. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/cls/IOP/PrivateSession/Message/Ack.cls +0 -0
  85. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/cls/IOP/PrivateSession/Message/Poll.cls +0 -0
  86. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/cls/IOP/PrivateSession/Message/Start.cls +0 -0
  87. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/cls/IOP/PrivateSession/Message/Stop.cls +0 -0
  88. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/cls/IOP/Projection.cls +0 -0
  89. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/cls/IOP/Service/Remote/Handler.cls +0 -0
  90. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/cls/IOP/Service/Remote/Rest/v1.cls +0 -0
  91. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/cls/IOP/Test.cls +0 -0
  92. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/cls/IOP/Utils.cls +0 -0
  93. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/cls/IOP/Wrapper.cls +0 -0
  94. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/components/__init__.py +0 -0
  95. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/components/async_request.py +0 -0
  96. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/components/business_host.py +0 -0
  97. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/components/business_operation.py +0 -0
  98. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/components/business_process.py +0 -0
  99. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/components/business_service.py +0 -0
  100. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/components/common.py +0 -0
  101. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/components/debugpy.py +0 -0
  102. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/components/generator_request.py +0 -0
  103. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/components/inbound_adapter.py +0 -0
  104. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/components/log_manager.py +0 -0
  105. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/components/outbound_adapter.py +0 -0
  106. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/components/polling_business_service.py +0 -0
  107. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/components/private_session_duplex.py +0 -0
  108. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/components/private_session_process.py +0 -0
  109. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/components/settings.py +0 -0
  110. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/messages/__init__.py +0 -0
  111. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/messages/base.py +0 -0
  112. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/messages/decorators.py +0 -0
  113. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/messages/dispatch.py +0 -0
  114. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/messages/persistent.py +0 -0
  115. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/messages/serialization.py +0 -0
  116. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/messages/validation.py +0 -0
  117. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/migration/__init__.py +0 -0
  118. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/migration/io.py +0 -0
  119. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/migration/manifest.py +0 -0
  120. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/migration/plans.py +0 -0
  121. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/migration/utils.py +0 -0
  122. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/production/__init__.py +0 -0
  123. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/production/actions.py +0 -0
  124. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/production/declarative.py +0 -0
  125. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/production/diff.py +0 -0
  126. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/production/import_.py +0 -0
  127. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/production/inspection.py +0 -0
  128. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/production/planning.py +0 -0
  129. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/production/reconstruction.py +0 -0
  130. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/production/runtime.py +0 -0
  131. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/production/source_inference.py +0 -0
  132. /iris_pex_embedded_python-4.0.1b6/src/iris_pex_embedded_python.egg-info/dependency_links.txt → /iris_pex_embedded_python-4.0.1b8/src/iop/py.typed +0 -0
  133. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/runtime/__init__.py +0 -0
  134. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/runtime/director.py +0 -0
  135. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/runtime/environment.py +0 -0
  136. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/runtime/iris.py +0 -0
  137. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/runtime/local.py +0 -0
  138. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/runtime/protocol.py +0 -0
  139. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/runtime/remote/__init__.py +0 -0
  140. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/runtime/remote/client.py +0 -0
  141. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/runtime/remote/director.py +0 -0
  142. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/runtime/remote/migration.py +0 -0
  143. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/runtime/remote/settings.py +0 -0
  144. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iop/runtime/remote/setup.py +0 -0
  145. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iris_pex_embedded_python.egg-info/entry_points.txt +0 -0
  146. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iris_pex_embedded_python.egg-info/requires.txt +0 -0
  147. {iris_pex_embedded_python-4.0.1b6 → iris_pex_embedded_python-4.0.1b8}/src/iris_pex_embedded_python.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: iris_pex_embedded_python
3
- Version: 4.0.1b6
3
+ Version: 4.0.1b8
4
4
  Summary: Iris Interoperability based on Embedded Python
5
5
  Author-email: grongier <guillaume.rongier@intersystems.com>
6
6
  License: MIT License
@@ -98,7 +98,7 @@ class HelloOperation(BusinessOperation):
98
98
  prod = Production("HelloWorld.Production", testing_enabled=True)
99
99
  service = prod.service("HelloService", HelloService)
100
100
  operation = prod.operation("HelloOperation", HelloOperation)
101
- prod.connect(service.Output, operation)
101
+ service.connect(HelloService.Output, operation)
102
102
 
103
103
  PRODUCTIONS = [prod]
104
104
  ```
@@ -44,7 +44,7 @@ class HelloOperation(BusinessOperation):
44
44
  prod = Production("HelloWorld.Production", testing_enabled=True)
45
45
  service = prod.service("HelloService", HelloService)
46
46
  operation = prod.operation("HelloOperation", HelloOperation)
47
- prod.connect(service.Output, operation)
47
+ service.connect(HelloService.Output, operation)
48
48
 
49
49
  PRODUCTIONS = [prod]
50
50
  ```
@@ -93,7 +93,8 @@ If another component sends to the operation, declare a `target()` setting on the
93
93
  sender and connect it:
94
94
 
95
95
  ```python
96
- prod.connect(process.Orders, operation)
96
+ process = prod.process("OrderProcess", OrderProcess)
97
+ process.connect(OrderProcess.Orders, operation)
97
98
  ```
98
99
 
99
100
  ## Migration Command
@@ -85,8 +85,8 @@ process = prod.process("OrderProcess", OrderProcess)
85
85
  accepted = prod.operation("AcceptedOperation", AcceptedOperation)
86
86
  rejected = prod.operation("RejectedOperation", RejectedOperation)
87
87
 
88
- prod.connect(process.Accepted, accepted)
89
- prod.connect(process.Rejected, rejected)
88
+ process.connect(OrderProcess.Accepted, accepted)
89
+ process.connect(OrderProcess.Rejected, rejected)
90
90
  ```
91
91
 
92
92
  ## Migration Command
@@ -113,4 +113,3 @@ iop --migrate settings.py
113
113
  intended precedence explicit.
114
114
  - Calling a downstream component directly instead of sending a production
115
115
  message through a target.
116
-
@@ -55,7 +55,7 @@ In `settings.py`:
55
55
  ```python
56
56
  service = prod.service("FilePollService", FilePollService)
57
57
  operation = prod.operation("TargetOperation", TargetOperation)
58
- prod.connect(service.Output, operation)
58
+ service.connect(FilePollService.Output, operation)
59
59
  ```
60
60
 
61
61
  ## Migration Command
@@ -74,7 +74,7 @@ prod = Production("HelloWorld.Production", testing_enabled=True)
74
74
 
75
75
  service = prod.service("HelloService", HelloService)
76
76
  operation = prod.operation("HelloOperation", HelloOperation)
77
- prod.connect(service.Output, operation)
77
+ service.connect(HelloService.Output, operation)
78
78
 
79
79
  PRODUCTIONS = [prod]
80
80
  ```
@@ -24,7 +24,7 @@ Implementation requirements:
24
24
  - Add services with prod.service(...), processes with prod.process(...), and
25
25
  operations with prod.operation(...).
26
26
  - Use target() attributes on component classes for outbound routing.
27
- - Use prod.connect(source.TargetName, destination) for graph edges.
27
+ - Use component.connect(ComponentClass.TargetName, destination) for graph edges.
28
28
  - Keep PRODUCTIONS = [prod] as the migration entrypoint.
29
29
  - Do not add raw CLASSES entries for components already declared in the
30
30
  Production graph.
@@ -51,8 +51,8 @@ process = prod.process("RouteProcess", RouteProcess)
51
51
  accepted = prod.operation("AcceptedOperation", AcceptedOperation)
52
52
  rejected = prod.operation("RejectedOperation", RejectedOperation)
53
53
 
54
- prod.connect(process.Accepted, accepted)
55
- prod.connect(process.Rejected, rejected)
54
+ process.connect(RouteProcess.Accepted, accepted)
55
+ process.connect(RouteProcess.Rejected, rejected)
56
56
  ```
57
57
 
58
58
  When a route should have a conventional default, pass the target item name to
@@ -126,7 +126,7 @@ prod = Production("HelloWorld.Production", testing_enabled=True)
126
126
 
127
127
  service = prod.service("HelloService", HelloService)
128
128
  operation = prod.operation("HelloOperation", HelloOperation)
129
- prod.connect(service.Output, operation)
129
+ service.connect(HelloService.Output, operation)
130
130
 
131
131
  PRODUCTIONS = [prod]
132
132
  ```
@@ -136,7 +136,7 @@ In this production:
136
136
  - `Production("HelloWorld.Production")` declares the IRIS production class.
137
137
  - `prod.service("HelloService", HelloService)` adds one service item.
138
138
  - `prod.operation("HelloOperation", HelloOperation)` adds one operation item.
139
- - `prod.connect(service.Output, operation)` sets the service `Output` target to `HelloOperation` and records the production graph edge.
139
+ - `service.connect(HelloService.Output, operation)` sets the service `Output` target to `HelloOperation` and records the production graph edge.
140
140
  - `PRODUCTIONS = [prod]` tells IoP what to migrate.
141
141
 
142
142
  You do not need a separate `CLASSES` dictionary for these production components. IoP registers Python component classes from the `Production` graph during migration.
@@ -40,7 +40,7 @@ class OrderOperation(BusinessOperation):
40
40
  prod = Production("Demo.Production", testing_enabled=True)
41
41
  file = prod.service("FileInput", FileService)
42
42
  orders = prod.operation("OrderOperation", OrderOperation)
43
- prod.connect(file.Output, orders)
43
+ file.connect(FileService.Output, orders)
44
44
 
45
45
  PRODUCTIONS = [prod]
46
46
  ```
@@ -55,7 +55,7 @@ Migration registers the generated IRIS proxy classes for `FileService` and
55
55
  `OrderOperation`, then saves `Demo.Production`.
56
56
 
57
57
  `target()` declares a configurable outbound target setting on the component
58
- class. `prod.connect(file.Output, orders)` sets that setting to the destination
58
+ class. `file.connect(FileService.Output, orders)` sets that setting to the destination
59
59
  component and records the production graph edge.
60
60
 
61
61
  When you need to test `FileService` at runtime, do not use `iop --test`.
@@ -0,0 +1,68 @@
1
+ # IoP (Interoperability On Python)
2
+
3
+ [![PyPI - Status](https://img.shields.io/pypi/status/iris-pex-embedded-python)](https://pypi.org/project/iris-pex-embedded-python/)
4
+ [![PyPI](https://img.shields.io/pypi/v/iris-pex-embedded-python)](https://pypi.org/project/iris-pex-embedded-python/)
5
+ [![PyPI - Downloads](https://img.shields.io/pypi/dm/iris-pex-embedded-python)](https://pypi.org/project/iris-pex-embedded-python/)
6
+ [![PyPI - License](https://img.shields.io/pypi/l/iris-pex-embedded-python)](https://pypi.org/project/iris-pex-embedded-python/)
7
+ ![GitHub last commit](https://img.shields.io/github/last-commit/grongierisc/interoperability-embedded-python)
8
+
9
+ Welcome to the **Interoperability On Python (IoP)** proof of concept! This project demonstrates how the **IRIS Interoperability Framework** can be utilized with a **Python-first approach**.
10
+
11
+ Documentation can be found [here](https://grongierisc.github.io/interoperability-embedded-python/).
12
+ For prompt-driven workflows, see [AI-assisted coding with IoP](https://grongierisc.github.io/interoperability-embedded-python/ai-coding/).
13
+ For task-oriented examples, see the [IoP cookbooks](https://grongierisc.github.io/interoperability-embedded-python/cookbooks/).
14
+ For application repositories, start from the [reusable AGENTS.md template](https://grongierisc.github.io/interoperability-embedded-python/agents-template/).
15
+
16
+ ## Example
17
+
18
+ Here's a tiny Python-authored production:
19
+
20
+ ```python
21
+ from dataclasses import dataclass
22
+
23
+ from iop import BusinessOperation, Message, PollingBusinessService, Production, target
24
+
25
+
26
+ @dataclass
27
+ class HelloRequest(Message):
28
+ text: str = "Hello World"
29
+
30
+
31
+ class HelloService(PollingBusinessService):
32
+ Output = target()
33
+
34
+ def on_poll(self):
35
+ self.send_request_async(self.Output, HelloRequest())
36
+
37
+
38
+ class HelloOperation(BusinessOperation):
39
+ def on_message(self, request: HelloRequest):
40
+ self.log_info(request.text)
41
+ return request
42
+
43
+
44
+ prod = Production("HelloWorld.Production", testing_enabled=True)
45
+ service = prod.service("HelloService", HelloService)
46
+ operation = prod.operation("HelloOperation", HelloOperation)
47
+ service.connect(HelloService.Output, operation)
48
+
49
+ PRODUCTIONS = [prod]
50
+ ```
51
+
52
+ ## Installation
53
+
54
+ To start using this proof of concept, install it using pip:
55
+
56
+ ```bash
57
+ pip install iris-pex-embedded-python
58
+ ```
59
+
60
+ ## Getting Started
61
+
62
+ If you're new to this project, begin by reading the [installation guide](https://grongierisc.github.io/interoperability-embedded-python/getting-started/installation). Then, follow the [first steps](https://grongierisc.github.io/interoperability-embedded-python/getting-started/first-steps) to create your first Python-authored production.
63
+
64
+ If you are using an AI coding assistant, start with [AI-assisted coding with IoP](https://grongierisc.github.io/interoperability-embedded-python/ai-coding/).
65
+ For concrete workflows, use the [IoP cookbooks](https://grongierisc.github.io/interoperability-embedded-python/cookbooks/).
66
+ For healthcare productions, also see [Healthcare AI-assisted coding](https://grongierisc.github.io/interoperability-embedded-python/healthcare-ai-coding/).
67
+
68
+ Happy coding!
@@ -145,9 +145,25 @@ Python-authored components use Python classes:
145
145
  prod = Production("Demo.Production")
146
146
  file = prod.service("FileInput", FileService)
147
147
  orders = prod.operation(OrderOperation)
148
- prod.connect(file.Output, orders)
148
+ file.connect(FileService.Output, orders)
149
149
  ```
150
150
 
151
+ For static autocomplete, bind through the component ref and pass the descriptor
152
+ from the component class:
153
+
154
+ ```python
155
+ first = prod.service("FirstInput", FileService)
156
+ second = prod.service("SecondInput", FileService)
157
+ orders = prod.operation(OrderOperation)
158
+
159
+ first.connect(FileService.Output, orders)
160
+ second.connect(FileService.Output, orders)
161
+ ```
162
+
163
+ The left-side `ComponentRef` selects the production item instance, so both
164
+ connections bind the same class-declared target setting to different configured
165
+ items.
166
+
151
167
  For a conventional route, the target can be defaulted on the component class:
152
168
 
153
169
  ```python
@@ -504,7 +504,7 @@ class OrderOperation(BusinessOperation):
504
504
  prod = Production("Demo.Production")
505
505
  file = prod.service("FileInput", FileService)
506
506
  orders = prod.operation(OrderOperation)
507
- prod.connect(file.Output, orders)
507
+ file.connect(FileService.Output, orders)
508
508
  ```
509
509
 
510
510
  The same topology can be declared as a production subclass. Instantiating the
@@ -561,7 +561,7 @@ class FileProduction(Production):
561
561
  `target()` declares a configurable outbound target setting on `FileService`.
562
562
  `Route(FileService.Output, ORDER_OPERATION)` wires that setting to a production
563
563
  item. This separation mirrors the instance-style form:
564
- `prod.connect(file.Output, orders)`.
564
+ `file.connect(FileService.Output, orders)`.
565
565
 
566
566
  For Python component classes, prefer passing the descriptor
567
567
  (`FileService.Output`) to `Route`. For built-in IRIS or ObjectScript classes,
@@ -615,6 +615,19 @@ file = (
615
615
  )
616
616
  ```
617
617
 
618
+ For Python components, `ComponentRef.connect(...)` also accepts the `target()`
619
+ descriptor from the component class. This keeps the left-side production item
620
+ instance explicit while giving static tools autocomplete on the class:
621
+
622
+ ```python
623
+ first = prod.service("FirstInput", FileService)
624
+ second = prod.service("SecondInput", FileService)
625
+ orders = prod.operation(OrderOperation)
626
+
627
+ first.connect(FileService.Output, orders)
628
+ second.connect(FileService.Output, orders)
629
+ ```
630
+
618
631
  For ObjectScript or built-in IRIS components, use manual target setting names:
619
632
 
620
633
  ```python
@@ -642,7 +655,9 @@ instead of shadowing those attributes.
642
655
 
643
656
  Declared target settings are available as dynamic `ComponentRef` attributes,
644
657
  such as `rest.my_target`, and are exposed through `dir(rest)` for runtime
645
- autocomplete.
658
+ autocomplete. For Pylance, mypy, and other static tools, prefer
659
+ `rest.connect(Rest.my_target, operation)` because completion happens on the
660
+ component class.
646
661
 
647
662
  Python `Production` is the source of truth for Python-authored topology. IRIS
648
663
  remains the runtime source of truth. Imported graphs are operational
@@ -41,7 +41,7 @@ class HelloOperation(BusinessOperation):
41
41
  prod = Production("Demo.Production", testing_enabled=True)
42
42
  service = prod.service("HelloService", HelloService)
43
43
  operation = prod.operation("HelloOperation", HelloOperation)
44
- prod.connect(service.Output, operation)
44
+ service.connect(HelloService.Output, operation)
45
45
 
46
46
  PRODUCTIONS = [prod]
47
47
  ```
@@ -201,13 +201,13 @@ class OrderOperation(BusinessOperation):
201
201
  prod = Production("Demo.Production", testing_enabled=True)
202
202
  file = prod.service("FileInput", FileService)
203
203
  orders = prod.operation(OrderOperation)
204
- prod.connect(file.Output, orders)
204
+ file.connect(FileService.Output, orders)
205
205
 
206
206
  PRODUCTIONS = [prod]
207
207
  ```
208
208
 
209
209
  `target()` declares an outbound target setting on the component class.
210
- `prod.connect()` sets that setting to the destination component and
210
+ `component.connect(ComponentClass.Target, destination)` sets that setting to the destination component and
211
211
  records graph edges available to Python.
212
212
 
213
213
  Pass a production item name as the first `target()` argument when a route should
@@ -310,7 +310,7 @@ PRODUCTIONS = [FileProduction()]
310
310
 
311
311
  `target()` declares the outbound target setting on the Python component class.
312
312
  `Route(FileService.Output, ORDER_OPERATION)` wires that setting to a production
313
- item. This is the class-style equivalent of `prod.connect(file.Output, orders)`.
313
+ item. This is the class-style equivalent of `file.connect(FileService.Output, orders)`.
314
314
 
315
315
  For Python component classes, prefer the descriptor form
316
316
  `Route(FileService.Output, ...)`. For existing IRIS classes, use the IRIS
@@ -617,7 +617,7 @@ feed = (
617
617
  .host_setting("Limit", int(os.environ.get("REDDIT_LIMIT", "10")))
618
618
  )
619
619
  exporter = prod.operation("FileExporter", FileOperation)
620
- prod.connect(feed.Output, exporter)
620
+ feed.connect(RedditService.Output, exporter)
621
621
 
622
622
  PRODUCTIONS = [prod]
623
623
  ```
@@ -3,7 +3,7 @@ requires = ["setuptools", "wheel"]
3
3
 
4
4
  [project]
5
5
  name = "iris_pex_embedded_python"
6
- version = "4.0.1b6"
6
+ version = "4.0.1b8"
7
7
  description = "Iris Interoperability based on Embedded Python"
8
8
  readme = "README.md"
9
9
  requires-python = ">=3.10"
@@ -53,6 +53,7 @@ exclude = ["tests*"]
53
53
 
54
54
  [tool.setuptools.package-data]
55
55
  "*" = ["*.cls", "cls/**/*.cls"]
56
+ "iop" = ["py.typed"]
56
57
 
57
58
  [tool.pytest.ini_options]
58
59
  asyncio_default_fixture_loop_scope = "class"
@@ -3,6 +3,8 @@ from __future__ import annotations
3
3
  import importlib
4
4
  from typing import Any
5
5
 
6
+ from ..components.settings import Setting
7
+
6
8
  PRODUCTION_SETTING_FIELDS: dict[str, tuple[str, Any]] = {
7
9
  "shutdown_timeout": ("ShutdownTimeout", 120),
8
10
  "update_timeout": ("UpdateTimeout", 10),
@@ -83,11 +85,21 @@ def _adapter_type_from_class_name(class_name: str | None) -> str:
83
85
  return _adapter_type_from_component_class(component_class)
84
86
 
85
87
 
88
+ def _setting_name(name: Any) -> str:
89
+ if isinstance(name, Setting) and name.name:
90
+ return name.name
91
+ return str(name)
92
+
93
+
94
+ def _normalize_settings_mapping(values: Any) -> dict[str, Any]:
95
+ return {_setting_name(key): value for key, value in dict(values or {}).items()}
96
+
97
+
86
98
  def _settings_to_iris(target_name: str, values: dict[str, Any]) -> list[dict[str, str]]:
87
99
  return [
88
100
  {
89
101
  "@Target": target_name,
90
- "@Name": name,
102
+ "@Name": _setting_name(name),
91
103
  "#text": _text_value(value),
92
104
  }
93
105
  for name, value in values.items()
@@ -97,6 +109,7 @@ def _settings_to_iris(target_name: str, values: dict[str, Any]) -> list[dict[str
97
109
  def _apply_settings_update(target: dict[str, Any], updates: Any) -> None:
98
110
  """Merge *updates* into *target*, treating ``None`` values as removals."""
99
111
  for key, value in (updates or {}).items():
112
+ key = _setting_name(key)
100
113
  if value is None:
101
114
  target.pop(key, None)
102
115
  else:
@@ -168,7 +168,7 @@ class ComponentRef:
168
168
 
169
169
  def connect(
170
170
  self,
171
- target_setting: str | TargetSettingRef,
171
+ target_setting: str | TargetSetting | TargetSettingRef,
172
172
  target_component: ComponentRef | str | None = None,
173
173
  **kwargs: Any,
174
174
  ) -> ComponentRef:
@@ -178,7 +178,7 @@ class ComponentRef:
178
178
 
179
179
  def _coerce_target_setting_ref(
180
180
  self,
181
- target_setting: str | TargetSettingRef,
181
+ target_setting: str | TargetSetting | TargetSettingRef,
182
182
  ) -> TargetSettingRef:
183
183
  if isinstance(target_setting, TargetSettingRef):
184
184
  if target_setting.production is not self.production:
@@ -190,6 +190,28 @@ class ComponentRef:
190
190
  "source target setting belongs to a different component"
191
191
  )
192
192
  return target_setting
193
+ if isinstance(target_setting, TargetSetting):
194
+ owner = target_setting.owner
195
+ if owner is None or not target_setting.name:
196
+ raise ValueError(
197
+ "target setting must be declared on a component class"
198
+ )
199
+ if self.component_class is None or not issubclass(
200
+ self.component_class,
201
+ owner,
202
+ ):
203
+ owner_name = f"{owner.__module__}.{owner.__qualname__}"
204
+ component_name = (
205
+ f"{self.component_class.__module__}."
206
+ f"{self.component_class.__qualname__}"
207
+ if self.component_class is not None
208
+ else self.class_name
209
+ )
210
+ raise ValueError(
211
+ f"target setting {target_setting.name!r} belongs to "
212
+ f"{owner_name}, not {component_name}"
213
+ )
214
+ return self.target_setting(target_setting.name)
193
215
  return self.target_setting(str(target_setting))
194
216
 
195
217
  def inspect(self, *, refresh: bool = True) -> dict[str, Any]:
@@ -2,9 +2,9 @@ from __future__ import annotations
2
2
 
3
3
  from collections.abc import Iterable, Mapping
4
4
  from dataclasses import dataclass, field
5
- from typing import Any, ClassVar, Protocol
5
+ from typing import Any, ClassVar, Protocol, cast
6
6
 
7
- from .common import SETTING_NAME_ALIASES
7
+ from .common import SETTING_NAME_ALIASES, _normalize_settings_mapping
8
8
  from .types import TargetSetting
9
9
 
10
10
 
@@ -36,7 +36,9 @@ class Route:
36
36
  targets = (self.targets,)
37
37
  else:
38
38
  try:
39
- targets = tuple(self.targets)
39
+ targets = tuple(
40
+ cast(Iterable[str | _NamedRouteTarget], self.targets)
41
+ )
40
42
  except TypeError as exc:
41
43
  raise TypeError(
42
44
  f"Route {self.target_setting_name!r} targets must be an item name, "
@@ -174,7 +176,7 @@ def _mapping(
174
176
  item_name: str,
175
177
  ) -> dict[str, Any]:
176
178
  try:
177
- return dict(values or {})
179
+ return _normalize_settings_mapping(values)
178
180
  except (TypeError, ValueError) as exc:
179
181
  raise TypeError(
180
182
  f"Production item {item_name!r} {field_name} must be a mapping"
@@ -9,6 +9,7 @@ from .common import (
9
9
  _adapter_type_from_component_class,
10
10
  _apply_settings_update,
11
11
  _auto_proxy_class_name,
12
+ _normalize_settings_mapping,
12
13
  )
13
14
  from .component import ComponentRef
14
15
  from .declarative import _DeclarativeProductionMixin
@@ -219,10 +220,10 @@ class Production(_DeclarativeProductionMixin):
219
220
 
220
221
  def _resolve_production_name(self, name: str | object) -> str:
221
222
  if name is not _MISSING:
222
- return name # type: ignore[return-value]
223
+ return str(name)
223
224
  class_name = getattr(type(self), "name", _MISSING)
224
225
  if class_name is not _MISSING:
225
- return class_name
226
+ return str(class_name)
226
227
  return f"{type(self).__module__}.{type(self).__name__}"
227
228
 
228
229
  def _production_default(
@@ -432,8 +433,8 @@ class Production(_DeclarativeProductionMixin):
432
433
  comment=comment,
433
434
  log_trace_events=log_trace_events,
434
435
  schedule=schedule,
435
- host_settings=dict(settings or {}),
436
- adapter_settings=dict(adapter_settings or {}),
436
+ host_settings=_normalize_settings_mapping(settings),
437
+ adapter_settings=_normalize_settings_mapping(adapter_settings),
437
438
  )
438
439
  self._add_item(ref)
439
440
  return ref
@@ -570,7 +571,12 @@ class Production(_DeclarativeProductionMixin):
570
571
  )
571
572
  ]
572
573
 
573
- def service(self, name_or_cls: str | type, cls: type | None = None, **kwargs):
574
+ def service(
575
+ self,
576
+ name_or_cls: str | type,
577
+ cls: type | None = None,
578
+ **kwargs: Any,
579
+ ) -> ComponentRef:
574
580
  """Add a BusinessService item to the production graph.
575
581
 
576
582
  See docs/cookbooks/hello-world-production.md and
@@ -578,14 +584,24 @@ class Production(_DeclarativeProductionMixin):
578
584
  """
579
585
  return self.component(name_or_cls, cls, kind="service", **kwargs)
580
586
 
581
- def process(self, name_or_cls: str | type, cls: type | None = None, **kwargs):
587
+ def process(
588
+ self,
589
+ name_or_cls: str | type,
590
+ cls: type | None = None,
591
+ **kwargs: Any,
592
+ ) -> ComponentRef:
582
593
  """Add a BusinessProcess item to the production graph.
583
594
 
584
595
  See docs/cookbooks/add-business-process.md.
585
596
  """
586
597
  return self.component(name_or_cls, cls, kind="process", **kwargs)
587
598
 
588
- def operation(self, name_or_cls: str | type, cls: type | None = None, **kwargs):
599
+ def operation(
600
+ self,
601
+ name_or_cls: str | type,
602
+ cls: type | None = None,
603
+ **kwargs: Any,
604
+ ) -> ComponentRef:
589
605
  """Add a BusinessOperation item to the production graph.
590
606
 
591
607
  See docs/cookbooks/add-business-operation.md.
@@ -650,6 +666,12 @@ class Production(_DeclarativeProductionMixin):
650
666
  mode: str = "replace",
651
667
  ) -> None:
652
668
  if not isinstance(source, TargetSettingRef):
669
+ if isinstance(source, TargetSetting):
670
+ raise TypeError(
671
+ "source must be bound to a production item. Use "
672
+ "component.connect(ComponentClass.Target, target_component) "
673
+ "or prod.connect(component.Target, target_component)."
674
+ )
653
675
  raise TypeError(
654
676
  "source must be a TargetSettingRef returned from a ComponentRef"
655
677
  )
@@ -465,9 +465,7 @@ def _connection_lines(production, variables: dict[str, str], item_names: set[str
465
465
  for source_item, source_target_setting in sorted(grouped):
466
466
  targets = grouped[(source_item, source_target_setting)]
467
467
  source_var = variables[source_item]
468
- source_expr = (
469
- f"{source_var}.target_setting({_literal(source_target_setting)})"
470
- )
468
+ source_expr = _literal(source_target_setting)
471
469
  valid_targets = [target for target in targets if target in variables]
472
470
  invalid_targets = [target for target in targets if target not in variables]
473
471
  for target in invalid_targets:
@@ -476,15 +474,16 @@ def _connection_lines(production, variables: dict[str, str], item_names: set[str
476
474
  continue
477
475
  if len(valid_targets) == 1:
478
476
  lines.append(
479
- f"prod.connect({source_expr}, {variables[valid_targets[0]]})"
477
+ f"{source_var}.connect({source_expr}, {variables[valid_targets[0]]})"
480
478
  )
481
479
  else:
482
480
  lines.append(
483
- f"prod.connect({source_expr}, {variables[valid_targets[0]]})"
481
+ f"{source_var}.connect({source_expr}, {variables[valid_targets[0]]})"
484
482
  )
485
483
  for target in valid_targets[1:]:
486
484
  lines.append(
487
- f"prod.connect({source_expr}, {variables[target]}, mode='add')"
485
+ f"{source_var}.connect({source_expr}, {variables[target]}, "
486
+ "mode='add')"
488
487
  )
489
488
 
490
489
  for edge in production.edges:
@@ -12,7 +12,7 @@ from ..components.settings import Category, Setting, controls
12
12
  class TargetSetting(Setting):
13
13
  """Production target setting descriptor created by target()."""
14
14
 
15
- def __init__(self, default: Any = "", **kwargs: Any):
15
+ def __init__(self, default: str = "", **kwargs: Any):
16
16
  kwargs.setdefault("iris_type", "Ens.DataType.ConfigName")
17
17
  kwargs.setdefault("category", Category.BASIC)
18
18
  kwargs.setdefault("control", controls.production_item())
@@ -34,7 +34,7 @@ class TargetSetting(Setting):
34
34
  return super().__get__(instance, owner)
35
35
 
36
36
 
37
- def target(default: Any = "", **kwargs: Any) -> TargetSetting:
37
+ def target(default: str = "", **kwargs: Any) -> TargetSetting:
38
38
  """Purpose:
39
39
  Declare a configurable outbound target setting on a component class.
40
40