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