[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
>regression.
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.
>Cheers,
>--Grant
>
>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
>changed!"
> print "Changing selectedDate ..."
> container.selectedDate += timedelta(days=1)
> assert container.calendar is calendar, "container.calendar
>changed!"
More information about the PEAK
mailing list