You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
It seems that @rpyc.service is not smart enough to detect that a method has already been exposed. For example:
import rpyc
@rpyc.service
class BaseService(rpyc.Service):
@rpyc.exposed
def foo(self): ...
@rpyc.service
class ExtendedService(BaseService):
@rpyc.exposed
def bar(self): ...
service = ExtendedService()
for attr in dir(service):
if attr.startswith('exposed_'):
print(attr)
Notice the ExtendedService's foo method is exposed twice.
Clearly I can avoid this by removing @rpyc.service from either class, but that doesn't seem to be the right solution. If I remove it from ExtendedService then bar disappears from exposure. If I remove it from BaseService then I can no longer use BaseService without having some @rpyc.service extend it.
I don't know if this will have negative side effects, but I find that if I change @rpyc.service to the following, this problem is resolved:
def service(cls):
"""find and rename exposed decorated attributes"""
# NOTE: inspect.getmembers invokes getattr for each attribute-name. Descriptors may raise AttributeError.
# Only the AttributeError exception is caught when raised. This decorator will fail if a descriptor raises
# any exception other than AttributeError when getattr is called.
# Track already exposed attributes from base classes
inherited_exposed = {
attr_name
for base in cls.__bases__
for attr_name, attr_obj in inspect.getmembers(base)
if getattr(attr_obj, '__exposed__', False)
}
for attr_name, attr_obj in inspect.getmembers(cls): # rebind exposed decorated attributes
exposed_prefix = getattr(attr_obj, '__exposed__', False)
if exposed_prefix and not inspect.iscode(attr_obj): # exclude the implementation
# Skip if the attribute is already exposed in a parent class
if attr_name in inherited_exposed:
continue
renamed = exposed_prefix + attr_name
if inspect.isclass(attr_obj): # recurse exposed objects such as a class
attr_obj = service(attr_obj)
setattr(cls, attr_name, attr_obj)
setattr(cls, renamed, attr_obj)
return cls
```
The text was updated successfully, but these errors were encountered:
It seems that @rpyc.service is not smart enough to detect that a method has already been exposed. For example:
The output of this is:
Notice the ExtendedService's
foo
method is exposed twice.Clearly I can avoid this by removing
@rpyc.service
from either class, but that doesn't seem to be the right solution. If I remove it from ExtendedService thenbar
disappears from exposure. If I remove it from BaseService then I can no longer use BaseService without having some @rpyc.service extend it.I don't know if this will have negative side effects, but I find that if I change @rpyc.service to the following, this problem is resolved:
The text was updated successfully, but these errors were encountered: