[Checkins] SVN: zope.configuration/branches/chrism-dictactions/src/zope/configuration/config.py resolved actions must be ordered via (order, i) to capture the intent
Chris McDonough
chrism at plope.com
Sun Dec 4 20:05:08 UTC 2011
Log message for revision 123571:
resolved actions must be ordered via (order, i) to capture the intent
Changed:
U zope.configuration/branches/chrism-dictactions/src/zope/configuration/config.py
-=-
Modified: zope.configuration/branches/chrism-dictactions/src/zope/configuration/config.py
===================================================================
--- zope.configuration/branches/chrism-dictactions/src/zope/configuration/config.py 2011-12-04 18:45:10 UTC (rev 123570)
+++ zope.configuration/branches/chrism-dictactions/src/zope/configuration/config.py 2011-12-04 20:05:08 UTC (rev 123571)
@@ -1627,44 +1627,65 @@
if not isinstance(action, dict):
# old-style tuple action
action = expand_action(*action)
+
+ # "order" is an integer grouping. Actions in a lower order will be
+ # executed before actions in a higher order. Within an order,
+ # actions are executed sequentially based on original action ordering
+ # ("i").
order = action['order'] or i
discriminator = action['discriminator']
+
+ # "ainfo" is a tuple of (order, i, action) where "order" is a
+ # user-supplied grouping, "i" is an integer expressing the relative
+ # position of this action in the action list being resolved, and
+ # "action" is an action dictionary. The purpose of an ainfo is to
+ # associate an "order" and an "i" with a particular action; "order"
+ # and "i" exist for sorting purposes after conflict resolution.
+ ainfo = (order, i, action)
+
if discriminator is None:
- # The discriminator is None, so this action can never
- # conflict. We can add it directly to the result.
- output.append((order, action))
+ # The discriminator is None, so this action can never conflict.
+ # We can add it directly to the result.
+ output.append(ainfo)
continue
L = unique.setdefault(discriminator, [])
- L.append((order, action))
+ L.append(ainfo)
# Check for conflicts
conflicts = {}
- for discriminator, dups in unique.items():
- # We need to sort the actions by the paths so that the shortest
- # path with a given prefix comes first:
- def bypath(tup):
- return tup[1]['includepath'], tup[0]
- dups.sort(key=bypath)
- order, first = dups[0]
- output.append(dups[0])
- basepath, baseinfo, discriminator = (first['includepath'],
- first['info'],
- first['discriminator'])
- for order, dup in dups[1:]:
- includepath = dup['includepath']
+ for discriminator, ainfos in unique.items():
+
+ # We use (includepath, order, i) as a sort key because we need to
+ # sort the actions by the paths so that the shortest path with a
+ # given prefix comes first. The "first" action is the one with the
+ # shortest include path. We break sorting ties using "order", then
+ # "i".
+ def bypath(ainfo):
+ return ainfo[2]['includepath'], ainfo[0], ainfo[1]
+
+ ainfos.sort(key=bypath)
+ ainfo, rest = ainfos[0], ainfos[1:]
+ output.append(ainfo)
+ _, _, action = ainfo
+ basepath, baseinfo, discriminator = (action['includepath'],
+ action['info'],
+ action['discriminator'])
+
+ for _, _, action in rest:
+ includepath = action['includepath']
# Test whether path is a prefix of opath
if (includepath[:len(basepath)] != basepath # not a prefix
or includepath == basepath):
L = conflicts.setdefault(discriminator, [baseinfo])
- L.append(dup['info'])
+ L.append(action['info'])
if conflicts:
raise ConfigurationConflictError(conflicts)
- output.sort(key=operator.itemgetter(0))
- return [ x[1] for x in output ]
+ # sort conflict-resolved actions by (order, i) and return them
+ return [ x[2] for x in sorted(output, key=operator.itemgetter(0, 1))]
class ConfigurationConflictError(ConfigurationError):
More information about the checkins
mailing list