iris-pex-embedded-python 3.2.1b3__py3-none-any.whl → 3.3.0__py3-none-any.whl

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.

Potentially problematic release.


This version of iris-pex-embedded-python might be problematic. Click here for more details.

@@ -1,10 +1,10 @@
1
1
  from iop._business_process import _BusinessProcess
2
- from iop._business_host import _BusinessHost
2
+ from iop._decorators import input_deserializer, output_serializer, input_serializer, output_deserializer
3
3
 
4
4
  class _PrivateSessionProcess(_BusinessProcess):
5
5
 
6
- @_BusinessHost.input_deserialzer
7
- @_BusinessHost.output_serialzer
6
+ @input_deserializer
7
+ @output_serializer
8
8
  def _dispatch_on_document(self, host_object,source_config_name, request):
9
9
  """ For internal use only. """
10
10
  self._restore_persistent_properties(host_object)
@@ -16,8 +16,8 @@ class _PrivateSessionProcess(_BusinessProcess):
16
16
  pass
17
17
 
18
18
 
19
- @_BusinessHost.input_deserialzer
20
- @_BusinessHost.output_serialzer
19
+ @input_deserializer
20
+ @output_serializer
21
21
  def _dispatch_on_private_session_started(self, host_object, source_config_name,self_generated):
22
22
  """ For internal use only. """
23
23
  self._restore_persistent_properties(host_object)
@@ -28,8 +28,8 @@ class _PrivateSessionProcess(_BusinessProcess):
28
28
  def on_private_session_started(self,source_config_name,self_generated):
29
29
  pass
30
30
 
31
- @_BusinessHost.input_deserialzer
32
- @_BusinessHost.output_serialzer
31
+ @input_deserializer
32
+ @output_serializer
33
33
  def _dispatch_on_private_session_stopped(self, host_object, source_config_name,self_generated,message):
34
34
  """ For internal use only. """
35
35
  self._restore_persistent_properties(host_object)
