iris-pex-embedded-python 4.0.0b4__tar.gz → 4.0.0b6__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.
- {iris_pex_embedded_python-4.0.0b4/src/iris_pex_embedded_python.egg-info → iris_pex_embedded_python-4.0.0b6}/PKG-INFO +1 -1
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/pyproject.toml +1 -1
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/__init__.py +12 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/cli/main.py +3 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/cli/parser.py +1 -1
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/cls/IOP/Utils.cls +10 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/components/settings.py +11 -1
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/migration/utils.py +15 -5
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/production/__init__.py +10 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/production/common.py +5 -0
- iris_pex_embedded_python-4.0.0b6/src/iop/production/declarations.py +194 -0
- iris_pex_embedded_python-4.0.0b6/src/iop/production/declarative.py +154 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/production/model.py +165 -36
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/production/reconstruction.py +3 -4
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/production/rendering.py +296 -18
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/production/types.py +10 -1
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/production/validation.py +7 -8
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6/src/iris_pex_embedded_python.egg-info}/PKG-INFO +1 -1
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iris_pex_embedded_python.egg-info/SOURCES.txt +2 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/LICENSE +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/README.md +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/setup.cfg +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/__main__.py +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/cli/__init__.py +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/cli/formatting.py +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/cli/types.py +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/cls/IOP/BusinessOperation.cls +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/cls/IOP/BusinessProcess.cls +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/cls/IOP/BusinessService.cls +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/cls/IOP/Common.cls +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/cls/IOP/Director.cls +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/cls/IOP/Duplex/Operation.cls +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/cls/IOP/Duplex/Process.cls +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/cls/IOP/Duplex/Service.cls +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/cls/IOP/Generator/Message/Ack.cls +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/cls/IOP/Generator/Message/Poll.cls +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/cls/IOP/Generator/Message/Start.cls +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/cls/IOP/Generator/Message/StartPickle.cls +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/cls/IOP/Generator/Message/Stop.cls +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/cls/IOP/InboundAdapter.cls +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/cls/IOP/Message/JSONSchema.cls +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/cls/IOP/Message.cls +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/cls/IOP/OutboundAdapter.cls +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/cls/IOP/PickleMessage.cls +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/cls/IOP/PrivateSession/Duplex.cls +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/cls/IOP/PrivateSession/Message/Ack.cls +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/cls/IOP/PrivateSession/Message/Poll.cls +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/cls/IOP/PrivateSession/Message/Start.cls +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/cls/IOP/PrivateSession/Message/Stop.cls +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/cls/IOP/Projection.cls +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/cls/IOP/Service/Remote/Handler.cls +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/cls/IOP/Service/Remote/Rest/v1.cls +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/cls/IOP/Test.cls +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/cls/IOP/Wrapper.cls +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/components/__init__.py +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/components/async_request.py +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/components/business_host.py +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/components/business_operation.py +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/components/business_process.py +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/components/business_service.py +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/components/common.py +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/components/debugpy.py +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/components/generator_request.py +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/components/inbound_adapter.py +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/components/log_manager.py +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/components/outbound_adapter.py +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/components/polling_business_service.py +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/components/private_session_duplex.py +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/components/private_session_process.py +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/messages/__init__.py +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/messages/base.py +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/messages/decorators.py +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/messages/dispatch.py +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/messages/persistent.py +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/messages/serialization.py +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/messages/validation.py +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/migration/__init__.py +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/migration/io.py +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/migration/plans.py +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/production/actions.py +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/production/component.py +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/production/diff.py +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/production/import_.py +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/production/inspection.py +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/production/runtime.py +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/runtime/__init__.py +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/runtime/director.py +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/runtime/environment.py +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/runtime/iris.py +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/runtime/local.py +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/runtime/protocol.py +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/runtime/remote/__init__.py +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/runtime/remote/client.py +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/runtime/remote/director.py +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/runtime/remote/migration.py +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/runtime/remote/settings.py +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/runtime/remote/setup.py +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iris_pex_embedded_python.egg-info/dependency_links.txt +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iris_pex_embedded_python.egg-info/entry_points.txt +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iris_pex_embedded_python.egg-info/requires.txt +0 -0
- {iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iris_pex_embedded_python.egg-info/top_level.txt +0 -0
|
@@ -25,8 +25,11 @@ from iop.migration.utils import list_bindings as list_bindings
|
|
|
25
25
|
from iop.migration.utils import register_component as register_component
|
|
26
26
|
from iop.migration.utils import unbind_component as unbind_component
|
|
27
27
|
from iop.migration.utils import unregister_component as unregister_component
|
|
28
|
+
from iop.production import ComponentItem as ComponentItem
|
|
28
29
|
from iop.production import ComponentRef as ComponentRef
|
|
30
|
+
from iop.production import OperationItem as OperationItem
|
|
29
31
|
from iop.production import Port as Port
|
|
32
|
+
from iop.production import ProcessItem as ProcessItem
|
|
30
33
|
from iop.production import Production as Production
|
|
31
34
|
from iop.production import ProductionDiff as ProductionDiff
|
|
32
35
|
from iop.production import ProductionDiffEntry as ProductionDiffEntry
|
|
@@ -35,6 +38,9 @@ from iop.production import ProductionValidationError as ProductionValidationErro
|
|
|
35
38
|
from iop.production import ProductionValidationIssue as ProductionValidationIssue
|
|
36
39
|
from iop.production import ProductionValidationReport as ProductionValidationReport
|
|
37
40
|
from iop.production import ProductionValidationWarning as ProductionValidationWarning
|
|
41
|
+
from iop.production import Route as Route
|
|
42
|
+
from iop.production import ServiceItem as ServiceItem
|
|
43
|
+
from iop.production import TargetSetting as TargetSetting
|
|
38
44
|
from iop.production import target as target
|
|
39
45
|
from iop.runtime.director import _Director
|
|
40
46
|
from iop.runtime.protocol import DirectorProtocol as DirectorProtocol
|
|
@@ -44,6 +50,7 @@ __all__ = [
|
|
|
44
50
|
"BusinessProcess",
|
|
45
51
|
"BusinessService",
|
|
46
52
|
"Category",
|
|
53
|
+
"ComponentItem",
|
|
47
54
|
"ComponentRef",
|
|
48
55
|
"Director",
|
|
49
56
|
"DirectorProtocol",
|
|
@@ -54,11 +61,13 @@ __all__ = [
|
|
|
54
61
|
"InboundAdapter",
|
|
55
62
|
"Message",
|
|
56
63
|
"Model",
|
|
64
|
+
"OperationItem",
|
|
57
65
|
"OutboundAdapter",
|
|
58
66
|
"PersistentMessage",
|
|
59
67
|
"PickleMessage",
|
|
60
68
|
"PollingBusinessService",
|
|
61
69
|
"Port",
|
|
70
|
+
"ProcessItem",
|
|
62
71
|
"Production",
|
|
63
72
|
"ProductionDiff",
|
|
64
73
|
"ProductionDiffEntry",
|
|
@@ -69,7 +78,10 @@ __all__ = [
|
|
|
69
78
|
"ProductionValidationWarning",
|
|
70
79
|
"PydanticMessage",
|
|
71
80
|
"PydanticPickleMessage",
|
|
81
|
+
"Route",
|
|
82
|
+
"ServiceItem",
|
|
72
83
|
"Setting",
|
|
84
|
+
"TargetSetting",
|
|
73
85
|
"Utils",
|
|
74
86
|
"bind_component",
|
|
75
87
|
"controls",
|
|
@@ -230,6 +230,9 @@ class Command:
|
|
|
230
230
|
if export_format == "python":
|
|
231
231
|
print(production.to_python(), end="")
|
|
232
232
|
return
|
|
233
|
+
if export_format == "class":
|
|
234
|
+
print(production.to_class(), end="")
|
|
235
|
+
return
|
|
233
236
|
if export_format == "graph":
|
|
234
237
|
print(production.graph())
|
|
235
238
|
return
|
|
@@ -105,7 +105,7 @@ def create_parser() -> argparse.ArgumentParser:
|
|
|
105
105
|
export.add_argument(
|
|
106
106
|
"--format",
|
|
107
107
|
dest="export_format",
|
|
108
|
-
choices=("json", "python", "graph"),
|
|
108
|
+
choices=("json", "python", "class", "graph"),
|
|
109
109
|
default="json",
|
|
110
110
|
help="export format for -e/--export",
|
|
111
111
|
)
|
{iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/cls/IOP/Utils.cls
RENAMED
|
@@ -595,6 +595,7 @@ ClassMethod CreateProductionFromJSON(
|
|
|
595
595
|
#dim tPayload As %DynamicObject
|
|
596
596
|
#dim tProductionData As %DynamicObject
|
|
597
597
|
#dim tProduction As Ens.Config.Production
|
|
598
|
+
#dim tProductionClass As %Dictionary.ClassDefinition
|
|
598
599
|
#dim tItems,tDeclaredName
|
|
599
600
|
Try {
|
|
600
601
|
Return:(""=pProductionName) $$$ERROR($$$EnsErrGeneral,"Production name is required.")
|
|
@@ -614,6 +615,15 @@ ClassMethod CreateProductionFromJSON(
|
|
|
614
615
|
}
|
|
615
616
|
}
|
|
616
617
|
|
|
618
|
+
If ('##class(%Dictionary.ClassDefinition).%ExistsId(pProductionName)) {
|
|
619
|
+
Set tProductionClass = ##class(%Dictionary.ClassDefinition).%New()
|
|
620
|
+
Set tProductionClass.Name = pProductionName
|
|
621
|
+
Set tProductionClass.Super = "Ens.Production"
|
|
622
|
+
Set tProductionClass.ClassVersion = 25
|
|
623
|
+
Set tSC = tProductionClass.%Save()
|
|
624
|
+
Quit:$$$ISERR(tSC)
|
|
625
|
+
}
|
|
626
|
+
|
|
617
627
|
Set tProduction = ##class(Ens.Config.Production).%New()
|
|
618
628
|
Set tProduction.Name = pProductionName
|
|
619
629
|
Set tProduction.Description = ..DynamicGet(tProductionData,"Description","")
|
{iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/components/settings.py
RENAMED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
from enum import Enum
|
|
2
|
-
from typing import Any
|
|
4
|
+
from typing import Any, overload
|
|
3
5
|
|
|
4
6
|
_MISSING = object()
|
|
5
7
|
|
|
@@ -45,9 +47,17 @@ class Setting:
|
|
|
45
47
|
self.control = control or ""
|
|
46
48
|
self.exclude = exclude
|
|
47
49
|
self.name = ""
|
|
50
|
+
self.owner = None
|
|
48
51
|
|
|
49
52
|
def __set_name__(self, owner, name):
|
|
50
53
|
self.name = name
|
|
54
|
+
self.owner = owner
|
|
55
|
+
|
|
56
|
+
@overload
|
|
57
|
+
def __get__(self, instance: None, owner: type | None = None) -> Setting: ...
|
|
58
|
+
|
|
59
|
+
@overload
|
|
60
|
+
def __get__(self, instance: object, owner: type | None = None) -> Any: ...
|
|
51
61
|
|
|
52
62
|
def __get__(self, instance, owner=None):
|
|
53
63
|
if instance is None:
|
{iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/migration/utils.py
RENAMED
|
@@ -1036,11 +1036,21 @@ def register_production_definition(production_name: str, production: dict):
|
|
|
1036
1036
|
:param production_name: full IRIS production class name
|
|
1037
1037
|
:param production: normalized {"Production": {...}} dictionary
|
|
1038
1038
|
"""
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1039
|
+
try:
|
|
1040
|
+
raise_on_error(
|
|
1041
|
+
_iris.get_iris()
|
|
1042
|
+
.cls("IOP.Utils")
|
|
1043
|
+
.CreateProductionFromJSON(production_name, json.dumps(production))
|
|
1044
|
+
)
|
|
1045
|
+
except RuntimeError as exc:
|
|
1046
|
+
if not _is_missing_production_class_error(exc, production_name):
|
|
1047
|
+
raise
|
|
1048
|
+
register_production(production_name, dict_to_xml(production))
|
|
1049
|
+
|
|
1050
|
+
|
|
1051
|
+
def _is_missing_production_class_error(exc: RuntimeError, production_name: str) -> bool:
|
|
1052
|
+
message = str(exc)
|
|
1053
|
+
return "CLASS DOES NOT EXIST" in message and production_name in message
|
|
1044
1054
|
|
|
1045
1055
|
|
|
1046
1056
|
def export_production(production_name):
|
{iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/production/__init__.py
RENAMED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from .component import ComponentRef as ComponentRef
|
|
4
|
+
from .declarations import ComponentItem as ComponentItem
|
|
5
|
+
from .declarations import OperationItem as OperationItem
|
|
6
|
+
from .declarations import ProcessItem as ProcessItem
|
|
7
|
+
from .declarations import Route as Route
|
|
8
|
+
from .declarations import ServiceItem as ServiceItem
|
|
4
9
|
from .model import Production as Production
|
|
5
10
|
from .runtime import resolve_target as resolve_target
|
|
6
11
|
from .types import GraphEdge as GraphEdge
|
|
@@ -19,10 +24,13 @@ from .validation import ProductionValidationWarning as ProductionValidationWarni
|
|
|
19
24
|
|
|
20
25
|
__all__ = [
|
|
21
26
|
"ComponentRef",
|
|
27
|
+
"ComponentItem",
|
|
22
28
|
"GraphEdge",
|
|
23
29
|
"GraphNode",
|
|
30
|
+
"OperationItem",
|
|
24
31
|
"PersistentMessageRegistration",
|
|
25
32
|
"Port",
|
|
33
|
+
"ProcessItem",
|
|
26
34
|
"Production",
|
|
27
35
|
"ProductionDiff",
|
|
28
36
|
"ProductionDiffEntry",
|
|
@@ -31,6 +39,8 @@ __all__ = [
|
|
|
31
39
|
"ProductionValidationIssue",
|
|
32
40
|
"ProductionValidationReport",
|
|
33
41
|
"ProductionValidationWarning",
|
|
42
|
+
"Route",
|
|
43
|
+
"ServiceItem",
|
|
34
44
|
"TargetSetting",
|
|
35
45
|
"resolve_target",
|
|
36
46
|
"target",
|
{iris_pex_embedded_python-4.0.0b4 → iris_pex_embedded_python-4.0.0b6}/src/iop/production/common.py
RENAMED
|
@@ -22,6 +22,11 @@ PRODUCTION_SETTING_FIELDS_BY_IRIS: dict[str, str] = {
|
|
|
22
22
|
for field_name, (iris_name, _default) in PRODUCTION_SETTING_FIELDS.items()
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
SETTING_NAME_ALIASES = {
|
|
26
|
+
"target_config_name": "TargetConfigName",
|
|
27
|
+
"target_config_names": "TargetConfigNames",
|
|
28
|
+
}
|
|
29
|
+
|
|
25
30
|
|
|
26
31
|
def _bool_text(value: bool | str) -> str:
|
|
27
32
|
if isinstance(value, bool):
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from collections.abc import Iterable, Mapping
|
|
4
|
+
from dataclasses import dataclass, field
|
|
5
|
+
from typing import Any, ClassVar, Protocol
|
|
6
|
+
|
|
7
|
+
from .common import SETTING_NAME_ALIASES
|
|
8
|
+
from .types import TargetSetting
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class _NamedRouteTarget(Protocol):
|
|
12
|
+
@property
|
|
13
|
+
def name(self) -> str: ...
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@dataclass(frozen=True)
|
|
17
|
+
class Route:
|
|
18
|
+
"""Declarative route from a production item port to one or more targets."""
|
|
19
|
+
|
|
20
|
+
port: str | TargetSetting
|
|
21
|
+
targets: str | _NamedRouteTarget | Iterable[str | _NamedRouteTarget]
|
|
22
|
+
logical_name: str = ""
|
|
23
|
+
|
|
24
|
+
@property
|
|
25
|
+
def port_name(self) -> str:
|
|
26
|
+
return normalize_route_port(self.port)
|
|
27
|
+
|
|
28
|
+
@property
|
|
29
|
+
def port_owner(self) -> type | None:
|
|
30
|
+
if isinstance(self.port, TargetSetting):
|
|
31
|
+
return self.port.owner
|
|
32
|
+
return None
|
|
33
|
+
|
|
34
|
+
@property
|
|
35
|
+
def route_logical_name(self) -> str:
|
|
36
|
+
if self.logical_name:
|
|
37
|
+
return self.logical_name
|
|
38
|
+
if isinstance(self.port, TargetSetting):
|
|
39
|
+
return self.port.logical_name
|
|
40
|
+
return ""
|
|
41
|
+
|
|
42
|
+
@property
|
|
43
|
+
def target_names(self) -> tuple[str, ...]:
|
|
44
|
+
if _is_route_target(self.targets):
|
|
45
|
+
targets = (self.targets,)
|
|
46
|
+
else:
|
|
47
|
+
try:
|
|
48
|
+
targets = tuple(self.targets)
|
|
49
|
+
except TypeError as exc:
|
|
50
|
+
raise TypeError(
|
|
51
|
+
f"Route {self.port_name!r} targets must be an item name, "
|
|
52
|
+
"a production item declaration, or an iterable of either"
|
|
53
|
+
) from exc
|
|
54
|
+
if not targets:
|
|
55
|
+
raise ValueError(f"Route {self.port_name!r} requires at least one target")
|
|
56
|
+
return tuple(_route_target_name(target, self.port_name) for target in targets)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
@dataclass(frozen=True)
|
|
60
|
+
class _ProductionItemDeclaration:
|
|
61
|
+
name: str
|
|
62
|
+
component: type | str | None = None
|
|
63
|
+
class_name: str | None = None
|
|
64
|
+
adapter_class: type | str | None = None
|
|
65
|
+
adapter_class_name: str | None = None
|
|
66
|
+
enabled: bool | str = True
|
|
67
|
+
pool_size: int | str = 1
|
|
68
|
+
category: str = ""
|
|
69
|
+
foreground: bool | str = False
|
|
70
|
+
comment: str = ""
|
|
71
|
+
log_trace_events: bool | str = False
|
|
72
|
+
schedule: str = ""
|
|
73
|
+
settings: Mapping[str, Any] | None = None
|
|
74
|
+
host_settings: Mapping[str, Any] | None = None
|
|
75
|
+
adapter_settings: Mapping[str, Any] | None = None
|
|
76
|
+
other_settings: Iterable[Mapping[str, Any]] | None = None
|
|
77
|
+
routes: Route | Iterable[Route] | None = field(default_factory=tuple)
|
|
78
|
+
|
|
79
|
+
kind: ClassVar[str] = "component"
|
|
80
|
+
|
|
81
|
+
@property
|
|
82
|
+
def host_setting_values(self) -> dict[str, Any]:
|
|
83
|
+
settings = _mapping(self.settings, "settings", self.name)
|
|
84
|
+
host_settings = _mapping(self.host_settings, "host_settings", self.name)
|
|
85
|
+
duplicates = sorted(settings.keys() & host_settings.keys())
|
|
86
|
+
if duplicates:
|
|
87
|
+
names = ", ".join(repr(name) for name in duplicates)
|
|
88
|
+
raise ValueError(
|
|
89
|
+
f"{self.kind.title()} item {self.name!r} declares duplicate "
|
|
90
|
+
f"Host setting keys: {names}"
|
|
91
|
+
)
|
|
92
|
+
merged = dict(settings)
|
|
93
|
+
merged.update(host_settings)
|
|
94
|
+
return merged
|
|
95
|
+
|
|
96
|
+
@property
|
|
97
|
+
def adapter_setting_values(self) -> dict[str, Any]:
|
|
98
|
+
return _mapping(self.adapter_settings, "adapter_settings", self.name)
|
|
99
|
+
|
|
100
|
+
@property
|
|
101
|
+
def other_setting_values(self) -> list[dict[str, Any]]:
|
|
102
|
+
return [dict(setting) for setting in self.other_settings or ()]
|
|
103
|
+
|
|
104
|
+
@property
|
|
105
|
+
def route_values(self) -> tuple[Route, ...]:
|
|
106
|
+
if self.routes is None:
|
|
107
|
+
return ()
|
|
108
|
+
if isinstance(self.routes, Route):
|
|
109
|
+
return (self.routes,)
|
|
110
|
+
routes = tuple(self.routes)
|
|
111
|
+
for route in routes:
|
|
112
|
+
if not isinstance(route, Route):
|
|
113
|
+
raise TypeError(
|
|
114
|
+
f"{self.kind.title()} item {self.name!r} routes must be Route "
|
|
115
|
+
f"instances"
|
|
116
|
+
)
|
|
117
|
+
return routes
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
@dataclass(frozen=True)
|
|
121
|
+
class ServiceItem(_ProductionItemDeclaration):
|
|
122
|
+
kind: ClassVar[str] = "service"
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
@dataclass(frozen=True)
|
|
126
|
+
class ComponentItem(_ProductionItemDeclaration):
|
|
127
|
+
kind: ClassVar[str] = "component"
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
@dataclass(frozen=True)
|
|
131
|
+
class ProcessItem(_ProductionItemDeclaration):
|
|
132
|
+
kind: ClassVar[str] = "process"
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
@dataclass(frozen=True)
|
|
136
|
+
class OperationItem(_ProductionItemDeclaration):
|
|
137
|
+
kind: ClassVar[str] = "operation"
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
def normalize_route_port(name: str | TargetSetting) -> str:
|
|
141
|
+
"""Normalize known Pythonic route aliases without changing other settings."""
|
|
142
|
+
|
|
143
|
+
if isinstance(name, TargetSetting):
|
|
144
|
+
if not name.name:
|
|
145
|
+
raise ValueError(
|
|
146
|
+
"Route target setting must be declared on a component class"
|
|
147
|
+
)
|
|
148
|
+
return name.name
|
|
149
|
+
port_name = str(name)
|
|
150
|
+
return SETTING_NAME_ALIASES.get(port_name, port_name)
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
def normalize_route_port_for_match(name: str | TargetSetting) -> str:
|
|
154
|
+
return normalize_route_port(name)
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def _is_route_target(value: Any) -> bool:
|
|
158
|
+
return isinstance(value, str) or isinstance(value, _ProductionItemDeclaration)
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
def _route_target_name(value: Any, port_name: str) -> str:
|
|
162
|
+
if isinstance(value, str):
|
|
163
|
+
if value:
|
|
164
|
+
return value
|
|
165
|
+
elif isinstance(value, _ProductionItemDeclaration):
|
|
166
|
+
if value.name:
|
|
167
|
+
return value.name
|
|
168
|
+
|
|
169
|
+
raise TypeError(
|
|
170
|
+
f"Route {port_name!r} targets must be item names or production item "
|
|
171
|
+
"declarations"
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
def _mapping(
|
|
176
|
+
values: Mapping[str, Any] | None,
|
|
177
|
+
field_name: str,
|
|
178
|
+
item_name: str,
|
|
179
|
+
) -> dict[str, Any]:
|
|
180
|
+
try:
|
|
181
|
+
return dict(values or {})
|
|
182
|
+
except (TypeError, ValueError) as exc:
|
|
183
|
+
raise TypeError(
|
|
184
|
+
f"Production item {item_name!r} {field_name} must be a mapping"
|
|
185
|
+
) from exc
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
__all__ = [
|
|
189
|
+
"ComponentItem",
|
|
190
|
+
"OperationItem",
|
|
191
|
+
"ProcessItem",
|
|
192
|
+
"Route",
|
|
193
|
+
"ServiceItem",
|
|
194
|
+
]
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from collections.abc import Iterable
|
|
4
|
+
from typing import Any, ClassVar
|
|
5
|
+
|
|
6
|
+
from .component import ComponentRef
|
|
7
|
+
from .declarations import (
|
|
8
|
+
_ProductionItemDeclaration,
|
|
9
|
+
normalize_route_port_for_match,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class _DeclarativeProductionMixin:
|
|
14
|
+
components: ClassVar[Iterable[_ProductionItemDeclaration] | None] = ()
|
|
15
|
+
services: ClassVar[Iterable[_ProductionItemDeclaration] | None] = ()
|
|
16
|
+
processes: ClassVar[Iterable[_ProductionItemDeclaration] | None] = ()
|
|
17
|
+
operations: ClassVar[Iterable[_ProductionItemDeclaration] | None] = ()
|
|
18
|
+
|
|
19
|
+
def _hydrate_declared_items(self) -> None:
|
|
20
|
+
declarations: list[_ProductionItemDeclaration] = []
|
|
21
|
+
for attr_name, expected_kind in (
|
|
22
|
+
("components", "component"),
|
|
23
|
+
("services", "service"),
|
|
24
|
+
("processes", "process"),
|
|
25
|
+
("operations", "operation"),
|
|
26
|
+
):
|
|
27
|
+
for declaration in self._declared_items(attr_name):
|
|
28
|
+
if declaration.kind != expected_kind:
|
|
29
|
+
raise TypeError(
|
|
30
|
+
f"{attr_name} must contain {expected_kind.title()}Item "
|
|
31
|
+
f"declarations"
|
|
32
|
+
)
|
|
33
|
+
self._raise_declared_route_conflicts(declaration)
|
|
34
|
+
self._add_declared_item(declaration)
|
|
35
|
+
declarations.append(declaration)
|
|
36
|
+
|
|
37
|
+
for declaration in declarations:
|
|
38
|
+
self._connect_declared_routes(declaration)
|
|
39
|
+
|
|
40
|
+
def _declared_items(self, attr_name: str) -> tuple[_ProductionItemDeclaration, ...]:
|
|
41
|
+
values = getattr(type(self), attr_name, ())
|
|
42
|
+
if values is None:
|
|
43
|
+
return ()
|
|
44
|
+
if isinstance(values, _ProductionItemDeclaration):
|
|
45
|
+
return (values,)
|
|
46
|
+
try:
|
|
47
|
+
declarations = tuple(values)
|
|
48
|
+
except TypeError as exc:
|
|
49
|
+
raise TypeError(f"{attr_name} must be an iterable of item declarations") from exc
|
|
50
|
+
for declaration in declarations:
|
|
51
|
+
if not isinstance(declaration, _ProductionItemDeclaration):
|
|
52
|
+
raise TypeError(f"{attr_name} must contain production item declarations")
|
|
53
|
+
return declarations
|
|
54
|
+
|
|
55
|
+
def _raise_declared_route_conflicts(
|
|
56
|
+
self,
|
|
57
|
+
declaration: _ProductionItemDeclaration,
|
|
58
|
+
) -> None:
|
|
59
|
+
host_ports = {
|
|
60
|
+
normalize_route_port_for_match(name)
|
|
61
|
+
for name in declaration.host_setting_values
|
|
62
|
+
}
|
|
63
|
+
route_ports = {route.port_name for route in declaration.route_values}
|
|
64
|
+
conflicts = sorted(host_ports & route_ports)
|
|
65
|
+
if not conflicts:
|
|
66
|
+
return
|
|
67
|
+
names = ", ".join(repr(name) for name in conflicts)
|
|
68
|
+
raise ValueError(
|
|
69
|
+
f"{declaration.kind.title()} item {declaration.name!r} declares route "
|
|
70
|
+
f"port(s) in Host settings: {names}. Declare route ports with Route only."
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
def _add_declared_item(self, declaration: _ProductionItemDeclaration) -> None:
|
|
74
|
+
kwargs: dict[str, Any] = {
|
|
75
|
+
"enabled": declaration.enabled,
|
|
76
|
+
"pool_size": declaration.pool_size,
|
|
77
|
+
"category": declaration.category,
|
|
78
|
+
"foreground": declaration.foreground,
|
|
79
|
+
"comment": declaration.comment,
|
|
80
|
+
"log_trace_events": declaration.log_trace_events,
|
|
81
|
+
"schedule": declaration.schedule,
|
|
82
|
+
"settings": declaration.host_setting_values,
|
|
83
|
+
"adapter_settings": declaration.adapter_setting_values,
|
|
84
|
+
}
|
|
85
|
+
if declaration.adapter_class is not None:
|
|
86
|
+
kwargs["adapter_class"] = declaration.adapter_class
|
|
87
|
+
if declaration.adapter_class_name is not None:
|
|
88
|
+
kwargs["adapter_class_name"] = declaration.adapter_class_name
|
|
89
|
+
|
|
90
|
+
method = {
|
|
91
|
+
"component": self.component,
|
|
92
|
+
"service": self.service,
|
|
93
|
+
"process": self.process,
|
|
94
|
+
"operation": self.operation,
|
|
95
|
+
}[declaration.kind]
|
|
96
|
+
|
|
97
|
+
component = declaration.component
|
|
98
|
+
if isinstance(component, type):
|
|
99
|
+
if declaration.class_name is not None:
|
|
100
|
+
kwargs["class_name"] = declaration.class_name
|
|
101
|
+
ref = method(declaration.name, component, **kwargs)
|
|
102
|
+
ref.other_settings = declaration.other_setting_values
|
|
103
|
+
return
|
|
104
|
+
|
|
105
|
+
class_name = declaration.class_name
|
|
106
|
+
if component is not None:
|
|
107
|
+
component_class_name = str(component)
|
|
108
|
+
if class_name is not None and class_name != component_class_name:
|
|
109
|
+
raise ValueError(
|
|
110
|
+
f"{declaration.kind.title()} item {declaration.name!r} "
|
|
111
|
+
"declares conflicting component and class_name values"
|
|
112
|
+
)
|
|
113
|
+
class_name = component_class_name
|
|
114
|
+
|
|
115
|
+
if class_name is None:
|
|
116
|
+
raise ValueError(
|
|
117
|
+
f"{declaration.kind.title()} item {declaration.name!r} requires "
|
|
118
|
+
"a component class or class_name"
|
|
119
|
+
)
|
|
120
|
+
kwargs["class_name"] = class_name
|
|
121
|
+
ref = method(declaration.name, **kwargs)
|
|
122
|
+
ref.other_settings = declaration.other_setting_values
|
|
123
|
+
|
|
124
|
+
def _connect_declared_routes(self, declaration: _ProductionItemDeclaration) -> None:
|
|
125
|
+
source = self.item(declaration.name)
|
|
126
|
+
for route in declaration.route_values:
|
|
127
|
+
self._raise_if_route_port_owner_mismatch(source, route)
|
|
128
|
+
port = source.port(
|
|
129
|
+
route.port_name,
|
|
130
|
+
logical_name=route.route_logical_name,
|
|
131
|
+
)
|
|
132
|
+
targets = route.target_names
|
|
133
|
+
self.connect(port, targets[0])
|
|
134
|
+
for target in targets[1:]:
|
|
135
|
+
self.connect_add(port, target)
|
|
136
|
+
|
|
137
|
+
def _raise_if_route_port_owner_mismatch(
|
|
138
|
+
self,
|
|
139
|
+
source: ComponentRef,
|
|
140
|
+
route: Any,
|
|
141
|
+
) -> None:
|
|
142
|
+
owner = route.port_owner
|
|
143
|
+
if (
|
|
144
|
+
owner is None
|
|
145
|
+
or source.component_class is None
|
|
146
|
+
or issubclass(source.component_class, owner)
|
|
147
|
+
):
|
|
148
|
+
return
|
|
149
|
+
raise ValueError(
|
|
150
|
+
f"Route port {route.port_name!r} belongs to "
|
|
151
|
+
f"{owner.__module__}.{owner.__qualname__}, not "
|
|
152
|
+
f"{source.component_class.__module__}."
|
|
153
|
+
f"{source.component_class.__qualname__}"
|
|
154
|
+
)
|