[Python-checkins] CVS: python/dist/src/Lib xmlrpclib.py,1.5,1.6

Fredrik Lundh effbot@users.sourceforge.net
Mon, 10 Sep 2001 12:45:04 -0700


Update of /cvsroot/python/python/dist/src/Lib
In directory usw-pr-cvs1:/tmp/cvs-serv7206

Modified Files:
	xmlrpclib.py 
Log Message:


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.


Index: xmlrpclib.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Lib/xmlrpclib.py,v
retrieving revision 1.5
retrieving revision 1.6
diff -C2 -d -r1.5 -r1.6
*** xmlrpclib.py	2001/09/04 18:55:03	1.5
--- xmlrpclib.py	2001/09/10 19:45:02	1.6
***************
*** 3,6 ****
--- 3,17 ----
  # $Id$
  #
+ # an XML-RPC client interface for Python.
+ #
+ # the marshalling and response parser code can also be used to
+ # implement XML-RPC servers.
+ #
+ # Notes:
+ # this version is designed to work with Python 1.5.2 or newer.
+ # unicode encoding support requires at least Python 1.6.
+ # experimental HTTPS requires Python 2.0 built with SSL sockets.
+ # expat parser support requires Python 2.0 with pyexpat support.
+ #
  # History:
  # 1999-01-14 fl  Created
***************
*** 19,22 ****
--- 30,35 ----
  # 2001-06-10 fl  Folded in _xmlrpclib accelerator support (1.0b2)
  # 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-10 fl  Lazy import of urllib, cgi, xmllib (20x import speedup)
  #
  # Copyright (c) 1999-2001 by Secret Labs AB.
***************
*** 83,139 ****
  implement XML-RPC servers.
  
- Notes:
- This version is designed to work with Python 1.5.2 or newer.
- Unicode encoding support requires at least Python 1.6.
- Experimental HTTPS requires Python 2.0 built with SSL sockets.
- Expat parser support requires Python 2.0 with pyexpat support.
- 
  Exported exceptions:
  
!     Error          Base class for client errors
!     ProtocolError  Indicates an HTTP protocol error
!     ResponseError  Indicates a broken response package
!     Fault          Indicates a XML-RPC fault package
  
  Exported classes:
  
!     Boolean        boolean wrapper to generate a "boolean" XML-RPC value
!     DateTime       dateTime wrapper for an ISO 8601 string or time tuple or
!                    localtime integer value to generate a "dateTime.iso8601"
!                    XML-RPC value
!     Binary         binary data wrapper
  
!     SlowParser     Slow but safe standard parser
!     Marshaller     Generate an XML-RPC params chunk from a Python data structure
!     Unmarshaller   Unmarshal an XML-RPC response from incoming XML event message
  
!     Transport      Handles an HTTP transaction to an XML-RPC server
!     SafeTransport  Handles an HTTPS transaction to an XML-RPC server
!     ServerProxy    Connect to a server through a proxy
!     Server         Same as ServerProxy
  
  Exported constants:
  
!     True
!     False
  
  Exported functions:
  
