[ajax] improve backward compatibility for redefined ajax functions (closes #2447189)
If an ajax function from stdlib (e.g. js_reledit_form) was redefined in a cube,
the cube version should still takes the precedence<
=> check for existing ajax function on deprecated controller _before_ checking
ajax function availability on the new one.
--- a/web/test/unittest_views_basecontrollers.py Tue Jul 31 11:04:45 2012 +0200
+++ b/web/test/unittest_views_basecontrollers.py Wed Aug 01 09:20:47 2012 +0200
@@ -781,6 +781,14 @@
res, req = self.remote_call('foo')
self.assertEqual(res, '12')
+ def test_monkeypatch_jsoncontroller_stdfunc(self):
+ @monkeypatch(JSonController)
+ @jsonize
+ def js_reledit_form(self):
+ return 12
+ res, req = self.remote_call('reledit_form')
+ self.assertEqual(res, '12')
+
class UndoControllerTC(CubicWebTC):
--- a/web/views/ajaxcontroller.py Tue Jul 31 11:04:45 2012 +0200
+++ b/web/views/ajaxcontroller.py Wed Aug 01 09:20:47 2012 +0200
@@ -63,6 +63,7 @@
__docformat__ = "restructuredtext en"
+from warnings import warn
from functools import partial
from logilab.common.date import strptime
@@ -114,22 +115,20 @@
fname = self._cw.form['fname']
except KeyError:
raise RemoteCallFailed('no method specified')
+ # 1/ check first for old-style (JSonController) ajax func for bw compat
try:
- func = self._cw.vreg['ajax-func'].select(fname, self._cw)
- except ObjectNotFound:
- # function not found in the registry, inspect JSonController for
- # backward compatibility
+ func = getattr(basecontrollers.JSonController, 'js_%s' % fname).im_func
+ func = partial(func, self)
+ except AttributeError:
+ # 2/ check for new-style (AjaxController) ajax func
try:
- func = getattr(basecontrollers.JSonController, 'js_%s' % fname).im_func
- func = partial(func, self)
- except AttributeError:
+ func = self._cw.vreg['ajax-func'].select(fname, self._cw)
+ except ObjectNotFound:
raise RemoteCallFailed('no %s method' % fname)
- else:
- self.warning('remote function %s found on JSonController, '
- 'use AjaxFunction / @ajaxfunc instead', fname)
- except NoSelectableObject:
- raise RemoteCallFailed('method %s not available in this context'
- % fname)
+ else:
+ warn('[3.15] remote function %s found on JSonController, '
+ 'use AjaxFunction / @ajaxfunc instead' % fname,
+ DeprecationWarning, stacklevel=2)
# no <arg> attribute means the callback takes no argument
args = self._cw.form.get('arg', ())
if not isinstance(args, (list, tuple)):