Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit c4c062f

Browse files
author
Fredrik Lundh
committed
sync with pythonware codebase: much faster import (doesn't import
xmllib unless needed), merged docstring patches, added overridable Transport.getparser to simplify plugging in different parsers.
1 parent 5432838 commit c4c062f

1 file changed

Lines changed: 70 additions & 65 deletions

File tree

Lib/xmlrpclib.py

Lines changed: 70 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,17 @@
22
# XML-RPC CLIENT LIBRARY
33
# $Id$
44
#
5+
# an XML-RPC client interface for Python.
6+
#
7+
# the marshalling and response parser code can also be used to
8+
# implement XML-RPC servers.
9+
#
10+
# Notes:
11+
# this version is designed to work with Python 1.5.2 or newer.
12+
# unicode encoding support requires at least Python 1.6.
13+
# experimental HTTPS requires Python 2.0 built with SSL sockets.
14+
# expat parser support requires Python 2.0 with pyexpat support.
15+
#
516
# History:
617
# 1999-01-14 fl Created
718
# 1999-01-15 fl Changed dateTime to use localtime
@@ -18,6 +29,8 @@
1829
# 2001-03-29 fl Don't require empty params element (from Nicholas Riley)
1930
# 2001-06-10 fl Folded in _xmlrpclib accelerator support (1.0b2)
2031
# 2001-08-20 fl Base xmlrpclib.Error on built-in Exception (from Paul Prescod)
32+
# 2001-09-03 fl Allow Transport subclass to override getparser
33+
# 2001-09-10 fl Lazy import of urllib, cgi, xmllib (20x import speedup)
2134
#
2235
# Copyright (c) 1999-2001 by Secret Labs AB.
2336
# Copyright (c) 1999-2001 by Fredrik Lundh.
@@ -82,59 +95,47 @@
8295
The marshalling and response parser code can also be used to
8396
implement XML-RPC servers.
8497
85-
Notes:
86-
This version is designed to work with Python 1.5.2 or newer.
87-
Unicode encoding support requires at least Python 1.6.
88-
Experimental HTTPS requires Python 2.0 built with SSL sockets.
89-
Expat parser support requires Python 2.0 with pyexpat support.
90-
9198
Exported exceptions:
9299
93-
Error Base class for client errors
94-
ProtocolError Indicates an HTTP protocol error
95-
ResponseError Indicates a broken response package
96-
Fault Indicates a XML-RPC fault package
100+
Error Base class for client errors
101+
ProtocolError Indicates an HTTP protocol error
102+
ResponseError Indicates a broken response package
103+
Fault Indicates an XML-RPC fault package
97104
98105
Exported classes:
99106
100-
Boolean boolean wrapper to generate a "boolean" XML-RPC value
101-
DateTime dateTime wrapper for an ISO 8601 string or time tuple or
102-
localtime integer value to generate a "dateTime.iso8601"
103-
XML-RPC value
104-
Binary binary data wrapper
107+
ServerProxy Represents a logical connection to an XML-RPC server
105108
106-
SlowParser Slow but safe standard parser
107-
Marshaller Generate an XML-RPC params chunk from a Python data structure
108-
Unmarshaller Unmarshal an XML-RPC response from incoming XML event message
109+
Boolean boolean wrapper to generate a "boolean" XML-RPC value
110+
DateTime dateTime wrapper for an ISO 8601 string or time tuple or
111+
localtime integer value to generate a "dateTime.iso8601"
112+
XML-RPC value
113+
Binary binary data wrapper
109114
110-
Transport Handles an HTTP transaction to an XML-RPC server
111-
SafeTransport Handles an HTTPS transaction to an XML-RPC server
112-
ServerProxy Connect to a server through a proxy
113-
Server Same as ServerProxy
115+
SlowParser Slow but safe standard parser (based on xmllib)
116+
Marshaller Generate an XML-RPC params chunk from a Python data structure
117+
Unmarshaller Unmarshal an XML-RPC response from incoming XML event message
118+
Transport Handles an HTTP transaction to an XML-RPC server
119+
SafeTransport Handles an HTTPS transaction to an XML-RPC server
114120
115121
Exported constants:
116122
117-
True
118-
False
123+
True
124+
False
119125
120126
Exported functions:
121127
122-
boolean Convert any Python value to an XML-RPC boolean
123-
datetime Convert value to an XML-RPC datetime
124-
binary Convert value to an XML-RPC binary value
125-
getparser Create instance of the fastest available parser & attach
126-
to an unmarshalling object
127-
dumps Convert an argument tuple or a Fault instance to an XML-RPC
128-
request (or response, if the methodresponse option is used).
129-
loads Convert an XML-RPC packet to unmarshalled data plus a method
130-
name (None if not present).
131-
128+
boolean Convert any Python value to an XML-RPC boolean
129+
getparser Create instance of the fastest available parser & attach
130+
to an unmarshalling object
131+
dumps Convert an argument tuple or a Fault instance to an XML-RPC
132+
request (or response, if the methodresponse option is used).
133+
loads Convert an XML-RPC packet to unmarshalled data plus a method
134+
name (None if not present).
132135
"""
133136

134137
import re, string, time, operator
135-
import urllib, xmllib
136138
from types import *
137-
from cgi import escape
138139

139140
try:
140141
unicode
@@ -181,24 +182,23 @@ def __repr__(self):
181182
)
182183

183184
class ResponseError(Error):
184-
"""Indicates a broken response package"""
185+
"""Indicates a broken response package."""
185186
pass
186187

187188
class Fault(Error):
188-
"""indicates a XML-RPC fault package"""
189+
"""Indicates an XML-RPC fault package."""
189190
def __init__(self, faultCode, faultString, **extra):
190191
self.faultCode = faultCode
191192
self.faultString = faultString
192193
def __repr__(self):
193194
return (
194195
"<Fault %s: %s>" %
195-
(self.faultCode, repr(self.faultString))
196+
(repr(self.faultCode), repr(self.faultString))
196197
)
197198

198199
# --------------------------------------------------------------------
199200
# Special values
200201

201-
202202
class Boolean:
203203
"""Boolean-value wrapper.
204204
@@ -231,18 +231,14 @@ def __nonzero__(self):
231231
True, False = Boolean(1), Boolean(0)
232232

