Index: twisted/test/test_xmlrpc.py =================================================================== RCS file: /cvs/Twisted/twisted/test/test_xmlrpc.py,v retrieving revision 1.7 diff -u -r1.7 test_xmlrpc.py --- twisted/test/test_xmlrpc.py 18 Jun 2003 16:31:20 -0000 1.7 +++ twisted/test/test_xmlrpc.py 13 Aug 2003 08:32:37 -0000 @@ -25,7 +25,7 @@ class XMLRPC: pass else: from twisted.web import xmlrpc - from twisted.web.xmlrpc import XMLRPC + from twisted.web.xmlrpc import XMLRPC, XMLRPCIntrospection from twisted.trial import unittest from twisted.web import server @@ -57,6 +57,9 @@ return defer.fail(xmlrpc.Fault(17, "hi")) +class TestIntrospection(Test, XMLRPCIntrospection): pass + + class XMLRPCTestCase(unittest.TestCase): def setUp(self): @@ -95,3 +98,18 @@ def proxy(self): return xmlrpc.Proxy("http://localhost:%d" % self.port) + + +class XMLRPCTestIntrospection(XMLRPCTestCase): + + def setUp(self): + self.p = reactor.listenTCP(0, server.Site(TestIntrospection()), + interface="127.0.0.1") + self.port = self.p.getHost()[2] + + def testListMethods(self): + d = self.proxy().callRemote("system.listMethods") + list = unittest.deferredResult(d) + list.sort() + self.failUnlessEqual(list, ['add', 'defer', 'deferFail', 'deferFault', + 'fail', 'fault', 'system.listMethods']) Index: twisted/web/xmlrpc.py =================================================================== RCS file: /cvs/Twisted/twisted/web/xmlrpc.py,v retrieving revision 1.27 diff -u -r1.27 xmlrpc.py --- twisted/web/xmlrpc.py 27 Jul 2003 00:04:14 -0000 1.27 +++ twisted/web/xmlrpc.py 13 Aug 2003 08:32:38 -0000 @@ -34,7 +34,7 @@ # Sibling Imports from twisted.web import resource, server from twisted.internet import defer, protocol, reactor -from twisted.python import log +from twisted.python import log, reflect from twisted.protocols import http # These are deprecated, use the class level definitions @@ -89,6 +89,7 @@ Binary, Boolean, DateTime, Deferreds, or Handler instances. By default methods beginning with 'xmlrpc_' are published. + Periods ('.') are converted to double underscores. """ # Error codes for Twisted, if they conflict with yours then @@ -147,6 +148,7 @@ policy is that given functionPath 'foo', return the method at self.xmlrpc_foo, i.e. getattr(self, "xmlrpc_" + functionPath). """ + functionPath = functionPath.replace('.', '__') f = getattr(self, "xmlrpc_%s" % functionPath, None) if f and callable(f): return f @@ -154,6 +156,16 @@ raise NoSuchFunction +class XMLRPCIntrospection: + """A mix-in that implements the XML-RPC Introspection API. + + """ + + def xmlrpc_system__listMethods(self): + list = reflect.prefixedMethodNames(self.__class__, 'xmlrpc_') + return [ name.replace('__', '.') for name in list ] + + class QueryProtocol(http.HTTPClient): def connectionMade(self): @@ -240,7 +252,8 @@ factory = QueryFactory(self.url, self.host, method, *args) if self.secure: from twisted.internet import ssl - reactor.connectSSL(self.host, self.port or 443, factory, ssl.ClientContextFactory()) + reactor.connectSSL(self.host, self.port or 443, + factory, ssl.ClientContextFactory()) else: reactor.connectTCP(self.host, self.port or 80, factory) return factory.deferred