iris-pex-embedded-python 4.0.0b10__tar.gz → 4.0.0b11__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 (104) hide show
  1. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/PKG-INFO +1 -1
  2. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/pyproject.toml +1 -1
  3. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/production/reconstruction.py +31 -3
  4. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/production/source_inference.py +61 -13
  5. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iris_pex_embedded_python.egg-info/PKG-INFO +1 -1
  6. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/LICENSE +0 -0
  7. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/README.md +0 -0
  8. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/setup.cfg +0 -0
  9. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/__init__.py +0 -0
  10. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/__main__.py +0 -0
  11. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/cli/__init__.py +0 -0
  12. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/cli/formatting.py +0 -0
  13. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/cli/main.py +0 -0
  14. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/cli/parser.py +0 -0
  15. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/cli/types.py +0 -0
  16. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/cls/IOP/BusinessOperation.cls +0 -0
  17. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/cls/IOP/BusinessProcess.cls +0 -0
  18. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/cls/IOP/BusinessService.cls +0 -0
  19. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/cls/IOP/Common.cls +0 -0
  20. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/cls/IOP/Director.cls +0 -0
  21. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/cls/IOP/Duplex/Operation.cls +0 -0
  22. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/cls/IOP/Duplex/Process.cls +0 -0
  23. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/cls/IOP/Duplex/Service.cls +0 -0
  24. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/cls/IOP/Generator/Message/Ack.cls +0 -0
  25. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/cls/IOP/Generator/Message/Poll.cls +0 -0
  26. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/cls/IOP/Generator/Message/Start.cls +0 -0
  27. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/cls/IOP/Generator/Message/StartPickle.cls +0 -0
  28. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/cls/IOP/Generator/Message/Stop.cls +0 -0
  29. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/cls/IOP/InboundAdapter.cls +0 -0
  30. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/cls/IOP/Message/JSONSchema.cls +0 -0
  31. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/cls/IOP/Message.cls +0 -0
  32. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/cls/IOP/OutboundAdapter.cls +0 -0
  33. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/cls/IOP/PickleMessage.cls +0 -0
  34. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/cls/IOP/PrivateSession/Duplex.cls +0 -0
  35. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/cls/IOP/PrivateSession/Message/Ack.cls +0 -0
  36. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/cls/IOP/PrivateSession/Message/Poll.cls +0 -0
  37. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/cls/IOP/PrivateSession/Message/Start.cls +0 -0
  38. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/cls/IOP/PrivateSession/Message/Stop.cls +0 -0
  39. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/cls/IOP/Projection.cls +0 -0
  40. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/cls/IOP/Service/Remote/Handler.cls +0 -0
  41. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/cls/IOP/Service/Remote/Rest/v1.cls +0 -0
  42. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/cls/IOP/Test.cls +0 -0
  43. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/cls/IOP/Utils.cls +0 -0
  44. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/cls/IOP/Wrapper.cls +0 -0
  45. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/components/__init__.py +0 -0
  46. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/components/async_request.py +0 -0
  47. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/components/business_host.py +0 -0
  48. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/components/business_operation.py +0 -0
  49. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/components/business_process.py +0 -0
  50. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/components/business_service.py +0 -0
  51. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/components/common.py +0 -0
  52. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/components/debugpy.py +0 -0
  53. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/components/generator_request.py +0 -0
  54. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/components/inbound_adapter.py +0 -0
  55. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/components/log_manager.py +0 -0
  56. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/components/outbound_adapter.py +0 -0
  57. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/components/polling_business_service.py +0 -0
  58. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/components/private_session_duplex.py +0 -0
  59. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/components/private_session_process.py +0 -0
  60. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/components/settings.py +0 -0
  61. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/messages/__init__.py +0 -0
  62. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/messages/base.py +0 -0
  63. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/messages/decorators.py +0 -0
  64. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/messages/dispatch.py +0 -0
  65. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/messages/persistent.py +0 -0
  66. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/messages/serialization.py +0 -0
  67. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/messages/validation.py +0 -0
  68. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/migration/__init__.py +0 -0
  69. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/migration/io.py +0 -0
  70. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/migration/manifest.py +0 -0
  71. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/migration/plans.py +0 -0
  72. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/migration/utils.py +0 -0
  73. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/production/__init__.py +0 -0
  74. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/production/actions.py +0 -0
  75. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/production/common.py +0 -0
  76. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/production/component.py +0 -0
  77. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/production/declarations.py +0 -0
  78. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/production/declarative.py +0 -0
  79. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/production/diff.py +0 -0
  80. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/production/import_.py +0 -0
  81. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/production/inspection.py +0 -0
  82. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/production/model.py +0 -0
  83. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/production/planning.py +0 -0
  84. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/production/rendering.py +0 -0
  85. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/production/runtime.py +0 -0
  86. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/production/types.py +0 -0
  87. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/production/validation.py +0 -0
  88. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/runtime/__init__.py +0 -0
  89. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/runtime/director.py +0 -0
  90. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/runtime/environment.py +0 -0
  91. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/runtime/iris.py +0 -0
  92. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/runtime/local.py +0 -0
  93. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/runtime/protocol.py +0 -0
  94. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/runtime/remote/__init__.py +0 -0
  95. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/runtime/remote/client.py +0 -0
  96. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/runtime/remote/director.py +0 -0
  97. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/runtime/remote/migration.py +0 -0
  98. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/runtime/remote/settings.py +0 -0
  99. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iop/runtime/remote/setup.py +0 -0
  100. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iris_pex_embedded_python.egg-info/SOURCES.txt +0 -0
  101. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iris_pex_embedded_python.egg-info/dependency_links.txt +0 -0
  102. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iris_pex_embedded_python.egg-info/entry_points.txt +0 -0
  103. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/src/iris_pex_embedded_python.egg-info/requires.txt +0 -0
  104. {iris_pex_embedded_python-4.0.0b10 → iris_pex_embedded_python-4.0.0b11}/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.0b10
