rl_accel.py: improvements and more tests working py33
authorrobin
Fri, 29 Nov 2013 15:57:46 +0000
branchpy33
changeset 3862 272e650eecf5
parent 3861 2c6bef69fa95
child 3863 53cdee53a6f9
rl_accel.py: improvements and more tests working
src/reportlab/lib/rl_accel.py
src/reportlab/lib/testutils.py
tests/test_rl_accel.py
--- a/src/reportlab/lib/rl_accel.py	Fri Nov 29 13:21:17 2013 +0000
+++ b/src/reportlab/lib/rl_accel.py	Fri Nov 29 15:57:46 2013 +0000
@@ -24,12 +24,14 @@
     try:
         exec('from reportlab.lib._rl_accel import %s as f' % fn)
         _c_funcs[fn] = f
+        if testing: _py_funcs[fn] = None
     except ImportError:
         _py_funcs[fn] = None
 
 if _py_funcs:
-    from reportlab.lib.utils import isBytes, isUnicode, isSeq, isPy3
+    from reportlab.lib.utils import isBytes, isUnicode, isSeq, isPy3, rawBytes
     from math import log
+    from struct import unpack
 
 if 'fp_str' in _py_funcs:
     _log_10 = lambda x,log=log,_log_e_10=log(10.0): log(x)/_log_e_10
@@ -92,10 +94,16 @@
     _py_funcs['unicode2T1'] = unicode2T1
 
 if 'instanceStringWidthT1' in _py_funcs:
-    def _instanceStringWidthT1(self, text, size, encoding='utf8'):
-        """This is the "purist" approach to width"""
-        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 isPy3:
+        def instanceStringWidthT1(self, text, size, encoding='utf8'):
+            """This is the "purist" approach to width"""
+            if not isUnicode(text): text = text.decode(encoding)
+            return sum([sum(map(f.widths.__getitem__,t)) for f, t in unicode2T1(text,[self]+self.substitutionFonts)])*0.001*size
+    else:
+        def instanceStringWidthT1(self, text, size, encoding='utf8'):
+            """This is the "purist" approach to width"""
+            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
     _py_funcs['instanceStringWidthT1'] = instanceStringWidthT1
 
 if 'instanceStringWidthTTF' in _py_funcs:
@@ -122,6 +130,7 @@
 if 'calcChecksum' in _py_funcs:
     def calcChecksum(data):
         """Calculates TTF-style checksums"""
+        data = rawBytes(data)
         if len(data)&3: data = data + (4-(len(data)&3))*"\0"
         return sum(unpack(">%dl" % (len(data)>>2), data)) & 0xFFFFFFFF
     _py_funcs['calcChecksum'] = calcChecksum
@@ -199,8 +208,7 @@
 
         #encode however many bytes we have as usual
         if remainder_size > 0:
-            while len(lastbit) < 4:
-                lastbit = lastbit + b'\000'
+            lastbit += (4-len(lastbit))*('\0' if doOrd else b'\000')
             b1 = lastbit[0]
             b2 = lastbit[1]
             b3 = lastbit[2]
--- a/src/reportlab/lib/testutils.py	Fri Nov 29 13:21:17 2013 +0000
+++ b/src/reportlab/lib/testutils.py	Fri Nov 29 15:57:46 2013 +0000
@@ -1,5 +1,8 @@
 #Copyright ReportLab Europe Ltd. 2000-2012
 #see license.txt for license details
+import __main__
+__main__._rl_testing=True
+del __main__
 __version__='''$Id$'''
 __doc__="""Provides support for the test suite.
 
--- a/tests/test_rl_accel.py	Fri Nov 29 13:21:17 2013 +0000
+++ b/tests/test_rl_accel.py	Fri Nov 29 15:57:46 2013 +0000
@@ -4,6 +4,8 @@
 setOutDir(__name__)
 
 import unittest
+def getFuncs(name):
+    return (_c_funcs.get(name,None),'c'),(_py_funcs.get(name,None),'py')
 
 def getrc(defns,depth=1):
     from sys import getrefcount, _getframe
@@ -36,33 +38,32 @@
     def testFpStr(self):
         # should give siz decimal places if less than 1.
         # if more, give up to seven sig figs
-        from _rl_accel import fp_str
-        assert fp_str(1,2,3)=='1 2 3'
-        assert fp_str(1) == '1'
-
-        assert fp_str(595.275574) == '595.2756'
-        assert fp_str(59.5275574) == '59.52756'
-        assert fp_str(5.95275574) == '5.952756'
+        for func, kind in getFuncs('fp_str'):
+            assert func(1,2,3)=='1 2 3', "%s fp_str(1,2,3)=='1 2 3' fails with value %s!" % (kind,ascii(func(1,2,3)))
+            assert func(1) == '1', "%s fp_str(1) == '1' fails with value %s!" % (kind,ascii(func(1)))
+            assert func(595.275574) == '595.2756', "%s fp_str(595.275574) == '595.2756' fails with value %s!" % (kind,ascii(func(595.25574)))
+            assert func(59.5275574) == '59.52756', "%s fp_str(59.5275574) == '59.52756' fails with value %s!" % (kind,ascii(func(59.525574)))
+            assert func(5.95275574) == '5.952756', "%s fp_str(5.95275574) == '5.952756' fails with value %s!" % (kind,ascii(func(5.9525574)))
 
-    def test_AsciiBase85Encode(self):
-        from _rl_accel import _AsciiBase85Encode
-        assert _AsciiBase85Encode('Dragan Andric')=='6ul^K@;[2RDIdd%@f~>'
+    def testAsciiBase85Encode(self):
+        for func, kind in getFuncs('asciiBase85Encode'):
+            assert func('Dragan Andric')=='6ul^K@;[2RDIdd%@f~>',"%s asciiBase85Encode('Dragan Andric')=='6ul^K@;[2RDIdd%@f~>' fails with value %s!" % (
+                    kind,ascii(func('Dragan Andric')))
 
-    def test_AsciiBase85Decode(self):
-        from _rl_accel import _AsciiBase85Decode
-        assert _AsciiBase85Decode('6ul^K@;[2RDIdd%@f~>')=='Dragan Andric'
+    def testAsciiBase85Decode(self):
+        for func, kind in getFuncs('asciiBase85Decode'):
+            assert func('6ul^K@;[2RDIdd%@f~>')=='Dragan Andric',"%s asciiBase85Decode('6ul^K@;[2RDIdd%@f~>')=='Dragan Andric' fails with value %s!" % (
+                    kind,ascii(func('Dragan Andric')))
 
     def testEscapePDF(self):
-        from _rl_accel import escapePDF
-        assert escapePDF('(test)')=='\\(test\\)'
-
-    def test_instanceEscapePDF(self):
-        from _rl_accel import _instanceEscapePDF
-        assert _instanceEscapePDF('', '(test)')=='\\(test\\)'
+        for func, kind in getFuncs('escapePDF'):
+            assert func('(test)')=='\\(test\\)',"%s escapePDF('(test)')=='\\\\(test\\\\)' fails with value %s!" % (
+                    kind,ascii(func('(test)')))
 
     def testCalcChecksum(self):
-        from _rl_accel import calcChecksum
-        assert calcChecksum('test')==1952805748
+        for func, kind in getFuncs('calcChecksum'):
+            assert func('test')==1952805748, "%s calcChecksum('test')==1952805748 fails with value %s!" % (
+                    kind,ascii(func(rawBytes('test'))))
 
     def test_instanceStringWidth(self):
         from reportlab.pdfbase.pdfmetrics import registerFont, getFont, _fonts, unicode2T1
@@ -71,50 +72,52 @@
         t1fn = 'Times-Roman'
         registerFont(TTFont(ttfn, "Vera.ttf"))
         ttf = getFont(ttfn)
+        ttfFuncs = getFuncs('instanceStringWidthTTF')
         t1f = getFont(t1fn)
-        testCp1252 = 'copyright %s trademark %s registered %s ReportLab! Ol%s!' % (chr(169), chr(153),chr(174), chr(0xe9))
+        t1Funcs = getFuncs('instanceStringWidthT1')
+        testCp1252 = b'copyright \xa9 trademark \x99 registered \xae ReportLab! Ol\xe9!'
         enc='cp1252'
         senc = 'utf8'
-        ts = 'ABCDEF\xce\x91\xce\xb2G'
-        utext = 'ABCDEF\xce\x91\xce\xb2G'.decode(senc)
+        ts = b'ABCDEF\xce\x91\xce\xb2G'
+        utext = b'ABCDEF\xce\x91\xce\xb2G'.decode(senc)
         fontSize = 12
         defns="ttfn t1fn ttf t1f testCp1252 enc senc ts utext fontSize ttf.face ttf.face.charWidths ttf.face.defaultWidth t1f.widths t1f.encName t1f.substitutionFonts _fonts"
         rcv = getrc(defns)
-        def tfunc(f,ts,fontSize,enc):
+        def tfunc(f,ts,fontSize,enc,funcs):
             w1 = f.stringWidth(ts,fontSize,enc)
-            w2 = f._py_stringWidth(ts,fontSize,enc)
+            w2 = funcs[1][0](f,ts,fontSize,enc)
             assert abs(w1-w2)<1e-10,"f(%r).stringWidthU(%r,%s,%r)-->%r != f._py_stringWidth(...)-->%r" % (f,ts,fontSize,enc,w1,w2)
-        tfunc(t1f,testCp1252,fontSize,enc)
-        tfunc(t1f,ts,fontSize,senc)
-        tfunc(t1f,utext,fontSize,senc)
-        tfunc(ttf,ts,fontSize,senc)
-        tfunc(ttf,testCp1252,fontSize,enc)
-        tfunc(ttf,utext,fontSize,senc)
+        tfunc(t1f,testCp1252,fontSize,enc,t1Funcs)
+        tfunc(t1f,ts,fontSize,senc,t1Funcs)
+        tfunc(t1f,utext,fontSize,senc,t1Funcs)
+        tfunc(ttf,ts,fontSize,senc,ttfFuncs)
+        tfunc(ttf,testCp1252,fontSize,enc,ttfFuncs)
+        tfunc(ttf,utext,fontSize,senc,ttfFuncs)
         rcc = checkrc(defns,rcv)
         assert not rcc, "rc diffs (%s)" % rcc
 
     def test_unicode2T1(self):
-        from reportlab.pdfbase.pdfmetrics import _py_unicode2T1, getFont, _fonts
-        from _rl_accel import unicode2T1
+        from reportlab.pdfbase.pdfmetrics import getFont, _fonts
         t1fn = 'Times-Roman'
         t1f = getFont(t1fn)
         enc = 'cp1252'
         senc = 'utf8'
-        testCp1252 = ('copyright %s trademark %s registered %s ReportLab! Ol%s!' % (chr(169), chr(153),chr(174), chr(0xe9))).decode(enc)
-        utext = 'This is the end of the \xce\x91\xce\xb2 world. This is the end of the \xce\x91\xce\xb2 world jap=\xe3\x83\x9b\xe3\x83\x86. This is the end of the \xce\x91\xce\xb2 world. This is the end of the \xce\x91\xce\xb2 world jap=\xe3\x83\x9b\xe3\x83\x86'.decode('utf8')
-        def tfunc(f,ts):
-            w1 = unicode2T1(ts,[f]+f.substitutionFonts)
-            w2 = _py_unicode2T1(ts,[f]+f.substitutionFonts)
-            assert w1==w2,"%r != %r" % (w1,w2)
+        testCp1252 = b'copyright \xa9 trademark \x99 registered \xae ReportLab! Ol\xe9!'.decode(enc)
+        utext = b'This is the end of the \xce\x91\xce\xb2 world. This is the end of the \xce\x91\xce\xb2 world jap=\xe3\x83\x9b\xe3\x83\x86. This is the end of the \xce\x91\xce\xb2 world. This is the end of the \xce\x91\xce\xb2 world jap=\xe3\x83\x9b\xe3\x83\x86'.decode('utf8')
+        FUNCS = getFuncs('unicode2T1')
+        def tfunc(f,ts,func,kind):
+            w1 = func(ts,[f]+f.substitutionFonts)
+            w2 = FUNCS[1][0](ts,[f]+f.substitutionFonts)
+            assert w1==w2,"%s unicode2T1 %r != %r" % (kind,w1,w2)
         defns="t1fn t1f testCp1252 enc senc utext t1f.widths t1f.encName t1f.substitutionFonts _fonts"
-        rcv = getrc(defns)
-        tfunc(t1f,testCp1252)
-        tfunc(t1f,utext)
-        rcc = checkrc(defns,rcv)
-        assert not rcc, "rc diffs (%s)" % rcc
+        for func,kind in FUNCS:
+            rcv = getrc(defns)
+            tfunc(t1f,testCp1252,func,kind)
+            tfunc(t1f,utext,func,kind)
+            rcc = checkrc(defns,rcv)
+            assert not rcc, "%s rc diffs (%s)" % rcc
 
     def test_sameFrag(self):
-        from _rl_accel import _sameFrag
         class ABag:
             def __init__(self,**kwd):
                 self.__dict__.update(kwd)
@@ -123,29 +126,34 @@
                 V.sort()
                 return 'ABag(%s)' % ','.join(V)
 
-        a=ABag(fontName='Helvetica',fontSize=12, textColor="red", rise=0, underline=0, strike=0, link="aaaa")
-        b=ABag(fontName='Helvetica',fontSize=12, textColor="red", rise=0, underline=0, strike=0, link="aaaa")
-        for name in ("fontName", "fontSize", "textColor", "rise", "underline", "strike", "link"):
-            old = getattr(a,name)
-            assert _sameFrag(a,b)==1, "_sameFrag(%s,%s)!=1" % (a,b)
-            assert _sameFrag(b,a)==1, "_sameFrag(%s,%s)!=1" % (b,a)
-            setattr(a,name,None)
-            assert _sameFrag(a,b)==0, "_sameFrag(%s,%s)!=0" % (a,b)
-            assert _sameFrag(b,a)==0, "_sameFrag(%s,%s)!=0" % (b,a)
-            delattr(a,name)
-            assert _sameFrag(a,b)==0, "_sameFrag(%s,%s)!=0" % (a,b)
-            assert _sameFrag(b,a)==0, "_sameFrag(%s,%s)!=0" % (b,a)
-            delattr(b,name)
-            assert _sameFrag(a,b)==1, "_sameFrag(%s,%s)!=1" % (a,b)
-            assert _sameFrag(b,a)==1, "_sameFrag(%s,%s)!=1" % (b,a)
-            setattr(a,name,old)
-            setattr(b,name,old)
+        for func,kind in getFuncs('sameFrag'):
+            if not func: continue
+            a=ABag(fontName='Helvetica',fontSize=12, textColor="red", rise=0, underline=0, strike=0, link="aaaa")
+            b=ABag(fontName='Helvetica',fontSize=12, textColor="red", rise=0, underline=0, strike=0, link="aaaa")
+            for name in ("fontName", "fontSize", "textColor", "rise", "underline", "strike", "link"):
+                old = getattr(a,name)
+                assert func(a,b)==1, "%s sameFrag(%s,%s)!=1" % (kind,a,b)
+                assert func(b,a)==1, "%s sameFrag(%s,%s)!=1" % (kind,b,a)
+                setattr(a,name,None)
+                assert func(a,b)==0, "%s sameFrag(%s,%s)!=0" % (kind,a,b)
+                assert func(b,a)==0, "%s sameFrag(%s,%s)!=0" % (kind,b,a)
+                delattr(a,name)
+                assert func(a,b)==0, "%s sameFrag(%s,%s)!=0" % (kind,a,b)
+                assert func(b,a)==0, "%s sameFrag(%s,%s)!=0" % (kind,b,a)
+                delattr(b,name)
+                assert func(a,b)==1, "%s sameFrag(%s,%s)!=1" % (kind,a,b)
+                assert func(b,a)==1, "%s sameFrag(%s,%s)!=1" % (kind,b,a)
+                setattr(a,name,old)
+                setattr(b,name,old)
 
 def makeSuite():
     # only run the tests if _rl_accel is present
     try:
-        import _rl_accel
+        from reportlab.lib import _rl_accel, rl_accel
         Klass = RlAccelTestCase
+        global _py_funcs, _c_funcs
+        _c_funcs=rl_accel._c_funcs
+        _py_funcs=rl_accel._py_funcs
     except:
         class Klass(unittest.TestCase):
             pass