233233
def boolean(value, truefalse=(False, True)):
234-
"""Convert any Python value to XML-RPC boolean."""
234+
"""Convert any Python value to XML-RPC 'boolean'."""
235235
return truefalse[operator.truth(value)]
236236

237-
#
238-
# dateTime wrapper
239-
# wrap your iso8601 string or time tuple or localtime integer value
240-
# in this class to generate a "dateTime.iso8601" XML-RPC value
241-
242237
class DateTime:
243-
"""DataTime wrapper for an ISO 8601 string or time tuple or
244-
localtime integer value to generate a 'dateTime.iso8601' XML-RPC
245-
value."""
238+
"""DateTime wrapper for an ISO 8601 string or time tuple or
239+
localtime integer value to generate 'dateTime.iso8601' XML-RPC
240+
value.
241+
"""
246242

247243
def __init__(self, value=0):
248244
if not isinstance(value, StringType):
@@ -274,7 +270,6 @@ def datetime(data):
274270
value.decode(data)
275271
return value
276272

277-
278273
class Binary:
279274
"""Wrapper for binary data."""
280275

@@ -354,6 +349,7 @@ def close(self):
354349
self.parser = self.feed = None # nuke circular reference
355350

356351
def handle_proc(self, tag, attr):
352+
import re
357353
m = re.search("encoding\s*=\s*['\"]([^\"']+)[\"']", attr)
358354
if m:
359355
self.handle_xml(m.group(1), 1)
@@ -391,13 +387,14 @@ def close(self):
391387
self._parser.Parse("", 1) # end of data
392388
del self._target, self._parser # get rid of circular references
393389