!     boolean        Convert any Python value to an XML-RPC boolean
!     datetime       Convert value to an XML-RPC datetime
!     binary         Convert value to an XML-RPC binary value
!     getparser      Create instance of the fastest available parser & attach
!                    to an unmarshalling object
!     dumps          Convert an argument tuple or a Fault instance to an XML-RPC
!                    request (or response, if the methodresponse option is used).
!     loads          Convert an XML-RPC packet to unmarshalled data plus a method
!                    name (None if not present).
! 
  """
  
  import re, string, time, operator
- import urllib, xmllib
  from types import *
- from cgi import escape
  
  try:
--- 96,140 ----
  implement XML-RPC servers.
  
  Exported exceptions:
  
!   Error          Base class for client errors
!   ProtocolError  Indicates an HTTP protocol error
!   ResponseError  Indicates a broken response package
!   Fault          Indicates an XML-RPC fault package
  
  Exported classes:
  
!   ServerProxy    Represents a logical connection to an XML-RPC server
  
!   Boolean        boolean wrapper to generate a "boolean" XML-RPC value
!   DateTime       dateTime wrapper for an ISO 8601 string or time tuple or
!                  localtime integer value to generate a "dateTime.iso8601"
!                  XML-RPC value
!   Binary         binary data wrapper
  
!   SlowParser     Slow but safe standard parser (based on xmllib)
!   Marshaller     Generate an XML-RPC params chunk from a Python data structure
!   Unmarshaller   Unmarshal an XML-RPC response from incoming XML event message
!   Transport      Handles an HTTP transaction to an XML-RPC server
!   SafeTransport  Handles an HTTPS transaction to an XML-RPC server
  
  Exported constants:
  
!   True
!   False
  
  Exported functions:
  
!   boolean        Convert any Python value to an XML-RPC boolean
!   getparser      Create instance of the fastest available parser & attach
!                  to an unmarshalling object
!   dumps          Convert an argument tuple or a Fault instance to an XML-RPC
!                  request (or response, if the methodresponse option is used).
!   loads          Convert an XML-RPC packet to unmarshalled data plus a method
!                  name (None if not present).
  """
  
  import re, string, time, operator
  from types import *
  
  try:
***************
*** 182,190 ****
  
  class ResponseError(Error):
!     """Indicates a broken response package"""
      pass
  
  class Fault(Error):
!     """indicates a XML-RPC fault package"""
      def __init__(self, faultCode, faultString, **extra):
          self.faultCode = faultCode
--- 183,191 ----
  
  class ResponseError(Error):
!     """Indicates a broken response package."""
      pass
  
  class Fault(Error):
!     """Indicates an XML-RPC fault package."""
      def __init__(self, faultCode, faultString, **extra):
          self.faultCode = faultCode
***************
*** 193,197 ****
          return (
              "<Fault %s: %s>" %
!             (self.faultCode, repr(self.faultString))
              )
  
--- 194,198 ----
          return (
              "<Fault %s: %s>" %
!             (repr(self.faultCode), repr(self.faultString))
              )
  
***************
*** 199,203 ****
  # Special values
  
- 
  class Boolean:
      """Boolean-value wrapper.
--- 200,203 ----
***************
*** 232,247 ****
  
  def boolean(value, truefalse=(False, True)):
!     """Convert any Python value to XML-RPC boolean."""
      return truefalse[operator.truth(value)]
  
- #
- # dateTime wrapper
- # wrap your iso8601 string or time tuple or localtime integer value
- # in this class to generate a "dateTime.iso8601" XML-RPC value
- 
  class DateTime:
!     """DataTime wrapper for an ISO 8601 string or time tuple or
!     localtime integer value to generate a 'dateTime.iso8601' XML-RPC
!     value."""
  
      def __init__(self, value=0):
--- 232,243 ----
  
  def boolean(value, truefalse=(False, True)):
!     """Convert any Python value to XML-RPC 'boolean'."""
      return truefalse[operator.truth(value)]
  
  class DateTime:
!     """DateTime wrapper for an ISO 8601 string or time tuple or
!     localtime integer value to generate 'dateTime.iso8601' XML-RPC
!     value.
!     """
  
      def __init__(self, value=0):
***************
*** 275,279 ****
      return value
  
- 
  class Binary:
      """Wrapper for binary data."""
--- 271,274 ----
***************
*** 355,358 ****
--- 350,354 ----
  
          def handle_proc(self, tag, attr):
+             import re
              m = re.search("encoding\s*=\s*['\"]([^\"']+)[\"']", attr)
              if m:
***************
*** 391,402 ****
              self._parser.Parse("", 1) # end of data
              del self._target, self._parser # get rid of circular references
- 
- class SlowParser(xmllib.XMLParser):
-     """XML parser using xmllib.XMLParser.
- 
-     This is about 10 times slower than sgmlop on roundtrip testing.
-     """
  
      def __init__(self, target):
          self.handle_xml = target.xml
          self.unknown_starttag = target.start
--- 387,399 ----
              self._parser.Parse("", 1) # end of data
              del self._target, self._parser # get rid of circular references
  
+ class SlowParser:
+     """Default XML parser (based on xmllib.XMLParser)."""
+     # this is about 10 times slower than sgmlop, on roundtrip
+     # testing.
      def __init__(self, target):
+         import xmllib # lazy subclassing (!)
+         if xmllib.XMLParser not in SlowParser.__bases__:
+             SlowParser.__bases__ = (xmllib.XMLParser,)
          self.handle_xml = target.xml
          self.unknown_starttag = target.start
***************
*** 412,420 ****
      """Generate an XML-RPC params chunk from a Python data structure.
  
