# HG changeset patch # User Adrien Di Mascio # Date 1343805647 -7200 # Node ID f21c7292866274be684ab4a5c5f8b69463e60d6f # Parent bfc1875ce9e3b9e615545454db04632d622a69ab [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. diff -r bfc1875ce9e3 -r f21c72928662 web/test/unittest_views_basecontrollers.py --- 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): diff -r bfc1875ce9e3 -r f21c72928662 web/views/ajaxcontroller.py --- 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 attribute means the callback takes no argument args = self._cw.form.get('arg', ()) if not isinstance(args, (list, tuple)):