[PEAK] interpreting CircularityError
Phillip J. Eby
pje at telecommunity.com
Tue Oct 21 20:39:04 EDT 2008
At 02:16 AM 10/22/2008 +0300, Sergey Schetinin wrote:
>If I understand correctly, when CircularityError is raised it's
>supposed that routes parameter describes the circularity in question.
>It's a dict that maps cells that need to run to sets of dependent
>cells. So the circularity means there should be a cycle in there, i.e.
>no possible order to calculate the tree running each cell rule no more
>than once. I can't see it this error I get:
>
>{LazyCell(<bound method AutoSize.y of AutoSize(376, 178)>, 178):
> set([LazyCell(<function <lambda> at 0x01C162B0>, 158)]),
> LazyCell(<function <lambda> at 0x01C162B0>, 158):
> set([LazyCell(<bound method OffsetPoint.y of OffsetPoint(384,
> 194)>, 194)]),
> LazyCell(<bound method OffsetPoint.y of OffsetPoint(384, 194)>, 194):
> set([Cell(<bound method OptionalPanel.track_rect of
><gui5.models.OptionalPanel object at 0x00E00830>>, None),
> LazyCell(<bound method AutoSize.y of AutoSize(376, 20)>, 20)]),
> LazyCell(<bound method AutoSize.y of AutoSize(376, 20)>, 20):
> set([Cell(<bound method OptionalPanel.track_rect of
><gui5.models.OptionalPanel object at 0x00E00830>>, None)])}
>
>
>This happens in response to resizing the window and it only happens
>once, after first 1px change, after that everything works as intended
>and without a glitch, which suggests it's a fluke of finding the
>proper order for running the rules. I'll also try to create a smaller
>test to reproduce it, so for now I'm just seeking assistance with
>.routes interpretation.
Hm. It appears it's possible for the cycle detection to be
over-enthusiastic. It declares a cycle if any retried rule triggers
the recalc of any other retried rule. It does not actually verify
that the rule triggers *itself*.
So, the raising of a circularity error should be replaced with a
check for an actual cycle, probably by calling a check_circularity
function, e.g.:
def check_circularity(item, routes, start=None, seen=None):
if seen is None: seen = {}
if start is None: start = item
for via in routes.get(item, ()):
if via is start:
raise CircularityError(routes, start)
elif via not in seen:
seen[via] = 1
check_circularity(via, routes, start, seen)
More information about the PEAK
mailing list