Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

closes #558 #559

Merged
merged 11 commits into from
Jun 24, 2024
4 changes: 2 additions & 2 deletions rpyc/core/protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -336,8 +336,8 @@ def _unbox(self, package): # boxing
return self._local_objects[value]
if label == consts.LABEL_REMOTE_REF:
id_pack = (str(value[0]), value[1], value[2]) # so value is a id_pack
if id_pack in self._proxy_cache:
proxy = self._proxy_cache[id_pack]
proxy = self._proxy_cache.get(id_pack)
if proxy is not None:
proxy.____refcount__ += 1 # if cached then remote incremented refcount, so sync refcount
else:
proxy = self._netref_factory(id_pack)
Expand Down
10 changes: 8 additions & 2 deletions rpyc/core/stream.py
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,10 @@ def from_std(cls):

:returns: a :class:`PipeStream` instance
"""
return cls(sys.stdin, sys.stdout)
pipestream = cls(sys.stdin, sys.stdout)
sys.stdin = os.open(os.devnull, os.O_RDWR)
sys.stdout = sys.stdin
return pipestream

@classmethod
def create_pair(cls):
Expand Down Expand Up @@ -405,7 +408,10 @@ def __init__(self, incoming, outgoing):

@classmethod
def from_std(cls):
return cls(sys.stdin, sys.stdout)
pipestream = cls(sys.stdin, sys.stdout)
sys.stdin = os.open(os.devnull, os.O_RDWR)
sys.stdout = sys.stdin
return pipestream

@classmethod
def create_pair(cls):
Expand Down
81 changes: 51 additions & 30 deletions rpyc/lib/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,44 +170,65 @@ def exp_backoff(collision):


def get_id_pack(obj):
"""introspects the given "local" object, returns id_pack as expected by BaseNetref
"""introspects the given "local" object, returns id_pack as expected by
BaseNetref

The given object is "local" in the sense that it is from the local cache. Any object in the local cache exists
in the current address space or is a netref. A netref in the local cache could be from a chained-connection.
To handle type related behavior properly, the attribute `__class__` is a descriptor for netrefs.
The given object is "local" in the sense that it is from the local
cache. Any object in the local cache exists in the current address
space or is a netref. A netref in the local cache could be from a
chained-connection. To handle type related behavior properly, the
attribute `__class__` is a descriptor for netrefs.

So, check thy assumptions regarding the given object when creating `id_pack`.
So, check thy assumptions regarding the given object when creating
`id_pack`.
"""
if hasattr(obj, '____id_pack__'):
# netrefs are handled first since __class__ is a descriptor
return obj.____id_pack__
elif inspect.ismodule(obj) or getattr(obj, '__name__', None) == 'module':
# TODO: not sure about this, need to enumerate cases in units
undef = object()
name_pack = getattr(obj, '____id_pack__', undef)
if name_pack is not undef:
return name_pack

obj_name = getattr(obj, '__name__', None)
if (inspect.ismodule(obj) or obj_name == 'module'):
if isinstance(obj, type): # module
obj_cls = type(obj)
name_pack = '{0}.{1}'.format(obj_cls.__module__, obj_cls.__name__)
name_pack = (
f'{obj_cls.__module__}.{obj_cls.__name__}'
)
return (name_pack, id(type(obj)), id(obj))

if inspect.ismodule(obj) and obj_name != 'module':
if obj_name in sys.modules:
name_pack = obj_name
else:
obj_cls = getattr(obj, '__class__', type(obj))
name_pack = (
f'{obj_cls.__module__}.{obj_name}'
)
elif inspect.ismodule(obj):
name_pack = (
f'{obj.__module__}.{obj_name}'
)
else:
if inspect.ismodule(obj) and obj.__name__ != 'module':
if obj.__name__ in sys.modules:
name_pack = obj.__name__
else:
name_pack = '{0}.{1}'.format(obj.__class__.__module__, obj.__name__)
elif inspect.ismodule(obj):
name_pack = '{0}.{1}'.format(obj.__module__, obj.__name__)
print(name_pack)
elif hasattr(obj, '__module__'):
name_pack = '{0}.{1}'.format(obj.__module__, obj.__name__)
obj_module = getattr(obj, '__module__', undef)
if obj_module is not undef:
name_pack = (
f'{obj.__module__}.{obj_name}'
)
else:
obj_cls = type(obj)
name_pack = '{0}'.format(obj.__name__)
return (name_pack, id(type(obj)), id(obj))
elif not inspect.isclass(obj):
name_pack = '{0}.{1}'.format(obj.__class__.__module__, obj.__class__.__name__)
name_pack = obj_name
return (name_pack, id(type(obj)), id(obj))
else:
name_pack = '{0}.{1}'.format(obj.__module__, obj.__name__)
return (name_pack, id(obj), 0)

if not inspect.isclass(obj):
obj_cls = getattr(obj, '__class__', type(obj))
name_pack = (
f'{obj_cls.__module__}.{obj_cls.__name__}'
)
return (name_pack, id(type(obj)), id(obj))

name_pack = (
f'{obj.__module__}.{obj_name}'
)
return (name_pack, id(obj), 0)


def get_methods(obj_attrs, obj):
Expand All @@ -229,6 +250,6 @@ def get_methods(obj_attrs, obj):
for basecls in mros:
attrs.update(basecls.__dict__)
for name, attr in attrs.items():
if name not in obj_attrs and hasattr(attr, "__call__"):
if name not in obj_attrs and inspect.isroutine(attr):
methods[name] = inspect.getdoc(attr)
return methods.items()
Loading