[reportlab-users] Canvas does not work with SpooledTemporaryFile

Robin Becker robin at reportlab.com
Mon Mar 15 05:11:30 EDT 2021

Hi Robert, thanks for the report. Your analysis seems perfectly correct. The spoole temp file will get a name when it 
rolls over. However, unless you keep a handle to it you have no guarantee it exists on disk. I assume you want to write 
it into a temporary location to read it later (perhaps to send it via another channel).

I will opt for a version of your solution 2 ie ensure we have a string on the branche where we have a callable write 
attribute. So that code will now look like

         if hasattr(getattr(filename, "write",None),'__call__'):
             myfile = 0
             f = filename
             filename = getattr(f,'name',None)
             if isinstance(filename,int):
                 filename = '<os fd:%d>'% filename
             elif not isStr(filename): #try to fix bug reported by Robert Schroll <rschroll at gmail.com>
                 filename = '<%s at 0X%8.8X>' % (f.__class__.__name__,id(f))
             filename = makeFileName(filename)

it gives us a bit of extra information should we ever see the filename. However, there's a flaw in that as soon as the 
file gets rolled over (if it ever does) then it will presumably get a name and it won't be the same.

It does fix the immediate bug though.

thanks again

On 15/03/2021 00:54, Robert Schroll wrote:
> Hi all,
> 2. Explicitly cast the name to a string:
>      filename = makeFileName(str(filename))
> This would avoid all such problems, at the risk of producing some
> strange-looking filenames.  But given that the existing code already
> produces such strange-looking filenames for ints, I suspect this is okay.
> Hope this makes sense.  Let me know if you have any questions,
> Robert
> Example code:
> import tempfile
> from reportlab.pdfgen import canvas
> f = tempfile.SpooledTemporaryFile()
> c = canvas.Canvas(f)
> c.save()  # Raises AttributeError

Robin Becker

More information about the reportlab-users mailing list