def expose(method_or_class):
"""
Decorator to mark a method or class to be exposed for remote calls.
You can apply it to a method or a class as a whole.
If you need to change the default instance mode or instance creator, also use a @behavior decorator.
"""
if inspect.isdatadescriptor(method_or_class):
func = method_or_class.fget or method_or_class.fset or method_or_class.fdel
if is_private_attribute(func.__name__):
raise AttributeError("exposing private names (starting with _) is not allowed")
func._pyroExposed = True
return method_or_class
attrname = getattr(method_or_class, "__name__", None)
if not attrname:
# we could be dealing with a descriptor (classmethod/staticmethod), this means the order of the decorators is wrong
if inspect.ismethoddescriptor(method_or_class):
attrname = method_or_class.__get__(None, dict).__name__
raise AttributeError("using @expose on a classmethod/staticmethod must be done "
"after @classmethod/@taticmethod. Method: " + attrname)
else:
raise AttributeError("@expose cannot determine what this is: "+repr(method_or_class))
if is_private_attribute(attrname):
raise AttributeError("exposing private names (starting with _) is not allowed")
if inspect.isclass(method_or_class):
clazz = method_or_class
log.debug("exposing all members of %r", clazz)
for name in clazz.__dict__:
if is_private_attribute(name):
continue
thing = getattr(clazz, name)
if inspect.isfunction(thing):
thing._pyroExposed = True
elif inspect.ismethod(thing):
thing.__func__._pyroExposed = True
elif inspect.isdatadescriptor(thing):
if getattr(thing, "fset", None):
thing.fset._pyroExposed = True
if getattr(thing, "fget", None):
thing.fget._pyroExposed = True
if getattr(thing, "fdel", None):
thing.fdel._pyroExposed = True
clazz._pyroExposed = True
return clazz
method_or_class._pyroExposed = True
return method_or_class
评论列表
文章目录