iop/_serialization.py ADDED
@@ -0,0 +1,196 @@
1
+ import base64
2
+ import codecs
3
+ import datetime
4
+ import decimal
5
+ import importlib
6
+ import json
7
+ import pickle
8
+ import uuid
9
+ from typing import Any, Dict, Type
10
+
11
+ from dacite import Config, from_dict
12
+ import iris
13
+
14
+ from iop._utils import _Utils
15
+
16
+ class IrisJSONEncoder(json.JSONEncoder):
17
+ """JSONEncoder that handles dates, decimals, UUIDs, etc."""
18
+
19
+ def default(self, o: Any) -> Any:
20
+ if o.__class__.__name__ == 'DataFrame':
21
+ return 'dataframe:' + o.to_json(orient="table")
22
+ elif isinstance(o, datetime.datetime):
23
+ r = o.isoformat()
24
+ if o.microsecond:
25
+ r = r[:23] + r[26:]
26
+ if r.endswith("+00:00"):
27
+ r = r[:-6] + "Z"
28
+ return 'datetime:' + r
29
+ elif isinstance(o, datetime.date):
30
+ return 'date:' + o.isoformat()
31
+ elif isinstance(o, datetime.time):
32
+ r = o.isoformat()
33
+ if o.microsecond:
34
+ r = r[:12]
35
+ return 'time:' + r
36
+ elif isinstance(o, decimal.Decimal):
37
+ return 'decimal:' + str(o)
38
+ elif isinstance(o, uuid.UUID):
39
+ return 'uuid:' + str(o)
40
+ elif isinstance(o, bytes):
41
+ return 'bytes:' + base64.b64encode(o).decode("UTF-8")
42
+ elif hasattr(o, '__dict__'):
43
+ return o.__dict__
44
+ return super().default(o)
45
+
46
+ class IrisJSONDecoder(json.JSONDecoder):
47
+ """JSONDecoder that handles special type annotations."""
48
+
49
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
50
+ json.JSONDecoder.__init__(
51
+ self, object_hook=self.object_hook, *args, **kwargs)
52
+
53
+ def object_hook(self, obj: Dict) -> Dict:
54
+ ret = {}
55
+ for key, value in obj.items():
56
+ i = 0
57
+ if isinstance(value, str):
58
+ i = value.find(":")
59
+ if i > 0:
60
+ typ = value[:i]
61
+ val = value[i+1:]
62
+ ret[key] = self._convert_typed_value(typ, val)
63
+ else:
64
+ ret[key] = value
65
+ return ret
66
+
67
+ def _convert_typed_value(self, typ: str, val: str) -> Any:
68
+ if typ == 'datetime':
69
+ return datetime.datetime.fromisoformat(val)
70
+ elif typ == 'date':
71
+ return datetime.date.fromisoformat(val)
72
+ elif typ == 'time':
73
+ return datetime.time.fromisoformat(val)
74
+ elif typ == 'dataframe':
75
+ module = importlib.import_module('pandas')
76
+ return module.read_json(val, orient="table")
77
+ elif typ == 'decimal':
78
+ return decimal.Decimal(val)
79
+ elif typ == 'uuid':
80
+ return uuid.UUID(val)
81
+ elif typ == 'bytes':
82
+ return base64.b64decode(val.encode("UTF-8"))
83
+ return val
84
+
85
+
86
+ def serialize_pickle_message(message: Any) -> iris.cls:
87
+ """Converts a python dataclass message into an iris iop.message.
88
+
89
+ Args:
90
+ message: The message to serialize, an instance of a class that is a subclass of Message.
91
+
92
+ Returns:
93
+ The message in json format.
94
+ """
95
+ pickle_string = codecs.encode(pickle.dumps(message), "base64").decode()
96
+ module = message.__class__.__module__
97
+ classname = message.__class__.__name__
98
+
99
+ msg = iris.cls('IOP.PickleMessage')._New()
100
+ msg.classname = module + "." + classname
101
+
102
+ stream = _Utils.string_to_stream(pickle_string)
103
+ msg.jstr = stream
104
+
105
+ return msg
106
+
107
+ def serialize_message(message: Any) -> iris.cls:
108
+ """Converts a python dataclass message into an iris iop.message.
109
+
110
+ Args:
111
+ message: The message to serialize, an instance of a class that is a subclass of Message.
112
+
113
+ Returns:
114
+ The message in json format.
115
+ """
116
+ json_string = json.dumps(message, cls=IrisJSONEncoder, ensure_ascii=False)
117
+ module = message.__class__.__module__
118
+ classname = message.__class__.__name__
119
+
120
+ msg = iris.cls('IOP.Message')._New()
121
+ msg.classname = module + "." + classname
122
+
123
+ if hasattr(msg, 'buffer') and len(json_string) > msg.buffer:
124
+ msg.json = _Utils.string_to_stream(json_string, msg.buffer)
125
+ else:
126
+ msg.json = json_string
127
+
128
+ return msg
129
+
130
+ def deserialize_pickle_message(serial: iris.cls) -> Any:
131
+ """Converts an iris iop.message into a python dataclass message.
132
+
133
+ Args:
134
+ serial: The serialized message
135
+
136
+ Returns:
137
+ The deserialized message
138
+ """
139
+ string = _Utils.stream_to_string(serial.jstr)
140
+
141
+ msg = pickle.loads(codecs.decode(string.encode(), "base64"))
142
+ return msg
143
+
144
+ def deserialize_message(serial: iris.cls) -> Any:
145
+ """Converts an iris iop.message into a python dataclass message.
146
+
147
+ Args:
148
+ serial: The serialized message
149
+
150
+ Returns:
151
+ The deserialized message
152
+ """
153
+ if (serial.classname is None):
154
+ raise ValueError("JSON message malformed, must include classname")
155
+ classname = serial.classname
156
+
157
+ j = classname.rindex(".")
158
+ if (j <= 0):
159
+ raise ValueError("Classname must include a module: " + classname)
160
+ try:
161
+ module = importlib.import_module(classname[:j])
162
+ msg = getattr(module, classname[j+1:])
163
+ except Exception:
164
+ raise ImportError("Class not found: " + classname)
165
+
166
+ string = ""
167
+ if (serial.type == 'Stream'):
168
+ string = _Utils.stream_to_string(serial.json)
169
+ else:
170
+ string = serial.json
171
+
172
+ jdict = json.loads(string, cls=IrisJSONDecoder)
173
+ msg = dataclass_from_dict(msg, jdict)
174
+ return msg
175
+
176
+ def dataclass_from_dict(klass: Type, dikt: Dict) -> Any:
177
+ """Converts a dictionary to a dataclass instance.
178
+
179
+ Args:
180
+ klass: The dataclass to convert to
181
+ dikt: The dictionary to convert to a dataclass
182
+
183
+ Returns:
184
+ A dataclass object with the fields of the dataclass and the fields of the dictionary.
185
+ """
186
+ ret = from_dict(klass, dikt, Config(check_types=False))
187
+
188
+ try:
189
+ fieldtypes = klass.__annotations__
190
+ except Exception as e:
191
+ fieldtypes = []
192
+
193
+ for key, val in dikt.items():
194
+ if key not in fieldtypes:
195
+ setattr(ret, key, val)
196
+ return ret
iop/_utils.py CHANGED
@@ -436,23 +436,31 @@ class _Utils():
436
436
  return stream
437
437
 
438
438
  @staticmethod
439
- def guess_path(module,path):
440
- if "." in module:
441
- if module.startswith("."):
442
- # count the number of dots at the beginning of the module name
443
- dots = 0
444
- for c in module:
445
- if c == ".":
446
- dots += 1
447
- else:
448
- break
449
- # remove the dots from the beginning of the module name
450
- module = module[dots:]
451
- # go to the parent directory dots times
452
- for i in range(dots)-1:
453
- path = os.path.dirname(path)
454
- return os.path.join(path, module.replace(".", os.sep) + ".py")
455
- else:
456
- return os.path.join(path, module.replace(".", os.sep) + ".py")
439
+ def guess_path(module: str, path: str) -> str:
440
+ """Determines the full file path for a given module.
441
+
442
+ Args:
443
+ module: Module name/path (e.g. 'foo.bar' or '.foo.bar')
444
+ path: Base directory path
445
+
446
+ Returns:
447
+ Full path to the module's .py file
448
+ """
449
+ if not module:
450
+ raise ValueError("Module name cannot be empty")
451
+
452
+ if module.startswith("."):
453
+ # Handle relative imports
454
+ dot_count = len(module) - len(module.lstrip("."))
455
+ module = module[dot_count:]
456
+
457
+ # Go up directory tree based on dot count
458
+ for _ in range(dot_count - 1):
459
+ path = os.path.dirname(path)
460
+
461
+ # Convert module path to file path
462
+ if module.endswith(".py"):
463
+ module_path = module.replace(".", os.sep)
457
464
  else:
458
- return os.path.join(path, module + ".py")
465
+ module_path = module.replace(".", os.sep) + ".py"
466
+ return os.path.join(path, module_path)
iop/cls/IOP/Common.cls CHANGED
@@ -193,7 +193,12 @@ ClassMethod OnGetConnections(
193
193
  pItem As Ens.Config.Item)
194
194
  {
195
195
  // finds any settings of type Ens.DataType.ConfigName
196
- do ..GetPropertyConnections(.pArray,pItem)
196
+ Try {
197
+ do ..GetPropertyConnections(.pArray,pItem)
198
+ }
199
+ Catch ex {
200
+ }
201
+
197
202
 
198
203
  // Get settings
199
204
  do pItem.GetModifiedSetting("%classpaths", .tClasspaths)
iop/cls/IOP/Message.cls CHANGED
@@ -467,6 +467,7 @@ ClassMethod HandleProperty(
467
467
  }
468
468
 
469
469
  If type = "array" Set key = key_"()"
470
+ Set pContents = idx
470
471
  Set pContents(idx,"name") = key
471
472
  Set pContents(idx,"alias") = key
472
473
  }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: iris_pex_embedded_python
3
- Version: 3.2.1b3
3
+ Version: 3.3.0
4
4
  Summary: Iris Interoperability based on Embedded Python
5
5
  Author-email: grongier <guillaume.rongier@intersystems.com>
6
6
  License: MIT License
@@ -92,28 +92,33 @@ intersystems_iris/pex/_OutboundAdapter.py,sha256=ao2Ubbta2DcrQGdzDUD_j1Zsk8bvUfc
92
92
  intersystems_iris/pex/__init__.py,sha256=l_I1dpnluWawbFrGMDC0GLHpuHwjbpd-nho8otFX6TE,1379
93
93
  iop/__init__.py,sha256=fX1Osx2Dmcuv8C5hmvoG4fPDIbk0qksJcIgpQibJ_p4,1067
94
94
  iop/__main__.py,sha256=pQzVtkDhAeI6dpNRC632dVk2SGZZIEDwDufdgZe8VWs,98
