one of my apps builds a PDF with a slightly dynamic layout. One part uses an
ImageAndFlowables, where the size of the image as well as the flowables are
controlled by the end user.
At some point it started to crash with a "strange" traceback, and I spent a
few hours trying to understand the reason, until I found it and distilled the
little script I'm attaching below.
The problem happens when the flowables include a List *and* the image is big
enough to "include" the List (sorry, I find it difficult to explain better
than that): in other words, if the image is "little" so that on its right
there are only Paragraphs it works, but as soon its height is enough to
"reach" the List, it breaks.
The following script demonstrates the issue: it builds two documents, one with
a tiny image, the second with a slightly bigger one, that gives this
traceback (slightly edited to reduce overly long lines):
$ python test_image.py
Created sample1.pdf
Traceback (most recent call last):
File "test_image.py", line 39, in <module>
doc.build([ImageAndFlowables(Image('pythonpowered.gif', 30, 30), elts, imageSide='left')])
File ".../python3.6/site-packages/reportlab/platypus/doctemplate.py", line 1213, in build
BaseDocTemplate.build(self,flowables, canvasmaker=canvasmaker)
File ".../python3.6/site-packages/reportlab/platypus/doctemplate.py", line 969, in build
self.handle_flowable(flowables)
File ".../python3.6/site-packages/reportlab/platypus/doctemplate.py", line 834, in handle_flowable
if frame.add(f, canv, trySplit=self.allowSplitting):
File ".../python3.6/site-packages/reportlab/platypus/frames.py", line 167, in _add
w, h = flowable.wrap(aW, h)
File ".../python3.6/site-packages/reportlab/platypus/flowables.py", line 1244, in wrap
W,H0,self._C0,self._C1 = self._findSplit(canv,iW,aH)
File ".../python3.6/site-packages/reportlab/platypus/flowables.py", line 1336, in _findSplit
S = cdeepcopy(f).splitOn(canv,availWidth,aH)
File ".../python3.6/site-packages/reportlab/platypus/flowables.py", line 881, in cdeepcopy
return deepcopy(obj)
File "/usr/lib/python3.6/copy.py", line 180, in deepcopy
y = _reconstruct(x, memo, *rv)
File "/usr/lib/python3.6/copy.py", line 280, in _reconstruct
state = deepcopy(state, memo)
File "/usr/lib/python3.6/copy.py", line 150, in deepcopy
y = copier(x, memo)
File "/usr/lib/python3.6/copy.py", line 240, in _deepcopy_dict
y[deepcopy(key, memo)] = deepcopy(value, memo)
File "/usr/lib/python3.6/copy.py", line 150, in deepcopy
y = copier(x, memo)
File "/usr/lib/python3.6/copy.py", line 215, in _deepcopy_list
append(deepcopy(a, memo))
File "/usr/lib/python3.6/copy.py", line 180, in deepcopy
y = _reconstruct(x, memo, *rv)
File "/usr/lib/python3.6/copy.py", line 281, in _reconstruct
if hasattr(y, '__setstate__'):
File ".../python3.6/site-packages/reportlab/platypus/flowables.py", line 1561, in __getattr__
return getattr(self._flowable,a)
File ".../python3.6/site-packages/reportlab/platypus/flowables.py", line 1557, in __getattr__
return self.__dict__[a]
KeyError: '_flowable'
This is the sample script:
from reportlab.lib.pagesizes import A4
from reportlab.platypus import ListFlowable, ListItem, Paragraph
from reportlab.platypus import ImageAndFlowables, SimpleDocTemplate, Image
from reportlab.lib.styles import getSampleStyleSheet
styles = getSampleStyleSheet()
doc = SimpleDocTemplate("sample1.pdf", pagesize=A4,
rightMargin=72, leftMargin=72,
topMargin=72, bottomMargin=18)
elts = [Paragraph("a adfj kjh kj hkjh k", styles['Normal']),
Paragraph("a adfj kjh kj hkjh k", styles['Normal']),
ListFlowable([
ListItem(Paragraph("a", styles['Normal'])),
ListItem(Paragraph("b", styles['Normal'])),
ListItem(Paragraph("c", styles['Normal'])),
ListItem(Paragraph("d", styles['Normal'])),
ListItem(Paragraph("e", styles['Normal'])),
], style=styles['ul'])]
doc.build([ImageAndFlowables(Image('pythonpowered.gif', 20, 20), elts, imageSide='left')])
print("Created sample1.pdf")
doc = SimpleDocTemplate("sample2.pdf", pagesize=A4,
rightMargin=72, leftMargin=72,
topMargin=72, bottomMargin=18)
elts = [Paragraph("a adfj kjh kj hkjh k", styles['Normal']),
Paragraph("a adfj kjh kj hkjh k", styles['Normal']),
ListFlowable([
ListItem(Paragraph("a", styles['Normal'])),
ListItem(Paragraph("b", styles['Normal'])),
ListItem(Paragraph("c", styles['Normal'])),
ListItem(Paragraph("d", styles['Normal'])),
ListItem(Paragraph("e", styles['Normal'])),
], style=styles['ul'])]
doc.build([ImageAndFlowables(Image('pythonpowered.gif', 30, 30), elts, imageSide='left')])
print("Created sample2.pdf")
Am I abusing the ImageAndFlowables here?
Thanks in advance for any hint,
ciao, lele.
--
nickname: Lele Gaifax | Quando vivrò di quello che ho pensato ieri
real: Emanuele Gaifas | comincerò ad aver paura di chi mi copia.
le...@metapensiero.it | -- Fortunato Depero, 1929.
_______________________________________________
reportlab-users mailing list
reportl...@lists2.reportlab.com
https://pairlist2.pair.net/mailman/listinfo/reportlab-users
> Hi Lele,
>
> thanks for the report. Unfortunately I have been ill last couple of weeks so
> have not had time to look at this.
Thank you Robin, and all the best for that!
> I don't think you are abusing ImageAndFlowables.
>
> List objects were introduced after ImageAndFlowables and I suspect the
> problem is in the list splitting not working properly for this case.
>
> I will take a look as time permits.
Great, there's no hurry since that is a completely new feature I introduced in
the last weeks and nobody is seriously using it yet ;-)
bye, lele.
--
nickname: Lele Gaifax | Quando vivrò di quello che ho pensato ieri
real: Emanuele Gaifas | comincerò ad aver paura di chi mi copia.
le...@metapensiero.it | -- Fortunato Depero, 1929.
_______________________________________________
> I just tried this with latest RL and it works for me. If you are just using
> pip install reportlab then I guess the version that's in python pypi is out
> of date. You can always try the packages from here
>
> https://www.reportlab.com/pypi
>
> where we put out the latest micro releases etc etc. You need a login id, but
> that's all.
Ok, will try that version and report back, thank you.
But, given that this particular app will be deployed with Docker, and that I
like to avoid hardwiring login credentials in the Dockerfile(s), do you have
any approximate idea on if/when a new release on PyPI will happen?
Have a good day,
ciao, lele.
--
nickname: Lele Gaifax | Quando vivrò di quello che ho pensato ieri
real: Emanuele Gaifas | comincerò ad aver paura di chi mi copia.
le...@metapensiero.it | -- Fortunato Depero, 1929.
_______________________________________________