Skip to content

Commit 4f654b4

Browse files
committed
Temporary fixes in RPyC monkeypatches while ghpythonlib.components.__namedtuple.__getattr__ is bonked
1 parent 4418a4f commit 4f654b4

1 file changed

Lines changed: 79 additions & 0 deletions

File tree

ghpythonremote/monkey.py

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,85 @@ def BYTES_LITERAL(text):
1111

1212
rpyc.lib.compat.BYTES_LITERAL = BYTES_LITERAL
1313

14+
# TODO: This will not be found in Rhino 5!
15+
# TODO: This will not work if in IronPython outside Rhino!
16+
# TODO: This loads the gh components early?? not needed if not accessing them??
17+
# TODO: Remove that when ghpythonlib.components.__namedtuple.__getattr__ is fixed
18+
import ghpythonlib.components
19+
20+
def get_id_pack(obj):
21+
"""introspects the given "local" object, returns id_pack as expected by BaseNetref
22+
23+
The given object is "local" in the sense that it is from the local cache. Any object in the local cache exists
24+
in the current address space or is a netref. A netref in the local cache could be from a chained-connection.
25+
To handle type related behavior properly, the attribute `__class__` is a descriptor for netrefs.
26+
27+
So, check thy assumptions regarding the given object when creating `id_pack`.
28+
"""
29+
30+
# TODO: Remove that when ghpythonlib.components.__namedtuple.__getattr__ is fixed
31+
if hasattr(obj, "____id_pack__") and not isinstance(
32+
obj, ghpythonlib.components.__namedtuple
33+
):
34+
# netrefs are handled first since __class__ is a descriptor
35+
return obj.____id_pack__
36+
elif inspect.ismodule(obj) or getattr(obj, "__name__", None) == "module":
37+
# TODO: not sure about this, need to enumerate cases in units
38+
if isinstance(obj, type): # module
39+
obj_cls = type(obj)
40+
name_pack = "{0}.{1}".format(obj_cls.__module__, obj_cls.__name__)
41+
return (name_pack, id(type(obj)), id(obj))
42+
else:
43+
if inspect.ismodule(obj) and obj.__name__ != "module":
44+
if obj.__name__ in sys.modules:
45+
name_pack = obj.__name__
46+
else:
47+
name_pack = "{0}.{1}".format(
48+
obj.__class__.__module__, obj.__name__
49+
)
50+
elif inspect.ismodule(obj):
51+
name_pack = "{0}.{1}".format(obj__module__, obj.__name__)
52+
print(name_pack)
53+
elif hasattr(obj, "__module__"):
54+
name_pack = "{0}.{1}".format(obj.__module__, obj.__name__)
55+
else:
56+
obj_cls = type(obj)
57+
name_pack = "{0}".format(obj.__name__)
58+
return (name_pack, id(type(obj)), id(obj))
59+
elif not inspect.isclass(obj):
60+
name_pack = "{0}.{1}".format(
61+
obj.__class__.__module__, obj.__class__.__name__
62+
)
63+
return (name_pack, id(type(obj)), id(obj))
64+
else:
65+
name_pack = "{0}.{1}".format(obj.__module__, obj.__name__)
66+
return (name_pack, id(obj), 0)
67+
68+
rpyc.lib.get_id_pack = get_id_pack
69+
rpyc.core.netref.get_id_pack = get_id_pack
70+
rpyc.core.protocol.get_id_pack = get_id_pack
71+
72+
# TODO: Remove that when ghpythonlib.components.__namedtuple.__getattr__ is fixed
73+
def _handle_inspect(self, id_pack): # request handler
74+
obj = self._local_objects[id_pack]
75+
if hasattr(obj, "____conn__") and not isinstance(
76+
obj, ghpythonlib.components.__namedtuple
77+
):
78+
# When RPyC is chained (RPyC over RPyC), id_pack is cached in local objects as a netref
79+
# since __mro__ is not a safe attribute the request is forwarded using the proxy connection
80+
# see issue #346 or tests.test_rpyc_over_rpyc.Test_rpyc_over_rpyc
81+
conn = self._local_objects[id_pack].____conn__
82+
return conn.sync_request(rpyc.core.consts.HANDLE_INSPECT, id_pack)
83+
else:
84+
return tuple(
85+
rpyc.lib.get_methods(
86+
rpyc.core.netref.LOCAL_ATTRS, self._local_objects[id_pack]
87+
)
88+
)
89+
90+
# TODO: Remove that when ghpythonlib.componentns.__namedtuple.__getattr__ is fixed
91+
rpyc.core.protocol.Connection._handle_inspect = _handle_inspect
92+
1493
if sys.version_info < (2, 7, 5):
1594

1695
def dump(obj):

0 commit comments

Comments
 (0)