394-
class SlowParser(xmllib.XMLParser):
395-
"""XML parser using xmllib.XMLParser.
396-
397-
This is about 10 times slower than sgmlop on roundtrip testing.
398-
"""
399-
390+
class SlowParser:
391+
"""Default XML parser (based on xmllib.XMLParser)."""
392+
# this is about 10 times slower than sgmlop, on roundtrip
393+
# testing.
400394
def __init__(self, target):
395+
import xmllib # lazy subclassing (!)
396+
if xmllib.XMLParser not in SlowParser.__bases__:
397+
SlowParser.__bases__ = (xmllib.XMLParser,)
401398
self.handle_xml = target.xml
402399
self.unknown_starttag = target.start
403400
self.handle_data = target.data
@@ -411,11 +408,11 @@ def __init__(self, target):
411408
class Marshaller:
412409
"""Generate an XML-RPC params chunk from a Python data structure.
413410
414-
Create a marshaller instance for each set of parameters, and use
415-
"dumps" method to convert your data (represented as a tuple) to a
416-
XML-RPC params chunk. to write a fault response, pass a Fault
417-
instance instead. You may prefer to use the "dumps" convenience
418-
function for this purpose (see below).
411+
Create a Marshaller instance for each set of parameters, and use
412+
the "dumps" method to convert your data (represented as a tuple)
413+
to an XML-RPC params chunk. To write a fault response, pass a
414+
Fault instance instead. You may prefer to use the "dumps" module
415+
function for this purpose.
419416
"""
420417

421418
# by the way, if you don't understand what's going on in here,
@@ -470,12 +467,14 @@ def dump_double(self, value):
470467
dispatch[FloatType] = dump_double
471468

472469
def dump_string(self, value):
470+
from cgi import escape
473471
self.write("<value><string>%s</string></value>\n" % escape(value))
474472
dispatch[StringType] = dump_string
475473

476474
if unicode:
477475
def dump_unicode(self, value):
478476
value = value.encode(self.encoding)
477+
from cgi import escape
479478
self.write("<value><string>%s</string></value>\n" % escape(value))
480479
dispatch[UnicodeType] = dump_unicode
481480

@@ -504,6 +503,7 @@ def dump_struct(self, value):
504503
write("<member>\n")
505504
if type(k) is not StringType:
506505
raise TypeError, "dictionary key must be string"
506+
from cgi import escape
507507
write("<name>%s</name>\n" % escape(k))
508508
self.__dump(v)
509509
write("</member>\n")
@@ -521,7 +521,7 @@ def dump_instance(self, value):
521521

522522
class Unmarshaller:
523523
"""Unmarshal an XML-RPC response, based on incoming XML event
524-
messages (start, data, end). Call close() to get the resulting
524+
messages (start, data, end). Call close to get the resulting
525525
data structure.
526526
527527
Note that this reader is fairly tolerant, and gladly accepts
@@ -802,7 +802,7 @@ def __call__(self, *args):
802802

803803

804804
class Transport:
805-
"""Handles an HTTP transaction to an XML-RPC server"""
805+
"""Handles an HTTP transaction to an XML-RPC server."""
806806

807807
# client identifier (may be overridden)
808808
user_agent = "xmlrpclib.py/%s (by www.pythonware.com)" % __version__
@@ -832,6 +832,10 @@ def request(self, host, handler, request_body, verbose=0):
832832

833833
return self.parse_response(h.getfile())
834834

835+
def getparser(self):
836+
# get parser and unmarshaller
837+
return getparser()
838+
835839
def make_connection(self, host):
836840
# create a HTTP connection object from a host descriptor
837841
import httplib
@@ -856,7 +860,7 @@ def send_content(self, connection, request_body):
856860
def parse_response(self, f):
857861
# read response from input file, and parse it
858862

859-
p, u = getparser()
863+
p, u = self.getparser()
860864

861865
while 1:
862866
response = f.read(1024)
@@ -872,7 +876,7 @@ def parse_response(self, f):
872876
return u.close()
873877

874878
class SafeTransport(Transport):
875-
"""Handles an HTTPS transaction to an XML-RPC server"""
879+
"""Handles an HTTPS transaction to an XML-RPC server."""
876880

877881
def make_connection(self, host):
878882
# create a HTTPS connection object from a host descriptor
@@ -921,6 +925,7 @@ def __init__(self, uri, transport=None, encoding=None, verbose=0):
921925
# establish a "logical" server connection
922926

923927
# get the url
928+
import urllib
924929
type, uri = urllib.splittype(uri)
925930
if type not in ("http", "https"):
926931
raise IOError, "unsupported XML-RPC protocol"

0 commit comments

Comments
 (0)