!     Create a marshaller instance for each set of parameters, and use
!     "dumps" method to convert your data (represented as a tuple) to a
!     XML-RPC params chunk.  to write a fault response, pass a Fault
!     instance instead.  You may prefer to use the "dumps" convenience
!     function for this purpose (see below).
      """
  
--- 409,417 ----
      """Generate an XML-RPC params chunk from a Python data structure.
  
!     Create a Marshaller instance for each set of parameters, and use
!     the "dumps" method to convert your data (represented as a tuple)
!     to an XML-RPC params chunk.  To write a fault response, pass a
!     Fault instance instead.  You may prefer to use the "dumps" module
!     function for this purpose.
      """
  
***************
*** 471,474 ****
--- 468,472 ----
  
      def dump_string(self, value):
+         from cgi import escape
          self.write("<value><string>%s</string></value>\n" % escape(value))
      dispatch[StringType] = dump_string
***************
*** 477,480 ****
--- 475,479 ----
          def dump_unicode(self, value):
              value = value.encode(self.encoding)
+             from cgi import escape
              self.write("<value><string>%s</string></value>\n" % escape(value))
          dispatch[UnicodeType] = dump_unicode
***************
*** 505,508 ****
--- 504,508 ----
              if type(k) is not StringType:
                  raise TypeError, "dictionary key must be string"
+             from cgi import escape
              write("<name>%s</name>\n" % escape(k))
              self.__dump(v)
***************
*** 522,526 ****
  class Unmarshaller:
      """Unmarshal an XML-RPC response, based on incoming XML event
!     messages (start, data, end).  Call close() to get the resulting
      data structure.
  
--- 522,526 ----
  class Unmarshaller:
      """Unmarshal an XML-RPC response, based on incoming XML event
!     messages (start, data, end).  Call close to get the resulting
      data structure.
  
***************
*** 803,807 ****
  
  class Transport:
!     """Handles an HTTP transaction to an XML-RPC server"""
  
      # client identifier (may be overridden)
--- 803,807 ----
  
  class Transport:
!     """Handles an HTTP transaction to an XML-RPC server."""
  
      # client identifier (may be overridden)
***************
*** 833,836 ****
--- 833,840 ----
          return self.parse_response(h.getfile())
  
+     def getparser(self):
+         # get parser and unmarshaller
+         return getparser()
+ 
      def make_connection(self, host):
          # create a HTTP connection object from a host descriptor
***************
*** 857,861 ****
          # read response from input file, and parse it
  
!         p, u = getparser()
  
          while 1:
--- 861,865 ----
          # read response from input file, and parse it
  
!         p, u = self.getparser()
  
          while 1:
***************
*** 873,877 ****
  
  class SafeTransport(Transport):
!     """Handles an HTTPS transaction to an XML-RPC server"""
  
      def make_connection(self, host):
--- 877,881 ----
  
  class SafeTransport(Transport):
!     """Handles an HTTPS transaction to an XML-RPC server."""
  
      def make_connection(self, host):
***************
*** 922,925 ****
--- 926,930 ----
  
          # get the url
+         import urllib
          type, uri = urllib.splittype(uri)
          if type not in ("http", "https"):