Make `NamespacePath` kinda support methods..

Obviously we can't deterministic-ally call `.load_ref()` (since you'd
have to point to an `id()` or something and presume a particular
py-runtime + virt-mem space for it to exist?) but it at least helps with
the `str` formatting for logging purposes (like `._cancel_rpc_tasks()`)
when `repr`-ing ctxs and their specific "rpc signatures".

Maybe in the future getting this working at least for singleton types
per process (like `Actor` XD ) will be a thing we can support and make
some sense of.. Bo
modden_spawn_from_client_req
Tyler Goodlet 2024-02-29 17:37:02 -05:00
parent b54cb6682c
commit 1e5810e56c
1 changed files with 27 additions and 10 deletions
tractor/msg

View File

@ -43,17 +43,24 @@ IPC-compat cross-mem-boundary object pointer.
# - https://github.com/msgpack/msgpack-python#packingunpacking-of-custom-data-type # - https://github.com/msgpack/msgpack-python#packingunpacking-of-custom-data-type
from __future__ import annotations from __future__ import annotations
from inspect import isfunction from inspect import (
isfunction,
ismethod,
)
from pkgutil import resolve_name from pkgutil import resolve_name
class NamespacePath(str): class NamespacePath(str):
''' '''
A serializeable description of a (function) Python object A serializeable `str`-subtype implementing a "namespace
location described by the target's module path and namespace pointer" to any Python object reference (like a function)
key meant as a message-native "packet" to allows actors to using the same format as the built-in `pkgutil.resolve_name()`
point-and-load objects by an absolute ``str`` (and thus system.
serializable) reference.
A value describes a target's module-path and namespace-key
separated by a ':' and thus can be easily used as
a IPC-message-native reference-type allowing memory isolated
actors to point-and-load objects via a minimal `str` value.
''' '''
_ref: object | type | None = None _ref: object | type | None = None
@ -81,13 +88,23 @@ class NamespacePath(str):
''' '''
if ( if (
isinstance(ref, object) isfunction(ref)
and not isfunction(ref)
): ):
name: str = type(ref).__name__
else:
name: str = getattr(ref, '__name__') name: str = getattr(ref, '__name__')
elif ismethod(ref):
# build out the path manually i guess..?
# TODO: better way?
name: str = '.'.join([
type(ref.__self__).__name__,
ref.__func__.__name__,
])
else: # object or other?
# isinstance(ref, object)
# and not isfunction(ref)
name: str = type(ref).__name__
# fully qualified namespace path, tuple. # fully qualified namespace path, tuple.
fqnp: tuple[str, str] = ( fqnp: tuple[str, str] = (
ref.__module__, ref.__module__,