[reportlab-users] platypus.paragraph not thread safe

Gerhard Kalab kalab at rosinak.at
Mon Jun 12 01:14:37 EDT 2006


I'm using reportlab within Zope 2 with the product RMLPageTemplate.

If paragraph.py is used from more then one thread the state of the 
global ParaParser is IMHO not guaranteed.

Applies to reportlab 1.20, 1.21, 2.0.

a little test program:
#-------------------------------
from reportlab.platypus.paragraph import Paragraph
from reportlab.lib.styles import ParagraphStyle

import threading

threadNo = 1
f = open("exception.txt", "w")

class MyThread(threading.Thread):

  def run(self):
      try:
          global threadNo
          print "running thread no %s" % threadNo
          a = Paragraph("text1", ParagraphStyle("mystyle"))
          print a
          threadNo = threadNo + 1
      except Exception, e:
          global f
          f.write("exception thrown\n")
          f.write("%s\n" % repr(e))
          f.write("%s\n" % str(e))
    for x in xrange(2000):
  MyThread().start()
#-------------------------------

The program writes the thrown exceptions to a file.

diff for reportlab 1.20:

Index: paragraph.py
===================================================================
--- paragraph.py    (revision ???)
+++ paragraph.py    (working copy)
@@ -38,7 +38,8 @@

#our one and only parser
# XXXXX if the parser has any internal state using only one is probably 
a BAD idea!
-_parser=ParaParser()
+# kalab: not thread safe - removed
+#_parser=ParaParser()

def _lineClean(L):
    return join(filter(truth,split(strip(L))))
@@ -397,6 +398,7 @@
    def _setup(self, text, style, bulletText, frags, cleaner):
        if frags is None:
            text = cleaner(text)
+            _parser=ParaParser()
            _parser.caseSensitive = self.caseSensitive
            style, frags, bulletTextFrags = _parser.parse(text,style)
            if frags is None:


Gerhard Kalab


More information about the reportlab-users mailing list