[reportlab-users] PageTemplate unexpectedly copies Frames from earlier PageTemplates
Nate Silva
nate at desi.com
Mon Nov 30 20:55:02 EST 2009
(Hey, another Portlander!)
Wow, that is subtle. I hope the ReportLab maintainers will fix it. In the meantime, knowing what I know now... I think I can work around it.
Regards,
Nate
On Nov 30, 2009, at 4:59 PM, Tim Roberts wrote:
> 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.
>
> _______________________________________________
> reportlab-users mailing list
> reportlab-users at lists2.reportlab.com
> http://two.pairlist.net/mailman/listinfo/reportlab-users
More information about the reportlab-users
mailing list