Commit b0209091 authored by Julien Muchembled's avatar Julien Muchembled

ExternalMethod: remove magic to decide if aq_parent should be passed or not as first argument

Instead of trying without and retry in case of TypeError, we now have a reliable
rule: aq_parent is passed if and only if the name of first argument is 'self'.
parent b45914fa
...@@ -24,7 +24,7 @@ elif (portal_type == "Web Manifest"): ...@@ -24,7 +24,7 @@ elif (portal_type == "Web Manifest"):
else: else:
if (mapping_dict is not None): if (mapping_dict is not None):
web_content = web_page.TextDocument_substituteTextContent(web_page, web_content, mapping_dict=mapping_dict) web_content = web_page.TextDocument_substituteTextContent(web_content, mapping_dict=mapping_dict)
# Do not allow to put inside an iframe # Do not allow to put inside an iframe
response.setHeader("X-Frame-Options", "SAMEORIGIN") response.setHeader("X-Frame-Options", "SAMEORIGIN")
response.setHeader("X-Content-Type-Options", "nosniff") response.setHeader("X-Content-Type-Options", "nosniff")
......
...@@ -24,7 +24,7 @@ elif (portal_type == "Web Manifest"): ...@@ -24,7 +24,7 @@ elif (portal_type == "Web Manifest"):
else: else:
if (mapping_dict is not None): if (mapping_dict is not None):
web_content = web_page.TextDocument_substituteTextContent(web_page, web_content, mapping_dict=mapping_dict) web_content = web_page.TextDocument_substituteTextContent(web_content, mapping_dict=mapping_dict)
# Do not allow to put inside an iframe # Do not allow to put inside an iframe
response.setHeader("X-Frame-Options", "SAMEORIGIN") response.setHeader("X-Frame-Options", "SAMEORIGIN")
response.setHeader("X-Content-Type-Options", "nosniff") response.setHeader("X-Content-Type-Options", "nosniff")
......
...@@ -24,7 +24,7 @@ elif (portal_type == "Web Manifest"): ...@@ -24,7 +24,7 @@ elif (portal_type == "Web Manifest"):
else: else:
if (mapping_dict is not None): if (mapping_dict is not None):
web_content = web_page.TextDocument_substituteTextContent(web_page, web_content, mapping_dict=mapping_dict) web_content = web_page.TextDocument_substituteTextContent(web_content, mapping_dict=mapping_dict)
# Do not allow to put inside an iframe # Do not allow to put inside an iframe
response.setHeader("X-Frame-Options", "SAMEORIGIN") response.setHeader("X-Frame-Options", "SAMEORIGIN")
response.setHeader("X-Content-Type-Options", "nosniff") response.setHeader("X-Content-Type-Options", "nosniff")
......
...@@ -25,7 +25,7 @@ elif (portal_type == "Web Manifest"): ...@@ -25,7 +25,7 @@ elif (portal_type == "Web Manifest"):
else: else:
if (mapping_dict is not None): if (mapping_dict is not None):
web_content = web_page.TextDocument_substituteTextContent(web_page, web_content, mapping_dict=mapping_dict) web_content = web_page.TextDocument_substituteTextContent(web_content, mapping_dict=mapping_dict)
content_security_policy = "default-src 'self' data: blob:" content_security_policy = "default-src 'self' data: blob:"
if (web_section): if (web_section):
......
...@@ -88,7 +88,6 @@ class TestScribusUtils(ERP5TypeTestCase): ...@@ -88,7 +88,6 @@ class TestScribusUtils(ERP5TypeTestCase):
generated (using convert), and a css file created''' generated (using convert), and a css file created'''
self.portal.ERP5Site_createModuleScribus( self.portal.ERP5Site_createModuleScribus(
self,
option_html=1, option_html=1,
desired_width=800, desired_width=800,
desired_height=1132, desired_height=1132,
...@@ -177,7 +176,6 @@ class TestScribusUtils(ERP5TypeTestCase): ...@@ -177,7 +176,6 @@ class TestScribusUtils(ERP5TypeTestCase):
# Update the ERP5Form, scribus, PDFForm, css and background picture # Update the ERP5Form, scribus, PDFForm, css and background picture
self.portal.ERP5Site_updateModuleScribus( self.portal.ERP5Site_updateModuleScribus(
self,
import_pdf_file=self.makeFileUpload('test_1.pdf'), import_pdf_file=self.makeFileUpload('test_1.pdf'),
import_scribus_file=self.makeFileUpload('test_2.sla'), import_scribus_file=self.makeFileUpload('test_2.sla'),
object_portal_type="Dummy") object_portal_type="Dummy")
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
############################################################################## ##############################################################################
from inspect import getargs from inspect import getargs
from types import MethodType
from Products.ExternalMethod.ExternalMethod import * from Products.ExternalMethod.ExternalMethod import *
from Products.ERP5Type.Globals import InitializeClass from Products.ERP5Type.Globals import InitializeClass
from zLOG import LOG, WARNING from zLOG import LOG, WARNING
...@@ -69,8 +70,15 @@ class _(PatchClass(ExternalMethod)): ...@@ -69,8 +70,15 @@ class _(PatchClass(ExternalMethod)):
return _f return _f
except AttributeError: except AttributeError:
pass pass
ff = getattr(f, 'im_func', f) code = f.func_code
self._v_f = _f = f, ff.func_defaults, FuncCode(ff, f is not ff) args = getargs(code)[0]
i = isinstance(f, MethodType)
ff = f.__func__ if i else f
has_self = len(args) > i and args[i] == 'self'
i += has_self
if i:
code = FuncCode(ff, i)
self._v_f = _f = (f, f.func_defaults, code, has_self)
return _f return _f
def __call__(self, *args, **kw): def __call__(self, *args, **kw):
...@@ -79,44 +87,17 @@ class _(PatchClass(ExternalMethod)): ...@@ -79,44 +87,17 @@ class _(PatchClass(ExternalMethod)):
Calling an External Method is roughly equivalent to calling Calling an External Method is roughly equivalent to calling
the original actual function from Python. Positional and the original actual function from Python. Positional and
keyword parameters can be passed as usual. Note however that keyword parameters can be passed as usual. Note however that
unlike the case of a normal Python method, the "self" argument if first argument is 'self', and only in this case, the
must be passed explicitly. An exception to this rule is made acquisition parent is passed as first positional parameter.
if:
- The supplied number of arguments is one less than the
required number of arguments, and
- The name of the function\'s first argument is 'self'.
In this case, the URL parent of the object is supplied as the
first argument.
""" """
self.checkGuard(True) self.checkGuard(True)
_f = self.getFunction() _f = self.getFunction()
f = _f[0]
__traceback_info__ = args, kw, _f[1] __traceback_info__ = args, kw, _f[1]
# XXX: We'd like to use inspect.getcallargs instead of try..except. if _f[3]:
# However, for the same reason as we use getargs instead of return _f[0](self.aq_parent, *args, **kw)
# getargspec, we need something that works for any callable return _f[0](*args, **kw)
# providing func_code & func_default (not only functions).
try: return f(*args, **kw)
except TypeError, v:
tb=sys.exc_info()[2]
try:
func_args, func_varargs, _ = getargs(f.func_code)
by_kw = set(kw)
if f.func_defaults:
by_kw.update(func_args[-len(f.func_defaults):])
if func_args[0] == 'self' and 'self' not in kw and (
func_varargs or len(set(func_args[len(args):]
).difference(by_kw)) == 1):
return f(self.aq_parent.this(), *args, **kw)
raise TypeError, v, tb
finally: tb=None
security = ClassSecurityInfo() security = ClassSecurityInfo()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment