mirror of
https://github.com/python/cpython.git
synced 2025-10-28 20:25:04 +00:00
restored 1.5.2 compatibility
added local escape method (made the dumps method some 50-80% faster) minor tweaks to the unmarshalling code
This commit is contained in:
parent
1ce3cf7749
commit
1538c23dec
1 changed files with 39 additions and 46 deletions
|
|
@ -31,6 +31,8 @@
|
||||||
# 2001-08-20 fl Base xmlrpclib.Error on built-in Exception (from Paul Prescod)
|
# 2001-08-20 fl Base xmlrpclib.Error on built-in Exception (from Paul Prescod)
|
||||||
# 2001-09-03 fl Allow Transport subclass to override getparser
|
# 2001-09-03 fl Allow Transport subclass to override getparser
|
||||||
# 2001-09-10 fl Lazy import of urllib, cgi, xmllib (20x import speedup)
|
# 2001-09-10 fl Lazy import of urllib, cgi, xmllib (20x import speedup)
|
||||||
|
# 2001-10-01 fl Remove containers from memo cache when done with them
|
||||||
|
# 2001-10-01 fl Use faster escape method (80% dumps speedup)
|
||||||
#
|
#
|
||||||
# Copyright (c) 1999-2001 by Secret Labs AB.
|
# Copyright (c) 1999-2001 by Secret Labs AB.
|
||||||
# Copyright (c) 1999-2001 by Fredrik Lundh.
|
# Copyright (c) 1999-2001 by Fredrik Lundh.
|
||||||
|
|
@ -70,24 +72,11 @@
|
||||||
#
|
#
|
||||||
# things to look into before 1.0 final:
|
# things to look into before 1.0 final:
|
||||||
|
|
||||||
# TODO: unicode marshalling -DONE
|
|
||||||
# TODO: ascii-compatible encoding support -DONE
|
|
||||||
# TODO: safe transport -DONE (but mostly untested)
|
|
||||||
# TODO: sgmlop memory leak -DONE
|
|
||||||
# TODO: sgmlop xml parsing -DONE
|
|
||||||
# TODO: support unicode method names -DONE
|
|
||||||
# TODO: update selftest -DONE
|
|
||||||
# TODO: add docstrings -DONE
|
|
||||||
# TODO: clean up parser encoding (trust the parser) -DONE
|
|
||||||
# TODO: expat support -DONE
|
|
||||||
# TODO: _xmlrpclib accelerator support -DONE
|
|
||||||
# TODO: use smarter/faster escape from effdom
|
|
||||||
# TODO: support basic authentication (see robin's patch)
|
# TODO: support basic authentication (see robin's patch)
|
||||||
# TODO: fix host tuple handling in the server constructor
|
# TODO: fix host tuple handling in the server constructor
|
||||||
# TODO: let transport verify schemes
|
# TODO: let transport verify schemes
|
||||||
# TODO: update documentation
|
# TODO: update documentation
|
||||||
# TODO: authentication plugins
|
# TODO: authentication plugins
|
||||||
# TODO: memo problem (see HP's mail)
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
An XML-RPC client interface for Python.
|
An XML-RPC client interface for Python.
|
||||||
|
|
@ -134,9 +123,9 @@
|
||||||
name (None if not present).
|
name (None if not present).
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import re, string, time, operator
|
import re, string, sys, time, operator
|
||||||
|
|
||||||
from types import *
|
from types import *
|
||||||
from cgi import escape as _escape
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
unicode
|
unicode
|
||||||
|
|
@ -149,6 +138,11 @@ def _decode(data, encoding, is8bit=re.compile("[\x80-\xff]").search):
|
||||||
data = unicode(data, encoding)
|
data = unicode(data, encoding)
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
def escape(s, replace=string.replace):
|
||||||
|
s = replace(s, "&", "&")
|
||||||
|
s = replace(s, "<", "<")
|
||||||
|
return replace(s, ">", ">",)
|
||||||
|
|
||||||
if unicode:
|
if unicode:
|
||||||
def _stringify(string):
|
def _stringify(string):
|
||||||
# convert to 7-bit ascii if possible
|
# convert to 7-bit ascii if possible
|
||||||
|
|
@ -160,7 +154,7 @@ def _stringify(string):
|
||||||
def _stringify(string):
|
def _stringify(string):
|
||||||
return string
|
return string
|
||||||
|
|
||||||
__version__ = "1.0b3"
|
__version__ = "1.0b4"
|
||||||
|
|
||||||
# --------------------------------------------------------------------
|
# --------------------------------------------------------------------
|
||||||
# Exceptions
|
# Exceptions
|
||||||
|
|
@ -472,51 +466,53 @@ def dump_double(self, value):
|
||||||
self.write("<value><double>%s</double></value>\n" % value)
|
self.write("<value><double>%s</double></value>\n" % value)
|
||||||
dispatch[FloatType] = dump_double
|
dispatch[FloatType] = dump_double
|
||||||
|
|
||||||
def dump_string(self, value):
|
def dump_string(self, value, escape=escape):
|
||||||
self.write("<value><string>%s</string></value>\n" % _escape(value))
|
self.write("<value><string>%s</string></value>\n" % escape(value))
|
||||||
dispatch[StringType] = dump_string
|
dispatch[StringType] = dump_string
|
||||||
|
|
||||||
if unicode:
|
if unicode:
|
||||||
def dump_unicode(self, value):
|
def dump_unicode(self, value, escape=escape):
|
||||||
value = value.encode(self.encoding)
|
value = value.encode(self.encoding)
|
||||||
self.write("<value><string>%s</string></value>\n" % _escape(value))
|
self.write("<value><string>%s</string></value>\n" % escape(value))
|
||||||
dispatch[UnicodeType] = dump_unicode
|
dispatch[UnicodeType] = dump_unicode
|
||||||
|
|
||||||
def container(self, value):
|
def opencontainer(self, value):
|
||||||
if value:
|
if value:
|
||||||
i = id(value)
|
i = id(value)
|
||||||
if self.memo.has_key(i):
|
if self.memo.has_key(i):
|
||||||
raise TypeError, "cannot marshal recursive data structures"
|
raise TypeError, "cannot marshal recursive data structures"
|
||||||
self.memo[i] = None
|
self.memo[i] = None
|
||||||
|
|
||||||
def endcontainer(self, value):
|
def closecontainer(self, value):
|
||||||
if value:
|
if value:
|
||||||
del self.memo[id(value)]
|
del self.memo[id(value)]
|
||||||
|
|
||||||
def dump_array(self, value):
|
def dump_array(self, value):
|
||||||
self.container(value)
|
self.opencontainer(value)
|
||||||
write = self.write
|
write = self.write
|
||||||
|
dump = self.__dump
|
||||||
write("<value><array><data>\n")
|
write("<value><array><data>\n")
|
||||||
for v in value:
|
for v in value:
|
||||||
self.__dump(v)
|
dump(v)
|
||||||
write("</data></array></value>\n")
|
write("</data></array></value>\n")
|
||||||
self.endcontainer(value)
|
self.closecontainer(value)
|
||||||
dispatch[TupleType] = dump_array
|
dispatch[TupleType] = dump_array
|
||||||
dispatch[ListType] = dump_array
|
dispatch[ListType] = dump_array
|
||||||
|
|
||||||
def dump_struct(self, value):
|
def dump_struct(self, value, escape=escape):
|
||||||
self.container(value)
|
self.opencontainer(value)
|
||||||
write = self.write
|
write = self.write
|
||||||
|
dump = self.__dump
|
||||||
write("<value><struct>\n")
|
write("<value><struct>\n")
|
||||||
for k, v in value.items():
|
for k, v in value.items():
|
||||||
write("<member>\n")
|
write("<member>\n")
|
||||||
if type(k) is not StringType:
|
if type(k) is not StringType:
|
||||||
raise TypeError, "dictionary key must be string"
|
raise TypeError, "dictionary key must be string"
|
||||||
write("<name>%s</name>\n" % _escape(k))
|
write("<name>%s</name>\n" % escape(k))
|
||||||
self.__dump(v)
|
dump(v)
|
||||||
write("</member>\n")
|
write("</member>\n")
|
||||||
write("</struct></value>\n")
|
write("</struct></value>\n")
|
||||||
self.endcontainer(value)
|
self.closecontainer(value)
|
||||||
dispatch[DictType] = dump_struct
|
dispatch[DictType] = dump_struct
|
||||||
|
|
||||||
def dump_instance(self, value):
|
def dump_instance(self, value):
|
||||||
|
|
@ -577,14 +573,14 @@ def start(self, tag, attrs):
|
||||||
def data(self, text):
|
def data(self, text):
|
||||||
self._data.append(text)
|
self._data.append(text)
|
||||||
|
|
||||||
def end(self, tag):
|
def end(self, tag, join=string.join):
|
||||||
# call the appropriate end tag handler
|
# call the appropriate end tag handler
|
||||||
try:
|
try:
|
||||||
f = self.dispatch[tag]
|
f = self.dispatch[tag]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass # unknown tag ?
|
pass # unknown tag ?
|
||||||
else:
|
else:
|
||||||
return f(self, self._data)
|
return f(self, join(self._data, ""))
|
||||||
|
|
||||||
#
|
#
|
||||||
# accelerator support
|
# accelerator support
|
||||||
|
|
@ -603,8 +599,7 @@ def end_dispatch(self, tag, data):
|
||||||
|
|
||||||
dispatch = {}
|
dispatch = {}
|
||||||
|
|
||||||
def end_boolean(self, data, join=string.join):
|
def end_boolean(self, data):
|
||||||
data = join(data, "")
|
|
||||||
if data == "0":
|
if data == "0":
|
||||||
self.append(False)
|
self.append(False)
|
||||||
elif data == "1":
|
elif data == "1":
|
||||||
|
|
@ -614,19 +609,18 @@ def end_boolean(self, data, join=string.join):
|
||||||
self._value = 0
|
self._value = 0
|
||||||
dispatch["boolean"] = end_boolean
|
dispatch["boolean"] = end_boolean
|
||||||
|
|
||||||
def end_int(self, data, join=string.join):
|
def end_int(self, data):
|
||||||
self.append(int(join(data, "")))
|
self.append(int(data))
|
||||||
self._value = 0
|
self._value = 0
|
||||||
dispatch["i4"] = end_int
|
dispatch["i4"] = end_int
|
||||||
dispatch["int"] = end_int
|
dispatch["int"] = end_int
|
||||||
|
|
||||||
def end_double(self, data, join=string.join):
|
def end_double(self, data):
|
||||||
self.append(float(join(data, "")))
|
self.append(float(data))
|
||||||
self._value = 0
|
self._value = 0
|
||||||
dispatch["double"] = end_double
|
dispatch["double"] = end_double
|
||||||
|
|
||||||
def end_string(self, data, join=string.join):
|
def end_string(self, data):
|
||||||
data = join(data, "")
|
|
||||||
if self._encoding:
|
if self._encoding:
|
||||||
data = _decode(data, self._encoding)
|
data = _decode(data, self._encoding)
|
||||||
self.append(_stringify(data))
|
self.append(_stringify(data))
|
||||||
|
|
@ -654,16 +648,16 @@ def end_struct(self, data):
|
||||||
self._value = 0
|
self._value = 0
|
||||||
dispatch["struct"] = end_struct
|
dispatch["struct"] = end_struct
|
||||||
|
|
||||||
def end_base64(self, data, join=string.join):
|
def end_base64(self, data):
|
||||||
value = Binary()
|
value = Binary()
|
||||||
value.decode(join(data, ""))
|
value.decode(data)
|
||||||
self.append(value)
|
self.append(value)
|
||||||
self._value = 0
|
self._value = 0
|
||||||
dispatch["base64"] = end_base64
|
dispatch["base64"] = end_base64
|
||||||
|
|
||||||
def end_dateTime(self, data, join=string.join):
|
def end_dateTime(self, data):
|
||||||
value = DateTime()
|
value = DateTime()
|
||||||
value.decode(join(data, ""))
|
value.decode(data)
|
||||||
self.append(value)
|
self.append(value)
|
||||||
dispatch["dateTime.iso8601"] = end_dateTime
|
dispatch["dateTime.iso8601"] = end_dateTime
|
||||||
|
|
||||||
|
|
@ -682,8 +676,7 @@ def end_fault(self, data):
|
||||||
self._type = "fault"
|
self._type = "fault"
|
||||||
dispatch["fault"] = end_fault
|
dispatch["fault"] = end_fault
|
||||||
|
|
||||||
def end_methodName(self, data, join=string.join):
|
def end_methodName(self, data):
|
||||||
data = join(data, "")
|
|
||||||
if self._encoding:
|
if self._encoding:
|
||||||
data = _decode(data, self._encoding)
|
data = _decode(data, self._encoding)
|
||||||
self._methodname = data
|
self._methodname = data
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue