[reportlab-users] PageTemplate unexpectedly copies Frames from earlier PageTemplates
    Tim Roberts 
    timr at probo.com
       
    Mon Nov 30 19:59:55 EST 2009
    
    
  
Nate Silva wrote:
> I've been pulling my hair out and finally boiled it down to the following snippet. Is this a bug?
>   
My goodness!  It's the famous default parameter closure bug, but it's
uncommon to find this in code actually released in the wild.
class PageTemplate:
    """
    essentially a list of Frames and an onPage routine to call at the start
    of a page when this is selected. onPageEnd gets called at the end.
    derived classes can also implement beforeDrawPage and afterDrawPage
if they
    """
    def __init__(self,id=None,frames=[],onPage=_doNothing,
onPageEnd=_doNothing,
                 pagesize=None):
        if type(frames) not in (ListType,TupleType): frames = [frames]
        assert filter(lambda x: not isinstance(x,Frame), frames)==[],
"frames argument error")
        self.id = id
        self.frames = frames
        self.onPage = onPage
The problem here is that all of the instances of PageTemplate share the
same instance of [] in the default "frames" parameter.  So, all of the
self.frames values are bound to the same object.  It starts out being a
null list, but later, when any instance modifies the list in place, it
modifies ALL instances.
Probably this should be something like:
    def __init__(self,id=None,frames=None,...):
        if frames is None: frames = [:]
Or, equally good:
        self.frames = frames[:]
-- 
Tim Roberts, timr at probo.com
Providenza & Boekelheide, Inc.
    
    
More information about the reportlab-users
mailing list