95
- iop/_business_host.py,sha256=7oXdGPpVSRl8lYWd0M_6VLebnMU-kayShcvzUU0BR1k,26363
96
- iop/_business_operation.py,sha256=Fc0bSXpbmLpt2_fCNBOh0Wh1O4ue7y85Jkv_nP6Kzv0,2901
97
- iop/_business_process.py,sha256=QPb3HM2Oz7gJMbI3uFgILH5ivOiQ6NVB37P9C_gmpNQ,8465
98
- iop/_business_service.py,sha256=8dYTr4z3RE0WupT7_DeDvYjyhVqZtdDj0jA52ZSKCQ0,3771
99
- iop/_cli.py,sha256=TRn1yCAf3E3e3fdLprxXLeti1LSg22IjTmIHV_LaLyI,7546
100
- iop/_common.py,sha256=3zX4Ua2rZuc5CBMjVTZbdUT1fv_mQTzAWdFFtDEzfn8,14050
101
- iop/_director.py,sha256=snFuj4NyvNdUClbajLee5phJFrS5fZO-YVYziW1WSe8,11586
95
+ iop/_async_request.py,sha256=btDFNFaO-Yvl6wvgXrCYNWoQb2RtbzEvTJsk7j03b30,2170
96
+ iop/_business_host.py,sha256=wI2LlVTVjEqE8GWE9nSz1WHvqTduAuJQTk7Ky7qkz4U,9658
97
+ iop/_business_operation.py,sha256=ml4BIn1BfrGx8AUGISFR71DZIUCP8vZ2yn9SQjaSzTM,3038
98
+ iop/_business_process.py,sha256=hj6nDIP5Mz5UYbm0vDjvs9lPSEYVQxGJl6tQRcDGTBk,8548
99
+ iop/_business_service.py,sha256=lPTp3_tcLTOWvHlE_YwrcImLGf1PJBUgIOrV-8ctFLw,3851
100
+ iop/_cli.py,sha256=IwvVxglSTVkCDXwANLMqnd8mfxGtWB6GjBSdEy8EMm0,7551
101
+ iop/_common.py,sha256=E_Mn2t--klAtT4p1MzW1KtcKcLrB1g4Flq5H4JlV8Vs,11619
102
+ iop/_decorators.py,sha256=ZpgEETLdKWv58AoSMfXnm3_mA-6qPphIegjG-npDgwg,2324
103
+ iop/_director.py,sha256=DrswFoqJ6IG62hkW-0ZffTtZdxw6KNozlZSIq3O6d-o,11629
104
+ iop/_dispatch.py,sha256=4317Z0ujXxDGUQaL7WX6zfGzBPOdw70MWiqmLUKxhik,6611
102
105
  iop/_inbound_adapter.py,sha256=PS5ToqhrYcXq9ZdLbCBqAfVp8kCeRACm_KF66pwBO9U,1652
103
- iop/_log_manager.py,sha256=4Qq7Rw7oatlXrTi9XMWyJOfO3G8P9qs83DWfk2QhJmw,3218
106
+ iop/_log_manager.py,sha256=PZnGWsi-zvWo-bumQO5BK-8kHG2XW-WnZ6ShL7QeZ4c,3499
104
107
  iop/_message.py,sha256=LSkfZcmEu1aj2hdSg3sUHSWNc8tWWZR8Q2_h9_axVrs,325
108
+ iop/_message_validator.py,sha256=xMMPOZOop3Nv12E3_QPI5caTgYgAzoKlRxcMmUkrj2c,1379
105
109
  iop/_outbound_adapter.py,sha256=YTAhLrRf9chEAd53mV6KKbpaHOKNOKJHoGgj5wakRR0,726
106
110
  iop/_pickle_message.py,sha256=noKfc2VkXufV3fqjKvNHN_oANQ1YN9ffCaSV0XSTAIE,331
107
- iop/_private_session_duplex.py,sha256=36OwAGlasbPtfwq2KgMFcr3a33RsNSqohJx243XcDWI,5153
108
- iop/_private_session_process.py,sha256=pGjWFOQhWpQxUVpTtvNKTPvDxgzjfw0VC4Aqj3KUq8w,1704
109
- iop/_utils.py,sha256=c59QrgQgrk528V_n6RInnq_N6RzIGAAEmaTGRwanTSI,19404
111
+ iop/_private_session_duplex.py,sha256=mzlFABh-ly51X1uSWw9YwQbktfMvuNdp2ALlRvlDow4,5152
112
+ iop/_private_session_process.py,sha256=todprfYFSDr-h-BMvWL_IGC6wbQqkMy3mPHWEWCUSE0,1686
113
+ iop/_serialization.py,sha256=rTASgu0Oc2oiV4rNMdhmYhaex5Nnd__xUZ5a9Y3t8LM,6064
114
+ iop/_utils.py,sha256=Aqtp9Jx3ghzkNs4f2cOZXYwv8cGsjmdBocnkP64fa3M,19574
110
115
  iop/cls/IOP/BusinessOperation.cls,sha256=lrymqZ8wHl5kJjXwdjbQVs5sScV__yIWGh-oGbiB_X0,914
111
116
  iop/cls/IOP/BusinessProcess.cls,sha256=s3t38w1ykHqM26ETcbCYLt0ocjZyVVahm-_USZkuJ1E,2855
