[PEAK] Re: A regression?

Phillip J. Eby pje at telecommunity.com
Thu Jul 19 23:35:11 EDT 2007

At 07:25 PM 7/19/2007 -0700, Grant Baillie wrote:
>I'm about to pack up for the day, but the code below fails after your
>recent checkin (r2359), but succeeds before. Unless I'm
>misunderstanding rules with no cell dependencies, that seems like a

Yep, sort of.  Basically, the problem is that to fix the other 
problem, I changed the meaning of the first setting of a cell, so 
that it takes effect immediately, rather than waiting till the next 
pulse.  However, the reason your code below was working before, was 
because it created a new calendar, then discarded it, allowing it to 
be overwritten by the keyword argument assignment.

I've fixed this in SVN, so that all the old stuff works.  However, it 
seems to me that all of these problems today are due to a lack of 
clarity around cell initialization from component constructor 
keywords.  I'm going to have to revisit all that, because in your 
example below, it seems you shouldn't have to set values() for 
calendar, unless you plan to be able to change the calendar.

Part of the problem is that basically the high level API is guessing 
from a bunch of different things, what a cell's construction 
arguments should be.  It does this in order to minimize the number of 
decorator functions you have to know about, but I suspect I may need 
to revisit that idea, and see if there is a better way to spell the 
API.  In the meantime, the current API works...  more or less.  One 
quirk is that in code like the below, the initializing rule will 
always run...  and its value will then be overwritten by the keyword 
argument.  This isn't good for rules that have side effects, although 
it's not necessarily a big deal.

I think probably what I need to do is arrange things so that 
assigning to a non-existent cell can influence its constructor.  If 
the cell that would be constructed would be a read-only rule cell, 
there's no need for it to run its rule just to get the value 
overwritten.  OTOH, this actually can be worked around now by passing 
e.g. 'Container(calendar=trellis.Constant(calendar))' -- which stops 
the rule from being run.

Hm.  Maybe what I should do is do that if a cell would be read-only 
otherwise, make it a constant if you set it in a keyword 
argument.  Thus, you could omit the 'values()' for 'calendar', below, 
and everything would work as you intended.  It shouldn't be necessary 
to set values() just to enable using something as a keyword argument.

Okay, now I've checked that into SVN, too.  :)  I may have to spend 
some more time in the future on whether the decorator API + 
Component.__init__ is really as well-specified as it should be.  I 
think there is still one corner case that should be elaborated on.

The good news is that all of the bugs today are coming from the same 
place: cell and component initialization inside of other rules.  This 
particular usage pattern is barely tested in the doctests at the 
moment; in fact, I think the tests added today were the first.  It 
will probably be good to add more at some point.

>import peak.events.trellis as trellis
>from datetime import *
>class Calendar(trellis.Component):
>     trellis.values(timezone="US/New_York")
>class Container(trellis.Component):
>     trellis.values(
>         calendar = None,
>         selectedDate = None,
>     )
>     trellis.rules(
>         calendar = lambda self: Calendar(),
>         selectedDate = lambda self: date.today(),
>     )
>if __name__ == "__main__":
>     calendar = Calendar()
>     container = Container(calendar=calendar)
>     assert container.calendar is calendar, "container.calendar
>     print "Changing selectedDate ..."
>     container.selectedDate += timedelta(days=1)
>     assert container.calendar is calendar, "container.calendar

More information about the PEAK mailing list