You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ro.py 2.0KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. ##############################################################################
  2. #
  3. # Copyright (c) 2003 Zope Foundation and Contributors.
  4. # All Rights Reserved.
  5. #
  6. # This software is subject to the provisions of the Zope Public License,
  7. # Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
  8. # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
  9. # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  10. # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
  11. # FOR A PARTICULAR PURPOSE.
  12. #
  13. ##############################################################################
  14. """Compute a resolution order for an object and its bases
  15. """
  16. __docformat__ = 'restructuredtext'
  17. def _mergeOrderings(orderings):
  18. """Merge multiple orderings so that within-ordering order is preserved
  19. Orderings are constrained in such a way that if an object appears
  20. in two or more orderings, then the suffix that begins with the
  21. object must be in both orderings.
  22. For example:
  23. >>> _mergeOrderings([
  24. ... ['x', 'y', 'z'],
  25. ... ['q', 'z'],
  26. ... [1, 3, 5],
  27. ... ['z']
  28. ... ])
  29. ['x', 'y', 'q', 1, 3, 5, 'z']
  30. """
  31. seen = {}
  32. result = []
  33. for ordering in reversed(orderings):
  34. for o in reversed(ordering):
  35. if o not in seen:
  36. seen[o] = 1
  37. result.insert(0, o)
  38. return result
  39. def _flatten(ob):
  40. result = [ob]
  41. i = 0
  42. for ob in iter(result):
  43. i += 1
  44. # The recursive calls can be avoided by inserting the base classes
  45. # into the dynamically growing list directly after the currently
  46. # considered object; the iterator makes sure this will keep working
  47. # in the future, since it cannot rely on the length of the list
  48. # by definition.
  49. result[i:i] = ob.__bases__
  50. return result
  51. def ro(object):
  52. """Compute a "resolution order" for an object
  53. """
  54. return _mergeOrderings([_flatten(object)])