another round of changes mostly type related py33
authorrptlab
Wed, 01 May 2013 16:43:09 +0100
branchpy33
changeset 3731 b233dd0577ff
parent 3730 690aaa390f45
child 3732 049e32c982df
another round of changes mostly type related
.hgignore
src/reportlab/lib/rl_accel.py
src/reportlab/lib/textsplit.py
src/reportlab/lib/utils.py
src/reportlab/lib/validators.py
src/reportlab/pdfbase/pdfdoc.py
src/reportlab/pdfbase/pdfmetrics.py
src/reportlab/pdfbase/pdfutils.py
src/reportlab/pdfgen/canvas.py
src/reportlab/pdfgen/pdfimages.py
src/reportlab/pdfgen/textobject.py
src/reportlab/platypus/doctemplate.py
src/reportlab/platypus/paragraph.py
src/reportlab/platypus/paraparser.py
src/reportlab/platypus/xpreformatted.py
tests/runAll.py
tests/test_platypus_xref.py
--- a/.hgignore	Thu Mar 07 17:54:44 2013 +0000
+++ b/.hgignore	Wed May 01 16:43:09 2013 +0100
@@ -34,8 +34,6 @@
 *.scc
 build
 __pycache__
-build
-__pycache__
 *.pyd
 demos/stdfonts/*.pdf
 docs/*.pdf
--- a/src/reportlab/lib/rl_accel.py	Thu Mar 07 17:54:44 2013 +0000
+++ b/src/reportlab/lib/rl_accel.py	Wed May 01 16:43:09 2013 +0100
@@ -1,10 +1,10 @@
-from reportlab.lib.utils import isUnicodeType, isSeqType
+from reportlab.lib.utils import isUnicode, isSeq
 from math import log
 _log_10 = lambda x,log=log,_log_e_10=log(10.0): log(x)/_log_e_10
 _fp_fmts = "%.0f", "%.1f", "%.2f", "%.3f", "%.4f", "%.5f", "%.6f"
 def fp_str(*a):
     '''convert separate arguments (or single sequence arg) into space separated numeric strings'''
-    if len(a)==1 and isSeqType(a[0]): a = a[0]
+    if len(a)==1 and isSeq(a[0]): a = a[0]
     s = []
     A = s.append
     for i in a:
@@ -39,7 +39,7 @@
         enc = 'UTF16'
     while utext:
         try:
-            if isUnicodeType(utext):
+            if isUnicode(utext):
                 s = utext.encode(enc)
             else:
                 s = utext
@@ -58,7 +58,7 @@
 
 def _instanceStringWidthU(self, text, size, encoding='utf8'):
     """This is the "purist" approach to width"""
-    if not isUnicodeType(text): text = text.decode(encoding)
+    if not isUnicode(text): text = text.decode(encoding)
     return sum([sum(map(f.widths.__getitem__,list(map(ord,t)))) for f, t in unicode2T1(text,[self]+self.substitutionFonts)])*0.001*size
 
 if __name__=='__main__':
@@ -70,7 +70,7 @@
             "_instanceStringWidthU(font,'abcde fghi . jkl ; mno',10)",
             "_instanceStringWidthU(font,u'abcde fghi . jkl ; mno',10)",
             ):
-            print '%s %s' % (modname,cmd)
+            print('%s %s' % (modname,cmd))
             s=';'.join((
                 "from reportlab.pdfbase.pdfmetrics import getFont",
                 "from %s import unicode2T1,_instanceStringWidthU" % modname,
--- a/src/reportlab/lib/textsplit.py	Thu Mar 07 17:54:44 2013 +0000
+++ b/src/reportlab/lib/textsplit.py	Wed May 01 16:43:09 2013 +0100
@@ -12,10 +12,10 @@
 
 __version__=''' $Id$ '''
 
-from types import StringType, UnicodeType
 from unicodedata import category
 from reportlab.pdfbase.pdfmetrics import stringWidth
 from reportlab.rl_config import _FUZZ
+from reportlab.lib.utils import isUnicode
 
 CANNOT_START_LINE = [
     #strongly prohibited e.g. end brackets, stop, exclamation...
@@ -72,7 +72,7 @@
     >>> wordSplit('HelloWorld', 31, 'Courier', 10)
     [[1.0, 'Hello'], [1.0, 'World']]
     """
-    if type(word) is not UnicodeType:
+    if not isUnicode(word):
         uword = word.decode(encoding)
     else:
         uword = word
@@ -80,7 +80,7 @@
     charWidths = getCharWidths(uword, fontName, fontSize)
     lines = dumbSplit(uword, charWidths, maxWidths)
 
-    if type(word) is not UnicodeType:
+    if not isUnicode(word):
         lines2 = []
         #convert back
         for (extraSpace, text) in lines:
@@ -115,7 +115,7 @@
     (u'\u65e5\u672c\u8a9e', u'\u306f\u96e3\u3057\u3044\u3067\u3059\u306d\uff01')
     """
     if not isinstance(maxWidths,(list,tuple)): maxWidths = [maxWidths]
-    assert type(word) is UnicodeType
+    assert isUnicode(word)
     lines = []
     i = widthUsed = lineStartPos = 0
     maxWidth = maxWidths[0]
--- a/src/reportlab/lib/utils.py	Thu Mar 07 17:54:44 2013 +0000
+++ b/src/reportlab/lib/utils.py	Wed May 01 16:43:09 2013 +0100
@@ -22,101 +22,51 @@
 
 isPython3 = sys.version_info[0]==3
 
-def isFunctionType(v):
-    return type(v) == type(isFunctionType)
+def isFunction(v):
+    return type(v) == type(isFunction)
 
 class c:
     def m(self): pass
 
-def isMethodType(v,mt=type(c.m)):
+def isMethod(v,mt=type(c.m)):
     return type(v) == mt
 del c
 
-def isModuleType(v):
+def isModule(v):
     return type(v) == type(sys)
 
-def isSeqType(v,_st=(tuple,list)):
+def isSeq(v,_st=(tuple,list)):
     return isinstance(v,_st)
 
 if isPython3:
     def UniChr(v):
         return chr(v)
 
-    def isStrType(v):
+    def isStr(v):
         return isinstance(v, str)
 
-    def isBytesType(v):
+    def isBytes(v):
         return isinstance(v, bytes)
 
-    def isUnicodeType(v):
+    def isUnicode(v):
         return isinstance(v, str)
 
-    def isClassType(v):
+    def isClass(v):
         return isinstance(v, type)
 else:
     def UniChr(v):
         return unichr(v)
 
-    def isStrType(v):
+    def isStr(v):
         return isinstance(v, basestring)
 
-    def isBytesType(v):
+    def isBytes(v):
         return isinstance(v, str)
 
-    def isUnicodeType(v):
+    def isUnicode(v):
         return isinstance(v, unicode)
 
-    def isClassType(v):
-        import types
-        return isinstance(v, types.ClassType)
-
-isPython3 = sys.version_info[0]==3
-
-def isFunctionType(v):
-    return type(v) == type(isFunctionType)
-
-class c:
-    def m(self): pass
-
-def isMethodType(v,mt=type(c.m)):
-    return type(v) == mt
-del c
-
-def isModuleType(v):
-    return type(v) == type(sys)
-
-def isSeqType(v,_st=(tuple,list)):
-    return isinstance(v,_st)
-
-if isPython3:
-    def UniChr(v):
-        return chr(v)
-
-    def isStrType(v):
-        return isinstance(v, str)
-
-    def isBytesType(v):
-        return isinstance(v, bytes)
-
-    def isUnicodeType(v):
-        return isinstance(v, str)
-
-    def isClassType(v):
-        return isinstance(v, type)
-else:
-    def UniChr(v):
-        return unichr(v)
-
-    def isStrType(v):
-        return isinstance(v, basestring)
-
-    def isBytesType(v):
-        return isinstance(v, str)
-
-    def isUnicodeType(v):
-        return isinstance(v, unicode)
-
-    def isClassType(v):
+    def isClass(v):
         import types
         return isinstance(v, types.ClassType)
 
@@ -310,6 +260,51 @@
 except ImportError:
     from reportlab.lib.rl_accel import fp_str   # specific
 
+def recursiveImport(modulename, baseDir=None, noCWD=0, debug=0):
+    """Dynamically imports possible packagized module, or raises ImportError"""
+    normalize = lambda x: os.path.normcase(os.path.abspath(os.path.normpath(x)))
+    path = map(normalize,sys.path)
+    if baseDir:
+        if not isSeq(baseDir):
+            tp = [baseDir]
+        else:
+            tp = filter(None,list(baseDir))
+        for p in tp:
+            p = normalize(p)
+            if p not in path: path.insert(0,p)
+
+    if noCWD:
+        for p in ('','.',normalize('.')):
+            while p in path:
+                if debug: print('removed "%s" from path' % p)
+                path.remove(p)
+    elif '.' not in path:
+            path.insert(0,'.')
+
+    if debug:
+        import pprint
+        pp = pprint.pprint
+        print('path=')
+        pp(path)
+
+    #make import errors a bit more informative
+    opath = sys.path
+    try:
+        sys.path = path
+        exec('import %s\nm = %s\n' % (modulename,modulename),locals())
+        sys.path = opath
+        return m
+    except ImportError:
+        sys.path = opath
+        msg = "Could not import '%s'" % modulename
+        if baseDir:
+            msg = msg + " under %s" % baseDir
+        raise ImportError(msg)
+    except:
+        e = sys.exc_info()
+        msg = "Exception raised while importing '%s': %s" % (modulename, e[1])
+        raise ImportError(msg)
+
 def recursiveGetAttr(obj, name):
     "Can call down into e.g. object1.object2[4].attr"
     return eval(name, obj.__dict__)
@@ -377,7 +372,7 @@
         if func:
             v = func(av)
         else:
-            if isStrType(v):
+            if isStr(v):
                 v = av
             elif isinstance(v,float):
                 v = float(av)
@@ -598,7 +593,7 @@
     def identity(self):
         '''try to return information that will identify the instance'''
         fn = self.fileName
-        if not isStrType(fn):
+        if not isStr(fn):
             fn = getattr(getattr(self,'fp',None),'name',None)
         ident = self._ident
         return '[%s@%s%s%s]' % (self.__class__.__name__,hex(id(self)),ident and (' ident=%r' % ident) or '',fn and (' filename=%r' % fn) or '')
@@ -952,7 +947,7 @@
 
 def _flatten(L,a):
     for x in L:
-        if isSeqType(x): _flatten(x,a)
+        if isSeq(x): _flatten(x,a)
         else: a(x)
 
 def flatten(L):
@@ -1182,12 +1177,12 @@
 
 def encode_label(args):
     s = base64.encodestring(pickle.dumps(args)).strip()
-    if not isStrType(s):
+    if not isStr(s):
         s = s.decode('utf-8')
     return s
 
 def decode_label(label):
-    if isUnicodeType(label):
+    if isUnicode(label):
         label = label.encode('utf-8')
     v = pickle.loads(base64.decodestring(label))
     return v
@@ -1219,7 +1214,6 @@
 
 def makeFileName(s):
     '''force filename strings to unicode so python can handle encoding stuff'''
-    assert isinstance(s,basestring),"filename is %r should be str or unicode" % s
-    if isinstance(s,str):
+    if not isUnicode(s):
         s = s.decode('utf8')
     return s
--- a/src/reportlab/lib/validators.py	Thu Mar 07 17:54:44 2013 +0000
+++ b/src/reportlab/lib/validators.py	Wed May 01 16:43:09 2013 +0100
@@ -5,9 +5,7 @@
 __doc__="""Standard verifying functions used by attrmap."""
 
 import string, sys, codecs
-from types import *
-_SequenceTypes = (ListType,TupleType)
-_NumberTypes = (FloatType,IntType)
+from reportlab.lib.utils import isSeq, isStr, isUnicode
 from reportlab.lib import colors
 if sys.hexversion<0x2030000:
     True = 1
@@ -78,7 +76,7 @@
 
 class _isNumber(Validator):
     def test(self,x):
-        if type(x) in _NumberTypes: return True
+        if isinstance(x,(float,int): return True
         return self.normalizeTest(x)
 
     def normalize(self,x):
@@ -128,7 +126,7 @@
     "ListOfShapes validator class."
     def test(self, x):
         from reportlab.graphics.shapes import Shape
-        if type(x) in _SequenceTypes:
+        if isSeq(x):
             answer = 1
             for e in x:
                 if not isinstance(e, Shape):
@@ -147,7 +145,7 @@
 class _isTransform(Validator):
     "Transform validator class."
     def test(self, x):
-        if type(x) in _SequenceTypes:
+        if isSeq(x):
             if len(x) == 6:
                 for element in x:
                     if not isNumber(element):
@@ -227,7 +225,7 @@
         if name: self._str = name
 
     def test(self, x):
-        if type(x) not in _SequenceTypes:
+        if not isSeq(x):
             if x is None: return self._NoneOK
             return False
         if x==[] or x==():
@@ -239,7 +237,7 @@
 
 class EitherOr(Validator):
     def __init__(self,tests,name=None):
-        if type(tests) not in _SequenceTypes: tests = (tests,)
+        if not isSeq(tests): tests = (tests,)
         self._tests = tests
         if name: self._str = name
 
--- a/src/reportlab/pdfbase/pdfdoc.py	Thu Mar 07 17:54:44 2013 +0000
+++ b/src/reportlab/pdfbase/pdfdoc.py	Wed May 01 16:43:09 2013 +0100
@@ -18,7 +18,7 @@
 from reportlab.pdfbase import pdfutils
 from reportlab.pdfbase.pdfutils import LINEEND # this constant needed in both
 from reportlab import rl_config
-from reportlab.lib.utils import import_zlib, open_for_read, fp_str, makeFileName, isSeqType, isBytesType, isUnicodeType, _digester
+from reportlab.lib.utils import import_zlib, open_for_read, fp_str, makeFileName, isSeq, isBytes, isUnicode, _digester
 from reportlab.pdfbase import pdfmetrics
 from hashlib import md5
 
@@ -228,7 +228,7 @@
             filename = makeFileName(filename)
             f = open(filename, "wb")
         data = self.GetPDFData(canvas)
-        if isUnicodeType(data):
+        if isUnicode(data):
             data = data.encode('utf8')
         f.write(data)
         if myfile:
@@ -551,7 +551,7 @@
         self.t = t
     def format(self, document):
         t = self.t
-        if isUnicodeType(t):
+        if isUnicode(t):
             t = t.encode('utf-8')
         result = binascii.hexlify(document.encrypt.encode(t))
         return b"<" + result + b">"
@@ -604,7 +604,7 @@
     def format(self, document):
         s = self.s
         enc = getattr(self,'enc','auto')
-        if (isBytesType(s)):
+        if (isBytes(s)):
             if enc is 'auto':
                 try:
                     u = s.decode(s.startswith(codecs.BOM_UTF16_BE) and 'utf16' or 'utf8')
@@ -618,7 +618,7 @@
                     except:
                         sys.stderr.write('Error in %s' % (repr(s),))
                         raise
-        elif isUnicodeType(s):
+        elif isUnicode(s):
             if enc is 'auto':
                 if _checkPdfdoc(s):
                     s = s.encode('pdfdoc')
@@ -755,7 +755,7 @@
         from reportlab.lib.utils import import_zlib
         zlib = import_zlib()
         if not zlib: raise ImportError("cannot z-compress zlib unavailable")
-        if isUnicodeType(text):
+        if isUnicode(text):
             text = text.encode('utf8')
         return zlib.compress(text)
     def decode(self, encoded):
@@ -1155,7 +1155,7 @@
     def setStream(self, code):
         if self.Override_default_compilation:
             raise ValueError("overridden! must set stream explicitly")
-        if isSeqType(code):
+        if isSeq(code):
             code = LINEEND.join(code)+LINEEND
         self.stream = code
 
@@ -1455,7 +1455,7 @@
         destinationnamestotitles = self.destinationnamestotitles
         destinationstotitles = self.destinationstotitles
         closedict = self.closedict
-        if isStrType(object):
+        if isStr(object):
             destination = canvas._bookmarkReference(object)
             title = object
             if object in destinationnamestotitles:
@@ -1466,7 +1466,7 @@
             if object in closedict:
                 closedict[destination] = 1 # mark destination closed
             return {object: canvas._bookmarkReference(object)} # name-->ref
-        if isSeqType(object):
+        if isSeq(object):
             L = []
             for o in object:
                 L.append(self.translateNames(canvas, o))
@@ -1505,7 +1505,7 @@
             levelname = "Outline.%s" % self.count
             if Parent is None:
                 raise ValueError("non-top level outline elt parent must be specified")
-        if not isSeqType(destinationtree):
+        if not isSeq(destinationtree):
             raise ValueError("destinationtree must be list or tuple, got %s")
         nelts = len(destinationtree)
         lastindex = nelts-1
@@ -1560,7 +1560,7 @@
         [(Title, Dest)] = list(leafdict.items())
         if closedict and Dest in closedict:
             return 1 # closed tree element
-    if isSeqType(tree):
+    if isSeq(tree):
         #return reduce(add, map(count, tree))
         counts = []
         for e in tree:
@@ -1620,7 +1620,7 @@
     def cvtdict(self, d, escape=1):
         """transform dict args from python form to pdf string rep as needed"""
         Rect = d["Rect"]
-        if not isStrType(Rect):
+        if not isStr(Rect):
             d["Rect"] = PDFArray(Rect)
         d["Contents"] = PDFString(d["Contents"],escape)
         return d
@@ -1916,7 +1916,7 @@
                 D[dname] = v
         v = self.ProcSet
         dname = "ProcSet"
-        if isSeqType(v):
+        if isSeq(v):
             if v:
                 dv = PDFArray(v)
                 D[dname] = dv
@@ -2010,7 +2010,7 @@
         self.lowerx = lowerx; self.lowery=lowery; self.upperx=upperx; self.uppery=uppery
 
     def setStreamList(self, data):
-        if isSeqType(data):
+        if isSeq(data):
             data = LINEEND.join(data)
         self.stream = data
 
--- a/src/reportlab/pdfbase/pdfmetrics.py	Thu Mar 07 17:54:44 2013 +0000
+++ b/src/reportlab/pdfbase/pdfmetrics.py	Wed May 01 16:43:09 2013 +0100
@@ -21,7 +21,7 @@
 import string, os, sys
 from reportlab.pdfbase import _fontdata
 from reportlab.lib.logger import warnOnce
-from reportlab.lib.utils import rl_isfile, rl_glob, rl_isdir, open_and_read, open_and_readlines, findInPaths, isSeqType, isStrType, isUnicodeType, isPython3
+from reportlab.lib.utils import rl_isfile, rl_glob, rl_isdir, open_and_read, open_and_readlines, findInPaths, isSeq, isStr, isUnicode, isPython3
 from reportlab.rl_config import defaultEncoding, T1SearchPath
 from . import rl_codecs
 _notdefChar = b'n'
@@ -227,11 +227,11 @@
             # assume based on the usual one
             self.baseEncodingName = defaultEncoding
             self.vector = _fontdata.encodings[defaultEncoding]
-        elif isStrType(base):
+        elif isStr(base):
             baseEnc = getEncoding(base)
             self.baseEncodingName = baseEnc.name
             self.vector = baseEnc.vector[:]
-        elif isSeqType(base):
+        elif isSeq(base):
             self.baseEncodingName = defaultEncoding
             self.vector = base[:]
         elif isinstance(base, Encoding):
--- a/src/reportlab/pdfbase/pdfutils.py	Thu Mar 07 17:54:44 2013 +0000
+++ b/src/reportlab/pdfbase/pdfutils.py	Wed May 01 16:43:09 2013 +0100
@@ -10,7 +10,7 @@
 import os
 import binascii
 from reportlab import rl_config
-from reportlab.lib.utils import getBytesIO, ImageReader, isStrType, isUnicodeType, isPython3
+from reportlab.lib.utils import getBytesIO, ImageReader, isStr, isUnicode, isPython3
 
 LINEEND = '\015\012'
 
@@ -192,7 +192,7 @@
     This is a verbose encoding used for binary data within
     a PDF file.  One byte binary becomes two bytes of ASCII.
     Helper function used by images."""
-    if isUnicodeType(input):
+    if isUnicode(input):
         input = input.encode('utf-8')
     output = getBytesIO()
     output.write(binascii.b2a_hex(input))
@@ -206,7 +206,7 @@
     Not used except to provide a test of the inverse function."""
 
     #strip out all whitespace
-    if not isStrType(input):
+    if not isStr(input):
         input = input.decode('utf-8')
     stripped = ''.join(input.split())
     assert stripped[-1] == '>', 'Invalid terminator for Ascii Hex Stream'
@@ -226,7 +226,7 @@
         whole_word_count, remainder_size = divmod(len(input), 4)
         cut = 4 * whole_word_count
         body, lastbit = input[0:cut], input[cut:]
-        if isPython3 and isStrType(lastbit):
+        if isPython3 and isStr(lastbit):
             lastbit = lastbit.encode('utf-8')
 
         out = [].append
@@ -236,10 +236,10 @@
             b2 = body[offset+1]
             b3 = body[offset+2]
             b4 = body[offset+3]
-            if isStrType(b1): b1 = ord(b1)
-            if isStrType(b2): b2 = ord(b2)
-            if isStrType(b3): b3 = ord(b3)
-            if isStrType(b4): b4 = ord(b4)
+            if isStr(b1): b1 = ord(b1)
+            if isStr(b2): b2 = ord(b2)
+            if isStr(b3): b3 = ord(b3)
+            if isStr(b4): b4 = ord(b4)
 
             if b1<128:
                 num = (((((b1<<8)|b2)<<8)|b3)<<8)|b4
@@ -274,10 +274,10 @@
             b2 = lastbit[1]
             b3 = lastbit[2]
             b4 = lastbit[3]
-            if isStrType(b1): b1 = ord(b1)
-            if isStrType(b2): b2 = ord(b2)
-            if isStrType(b3): b3 = ord(b3)
-            if isStrType(b4): b4 = ord(b4)
+            if isStr(b1): b1 = ord(b1)
+            if isStr(b2): b2 = ord(b2)
+            if isStr(b3): b3 = ord(b3)
+            if isStr(b4): b4 = ord(b4)
 
             num = 16777216 * b1 + 65536 * b2 + 256 * b3 + b4
 
--- a/src/reportlab/pdfgen/canvas.py	Thu Mar 07 17:54:44 2013 +0000
+++ b/src/reportlab/pdfgen/canvas.py	Wed May 01 16:43:09 2013 +0100
@@ -22,7 +22,7 @@
 from reportlab.pdfbase import pdfmetrics
 from reportlab.pdfgen  import pdfgeom, pathobject, textobject
 from reportlab.lib.colors import black, _chooseEnforceColorSpace, Color, CMYKColor, toColor
-from reportlab.lib.utils import import_zlib, ImageReader, fp_str, isSeqType, isStrType, isUnicodeType, _digester
+from reportlab.lib.utils import import_zlib, ImageReader, fp_str, isSeq, isStr, isUnicode, _digester
 from reportlab.lib.boxstuff import aspectRatioFix
 
 digitPat = re.compile('\d')  #used in decimal alignment
@@ -313,8 +313,8 @@
         '''
         if encrypt:
             from reportlab.lib import pdfencrypt
-            if isStrType(encrypt): #encrypt is the password itself
-                if isUnicodeType(encrypt):
+            if isStr(encrypt): #encrypt is the password itself
+                if isUnicode(encrypt):
                     encrypt = encrypt.encode('utf-8')
                 encrypt = pdfencrypt.StandardEncryption(encrypt)    #now it's the encrypt object
                 encrypt.setAllPermissions(1)
@@ -907,13 +907,13 @@
                 mdata = smask.getRGBData()
             else:
                 mdata = str(mask)
-            if isUnicodeType(mdata):
+            if isUnicode(mdata):
                 mdata = mdata.encode('utf8')
             name = _digester(rawdata+mdata)
         else:
             #filename, use it
             s = '%s%s' % (image, mask)
-            if isUnicodeType(s):
+            if isUnicode(s):
                 s = s.encode('utf-8')
             name = _digester(s)
 
@@ -1044,7 +1044,7 @@
         will error in Distiller but work on printers supporting it.
         """
         #check if we've done this one already...
-        if isUnicodeType(command):
+        if isUnicode(command):
             rawName = 'PS' + hashlib.md5(command.encode('utf-8')).hexdigest()
         else:
             rawName = 'PS' + hashlib.md5(command).hexdigest()
@@ -1202,7 +1202,7 @@
         After this operation the canvas must not be used further."""
         if len(self._code): self.showPage()
         s = self._doc.GetPDFData(self)
-        if isUnicodeType(s):
+        if isUnicode(s):
             s = s.encode('utf-8')
         return s
 
@@ -1640,7 +1640,7 @@
         """Two notations.  pass two numbers, or an array and phase"""
         if isinstance(array,(int,float)):
             self._code.append('[%s %s] 0 d' % (array, phase))
-        elif isSeqType(array):
+        elif isSeq(array):
             assert phase >= 0, "phase is a length in user space"
             textarray = ' '.join([str(s) for s in array])
             self._code.append('[%s] %s d' % (textarray, phase))
--- a/src/reportlab/pdfgen/pdfimages.py	Thu Mar 07 17:54:44 2013 +0000
+++ b/src/reportlab/pdfgen/pdfimages.py	Wed May 01 16:43:09 2013 +0100
@@ -11,7 +11,7 @@
 from reportlab import rl_config
 from reportlab.pdfbase import pdfutils
 from reportlab.pdfbase import pdfdoc
-from reportlab.lib.utils import fp_str, getBytesIO, isStrType
+from reportlab.lib.utils import fp_str, getBytesIO, isStr
 from reportlab.lib.utils import import_zlib, haveImages
 from reportlab.lib.boxstuff import aspectRatioFix
 
@@ -136,7 +136,7 @@
         "Gets data, height, width - whatever type of image"
         image = self.image
 
-        if isStrType(image):
+        if isStr(image):
             self.filename = image
             if os.path.splitext(image)[1] in ['.jpg', '.JPG', '.jpeg', '.JPEG']:
                 try:
--- a/src/reportlab/pdfgen/textobject.py	Thu Mar 07 17:54:44 2013 +0000
+++ b/src/reportlab/pdfgen/textobject.py	Wed May 01 16:43:09 2013 +0100
@@ -13,7 +13,7 @@
 import string
 from types import *
 from reportlab.lib.colors import Color, CMYKColor, CMYKColorSep, toColor, black, white, _CMYK_black, _CMYK_white
-from reportlab.lib.utils import fp_str, isStrType, isPython3
+from reportlab.lib.utils import fp_str, isStr, isPython3
 from reportlab.pdfbase import pdfmetrics
 
 class _PDFColorSetter:
@@ -79,7 +79,7 @@
                 self._code.append('%s k' % fp_str(aColor))
             else:
                 raise ValueError('Unknown color %r' % aColor)
-        elif isStrType(aColor):
+        elif isStr(aColor):
             self.setFillColor(toColor(aColor))
         else:
             raise ValueError('Unknown color %r' % aColor)
@@ -115,7 +115,7 @@
                 self._code.append('%s K' % fp_str(aColor))
             else:
                 raise ValueError('Unknown color %r' % aColor)
-        elif isStrType(aColor):
+        elif isStr(aColor):
             self.setStrokeColor(toColor(aColor))
         else:
             raise ValueError('Unknown color %r' % aColor)
@@ -432,7 +432,7 @@
         since this may be indented, by default it trims whitespace
         off each line and from the beginning; set trim=0 to preserve
         whitespace."""
-        if isStrType(stuff):
+        if isStr(stuff):
             lines = '\n'.split(stuff.strip())
             if trim==1:
                 lines = [s.strip() for s in lines]
--- a/src/reportlab/platypus/doctemplate.py	Thu Mar 07 17:54:44 2013 +0000
+++ b/src/reportlab/platypus/doctemplate.py	Wed May 01 16:43:09 2013 +0100
@@ -35,6 +35,7 @@
 from reportlab.rl_config import defaultPageSize, verbose
 import reportlab.lib.sequencer
 from reportlab.pdfgen import canvas
+from reportlab.lib.utils import isSeq
 try:
     set
 except NameError:
@@ -48,7 +49,6 @@
 dumps = pickle.dumps
 loads = pickle.loads
 
-from types import *
 import sys
 import logging
 logger = logging.getLogger("reportlab.platypus")
@@ -128,7 +128,7 @@
         #must call super init to ensure it has a width and height (of zero),
         #as in some cases the packer might get called on it...
         Flowable.__init__(self)
-        if type(action) not in (ListType, TupleType):
+        if not isSeq(action):
             action = (action,)
         self.action = tuple(action)
 
@@ -202,10 +202,10 @@
 PageBegin = LCActionFlowable('pageBegin')
 
 def _evalMeasurement(n):
-    if type(n) is type(''):
+    if isinstance(n,str):
         from .paraparser import _num
         n = _num(n)
-        if type(n) is type(()): n = n[1]
+        if isSeq(n): n = n[1]
     return n
 
 class FrameActionFlowable(Flowable):
@@ -255,7 +255,7 @@
     def __init__(self,id=None,frames=[],onPage=_doNothing, onPageEnd=_doNothing,
                  pagesize=None, autoNextPageTemplate=None):
         frames = frames or []
-        if type(frames) not in (ListType,TupleType): frames = [frames]
+        if not isSeq(frames): frames = [frames]
         assert [x for x in frames if not isinstance(x,Frame)]==[], "frames argument error"
         self.id = id
         self.frames = frames
@@ -521,7 +521,7 @@
 
     def addPageTemplates(self,pageTemplates):
         'add one or a sequence of pageTemplates'
-        if type(pageTemplates) not in (ListType,TupleType):
+        if not isSeq(pageTemplates):
             pageTemplates = [pageTemplates]
         #this test below fails due to inconsistent imports!
         #assert filter(lambda x: not isinstance(x,PageTemplate), pageTemplates)==[], "pageTemplates argument error"
@@ -638,17 +638,17 @@
 
     def handle_nextPageTemplate(self,pt):
         '''On endPage change to the page template with name or index pt'''
-        if type(pt) is StringType:
+        if isinstance(pt,''):
             if hasattr(self, '_nextPageTemplateCycle'): del self._nextPageTemplateCycle
             for t in self.pageTemplates:
                 if t.id == pt:
                     self._nextPageTemplateIndex = self.pageTemplates.index(t)
                     return
             raise ValueError("can't find template('%s')"%pt)
-        elif type(pt) is IntType:
+        elif isinstance(pt,int):
             if hasattr(self, '_nextPageTemplateCycle'): del self._nextPageTemplateCycle
             self._nextPageTemplateIndex = pt
-        elif type(pt) in (ListType, TupleType):
+        elif isSeq(pt):
             #used for alternating left/right pages
             #collect the refs to the template objects, complain if any are bad
             c = PTCycle()
@@ -675,13 +675,13 @@
 
     def handle_nextFrame(self,fx,resume=0):
         '''On endFrame change to the frame with name or index fx'''
-        if type(fx) is StringType:
+        if isinstance(fx,str):
             for f in self.pageTemplate.frames:
                 if f.id == fx:
                     self._nextFrameIndex = self.pageTemplate.frames.index(f)
                     return
             raise ValueError("can't find frame('%s') in %r(%s) which has frames %r"%(fx,self.pageTemplate,self.pageTemplate.id,[(f,f.id) for f in self.pageTemplate.frames]))
-        elif type(fx) is IntType:
+        elif isinstance(fx,int):
             self._nextFrameIndex = fx
         else:
             raise TypeError("argument fx should be string or integer")
--- a/src/reportlab/platypus/paragraph.py	Thu Mar 07 17:54:44 2013 +0000
+++ b/src/reportlab/platypus/paragraph.py	Wed May 01 16:43:09 2013 +0100
@@ -3,9 +3,8 @@
 #history http://www.reportlab.co.uk/cgi-bin/viewcvs.cgi/public/reportlab/trunk/reportlab/platypus/paragraph.py
 __version__=''' $Id$ '''
 __doc__='''The standard paragraph implementation'''
-from string import join, whitespace
+from string import whitespace
 from operator import truth
-from types import StringType, ListType
 from unicodedata import category
 from reportlab.pdfbase.pdfmetrics import stringWidth, getFont, getAscentDescent
 from reportlab.platypus.paraparser import ParaParser
@@ -19,6 +18,7 @@
 from reportlab.lib.abag import ABag
 from reportlab.rl_config import platypus_link_underline
 from reportlab import rl_config
+from reportlab.lib.utils import isUnicode, isStr
 import re
 
 #on UTF8 branch, split and strip must be unicode-safe!
@@ -59,15 +59,15 @@
 _wsc_re_split=re.compile('[%s]+'% re.escape(_wsc)).split
 
 def split(text, delim=None):
-    if type(text) is str: text = text.decode('utf8')
-    if type(delim) is str: delim = delim.decode('utf8')
+    if not isUnicode(text): text = text.decode('utf8')
+    if delim is not None and not isUnicode(delim): delim = delim.decode('utf8')
     if delim is None and '\xa0' in text:
         return [uword.encode('utf8') for uword in _wsc_re_split(text)]
-    return [uword.encode('utf8') for uword in text.split(delim)]
+    return [uword for uword in text.split(delim)]
 
 def strip(text):
-    if type(text) is str: text = text.decode('utf8')
-    return text.strip(_wsc).encode('utf8')
+    if not isUnicode(text): text = text.decode('utf8')
+    return text.strip(_wsc)
 
 class ParaLines(ABag):
     """
@@ -92,14 +92,14 @@
     """
 
 def _lineClean(L):
-    return join(list(filter(truth,split(strip(L)))))
+    return ' '.join(list(filter(truth,split(strip(L)))))
 
 def cleanBlockQuotedText(text,joiner=' '):
     """This is an internal utility which takes triple-
     quoted text form within the document and returns
     (hopefully) the paragraph the user intended originally."""
     L=list(filter(truth,list(map(_lineClean, split(text, '\n')))))
-    return join(L, joiner)
+    return joiner.join(L)
 
 def setXPos(tx,dx):
     if dx>1e-6 or dx<-1e-6:
@@ -107,33 +107,33 @@
 
 def _leftDrawParaLine( tx, offset, extraspace, words, last=0):
     setXPos(tx,offset)
-    tx._textOut(join(words),1)
+    tx._textOut(' '.join(words),1)
     setXPos(tx,-offset)
     return offset
 
 def _centerDrawParaLine( tx, offset, extraspace, words, last=0):
     m = offset + 0.5 * extraspace
     setXPos(tx,m)
-    tx._textOut(join(words),1)
+    tx._textOut(' '.join(words),1)
     setXPos(tx,-m)
     return m
 
 def _rightDrawParaLine( tx, offset, extraspace, words, last=0):
     m = offset + extraspace
     setXPos(tx,m)
-    tx._textOut(join(words),1)
+    tx._textOut(' '.join(words),1)
     setXPos(tx,-m)
     return m
 
 def _nbspCount(w):
-    if isinstance(w,str):
+    if isStr(str):
         return w.count('\xc2\xa0')
     else:
         return w.count('\xa0')
 
 def _justifyDrawParaLine( tx, offset, extraspace, words, last=0):
     setXPos(tx,offset)
-    text  = join(words)
+    text  = ' '.join(words)
     if last or extraspace<=1e-8:
         #last one, left align
         tx._textOut(text,1)
@@ -607,7 +607,7 @@
 
 def _do_under_line(i, t_off, ws, tx, lm=-0.125):
     y = tx.XtraState.cur_y - i*tx.XtraState.style.leading + lm*tx.XtraState.f.fontSize
-    textlen = tx._canvas.stringWidth(join(tx.XtraState.lines[i][1]), tx._fontname, tx._fontsize)
+    textlen = tx._canvas.stringWidth(' '.join(tx.XtraState.lines[i][1]), tx._fontname, tx._fontsize)
     tx._canvas.line(t_off, y, t_off+textlen+ws, y)
 
 _scheme_re = re.compile('^[a-zA-Z][-+a-zA-Z0-9]+$')
@@ -630,7 +630,7 @@
     xs = tx.XtraState
     leading = xs.style.leading
     y = xs.cur_y - i*leading - xs.f.fontSize/8.0 # 8.0 factor copied from para.py
-    text = join(xs.lines[i][1])
+    text = ' '.join(xs.lines[i][1])
     textlen = tx._canvas.stringWidth(text, tx._fontname, tx._fontsize)
     _doLink(tx, xs.link, (t_off, y, t_off+textlen+ws, y+leading))
 
@@ -1594,7 +1594,7 @@
             for frag in frags:
                 if hasattr(frag, 'text'):
                     plains.append(frag.text)
-            return join(plains, '')
+            return ''.join(plains)
         elif identify:
             text = getattr(self,'text',None)
             if text is None: text = repr(self)
--- a/src/reportlab/platypus/paraparser.py	Thu Mar 07 17:54:44 2013 +0000
+++ b/src/reportlab/platypus/paraparser.py	Wed May 01 16:43:09 2013 +0100
@@ -5,7 +5,6 @@
 __doc__='''The parser used to process markup within paragraphs'''
 import string
 import re
-from types import TupleType, UnicodeType, StringType
 import sys
 import os
 import copy
@@ -106,7 +105,7 @@
     raise ValueError('Invalid autoLeading=%r' % x )
 
 def _align(s):
-    s = string.lower(s)
+    s = s.lower()
     if s=='left': return TA_LEFT
     elif s=='right': return TA_RIGHT
     elif s=='justify': return TA_JUSTIFY
@@ -207,7 +206,7 @@
     for k in K:
         n = m[k][0]
         if n not in m: m[n] = m[k]
-        n = string.lower(n)
+        n = n.lower()
         if n not in m: m[n] = m[k]
 
 _addAttributeNames(_paraAttrMap)
@@ -219,7 +218,7 @@
 
 def _applyAttributes(obj, attr):
     for k, v in attr.items():
-        if type(v) is TupleType and v[0]=='relative':
+        if isisntance(v,(list,tuple)) and v[0]=='relative':
             #AR 20/5/2000 - remove 1.5.2-ism
             #v = v[1]+getattr(obj,k,0)
             if hasattr(obj, k):
@@ -980,7 +979,7 @@
         A = {}
         for k, v in attr.items():
             if not self.caseSensitive:
-                k = string.lower(k)
+                k = k.lower()
             if k in list(attrMap.keys()):
                 j = attrMap[k]
                 func = j[1]
@@ -1070,7 +1069,7 @@
         # and revert at end.  Yuk.  Preliminary step prior to
         # removal of parser altogether.
         enc = self._enc = 'utf8' #our legacy default
-        self._UNI = type(text) is UnicodeType
+        self._UNI = isinstance(text,str)
         if self._UNI:
             text = text.encode(enc)
 
@@ -1118,7 +1117,7 @@
         if C:
             M = self._tt_handlers
             for c in C:
-                M[type(c) is TupleType](c)
+                M[isinstance(c,(list,tuple))](c)
         end()
 
     def tt_parse(self,tt,style):
--- a/src/reportlab/platypus/xpreformatted.py	Thu Mar 07 17:54:44 2013 +0000
+++ b/src/reportlab/platypus/xpreformatted.py	Wed May 01 16:43:09 2013 +0100
@@ -4,7 +4,6 @@
 __version__=''' $Id$ '''
 __doc__='''A 'rich preformatted text' widget allowing internal markup'''
 import string
-from types import StringType, ListType
 from reportlab.lib import PyFontify
 from .paragraph import Paragraph, cleanBlockQuotedText, _handleBulletWidth, \
      ParaLines, _getFragWords, stringWidth, _sameFrag, getAscentDescent, imgVRange, imgNormV
@@ -113,7 +112,7 @@
         different first line indent; a longer list could be created to facilitate custom wraps
         around irregular objects."""
 
-        if type(width) != ListType: maxWidths = [width]
+        if not isSeq(width): maxWidths = [width]
         else: maxWidths = width
         lines = []
         lineno = 0
--- a/tests/runAll.py	Thu Mar 07 17:54:44 2013 +0000
+++ b/tests/runAll.py	Wed May 01 16:43:09 2013 +0100
@@ -4,7 +4,7 @@
 """Runs all test files in all subfolders.
 """
 __version__=''' $Id$ '''
-import os, glob, sys, string, traceback, unittest
+import os, glob, sys, traceback, unittest
 
 #we need to ensure 'tests' is on the path.  It will be if you
 #run 'setup.py tests', but won't be if you CD into the tests
@@ -87,7 +87,7 @@
     # special case for tests directory - clean up
     # all PDF & log files before starting run.  You don't
     # want this if reusing runAll anywhere else.
-    if string.find(folder, os.sep+'tests') > -1: cleanup(folder)
+    if os.sep+'tests' in folder: cleanup(folder)
     cleanup(outputfile(''))
     NI = []
     cleanOnly = '--clean' in sys.argv
@@ -100,7 +100,7 @@
         if NI:
             sys.stderr.write('\n###################### the following tests could not be imported\n')
             for f,tb in NI:
-                print('file: "%s"\n%s\n' % (f,string.join(tb,'')))
+                print('file: "%s"\n%s\n' % (f,''.join(tb)))
         printLocation()
 
 def mainEx():
--- a/tests/test_platypus_xref.py	Thu Mar 07 17:54:44 2013 +0000
+++ b/tests/test_platypus_xref.py	Wed May 01 16:43:09 2013 +0100
@@ -6,9 +6,7 @@
 from reportlab.lib.testutils import setOutDir,makeSuiteForClasses, outputfile, printLocation
 setOutDir(__name__)
 import sys, os, time
-from string import split, strip, join, whitespace, find
 from operator import truth
-from types import StringType, ListType
 import unittest
 from reportlab.lib import colors
 from reportlab.lib.units import cm
@@ -63,7 +61,7 @@
             except:
                 return
             for phrase in ['uniform','depraved','finger', 'Fraudulin']:
-                if find(text, phrase) > -1:
+                if text.find(phrase) > -1:
                     self.notify('IndexEntry', (phrase, self.page))
                     #print 'IndexEntry:',phrase, self.page