Get rid of the function wrapper. The only case it was needed is for exposing a function several times, but this case can be handled differently. I may reintroduce it as an option.

This commit is contained in:
Christophe de Vienne 2012-10-13 21:14:26 +02:00
parent 97f1b197ce
commit 5a840a4bd8
3 changed files with 13 additions and 40 deletions

View File

@ -26,6 +26,10 @@ def scan_api(controller, path=[]):
yield i
def iswsmefunction(f):
return hasattr(f, '_wsme_definition')
class FunctionArgument(object):
"""
An argument definition of an api entry
@ -47,34 +51,6 @@ class FunctionArgument(object):
self.datatype = registry.resolve_type(self.datatype)
def funcproxy(func):
"""
A very simple wrapper for exposed function.
It will carry the FunctionDefinition in place of the
decorared function so that a same function can be exposed
several times (for example a parent function can be exposed
in different ways in the children classes).
The returned function also carry a ``_original_func`` attribute
so that it can be inspected if needed.
"""
def newfunc(*args, **kw):
return func(*args, **kw)
newfunc._is_wsme_funcproxy = True
newfunc._original_func = func
newfunc.__doc__ = func.__doc__
newfunc.__name__ = func.__name__
return newfunc
def isfuncproxy(func):
"""
Returns True if ``func`` is already a function proxy.
"""
return getattr(func, '_is_wsme_funcproxy', False)
class FunctionDefinition(object):
"""
An api entry definition
@ -108,12 +84,11 @@ class FunctionDefinition(object):
"""
Returns the :class:`FunctionDefinition` of a method.
"""
if not isfuncproxy(func):
if not hasattr(func, '_wsme_definition'):
fd = FunctionDefinition(func)
func = funcproxy(func)
func._wsme_definition = fd
return func, func._wsme_definition
return func._wsme_definition
def get_arg(self, name):
"""
@ -148,7 +123,7 @@ class expose(object):
self.options = options
def __call__(self, func):
func, fd = FunctionDefinition.get(func)
fd = FunctionDefinition.get(func)
if fd.extra_options is not None:
raise ValueError("This function is already exposed")
fd.return_type = self.return_type
@ -173,7 +148,7 @@ class pexpose(object):
self.contenttype = contenttype
def __call__(self, func):
func, fd = FunctionDefinition.get(func)
fd = FunctionDefinition.get(func)
fd.return_type = self.return_type
fd.protocol_specific = True
fd.contenttype = self.contenttype
@ -197,9 +172,8 @@ class validate(object):
self.param_types = param_types
def __call__(self, func):
func, fd = FunctionDefinition.get(func)
args, varargs, keywords, defaults = inspect.getargspec(
func._original_func)
fd = FunctionDefinition.get(func)
args, varargs, keywords, defaults = inspect.getargspec(func)
if args[0] == 'self':
args = args[1:]
for i, argname in enumerate(args):

View File

@ -314,13 +314,12 @@ class FunctionDocumenter(autodoc.MethodDocumenter):
@classmethod
def can_document_member(cls, member, membername, isattr, parent):
return isinstance(parent, ServiceDocumenter) \
and wsme.api.isfuncproxy(member)
and wsme.api.iswsmefunction(member)
def import_object(self):
ret = super(FunctionDocumenter, self).import_object()
self.directivetype = 'function'
self.object, self.wsme_fd = \
wsme.api.FunctionDefinition.get(self.object)
self.wsme_fd = wsme.api.FunctionDefinition.get(self.object)
self.retann = self.wsme_fd.return_type.__name__
return ret

View File

@ -31,7 +31,7 @@ def test_pexpose():
def ufunc(self):
return u("<p>\xc3\xa9</p>")
func, fd = FunctionDefinition.get(Proto.func)
fd = FunctionDefinition.get(Proto.func)
assert fd.return_type is None
assert fd.protocol_specific
assert fd.contenttype == "text/xml"