utils.py 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. from __future__ import absolute_import, division, unicode_literals
  2. from types import ModuleType
  3. try:
  4. import xml.etree.cElementTree as default_etree
  5. except ImportError:
  6. import xml.etree.ElementTree as default_etree
  7. __all__ = ["default_etree", "MethodDispatcher", "isSurrogatePair",
  8. "surrogatePairToCodepoint", "moduleFactoryFactory"]
  9. class MethodDispatcher(dict):
  10. """Dict with 2 special properties:
  11. On initiation, keys that are lists, sets or tuples are converted to
  12. multiple keys so accessing any one of the items in the original
  13. list-like object returns the matching value
  14. md = MethodDispatcher({("foo", "bar"):"baz"})
  15. md["foo"] == "baz"
  16. A default value which can be set through the default attribute.
  17. """
  18. def __init__(self, items=()):
  19. # Using _dictEntries instead of directly assigning to self is about
  20. # twice as fast. Please do careful performance testing before changing
  21. # anything here.
  22. _dictEntries = []
  23. for name, value in items:
  24. if type(name) in (list, tuple, frozenset, set):
  25. for item in name:
  26. _dictEntries.append((item, value))
  27. else:
  28. _dictEntries.append((name, value))
  29. dict.__init__(self, _dictEntries)
  30. self.default = None
  31. def __getitem__(self, key):
  32. return dict.get(self, key, self.default)
  33. # Some utility functions to dal with weirdness around UCS2 vs UCS4
  34. # python builds
  35. def isSurrogatePair(data):
  36. return (len(data) == 2 and
  37. ord(data[0]) >= 0xD800 and ord(data[0]) <= 0xDBFF and
  38. ord(data[1]) >= 0xDC00 and ord(data[1]) <= 0xDFFF)
  39. def surrogatePairToCodepoint(data):
  40. char_val = (0x10000 + (ord(data[0]) - 0xD800) * 0x400 +
  41. (ord(data[1]) - 0xDC00))
  42. return char_val
  43. # Module Factory Factory (no, this isn't Java, I know)
  44. # Here to stop this being duplicated all over the place.
  45. def moduleFactoryFactory(factory):
  46. moduleCache = {}
  47. def moduleFactory(baseModule, *args, **kwargs):
  48. if isinstance(ModuleType.__name__, type("")):
  49. name = "_%s_factory" % baseModule.__name__
  50. else:
  51. name = b"_%s_factory" % baseModule.__name__
  52. if name in moduleCache:
  53. return moduleCache[name]
  54. else:
  55. mod = ModuleType(name)
  56. objs = factory(baseModule, *args, **kwargs)
  57. mod.__dict__.update(objs)
  58. moduleCache[name] = mod
  59. return mod
  60. return moduleFactory