iris-pex-embedded-python 4.0.1b2__py3-none-any.whl → 4.0.1b4__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.
- iop/messages/dispatch.py +137 -16
- {iris_pex_embedded_python-4.0.1b2.dist-info → iris_pex_embedded_python-4.0.1b4.dist-info}/METADATA +1 -1
- {iris_pex_embedded_python-4.0.1b2.dist-info → iris_pex_embedded_python-4.0.1b4.dist-info}/RECORD +7 -7
- {iris_pex_embedded_python-4.0.1b2.dist-info → iris_pex_embedded_python-4.0.1b4.dist-info}/WHEEL +0 -0
- {iris_pex_embedded_python-4.0.1b2.dist-info → iris_pex_embedded_python-4.0.1b4.dist-info}/entry_points.txt +0 -0
- {iris_pex_embedded_python-4.0.1b2.dist-info → iris_pex_embedded_python-4.0.1b4.dist-info}/licenses/LICENSE +0 -0
- {iris_pex_embedded_python-4.0.1b2.dist-info → iris_pex_embedded_python-4.0.1b4.dist-info}/top_level.txt +0 -0
iop/messages/dispatch.py
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import ast
|
|
1
2
|
import logging
|
|
2
3
|
from collections.abc import Callable
|
|
3
4
|
from dataclasses import dataclass
|
|
@@ -36,6 +37,8 @@ _PICKLE_MESSAGE_CLASSES = {
|
|
|
36
37
|
"IOP.Generator.Message.StartPickle",
|
|
37
38
|
}
|
|
38
39
|
_HANDLER_ATTRIBUTE = "__iop_handler_message__"
|
|
40
|
+
_IRIS_MODULE_PREFIX = "iris."
|
|
41
|
+
_UNRESOLVED = object()
|
|
39
42
|
|
|
40
43
|
|
|
41
44
|
@dataclass(frozen=True)
|
|
@@ -60,7 +63,7 @@ def handler(message_type: Any) -> Callable[[Callable], Callable]:
|
|
|
60
63
|
message_type: The message class, fully qualified class name string, or
|
|
61
64
|
IRIS object instance this method handles.
|
|
62
65
|
"""
|
|
63
|
-
message =
|
|
66
|
+
message = _message_key_from_declared(message_type)
|
|
64
67
|
if message is None:
|
|
65
68
|
raise TypeError("handler() requires a message class or class name")
|
|
66
69
|
|
|
@@ -154,11 +157,10 @@ def dispatch_message(host: Any, request: Any) -> Any:
|
|
|
154
157
|
"""
|
|
155
158
|
call = "on_message"
|
|
156
159
|
|
|
157
|
-
|
|
158
|
-
classname = request.__class__.__name__
|
|
160
|
+
message_names = _message_keys_from_request(request)
|
|
159
161
|
|
|
160
162
|
for msg, method in host.DISPATCH:
|
|
161
|
-
if msg
|
|
163
|
+
if msg in message_names:
|
|
162
164
|
return getattr(host, method)(request)
|
|
163
165
|
|
|
164
166
|
return getattr(host, call)(request)
|
|
@@ -202,15 +204,24 @@ def create_dispatch(host: Any) -> None:
|
|
|
202
204
|
|
|
203
205
|
def _declared_dispatch(host: Any) -> list[tuple[str, str]]:
|
|
204
206
|
if "DISPATCH" in getattr(host, "__dict__", {}):
|
|
205
|
-
return
|
|
207
|
+
return _normalized_dispatch(host.__dict__["DISPATCH"])
|
|
206
208
|
|
|
207
209
|
class_dispatch = host.__class__.__dict__.get("DISPATCH")
|
|
208
210
|
if class_dispatch is not None:
|
|
209
|
-
return
|
|
211
|
+
return _normalized_dispatch(class_dispatch)
|
|
210
212
|
|
|
211
213
|
return []
|
|
212
214
|
|
|
213
215
|
|
|
216
|
+
def _normalized_dispatch(dispatch: Any) -> list[tuple[str, str]]:
|
|
217
|
+
entries = []
|
|
218
|
+
for message, method in dispatch:
|
|
219
|
+
key = _message_key_from_declared(message)
|
|
220
|
+
if key is not None:
|
|
221
|
+
entries.append((key, method))
|
|
222
|
+
return entries
|
|
223
|
+
|
|
224
|
+
|
|
214
225
|
def _decorated_dispatch(host: Any) -> list[tuple[str, str]]:
|
|
215
226
|
dispatch = []
|
|
216
227
|
for method_name in dir(host):
|
|
@@ -306,13 +317,9 @@ def get_handler_info(host: Any, method_name: str) -> tuple[str, str] | None:
|
|
|
306
317
|
if len(params) != 1:
|
|
307
318
|
return None
|
|
308
319
|
|
|
320
|
+
method = getattr(host, method_name)
|
|
309
321
|
param: Parameter = next(iter(params.values()))
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
if annotation == Parameter.empty:
|
|
313
|
-
return None
|
|
314
|
-
|
|
315
|
-
message = _message_class_name(annotation)
|
|
322
|
+
message = _message_key_from_annotation(host, method, param.annotation)
|
|
316
323
|
if message is None:
|
|
317
324
|
return None
|
|
318
325
|
|
|
@@ -322,12 +329,63 @@ def get_handler_info(host: Any, method_name: str) -> tuple[str, str] | None:
|
|
|
322
329
|
return None
|
|
323
330
|
|
|
324
331
|
|
|
325
|
-
def
|
|
332
|
+
def _message_key_from_annotation(
|
|
333
|
+
host: Any, method: Callable, annotation: Any
|
|
334
|
+
) -> str | None:
|
|
335
|
+
if annotation == Parameter.empty:
|
|
336
|
+
return None
|
|
337
|
+
|
|
338
|
+
if not isinstance(annotation, str):
|
|
339
|
+
return _message_key_from_declared(annotation, allow_bare_string=False)
|
|
340
|
+
|
|
341
|
+
value: Any = annotation
|
|
342
|
+
for _ in range(3):
|
|
343
|
+
if not isinstance(value, str):
|
|
344
|
+
return _message_key_from_declared(value, allow_bare_string=False)
|
|
345
|
+
|
|
346
|
+
key = _message_key_from_string(value, allow_bare=False)
|
|
347
|
+
if key is not None:
|
|
348
|
+
return key
|
|
349
|
+
|
|
350
|
+
unquoted = _unquote_string(value)
|
|
351
|
+
if unquoted is not None and unquoted != value:
|
|
352
|
+
value = unquoted
|
|
353
|
+
continue
|
|
354
|
+
|
|
355
|
+
value = _lookup_annotation_name(host, method, value)
|
|
356
|
+
if value is _UNRESOLVED:
|
|
357
|
+
return None
|
|
358
|
+
|
|
359
|
+
return None
|
|
360
|
+
|
|
361
|
+
|
|
362
|
+
def _message_keys_from_request(request: Any) -> tuple[str, ...]:
|
|
363
|
+
module = request.__class__.__module__
|
|
364
|
+
classname = request.__class__.__name__
|
|
365
|
+
names = [f"{module}.{classname}"]
|
|
366
|
+
|
|
367
|
+
if module.startswith("iris"):
|
|
368
|
+
native_name = _native_iris_message_key(request)
|
|
369
|
+
if native_name:
|
|
370
|
+
names.append(native_name)
|
|
371
|
+
names.append(f"{_IRIS_MODULE_PREFIX}{native_name}")
|
|
372
|
+
|
|
373
|
+
return tuple(dict.fromkeys(names))
|
|
374
|
+
|
|
375
|
+
|
|
376
|
+
def _message_key_from_declared(
|
|
377
|
+
message_type: Any, *, allow_bare_string: bool = True
|
|
378
|
+
) -> str | None:
|
|
326
379
|
if isinstance(message_type, str):
|
|
327
|
-
return
|
|
380
|
+
return _message_key_from_string(
|
|
381
|
+
message_type,
|
|
382
|
+
allow_bare=allow_bare_string,
|
|
383
|
+
)
|
|
328
384
|
|
|
329
385
|
if is_iris_object_instance(message_type):
|
|
330
|
-
return
|
|
386
|
+
return _native_iris_message_key(message_type) or _python_class_key(
|
|
387
|
+
type(message_type)
|
|
388
|
+
)
|
|
331
389
|
|
|
332
390
|
if message_type is Any or message_type is object:
|
|
333
391
|
return None
|
|
@@ -338,7 +396,70 @@ def _message_class_name(message_type: Any) -> str | None:
|
|
|
338
396
|
if not _is_dispatch_message_class(message_type):
|
|
339
397
|
return None
|
|
340
398
|
|
|
341
|
-
return
|
|
399
|
+
return _python_class_key(message_type)
|
|
400
|
+
|
|
401
|
+
|
|
402
|
+
def _message_key_from_string(value: str, *, allow_bare: bool) -> str | None:
|
|
403
|
+
if not value or _unquote_string(value) is not None:
|
|
404
|
+
return None
|
|
405
|
+
|
|
406
|
+
normalized = _strip_iris_prefix(value)
|
|
407
|
+
if "." in normalized:
|
|
408
|
+
return normalized if _looks_like_message_key(normalized) else None
|
|
409
|
+
|
|
410
|
+
return normalized if allow_bare else None
|
|
411
|
+
|
|
412
|
+
|
|
413
|
+
def _native_iris_message_key(message: Any) -> str | None:
|
|
414
|
+
iris_classname = get_iris_object_classname(message)
|
|
415
|
+
if not iris_classname:
|
|
416
|
+
return None
|
|
417
|
+
return _strip_iris_prefix(iris_classname)
|
|
418
|
+
|
|
419
|
+
|
|
420
|
+
def _python_class_key(klass: type) -> str:
|
|
421
|
+
return f"{klass.__module__}.{klass.__name__}"
|
|
422
|
+
|
|
423
|
+
|
|
424
|
+
def _strip_iris_prefix(value: str) -> str:
|
|
425
|
+
if value.startswith(_IRIS_MODULE_PREFIX):
|
|
426
|
+
return value[len(_IRIS_MODULE_PREFIX) :]
|
|
427
|
+
return value
|
|
428
|
+
|
|
429
|
+
|
|
430
|
+
def _looks_like_message_key(value: str) -> bool:
|
|
431
|
+
return not any(character in value for character in "'\"[](){} ,:")
|
|
432
|
+
|
|
433
|
+
|
|
434
|
+
def _unquote_string(value: str) -> str | None:
|
|
435
|
+
try:
|
|
436
|
+
literal = ast.literal_eval(value)
|
|
437
|
+
except (SyntaxError, ValueError):
|
|
438
|
+
return None
|
|
439
|
+
return literal if isinstance(literal, str) else None
|
|
440
|
+
|
|
441
|
+
|
|
442
|
+
def _lookup_annotation_name(host: Any, method: Callable, name: str) -> Any:
|
|
443
|
+
if not name.isidentifier():
|
|
444
|
+
return _UNRESOLVED
|
|
445
|
+
|
|
446
|
+
localns = _annotation_localns(host)
|
|
447
|
+
if name in localns:
|
|
448
|
+
return localns[name]
|
|
449
|
+
|
|
450
|
+
return _annotation_globalns(method).get(name, _UNRESOLVED)
|
|
451
|
+
|
|
452
|
+
|
|
453
|
+
def _annotation_globalns(method: Callable) -> dict[str, Any]:
|
|
454
|
+
function = getattr(method, "__func__", method)
|
|
455
|
+
return getattr(function, "__globals__", {})
|
|
456
|
+
|
|
457
|
+
|
|
458
|
+
def _annotation_localns(host: Any) -> dict[str, Any]:
|
|
459
|
+
namespace: dict[str, Any] = {}
|
|
460
|
+
for klass in reversed(type(host).__mro__):
|
|
461
|
+
namespace.update(vars(klass))
|
|
462
|
+
return namespace
|
|
342
463
|
|
|
343
464
|
|
|
344
465
|
def _is_dispatch_message_class(klass: type) -> bool:
|
{iris_pex_embedded_python-4.0.1b2.dist-info → iris_pex_embedded_python-4.0.1b4.dist-info}/RECORD
RENAMED
|
@@ -53,7 +53,7 @@ iop/components/settings.py,sha256=USAKAisdersKlAEIk8HDu_TuYtkO-Sc3an3PXjPcDRA,62
|
|
|
53
53
|
iop/messages/__init__.py,sha256=k1AKplpjdqSxM5Gl7bpWAfw93xUgigovlI4SKhwKHRI,355
|
|
54
54
|
iop/messages/base.py,sha256=ZrVXEz7JrYHnt5b3M7avxcJCB0_OZxm1uWm9gQ4_eAw,1906
|
|
55
55
|
iop/messages/decorators.py,sha256=CWk08k8U2aTJv7Dx1n2jp8sjZZSCD8NJPoifKLB3W2g,2488
|
|
56
|
-
iop/messages/dispatch.py,sha256=
|
|
56
|
+
iop/messages/dispatch.py,sha256=l7FX-TAx5cLgjxoxNpL8ul3Lj4w4-taxTtyeZU3W85I,14001
|
|
57
57
|
iop/messages/persistent.py,sha256=ibRhRTqzwGcAqem744KZzHiouUlc8-J3ftB4zyzQYx4,16906
|
|
58
58
|
iop/messages/serialization.py,sha256=BW0o-7GaceMW7RMOzOJ8g9rKEv28NYnYFwtTLmAf7Yg,9255
|
|
59
59
|
iop/messages/validation.py,sha256=X6MSWsjLZDuyX1Tfx0TP3T6OI4nj1HZccwR2Z9PSubY,1606
|
|
@@ -91,9 +91,9 @@ iop/runtime/remote/director.py,sha256=bkie751GrYLgGs7ApRCowHpSnJA8KupxCOrFDQmjyO
|
|
|
91
91
|
iop/runtime/remote/migration.py,sha256=Iboz-Ye7i9xif9bn433GazCF-gtD-HJW3wiUwWS5P6w,1831
|
|
92
92
|
iop/runtime/remote/settings.py,sha256=P1Hsgld5o57HpSZgPVZzobyjlUmxJj6bstiWvR0JXnc,2144
|
|
93
93
|
iop/runtime/remote/setup.py,sha256=Tr80F3JJTy7oSUso2jyx0iA_KZayd4MYt9vL0BvPpMA,2600
|
|
94
|
-
iris_pex_embedded_python-4.0.
|
|
95
|
-
iris_pex_embedded_python-4.0.
|
|
96
|
-
iris_pex_embedded_python-4.0.
|
|
97
|
-
iris_pex_embedded_python-4.0.
|
|
98
|
-
iris_pex_embedded_python-4.0.
|
|
99
|
-
iris_pex_embedded_python-4.0.
|
|
94
|
+
iris_pex_embedded_python-4.0.1b4.dist-info/licenses/LICENSE,sha256=rZSiBFId_sfbJ6RL0GjjPX-InNLkNS9ou7eQsikciI8,1089
|
|
95
|
+
iris_pex_embedded_python-4.0.1b4.dist-info/METADATA,sha256=TVZxDq5vdJrEGPJ4dc2dqySOdfyEzdZWDGNc8hda_dE,5846
|
|
96
|
+
iris_pex_embedded_python-4.0.1b4.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
97
|
+
iris_pex_embedded_python-4.0.1b4.dist-info/entry_points.txt,sha256=fzS8ZFsPe8cnpEx208X60DNugCPQmuSloPeg4pyyJDY,42
|
|
98
|
+
iris_pex_embedded_python-4.0.1b4.dist-info/top_level.txt,sha256=BM54-OXQ6l2BDtmesWNXckh033s9gcjoO7bfjbwZbxU,4
|
|
99
|
+
iris_pex_embedded_python-4.0.1b4.dist-info/RECORD,,
|
{iris_pex_embedded_python-4.0.1b2.dist-info → iris_pex_embedded_python-4.0.1b4.dist-info}/WHEEL
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|