[ajax] improve backward compatibility for redefined ajax functions (closes #2447189) stable
authorAdrien Di Mascio <Adrien.DiMascio@logilab.fr>
Wed, 01 Aug 2012 09:20:47 +0200
branchstable
changeset 8504 f21c72928662
parent 8500 bfc1875ce9e3
child 8508 7801f2acd1dc
[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.
web/test/unittest_views_basecontrollers.py
web/views/ajaxcontroller.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):
 
--- 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)):