summaryrefslogtreecommitdiffstats
path: root/Lib/xmlrpclib.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/xmlrpclib.py')
-rw-r--r--Lib/xmlrpclib.py134
1 files changed, 93 insertions, 41 deletions
diff --git a/Lib/xmlrpclib.py b/Lib/xmlrpclib.py
index 6fb6c68..a916fa1 100644
--- a/Lib/xmlrpclib.py
+++ b/Lib/xmlrpclib.py
@@ -282,10 +282,13 @@ class Fault(Error):
# @param value A boolean value. Any true value is interpreted as True,
# all other values are interpreted as False.
+from sys import modules
+mod_dict = modules[__name__].__dict__
if _bool_is_builtin:
boolean = Boolean = bool
# to avoid breaking code which references xmlrpclib.{True,False}
- True, False = True, False
+ mod_dict['True'] = True
+ mod_dict['False'] = False
else:
class Boolean:
"""Boolean-value wrapper.
@@ -316,7 +319,8 @@ else:
def __nonzero__(self):
return self.value
- True, False = Boolean(1), Boolean(0)
+ mod_dict['True'] = Boolean(1)
+ mod_dict['False'] = Boolean(0)
##
# Map true or false value to XML-RPC boolean values.
@@ -333,6 +337,8 @@ else:
"""Convert any Python value to XML-RPC 'boolean'."""
return _truefalse[operator.truth(value)]
+del modules, mod_dict
+
##
# Wrapper for XML-RPC DateTime values. This converts a time value to
# the format used by XML-RPC.
@@ -346,6 +352,20 @@ else:
# @param value The time, given as an ISO 8601 string, a time
# tuple, or a integer time value.
+def _strftime(value):
+ if datetime:
+ if isinstance(value, datetime.datetime):
+ return "%04d%02d%02dT%02d:%02d:%02d" % (
+ value.year, value.month, value.day,
+ value.hour, value.minute, value.second)
+
+ if not isinstance(value, (TupleType, time.struct_time)):
+ if value == 0:
+ value = time.time()
+ value = time.localtime(value)
+
+ return "%04d%02d%02dT%02d:%02d:%02d" % value[:6]
+
class DateTime:
"""DateTime wrapper for an ISO 8601 string or time tuple or
localtime integer value to generate 'dateTime.iso8601' XML-RPC
@@ -353,28 +373,62 @@ class DateTime:
"""
def __init__(self, value=0):
- if not isinstance(value, StringType):
- if datetime and isinstance(value, datetime.datetime):
- self.value = value.strftime("%Y%m%dT%H:%M:%S")
- return
- if datetime and isinstance(value, datetime.date):
- self.value = value.strftime("%Y%m%dT%H:%M:%S")
- return
- if datetime and isinstance(value, datetime.time):
- today = datetime.datetime.now().strftime("%Y%m%d")
- self.value = value.strftime(today+"T%H:%M:%S")
- return
- if not isinstance(value, (TupleType, time.struct_time)):
- if value == 0:
- value = time.time()
- value = time.localtime(value)
- value = time.strftime("%Y%m%dT%H:%M:%S", value)
- self.value = value
+ if isinstance(value, StringType):
+ self.value = value
+ else:
+ self.value = _strftime(value)
- def __cmp__(self, other):
+ def make_comparable(self, other):
if isinstance(other, DateTime):
- other = other.value
- return cmp(self.value, other)
+ s = self.value
+ o = other.value
+ elif datetime and isinstance(other, datetime.datetime):
+ s = self.value
+ o = other.strftime("%Y%m%dT%H:%M:%S")
+ elif isinstance(other, (str, unicode)):
+ s = self.value
+ o = other
+ elif hasattr(other, "timetuple"):
+ s = self.timetuple()
+ o = other.timetuple()
+ else:
+ otype = (hasattr(other, "__class__")
+ and other.__class__.__name__
+ or type(other))
+ raise TypeError("Can't compare %s and %s" %
+ (self.__class__.__name__, otype))
+ return s, o
+
+ def __lt__(self, other):
+ s, o = self.make_comparable(other)
+ return s < o
+
+ def __le__(self, other):
+ s, o = self.make_comparable(other)
+ return s <= o
+
+ def __gt__(self, other):
+ s, o = self.make_comparable(other)
+ return s > o
+
+ def __ge__(self, other):
+ s, o = self.make_comparable(other)
+ return s >= o
+
+ def __eq__(self, other):
+ s, o = self.make_comparable(other)
+ return s == o
+
+ def __ne__(self, other):
+ s, o = self.make_comparable(other)
+ return s != o
+
+ def timetuple(self):
+ return time.strptime(self.value, "%Y%m%dT%H:%M:%S")
+
+ def __cmp__(self, other):
+ s, o = self.make_comparable(other)
+ return cmp(s, o)
##
# Get date/time value.
@@ -630,9 +684,19 @@ class Marshaller:
try:
f = self.dispatch[type(value)]
except KeyError:
- raise TypeError, "cannot marshal %s objects" % type(value)
- else:
- f(self, value, write)
+ # check if this object can be marshalled as a structure
+ try:
+ value.__dict__
+ except:
+ raise TypeError, "cannot marshal %s objects" % type(value)
+ # check if this class is a sub-class of a basic type,
+ # because we don't know how to marshal these types
+ # (e.g. a string sub-class)
+ for type_ in type(value).__mro__:
+ if type_ in self.dispatch.keys():
+ raise TypeError, "cannot marshal %s objects" % type(value)
+ f = self.dispatch[InstanceType]
+ f(self, value, write)
def dump_nil (self, value, write):
if not self.allow_none:
@@ -686,7 +750,7 @@ class Marshaller:
def dump_array(self, value, write):
i = id(value)
- if self.memo.has_key(i):
+ if i in self.memo:
raise TypeError, "cannot marshal recursive sequences"
self.memo[i] = None
dump = self.__dump
@@ -700,7 +764,7 @@ class Marshaller:
def dump_struct(self, value, write, escape=escape):
i = id(value)
- if self.memo.has_key(i):
+ if i in self.memo:
raise TypeError, "cannot marshal recursive dictionaries"
self.memo[i] = None
dump = self.__dump
@@ -722,23 +786,10 @@ class Marshaller:
if datetime:
def dump_datetime(self, value, write):
write("<value><dateTime.iso8601>")
- write(value.strftime("%Y%m%dT%H:%M:%S"))
+ write(_strftime(value))
write("</dateTime.iso8601></value>\n")
dispatch[datetime.datetime] = dump_datetime
- def dump_date(self, value, write):
- write("<value><dateTime.iso8601>")
- write(value.strftime("%Y%m%dT00:00:00"))
- write("</dateTime.iso8601></value>\n")
- dispatch[datetime.date] = dump_date
-
- def dump_time(self, value, write):
- write("<value><dateTime.iso8601>")
- write(datetime.datetime.now().date().strftime("%Y%m%dT"))
- write(value.strftime("%H:%M:%S"))
- write("</dateTime.iso8601></value>\n")
- dispatch[datetime.time] = dump_time
-
def dump_instance(self, value, write):
# check for special wrappers
if value.__class__ in WRAPPERS:
@@ -852,6 +903,7 @@ class Unmarshaller:
self.append(int(data))
self._value = 0
dispatch["i4"] = end_int
+ dispatch["i8"] = end_int
dispatch["int"] = end_int
def end_double(self, data):