#12 bug when doc.multibuild is used


(see Harald Armin Massa's posting to the RL mailing list):

on updating some projekt to RL 2.2; and wordaxe 0.3.0, I ran into some
obscure wrapping / splitting bug.

As it turned out:

the SplitRoutine within NewParagraph get's problems when doc.multibuild is used.

I tracked it down to:

if not hasattr(self, "_lines"):
# This can only happen when split has been called
# without a previous wrap for this Paragraph.
# From looking at doctemplate.py and frames.py,
# I assume this is only the case if the free space
# in the frame is not even enough for getSpaceBefore.
# Thus we can safely return []
#~ print "split without previous wrap"
return []

NewParagraph of Wordaxe relying on self._lines NOT being present when
there was no "wrap" in the actual build pass, to return "I cannot


in a multibuild, in the second build pass that self._lines is present
from the first build pass ... , and _unused is an empty list (as some
wraps from the build pass before have used up everything)

So MY fix was in doctemplate multibuild:

#clean up so multi-build does not go wrong - the frame
#packer might have tacked an attribute onto some flowables
for elem in story:
if hasattr(elem, '_postponed'):
del elem._postponed
if hasattr(elem, '_lines'):
del elem._lines

to extend the "cleanup" part to also delete the _lines attribute of a
NewParagraph; together with the _postponed attribut.

So everything works fine ... but I am not sure if this is really the
best approach, and the NewParagraph split/wrap is quite to challenging
to really be sure.

That's why I am posting this fix for others to enjoy and for more
enlightened ones to check:)



  • H. von Bargen

    H. von Bargen - 2008-12-21

    Robin Becker posted on the ReportLab users list that at least in the RL trunk, there's an attribute doc._multiBuildEdits which was made to solve problems like this. I'll have to see if this part of ReportLab 2.3

  • Nobody/Anonymous

    Today RL 2.3 was released. I'll try and build a wordaxe version for RL 2.3 which fixes this bug in the next few days.

  • Christoph Zwerschke

    I stumbled over the same problem today when creating a document with a table of contents (and therefore calling doc.multibuild).

    Harald is right, the problem here is the caching in the _lines attribute. In the second pass, a paragraph may have to be split, but Paragraph.wrap() in wordaxe.rl returns the unsplit paragraph if _lines is set. My workaround was changing Paragraph.wrap() as follows:

    def wrap(self, availW, availH):
    # print id(self), "wrap", availW, availH
    if hasattr(self, "_lines"):
    height = sum([line.height for line in self._lines])
    if height <= availH:
    return availW, height
    style = self.style
    leftIndent = style.leftIndent
    first_line_width = availW - (leftIndent+style.firstLineIndent) - style.rightIndent
    later_widths = availW - leftIndent - style.rightIndent
    max_widths = [first_line_width, later_widths]
    return self.i_wrap(availW, availH, max_widths)

  • Christoph Zwerschke

    My patch in the last comment was insufficient and SF removed the indentation, but SF does not allow me to append a patch here. Therefore I uploaded it as a new patch with ID 2580054 (https://sourceforge.net/tracker2/?func=detail&aid=2580054&group_id=105867&atid=642480).

    This is an alternative to Harald's patch which works as well but is unwieldy because it needs to be applied to RL, not Wordaxe. The new patch is a bit safer because it also catches other unusual ways of calling wrap() and split().

  • H. von Bargen

    H. von Bargen - 2009-02-08

    I just tried another way to get rid of this bug which does not require to patch RL, but requires the new ReportLab 2.3 release.

    Please the SVN repository.

    I did not yet examine your patch, but your comment for the patch looks reasonable.
    Maybe the patches can be unified?

  • Christoph Zwerschke

    Your patch works for me. It's essentially the same as Harald's, but you avoid patching RL.

    If you patch like that, then there is no need for my patch. I still would prefer my patch. It has the advantage that it does not need RL 2.3, and also works when multi builds are done manually, not with the RL mechanism. Also, it reuses the cached _lines attribute if possible, so it has an performance advantage.

    In my patch, instead of storing the corresponding availW, availH parameters for which _lines had been calculated as attributes of the Paragraph, it may be clearer to store them as subattributes of the _lines attribute. Or, _lines could be even made a dictionary with the corresponding (availW, availH) as key. If you want that, I can post a modified patch.

  • H. von Bargen

    H. von Bargen - 2009-02-08

    Now I tried your patch.
    I had to modify it slightly, otherwise it broke a test case I got from Harald:
    In the split method I added one line:
    first.height = self.height
    first._JustifyLast = 1
    + first._availWH = self._availWH
    if style.firstLineIndent != 0:
    style = deepcopy(style)

    But it still breaks the test_platypus_indents.py test script and raises a LayoutError, whereas my patch passes this test (.

    Nevertheless I like the idea of your patch.
    If you can get it to pass the test_platypus-indents.py, I'd be happy to use it.

    According your idea with the _lines attribute:
    Why not call the attribute "_cache", with a subattribute "lines" that stores the dictionary you mentioned?

  • Christoph Zwerschke

    Just tried to run the test suite, but I cannot get it running even with a clean checkout. Something is weird here, for instance, though the package directory is called "test" (without "s"), all the tests inside expect a package named "tests". And "python setup.py tests" gives "invalid command "tests".

  • H. von Bargen

    H. von Bargen - 2009-02-09

    Yes, the test suite is weird. The test/tests problem is due to me being a Subversion noob.
    Just rename the directory and forget about setup.py (I use to use *.pth files instead).

    And yes, the test suite spits out errors (the test_wordlist*.py script because the hyphenation does not work perfectly, 2 other scripts because the ReportLab setup changed (the test/s directory won't be installed anymore, and test_frames3f.py did never work).

    Just try to make test_platypus_indents.py work with your patch.

  • Christoph Zwerschke

    It should be possible to rename the test directory with "svn mv test tests".

    I had some problems running the tests, because there was already a tests module in my path. I suggest improving the runPart to take a pattern as command line argument so that you can run individual tests with the proper setup of sys.path like that:
    sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

    I have now attached an improved patch here: https://sourceforge.net/tracker2/?func=detail&aid=2580054&group_id=105867&atid=642480 It also includes the min_width() patch. Unfortunately, I forgot that my editor removes trailing spaces, so a diff will be long if it does not ignores whitespace while actually I did not change so much.

    test_platypus_indents.py is working with the new test.

  • H. von Bargen

    H. von Bargen - 2009-02-12
    • status: open --> closed-fixed
  • H. von Bargen

    H. von Bargen - 2009-02-12

    The bug is fixed in the trunk.
    cito provided an alternative approach in his patch, but that didn't work for me.
    So I'll mark this bug as fixed, but leave it open for comments.


Log in to post a comment.

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:

JavaScript is required for this form.

No, thanks