3
+ Version: 4.0.0b11
4
4
  Summary: Iris Interoperability based on Embedded Python
5
5
  Author-email: grongier <guillaume.rongier@intersystems.com>
6
6
  License: MIT License
@@ -3,7 +3,7 @@ requires = ["setuptools", "wheel"]
3
3
 
4
4
  [project]
5
5
  name = "iris_pex_embedded_python"
6
- version = "4.0.0b10"
6
+ version = "4.0.0b11"
7
7
  description = "Iris Interoperability based on Embedded Python"
8
8
  readme = "README.md"
9
9
  requires-python = ">=3.10"
@@ -218,17 +218,24 @@ def _infer_connections_from_host_settings(
218
218
  runtime_sources_with_targets: set[str],
219
219
  ) -> None:
220
220
  for ref in production._items:
221
- if ref.name in runtime_sources_with_targets:
222
- continue
223
221
  for setting_name, value in ref.host_settings.items():
224
222
  if str(setting_name).startswith("%"):
225
223
  continue
224
+ has_runtime_targets = ref.name in runtime_sources_with_targets
225
+ if has_runtime_targets and not _is_target_config_setting(setting_name):
226
+ continue
226
227
  for target_name in _setting_targets(value):
227
228
  if target_name not in production._items_by_name:
228
229
  continue
230
+ if _has_connection(production, ref.name, setting_name, target_name):
231
+ continue
229
232
  ref.target_setting_names.add(setting_name)
230
233
  metadata = {"source": "Host setting fallback"}
231
- if ref.name in runtime_sources:
234
+ if has_runtime_targets:
235
+ metadata["reason"] = (
236
+ "runtime discovery did not report this target setting"
237
+ )
238
+ elif ref.name in runtime_sources:
232
239
  metadata["reason"] = "runtime discovery returned no targets"