112
117
  iop/cls/IOP/BusinessService.cls,sha256=7ebn32J9PiZXUgXuh5Xxm_7X6zHBiqkJr9c_dWxbPO8,1021
113
- iop/cls/IOP/Common.cls,sha256=4f4ZpLj8fsj8IKJDNb9pKoCokzo522JHWX0OqpAaC5g,11192
118
+ iop/cls/IOP/Common.cls,sha256=mJvfTGxJeqLDlBxdnCt-hYiVZEJpfvmdzYEC_UqKeHo,11234
114
119
  iop/cls/IOP/Director.cls,sha256=M43LoTb6lwSr0J81RFxi1YLW1mwda09wQ7Xqr3nBtxo,2008
115
120
  iop/cls/IOP/InboundAdapter.cls,sha256=GeoCm6q5HcLJ5e4VxgqXiErJXqolBbpKwpunaNzpvjU,610
116
- iop/cls/IOP/Message.cls,sha256=EJWt0ifN3v-QxFit-xvU4Brodx58_jWeYZDoiyHuHa8,25156
121
+ iop/cls/IOP/Message.cls,sha256=ZrYQHosgfTG9wv7i-WQ8j71YXZMmL4_mN16xtIDwcRg,25180
117
122
  iop/cls/IOP/OutboundAdapter.cls,sha256=9eOwy5ojwcTzwrHs6LNrFQvUD8aqcoNCZrILN1ycdDM,958
118
123
  iop/cls/IOP/PickleMessage.cls,sha256=S3y7AClQ8mAILjxPuHdCjGosBZYzGbUQ5WTv4mYPNMQ,1673
119
124
  iop/cls/IOP/Test.cls,sha256=gAC9PEfMZsvAEWIa241-ug2FWAhITbN1SOispZzJPnI,2094
@@ -131,9 +136,9 @@ iop/cls/IOP/Service/WSGI.cls,sha256=VLNCXEwmHW9dBnE51uGE1nvGX6T4HjhqePT3LVhsjAE,
131
136
  iop/wsgi/handlers.py,sha256=NrFLo_YbAh-x_PlWhAiWkQnUUN2Ss9HoEm63dDWCBpQ,2947
132
137
  irisnative/_IRISNative.py,sha256=HQ4nBhc8t8_5OtxdMG-kx1aa-T1znf2I8obZOPLOPzg,665
133
138
  irisnative/__init__.py,sha256=6YmvBLQSURsCPKaNg7LK-xpo4ipDjrlhKuwdfdNb3Kg,341
134
- iris_pex_embedded_python-3.2.1b3.dist-info/LICENSE,sha256=rZSiBFId_sfbJ6RL0GjjPX-InNLkNS9ou7eQsikciI8,1089
135
- iris_pex_embedded_python-3.2.1b3.dist-info/METADATA,sha256=6SdwtY4FY9nVc6SwKC1WWeIPwL5hkrQgOL-9LUgRdA4,4427
136
- iris_pex_embedded_python-3.2.1b3.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
137
- iris_pex_embedded_python-3.2.1b3.dist-info/entry_points.txt,sha256=pj-i4LSDyiSP6xpHlVjMCbg1Pik7dC3_sdGY3Yp9Vhk,38
138
- iris_pex_embedded_python-3.2.1b3.dist-info/top_level.txt,sha256=VWDlX4YF4qFVRGrG3-Gs0kgREol02i8gIpsHNbhfFPw,42
139
- iris_pex_embedded_python-3.2.1b3.dist-info/RECORD,,
139
+ iris_pex_embedded_python-3.3.0.dist-info/LICENSE,sha256=rZSiBFId_sfbJ6RL0GjjPX-InNLkNS9ou7eQsikciI8,1089
140
+ iris_pex_embedded_python-3.3.0.dist-info/METADATA,sha256=8i-L9CyBUN_Mtc_9VPtSN_NaoEMKHCheH7lIMJPZHV4,4425
141
+ iris_pex_embedded_python-3.3.0.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
142
+ iris_pex_embedded_python-3.3.0.dist-info/entry_points.txt,sha256=pj-i4LSDyiSP6xpHlVjMCbg1Pik7dC3_sdGY3Yp9Vhk,38
143
+ iris_pex_embedded_python-3.3.0.dist-info/top_level.txt,sha256=VWDlX4YF4qFVRGrG3-Gs0kgREol02i8gIpsHNbhfFPw,42
144
+ iris_pex_embedded_python-3.3.0.dist-info/RECORD,,