Commits

Olemis Lang  committed b2f34d7

TracRpc: Consistent names for `kwargs`. Storing protocol in `req.rpc`.

  • Participants
  • Parent commits 935c332

Comments (0)

Files changed (4)

 
 # Including keyword args in Method class
-t0000/t0000-kwdargs-r7971.diff
+t0000/t0000-kwargs-r7971.diff
 t0000/t0000-reuse-method-r7971.diff
 
 

File t0000/t0000-kwargs-r7971.diff

+Introducing keyword args in instances of Method class
+
+diff -r fa00f1619d65 trunk/setup.py
+--- a/trunk/setup.py	Fri May 21 12:35:35 2010 +0200
++++ b/trunk/setup.py	Fri Sep 17 19:43:15 2010 -0400
+@@ -19,7 +19,7 @@
+ 
+ setup(
+     name='TracXMLRPC',
+-    version='1.1.0',
++    version='1.1.1',
+     license='BSD',
+     author='Alec Thomas',
+     author_email='alec@swapoff.org',
+diff -r fa00f1619d65 trunk/tracrpc/api.py
+--- a/trunk/tracrpc/api.py	Fri May 21 12:35:35 2010 +0200
++++ b/trunk/tracrpc/api.py	Fri Sep 17 19:43:15 2010 -0400
+@@ -98,6 +98,7 @@
+ 
+         method  (MANDATORY): target method name (e.g. 'ticket.get')
+         params  (OPTIONAL) : a tuple containing input positional arguments
++        kwparams (OPTIONAL): a dictionary containing input keyword arguments
+         headers (OPTIONAL) : if the protocol supports custom headers set 
+                               by the client, then this value SHOULD be a 
+                               dictionary binding `header name` to `value`. 
+@@ -191,10 +192,11 @@
+         self.namespace = provider.xmlrpc_namespace()
+         self.namespace_description = inspect.getdoc(provider)
+ 
+-    def __call__(self, req, args):
++    def __call__(self, req, args, kwargs=None):
+         if self.permission:
+             req.perm.assert_permission(self.permission)
+-        result = self.callable(req, *args)
++        kwargs = kwargs or {}
++        result = self.callable(req, *args, **kwargs)
+         # If result is null, return a zero
+         if result is None:
+             result = 0
+diff -r fa00f1619d65 trunk/tracrpc/tests/api.py
+--- a/trunk/tracrpc/tests/api.py	Fri May 21 12:35:35 2010 +0200
++++ b/trunk/tracrpc/tests/api.py	Fri Sep 17 19:43:15 2010 -0400
+@@ -5,8 +5,9 @@
+ (c) 2009      ::: www.CodeResort.com - BV Network AS (simon-code@bvnetwork.no)
+ """
+ 
+-import os
++import os.path
+ import unittest
++import urllib
+ import urllib2
+ 
+ from tracrpc.tests import rpc_testenv, TracRpcTestCase
+@@ -14,14 +15,21 @@
+ from tracrpc.api import IRPCProtocol
+ 
+ from trac.core import *
+-from trac.test import Mock
+ 
+ class ProtocolProviderTestCase(TracRpcTestCase):
+ 
+     def setUp(self):
+         TracRpcTestCase.setUp(self)
++        # Make a new plugin 
++        self.pluginfile = os.path.join(rpc_testenv.tracdir, 'plugins', 'DummyProvider.py')
+ 
+     def tearDown(self):
++        if os.path.exists(self.pluginfile):
++            # Clean up so that provider don't affect further tests
++            os.unlink(self.pluginfile)
++            rpc_testenv.restart()
++        # Release some memory ???
++        self.pluginfile = None 
+         TracRpcTestCase.tearDown(self)
+ 
+     def test_invalid_content_type(self):
+@@ -47,9 +55,7 @@
+             self.fail("Expected urllib2.HTTPError")
+         except urllib2.HTTPError, e:
+             self.assertEquals(e.code, 415)
+-        # Make a new plugin 
+-        provider = os.path.join(rpc_testenv.tracdir, 'plugins', 'DummyProvider.py')
+-        open(provider, 'w').write(
++        open(self.pluginfile, 'w').write(
+             "from trac.core import *\n"
+             "from tracrpc.api import *\n"
+             "class DummyProvider(Component):\n"
+@@ -70,23 +76,75 @@
+             "        response = 'Got a result!'\n"
+             "        req.send(response, rpcreq['mimetype'], 200)\n")
+         rpc_testenv.restart()
++        req = urllib2.Request(rpc_testenv.url_anon,
++                    headers={'Content-Type': 'application/x-tracrpc-test'})
++        resp = urllib2.urlopen(req)
++        self.assertEquals(200, resp.code)
++        self.assertEquals("Got a result!", resp.read())
++        self.assertEquals(resp.headers['Content-Type'],
++                              'application/x-tracrpc-test;charset=utf-8')
++
++    def test_valid_kwargs(self):
++        # Confirm the request won't work before adding plugin
++        req = urllib2.Request(rpc_testenv.url_anon,
++                        headers={'Content-Type': 'application/x-tracrpc-test'},
++                        data="Fail! No RPC for application/x-tracrpc-test")
+         try:
+-            req = urllib2.Request(rpc_testenv.url_anon,
+-                        headers={'Content-Type': 'application/x-tracrpc-test'})
+             resp = urllib2.urlopen(req)
+-            self.assertEquals(200, resp.code)
+-            self.assertEquals("Got a result!", resp.read())
+-            self.assertEquals(resp.headers['Content-Type'],
+-                                  'application/x-tracrpc-test;charset=utf-8')
+-        finally:
+-            # Clean up so that provider don't affect further tests
+-            os.unlink(provider)
+-            rpc_testenv.restart()
++            self.fail("Expected urllib2.HTTPError")
++        except urllib2.HTTPError, e:
++            self.assertEquals(e.code, 415)
++        open(self.pluginfile, 'w').write(
++            "from trac.core import *\n"
++            "from trac.web.api import IRequestFilter\n"
++            "from tracrpc.api import *\n"
++            "from tracrpc.web_ui import *\n"
++            "class DummyProvider(Component):\n"
++            "    implements(IRPCProtocol, IRequestFilter)\n"
++            "    def pre_process_request(self, req, handler):\n"
++            "        if handler is RPCWeb(self.env) :\n"
++            "            # Avoid XSRF check \n"
++            "            self.log.debug('Tweaking XSRF protection')\n"
++            "            req.args['__FORM_TOKEN'] = req.form_token\n"
++            "            req.incookie['trac_form_token'] = "
++            "                             req.outcookie['trac_form_token']\n"
++            "        return handler\n"
++            "    def post_process_request(self, req, template, "
++            "                             data, content_type):\n"
++            "        return template, data, content_type\n"
++            "    def rpc_info(self):\n"
++            "        return ('TEST-RPC', 'No Docs!')\n"
++            "    def rpc_match(self):\n"
++            "        yield ('rpc', 'application/x-www-form-urlencoded')\n"
++            "        yield ('rpc', 'application/x-tracrpc-test')\n"
++            "    def parse_rpc_request(self, req, content_type):\n"
++            "        return dict(method=req.args.pop('_function', None),"
++            "                    kwparams=dict([k, v] "
++            "                                   for k,v in req.args.items()"
++            "                                   if k[0] != '_'))\n"
++            "    def send_rpc_error(self, req, e):\n"
++            "        rpcreq = req.rpc\n"
++            "        req.send_error(None, template='', content_type=rpcreq['mimetype'],\n"
++            "                       status=500, env=None, data='Test failure ')\n"
++            "    def send_rpc_result(self, req, result):\n"
++            "        rpcreq = req.rpc\n"
++            "        response = 'Got a result!'\n"
++            "        req.send(response, 'text/plain', 200)\n")
++        rpc_testenv.restart()
++        req = urllib2.Request(rpc_testenv.url_anon,
++                    headers={'Content-Type': 'application/x-www-form-urlencoded'},
++                    data=urllib.urlencode(
++                            {'_function' : 'system.methodHelp',
++                            'method' : 'system.methodHelp',})
++                    )
++        resp = urllib2.urlopen(req)
++        self.assertEquals(200, resp.code)
++        self.assertEquals("Got a result!", resp.read())
++        self.assertEquals(resp.headers['Content-Type'],
++                              'text/plain;charset=utf-8')
+ 
+     def test_general_provider_error(self):
+-        # Make a new plugin and restart server
+-        provider = os.path.join(rpc_testenv.tracdir, 'plugins', 'DummyProvider.py')
+-        open(provider, 'w').write(
++        open(self.pluginfile, 'w').write(
+             "from trac.core import *\n"
+             "from tracrpc.api import *\n"
+             "class DummyProvider(Component):\n"
+@@ -118,10 +176,6 @@
+             self.assertEquals(500, e.code)
+             self.assertEquals("No good.", e.fp.read())
+             self.assertTrue(e.hdrs['Content-Type'].startswith('text/plain'))
+-        finally:
+-            # Clean up so that provider don't affect further tests
+-            os.unlink(provider)
+-            rpc_testenv.restart()
+ 
+ def test_suite():
+     return unittest.makeSuite(ProtocolProviderTestCase)
+diff -r fa00f1619d65 trunk/tracrpc/web_ui.py
+--- a/trunk/tracrpc/web_ui.py	Fri May 21 12:35:35 2010 +0200
++++ b/trunk/tracrpc/web_ui.py	Fri Sep 17 19:43:15 2010 -0400
+@@ -54,13 +54,16 @@
+                 if req.path_info in ['/%s' % p_path, '/login/%s' % p_path]:
+                     must_handle_request = True
+                     if content_type.startswith(p_type):
+-                        req.args['protocol'] = protocol
++                        req.rpc = {'protocol' : protocol}
+                         return True
+         # No protocol call, need to handle for docs or error if handled path
+         return must_handle_request
+ 
+     def process_request(self, req):
+-        protocol = req.args.get('protocol', None)
++        try :
++            protocol = req.rpc['protocol']
++        except AttributeError :
++            protocol = None
+         content_type = req.get_header('Content-Type') or 'text/html'
+         if protocol:
+             # Perform the method call
+@@ -151,10 +154,11 @@
+             if method_name is None :
+                 raise ProtocolException('Missing method name')
+             args = rpcreq.get('params') or []
++            kwargs = rpcreq.get('kwparams') or {}
+             self.log.debug("RPC(%s) call by '%s' %s", proto_id, \
+                                               req.authname, method_name)
+             try :
+-                result = (XMLRPCSystem(self.env).get_method(method_name)(req, args))[0]
++                result = (XMLRPCSystem(self.env).get_method(method_name)(req, args, kwargs))[0]
+                 if isinstance(result, GeneratorType):
+                     result = list(result)
+             except (RPCError, PermissionError, ResourceNotFound), e:

File t0000/t0000-kwdargs-r7971.diff

-Introducing keyword args in instances of Method class
-
-diff -r fa00f1619d65 trunk/setup.py
---- a/trunk/setup.py	Fri May 21 12:35:35 2010 +0200
-+++ b/trunk/setup.py	Fri Sep 10 23:09:17 2010 -0400
-@@ -19,7 +19,7 @@
- 
- setup(
-     name='TracXMLRPC',
--    version='1.1.0',
-+    version='1.1.1',
-     license='BSD',
-     author='Alec Thomas',
-     author_email='alec@swapoff.org',
-diff -r fa00f1619d65 trunk/tracrpc/api.py
---- a/trunk/tracrpc/api.py	Fri May 21 12:35:35 2010 +0200
-+++ b/trunk/tracrpc/api.py	Fri Sep 10 23:09:17 2010 -0400
-@@ -98,6 +98,7 @@
- 
-         method  (MANDATORY): target method name (e.g. 'ticket.get')
-         params  (OPTIONAL) : a tuple containing input positional arguments
-+        kparams (OPTIONAL) : a dictionary containing input keyword arguments
-         headers (OPTIONAL) : if the protocol supports custom headers set 
-                               by the client, then this value SHOULD be a 
-                               dictionary binding `header name` to `value`. 
-@@ -191,10 +192,11 @@
-         self.namespace = provider.xmlrpc_namespace()
-         self.namespace_description = inspect.getdoc(provider)
- 
--    def __call__(self, req, args):
-+    def __call__(self, req, args, kwds=None):
-         if self.permission:
-             req.perm.assert_permission(self.permission)
--        result = self.callable(req, *args)
-+        kwds = kwds or {}
-+        result = self.callable(req, *args, **kwds)
-         # If result is null, return a zero
-         if result is None:
-             result = 0
-diff -r fa00f1619d65 trunk/tracrpc/tests/api.py
---- a/trunk/tracrpc/tests/api.py	Fri May 21 12:35:35 2010 +0200
-+++ b/trunk/tracrpc/tests/api.py	Fri Sep 10 23:09:17 2010 -0400
-@@ -5,8 +5,9 @@
- (c) 2009      ::: www.CodeResort.com - BV Network AS (simon-code@bvnetwork.no)
- """
- 
--import os
-+import os.path
- import unittest
-+import urllib
- import urllib2
- 
- from tracrpc.tests import rpc_testenv, TracRpcTestCase
-@@ -14,14 +15,21 @@
- from tracrpc.api import IRPCProtocol
- 
- from trac.core import *
--from trac.test import Mock
- 
- class ProtocolProviderTestCase(TracRpcTestCase):
- 
-     def setUp(self):
-         TracRpcTestCase.setUp(self)
-+        # Make a new plugin 
-+        self.pluginfile = os.path.join(rpc_testenv.tracdir, 'plugins', 'DummyProvider.py')
- 
-     def tearDown(self):
-+        if os.path.exists(self.pluginfile):
-+            # Clean up so that provider don't affect further tests
-+            os.unlink(self.pluginfile)
-+            rpc_testenv.restart()
-+        # Release some memory ???
-+        self.pluginfile = None 
-         TracRpcTestCase.tearDown(self)
- 
-     def test_invalid_content_type(self):
-@@ -47,9 +55,7 @@
-             self.fail("Expected urllib2.HTTPError")
-         except urllib2.HTTPError, e:
-             self.assertEquals(e.code, 415)
--        # Make a new plugin 
--        provider = os.path.join(rpc_testenv.tracdir, 'plugins', 'DummyProvider.py')
--        open(provider, 'w').write(
-+        open(self.pluginfile, 'w').write(
-             "from trac.core import *\n"
-             "from tracrpc.api import *\n"
-             "class DummyProvider(Component):\n"
-@@ -70,23 +76,75 @@
-             "        response = 'Got a result!'\n"
-             "        req.send(response, rpcreq['mimetype'], 200)\n")
-         rpc_testenv.restart()
-+        req = urllib2.Request(rpc_testenv.url_anon,
-+                    headers={'Content-Type': 'application/x-tracrpc-test'})
-+        resp = urllib2.urlopen(req)
-+        self.assertEquals(200, resp.code)
-+        self.assertEquals("Got a result!", resp.read())
-+        self.assertEquals(resp.headers['Content-Type'],
-+                              'application/x-tracrpc-test;charset=utf-8')
-+
-+    def test_valid_kwdargs(self):
-+        # Confirm the request won't work before adding plugin
-+        req = urllib2.Request(rpc_testenv.url_anon,
-+                        headers={'Content-Type': 'application/x-tracrpc-test'},
-+                        data="Fail! No RPC for application/x-tracrpc-test")
-         try:
--            req = urllib2.Request(rpc_testenv.url_anon,
--                        headers={'Content-Type': 'application/x-tracrpc-test'})
-             resp = urllib2.urlopen(req)
--            self.assertEquals(200, resp.code)
--            self.assertEquals("Got a result!", resp.read())
--            self.assertEquals(resp.headers['Content-Type'],
--                                  'application/x-tracrpc-test;charset=utf-8')
--        finally:
--            # Clean up so that provider don't affect further tests
--            os.unlink(provider)
--            rpc_testenv.restart()
-+            self.fail("Expected urllib2.HTTPError")
-+        except urllib2.HTTPError, e:
-+            self.assertEquals(e.code, 415)
-+        open(self.pluginfile, 'w').write(
-+            "from trac.core import *\n"
-+            "from trac.web.api import IRequestFilter\n"
-+            "from tracrpc.api import *\n"
-+            "from tracrpc.web_ui import *\n"
-+            "class DummyProvider(Component):\n"
-+            "    implements(IRPCProtocol, IRequestFilter)\n"
-+            "    def pre_process_request(self, req, handler):\n"
-+            "        if handler is RPCWeb(self.env) :\n"
-+            "            # Avoid XSRF check \n"
-+            "            self.log.debug('Tweaking XSRF protection')\n"
-+            "            req.args['__FORM_TOKEN'] = req.form_token\n"
-+            "            req.incookie['trac_form_token'] = "
-+            "                             req.outcookie['trac_form_token']\n"
-+            "        return handler\n"
-+            "    def post_process_request(self, req, template, "
-+            "                             data, content_type):\n"
-+            "        return template, data, content_type\n"
-+            "    def rpc_info(self):\n"
-+            "        return ('TEST-RPC', 'No Docs!')\n"
-+            "    def rpc_match(self):\n"
-+            "        yield ('rpc', 'application/x-www-form-urlencoded')\n"
-+            "        yield ('rpc', 'application/x-tracrpc-test')\n"
-+            "    def parse_rpc_request(self, req, content_type):\n"
-+            "        return dict(method=req.args.pop('_function', None),"
-+            "                    kparams=dict([k, v] "
-+            "                                   for k,v in req.args.items()"
-+            "                                   if k[0] != '_'))\n"
-+            "    def send_rpc_error(self, req, e):\n"
-+            "        rpcreq = req.rpc\n"
-+            "        req.send_error(None, template='', content_type=rpcreq['mimetype'],\n"
-+            "                       status=500, env=None, data='Test failure ')\n"
-+            "    def send_rpc_result(self, req, result):\n"
-+            "        rpcreq = req.rpc\n"
-+            "        response = 'Got a result!'\n"
-+            "        req.send(response, 'text/plain', 200)\n")
-+        rpc_testenv.restart()
-+        req = urllib2.Request(rpc_testenv.url_anon,
-+                    headers={'Content-Type': 'application/x-www-form-urlencoded'},
-+                    data=urllib.urlencode(
-+                            {'_function' : 'system.methodHelp',
-+                            'method' : 'system.methodHelp',})
-+                    )
-+        resp = urllib2.urlopen(req)
-+        self.assertEquals(200, resp.code)
-+        self.assertEquals("Got a result!", resp.read())
-+        self.assertEquals(resp.headers['Content-Type'],
-+                              'text/plain;charset=utf-8')
- 
-     def test_general_provider_error(self):
--        # Make a new plugin and restart server
--        provider = os.path.join(rpc_testenv.tracdir, 'plugins', 'DummyProvider.py')
--        open(provider, 'w').write(
-+        open(self.pluginfile, 'w').write(
-             "from trac.core import *\n"
-             "from tracrpc.api import *\n"
-             "class DummyProvider(Component):\n"
-@@ -118,10 +176,6 @@
-             self.assertEquals(500, e.code)
-             self.assertEquals("No good.", e.fp.read())
-             self.assertTrue(e.hdrs['Content-Type'].startswith('text/plain'))
--        finally:
--            # Clean up so that provider don't affect further tests
--            os.unlink(provider)
--            rpc_testenv.restart()
- 
- def test_suite():
-     return unittest.makeSuite(ProtocolProviderTestCase)
-diff -r fa00f1619d65 trunk/tracrpc/web_ui.py
---- a/trunk/tracrpc/web_ui.py	Fri May 21 12:35:35 2010 +0200
-+++ b/trunk/tracrpc/web_ui.py	Fri Sep 10 23:09:17 2010 -0400
-@@ -54,13 +54,13 @@
-                 if req.path_info in ['/%s' % p_path, '/login/%s' % p_path]:
-                     must_handle_request = True
-                     if content_type.startswith(p_type):
--                        req.args['protocol'] = protocol
-+                        req.rpc_protocol = protocol
-                         return True
-         # No protocol call, need to handle for docs or error if handled path
-         return must_handle_request
- 
-     def process_request(self, req):
--        protocol = req.args.get('protocol', None)
-+        protocol = getattr(req, 'rpc_protocol', None)
-         content_type = req.get_header('Content-Type') or 'text/html'
-         if protocol:
-             # Perform the method call
-@@ -151,10 +151,11 @@
-             if method_name is None :
-                 raise ProtocolException('Missing method name')
-             args = rpcreq.get('params') or []
-+            kwds = rpcreq.get('kparams') or {}
-             self.log.debug("RPC(%s) call by '%s' %s", proto_id, \
-                                               req.authname, method_name)
-             try :
--                result = (XMLRPCSystem(self.env).get_method(method_name)(req, args))[0]
-+                result = (XMLRPCSystem(self.env).get_method(method_name)(req, args, kwds))[0]
-                 if isinstance(result, GeneratorType):
-                     result = list(result)
-             except (RPCError, PermissionError, ResourceNotFound), e:

File t0000/t0000-reuse-method-r7971.diff

  
 -        method  (MANDATORY): target method name (e.g. 'ticket.get')
 -        params  (OPTIONAL) : a tuple containing input positional arguments
--        kparams (OPTIONAL) : a dictionary containing input keyword arguments
+-        kwparams (OPTIONAL): a dictionary containing input keyword arguments
 -        headers (OPTIONAL) : if the protocol supports custom headers set 
 -                              by the client, then this value SHOULD be a 
 -                              dictionary binding `header name` to `value`. 
 +                                signatures to decode RPC messages (e.g. 
 +                                static-typed RPC protocols).
 +        params    (OPTIONAL) : a tuple containing input positional arguments
-+        kparams   (OPTIONAL) : a dictionary containing input keyword arguments
++        kwparams  (OPTIONAL) : a dictionary containing input keyword arguments
 +        headers   (OPTIONAL) : if the protocol supports custom headers set 
 +                                by the client, then this value SHOULD be a 
 +                                dictionary binding `header name` to `value`. 
              self.log.debug("RPC(%s) call by '%s' %s", proto_id, \
                                                req.authname, method_name)
              try :
--                result = (XMLRPCSystem(self.env).get_method(method_name)(req, args, kwds))[0]
+-                result = (XMLRPCSystem(self.env).get_method(method_name)(req, args, kwargs))[0]
 +                method = rpcreq.get('methodobj') or \
 +                         XMLRPCSystem(self.env).get_method(method_name)
-+                result = method(req, args, kwds)[0]
++                result = method(req, args, kwargs)[0]
                  if isinstance(result, GeneratorType):
                      result = list(result)
              except (RPCError, PermissionError, ResourceNotFound), e: