_entry_points.py 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. import functools
  2. import operator
  3. import itertools
  4. from .extern.jaraco.text import yield_lines
  5. from .extern.jaraco.functools import pass_none
  6. from ._importlib import metadata
  7. from ._itertools import ensure_unique
  8. from .extern.more_itertools import consume
  9. def ensure_valid(ep):
  10. """
  11. Exercise one of the dynamic properties to trigger
  12. the pattern match.
  13. """
  14. ep.extras
  15. def load_group(value, group):
  16. """
  17. Given a value of an entry point or series of entry points,
  18. return each as an EntryPoint.
  19. """
  20. # normalize to a single sequence of lines
  21. lines = yield_lines(value)
  22. text = f'[{group}]\n' + '\n'.join(lines)
  23. return metadata.EntryPoints._from_text(text)
  24. def by_group_and_name(ep):
  25. return ep.group, ep.name
  26. def validate(eps: metadata.EntryPoints):
  27. """
  28. Ensure entry points are unique by group and name and validate each.
  29. """
  30. consume(map(ensure_valid, ensure_unique(eps, key=by_group_and_name)))
  31. return eps
  32. @functools.singledispatch
  33. def load(eps):
  34. """
  35. Given a Distribution.entry_points, produce EntryPoints.
  36. """
  37. groups = itertools.chain.from_iterable(
  38. load_group(value, group)
  39. for group, value in eps.items())
  40. return validate(metadata.EntryPoints(groups))
  41. @load.register(str)
  42. def _(eps):
  43. r"""
  44. >>> ep, = load('[console_scripts]\nfoo=bar')
  45. >>> ep.group
  46. 'console_scripts'
  47. >>> ep.name
  48. 'foo'
  49. >>> ep.value
  50. 'bar'
  51. """
  52. return validate(metadata.EntryPoints(metadata.EntryPoints._from_text(eps)))
  53. load.register(type(None), lambda x: x)
  54. @pass_none
  55. def render(eps: metadata.EntryPoints):
  56. by_group = operator.attrgetter('group')
  57. groups = itertools.groupby(sorted(eps, key=by_group), by_group)
  58. return '\n'.join(
  59. f'[{group}]\n{render_items(items)}\n'
  60. for group, items in groups
  61. )
  62. def render_items(eps):
  63. return '\n'.join(
  64. f'{ep.name} = {ep.value}'
  65. for ep in sorted(eps)
  66. )