233
240
  production._register_connection(
234
241
  ref.name,
@@ -240,6 +247,27 @@ def _infer_connections_from_host_settings(
240
247
  )
241
248
 
242
249
 
250
+ def _is_target_config_setting(setting_name: Any) -> bool:
251
+ normalized = str(setting_name or "").strip().lower()
252
+ return normalized.endswith("targetconfigname") or normalized.endswith(
253
+ "targetconfignames"
254
+ )
255
+
256
+
257
+ def _has_connection(
258
+ production,
259
+ source_item: str,
260
+ source_target_setting: str,
261
+ target_name: str,
262
+ ) -> bool:
263
+ return any(
264
+ edge.source_item == source_item
265
+ and edge.source_target_setting == source_target_setting
266
+ and edge.target == target_name
267
+ for edge in production._edges
268
+ )
269
+
270
+
243
271
  def _infer_connections_from_source(production) -> None:
244
272
  existing = {
245
273
  (edge.source_item, edge.target): edge
@@ -15,6 +15,7 @@ class SourceConnection:
15
15
  source: str
16
16
  detail: str = ""
17
17
  interaction: str = "request"
18
+ target_reference: str = ""
18
19
 
19
20
 
20
21
  _PYTHON_REQUEST_METHODS = {
@@ -93,7 +94,7 @@ def infer_source_connections(
93
94
 
94
95
  def _infer_python_connections(
95
96
  class_name: str,
96
- _host_settings: dict[str, Any],
97
+ host_settings: dict[str, Any],
97
98
  roots: tuple[Path, ...],
98
99
  ) -> list[SourceConnection]:
99
100
  candidates = []
@@ -114,7 +115,12 @@ def _infer_python_connections(
114
115
 
115
116
  connections: list[SourceConnection] = []
116
117
  for _root_index, candidate in candidates[:1]:
117
- connections.extend(candidate.connections)
118
+ connections.extend(
119
+ _python_connections_for_host_settings(
120
+ candidate.connections,
121
+ host_settings,
122
+ )
123
+ )
118
124
  return _unique_connections(connections)
119
125
 
120
126
 
@@ -281,7 +287,7 @@ def _python_class_connections(class_node: ast.ClassDef) -> list[SourceConnection
281
287
  continue
282
288
  call_name = _python_call_name(node.func)
283
289
  if call_name in _PYTHON_REQUEST_METHODS:
284
- for target, detail, interaction in _python_request_targets(
290
+ for target, detail, interaction, target_reference in _python_request_targets(
285
291
  node,
286
292
  string_values,
287
293
  call_name,
@@ -292,10 +298,11 @@ def _python_class_connections(class_node: ast.ClassDef) -> list[SourceConnection
292
298
  source="Python source",
293
299
  detail=detail,
294
300
  interaction=interaction,
301
+ target_reference=target_reference,
295
302
  )
296
303
  )
297
304
  elif call_name in _PYTHON_MULTI_REQUEST_METHODS:
298
- for target, detail, interaction in _python_multi_request_targets(
305
+ for target, detail, interaction, target_reference in _python_multi_request_targets(
299
306
  node,
300
307
  string_values,
301
308
  call_name,
@@ -306,6 +313,7 @@ def _python_class_connections(class_node: ast.ClassDef) -> list[SourceConnection
306
313
  source="Python source",
307
314
  detail=detail,
308
315
  interaction=interaction,
316
+ target_reference=target_reference,
309
317
  )
310
318
  )
311
319
  return _unique_connections(connections)
@@ -367,7 +375,7 @@ def _python_request_targets(
367
375
  call: ast.Call,
368
376
  string_values: dict[str, list[str]],
369
377
  call_name: str,
370
- ) -> list[tuple[str, str, str]]:
378
+ ) -> list[tuple[str, str, str, str]]:
371
379
  target_node = _python_call_target_node(call)
372
380
  if target_node is None:
373
381
  return []
@@ -383,14 +391,14 @@ def _python_multi_request_targets(
383
391
  call: ast.Call,
384
392
  string_values: dict[str, list[str]],
385
393
  call_name: str,
386
- ) -> list[tuple[str, str, str]]:
394
+ ) -> list[tuple[str, str, str, str]]:
387
395
  if not call.args:
388
396
  return []
389
397
  collection = call.args[0]
390
398
  if not isinstance(collection, (ast.List, ast.Tuple)):
391
399
  return []
392
400
 
393
- targets: list[tuple[str, str, str]] = []
401
+ targets: list[tuple[str, str, str, str]] = []
394
402
  for item in collection.elts:
395
403
  if not isinstance(item, ast.Tuple) or not item.elts:
396
404
  continue
@@ -410,20 +418,59 @@ def _resolve_python_targets(
410
418
  string_values: dict[str, list[str]],
411
419
  call_name: str,
412
420
  interaction: str,
413
- ) -> list[tuple[str, str, str]]:
421
+ ) -> list[tuple[str, str, str, str]]:
414
422
  literal = _python_literal_string(node)
415
423
  if literal is not None:
416
- return [(literal, f"{call_name} literal", interaction)]
424
+ return [(literal, f"{call_name} literal", interaction, "")]
417
425
 
418
426
  name = _python_reference_name(node)
419
427
  if name is None:
420
428
  return []
429
+ detail = f"{call_name} {name}"
430
+ values = string_values.get(name, [])
431
+ if not values:
432
+ return [("", detail, interaction, name)]
421
433
  return [
422
- (value, f"{call_name} {name}", interaction)
423
- for value in string_values.get(name, [])
434
+ (value, detail, interaction, name)
435
+ for value in values
424
436
  ]
425
437
 
426
438
 
439
+ def _python_connections_for_host_settings(
440
+ connections: tuple[SourceConnection, ...],
441
+ host_settings: dict[str, Any],
442
+ ) -> list[SourceConnection]:
443
+ resolved: list[SourceConnection] = []
444
+ for connection in connections:
445
+ setting_name = _python_reference_setting_name(connection.target_reference)
446
+ setting_targets = (
447
+ _split_targets(host_settings.get(setting_name, ""))
448
+ if setting_name
449
+ else []
450
+ )
451
+ if setting_targets:
452
+ for target in setting_targets:
453
+ resolved.append(
454
+ SourceConnection(
455
+ target=target,
456
+ source=connection.source,
457
+ detail=connection.detail,
458
+ interaction=connection.interaction,
459
+ target_reference=connection.target_reference,
460
+ )
461
+ )
462
+ continue
463
+ if connection.target:
464
+ resolved.append(connection)
465
+ return resolved
466
+
467
+
468
+ def _python_reference_setting_name(reference: str) -> str:
469
+ if not reference.startswith("self."):
470
+ return ""
471
+ return reference.removeprefix("self.")
472
+
473
+
427
474
  def _python_call_target_node(call: ast.Call) -> ast.AST | None:
428
475
  for keyword in call.keywords:
429
476
  if keyword.arg == "target":
@@ -664,15 +711,16 @@ def _root_key(root: Path) -> str:
664
711
 
665
712
  def _unique_connections(connections: list[SourceConnection]) -> list[SourceConnection]:
666
713
  unique: list[SourceConnection] = []
667
- seen: set[tuple[str, str, str, str]] = set()
714
+ seen: set[tuple[str, str, str, str, str]] = set()
668
715
  for connection in connections:
669
- if not connection.target:
716
+ if not connection.target and not connection.target_reference:
670
717
  continue
671
718
  key = (
672
719
  connection.target,
673
720
  connection.source,
674
721
  connection.detail,
675
722
  connection.interaction,
723
+ connection.target_reference,
676
724
  )
677
725
  if key in seen:
678
726
  continue
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: iris_pex_embedded_python
3
- Version: 4.0.0b10
3
+ Version: 4.0.0b11
4
4
  Summary: Iris Interoperability based on Embedded Python
5
5
  Author-email: grongier <guillaume.rongier@intersystems.com>
6
6
  License: MIT License