strdispatch.py 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. """String dispatch class to match regexps and dispatch commands.
  2. """
  3. # Stdlib imports
  4. import re
  5. # Our own modules
  6. from IPython.core.hooks import CommandChainDispatcher
  7. from typing import Callable
  8. # Code begins
  9. class StrDispatch:
  10. """Dispatch (lookup) a set of strings / regexps for match.
  11. Example:
  12. >>> dis = StrDispatch()
  13. >>> dis.add_s('hei',34, priority = 4)
  14. >>> dis.add_s('hei',123, priority = 2)
  15. >>> dis.add_re('h.i', 686)
  16. >>> print(list(dis.flat_matches('hei')))
  17. [123, 34, 686]
  18. """
  19. def __init__(self):
  20. self.strs = {}
  21. self.regexs = {}
  22. def add_s(self, s: str, obj: Callable, priority: int= 0 ):
  23. """ Adds a target 'string' for dispatching """
  24. chain = self.strs.get(s, CommandChainDispatcher())
  25. chain.add(obj,priority)
  26. self.strs[s] = chain
  27. def add_re(self, regex, obj, priority= 0 ):
  28. """ Adds a target regexp for dispatching """
  29. chain = self.regexs.get(regex, CommandChainDispatcher())
  30. chain.add(obj,priority)
  31. self.regexs[regex] = chain
  32. def dispatch(self, key):
  33. """ Get a seq of Commandchain objects that match key """
  34. if key in self.strs:
  35. yield self.strs[key]
  36. for r, obj in self.regexs.items():
  37. if re.match(r, key):
  38. yield obj
  39. else:
  40. # print("nomatch",key) # dbg
  41. pass
  42. def __repr__(self):
  43. return "<Strdispatch %s, %s>" % (self.strs, self.regexs)
  44. def s_matches(self, key):
  45. if key not in self.strs:
  46. return
  47. for el in self.strs[key]:
  48. yield el[1]
  49. def flat_matches(self, key):
  50. """ Yield all 'value' targets, without priority """
  51. for val in self.dispatch(key):
  52. for el in val:
  53. yield el[1] # only value, no priority
  54. return