@@ -386,8 +386,8 @@ def __init__(self, data=None):
386386 if data is None :
387387 data = b""
388388 else :
389- if not isinstance (data , bytes ):
390- raise TypeError ("expected bytes, not %s" %
389+ if not isinstance (data , ( bytes , bytearray ) ):
390+ raise TypeError ("expected bytes or bytearray , not %s" %
391391 data .__class__ .__name__ )
392392 data = bytes (data ) # Make a copy of the bytes!
393393 self .data = data
@@ -559,6 +559,14 @@ def dump_unicode(self, value, write, escape=escape):
559559 write ("</string></value>\n " )
560560 dispatch [str ] = dump_unicode
561561
562+ def dump_bytes (self , value , write ):
563+ write ("<value><base64>\n " )
564+ encoded = base64 .encodebytes (value )
565+ write (encoded .decode ('ascii' ))
566+ write ("</base64></value>\n " )
567+ dispatch [bytes ] = dump_bytes
568+ dispatch [bytearray ] = dump_bytes
569+
562570 def dump_array (self , value , write ):
563571 i = id (value )
564572 if i in self .memo :
@@ -629,15 +637,16 @@ class Unmarshaller:
629637 # and again, if you don't understand what's going on in here,
630638 # that's perfectly ok.
631639
632- def __init__ (self , use_datetime = False ):
640+ def __init__ (self , use_datetime = False , use_builtin_types = False ):
633641 self ._type = None
634642 self ._stack = []
635643 self ._marks = []
636644 self ._data = []
637645 self ._methodname = None
638646 self ._encoding = "utf-8"
639647 self .append = self ._stack .append
640- self ._use_datetime = use_datetime
648+ self ._use_datetime = use_builtin_types or use_datetime
649+ self ._use_bytes = use_builtin_types
641650
642651 def close (self ):
643652 # return response tuple and target method
@@ -749,6 +758,8 @@ def end_struct(self, data):
749758 def end_base64 (self , data ):
750759 value = Binary ()
751760 value .decode (data .encode ("ascii" ))
761+ if self ._use_bytes :
762+ value = value .data
752763 self .append (value )
753764 self ._value = 0
754765 dispatch ["base64" ] = end_base64
@@ -860,21 +871,26 @@ def __call__(self):
860871#
861872# return A (parser, unmarshaller) tuple.
862873
863- def getparser (use_datetime = False ):
874+ def getparser (use_datetime = False , use_builtin_types = False ):
864875 """getparser() -> parser, unmarshaller
865876
866877 Create an instance of the fastest available parser, and attach it
867878 to an unmarshalling object. Return both objects.
868879 """
869880 if FastParser and FastUnmarshaller :
870- if use_datetime :
881+ if use_builtin_types :
882+ mkdatetime = _datetime_type
883+ mkbytes = base64 .decodebytes
884+ elif use_datetime :
871885 mkdatetime = _datetime_type
886+ mkbytes = _binary
872887 else :
873888 mkdatetime = _datetime
874- target = FastUnmarshaller (True , False , _binary , mkdatetime , Fault )
889+ mkbytes = _binary
890+ target = FastUnmarshaller (True , False , mkbytes , mkdatetime , Fault )
875891 parser = FastParser (target )
876892 else :
877- target = Unmarshaller (use_datetime = use_datetime )
893+ target = Unmarshaller (use_datetime = use_datetime , use_builtin_types = use_builtin_types )
878894 if FastParser :
879895 parser = FastParser (target )
880896 else :
@@ -912,7 +928,7 @@ def dumps(params, methodname=None, methodresponse=None, encoding=None,
912928
913929 encoding: the packet encoding (default is UTF-8)
914930
915- All 8-bit strings in the data structure are assumed to use the
931+ All byte strings in the data structure are assumed to use the
916932 packet encoding. Unicode strings are automatically converted,
917933 where necessary.
918934 """
@@ -971,7 +987,7 @@ def dumps(params, methodname=None, methodresponse=None, encoding=None,
971987# (None if not present).
972988# @see Fault
973989
974- def loads (data , use_datetime = False ):
990+ def loads (data , use_datetime = False , use_builtin_types = False ):
975991 """data -> unmarshalled data, method name
976992
977993 Convert an XML-RPC packet to unmarshalled data plus a method
@@ -980,7 +996,7 @@ def loads(data, use_datetime=False):
980996 If the XML-RPC packet represents a fault condition, this function
981997 raises a Fault exception.
982998 """
983- p , u = getparser (use_datetime = use_datetime )
999+ p , u = getparser (use_datetime = use_datetime , use_builtin_types = use_builtin_types )
9841000 p .feed (data )
9851001 p .close ()
9861002 return u .close (), u .getmethodname ()
@@ -1092,8 +1108,9 @@ class Transport:
10921108 # that they can decode such a request
10931109 encode_threshold = None #None = don't encode
10941110
1095- def __init__ (self , use_datetime = False ):
1111+ def __init__ (self , use_datetime = False , use_builtin_types = False ):
10961112 self ._use_datetime = use_datetime
1113+ self ._use_builtin_types = use_builtin_types
10971114 self ._connection = (None , None )
10981115 self ._extra_headers = []
10991116
@@ -1154,7 +1171,8 @@ def single_request(self, host, handler, request_body, verbose=False):
11541171
11551172 def getparser (self ):
11561173 # get parser and unmarshaller
1157- return getparser (use_datetime = self ._use_datetime )
1174+ return getparser (use_datetime = self ._use_datetime ,
1175+ use_builtin_types = self ._use_builtin_types )
11581176
11591177 ##
11601178 # Get authorization info from host parameter
@@ -1361,7 +1379,7 @@ class ServerProxy:
13611379 """
13621380
13631381 def __init__ (self , uri , transport = None , encoding = None , verbose = False ,
1364- allow_none = False , use_datetime = False ):
1382+ allow_none = False , use_datetime = False , use_builtin_types = False ):
13651383 # establish a "logical" server connection
13661384
13671385 # get the url
@@ -1375,9 +1393,11 @@ def __init__(self, uri, transport=None, encoding=None, verbose=False,
13751393
13761394 if transport is None :
13771395 if type == "https" :
1378- transport = SafeTransport ( use_datetime = use_datetime )
1396+ handler = SafeTransport
13791397 else :
1380- transport = Transport (use_datetime = use_datetime )
1398+ handler = Transport
1399+ transport = handler (use_datetime = use_datetime ,
1400+ use_builtin_types = use_builtin_types )
13811401 self .__transport = transport
13821402
13831403 self .__encoding = encoding or 'utf-8'
0 commit comments