12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788 |
- import functools
- import operator
- import itertools
- from .errors import OptionError
- from .extern.jaraco.text import yield_lines
- from .extern.jaraco.functools import pass_none
- from ._importlib import metadata
- from ._itertools import ensure_unique
- from .extern.more_itertools import consume
- def ensure_valid(ep):
- """
- Exercise one of the dynamic properties to trigger
- the pattern match.
- """
- try:
- ep.extras
- except AttributeError as ex:
- msg = (
- f"Problems to parse {ep}.\nPlease ensure entry-point follows the spec: "
- "https://packaging.python.org/en/latest/specifications/entry-points/"
- )
- raise OptionError(msg) from ex
- def load_group(value, group):
- """
- Given a value of an entry point or series of entry points,
- return each as an EntryPoint.
- """
- # normalize to a single sequence of lines
- lines = yield_lines(value)
- text = f'[{group}]\n' + '\n'.join(lines)
- return metadata.EntryPoints._from_text(text)
- def by_group_and_name(ep):
- return ep.group, ep.name
- def validate(eps: metadata.EntryPoints):
- """
- Ensure entry points are unique by group and name and validate each.
- """
- consume(map(ensure_valid, ensure_unique(eps, key=by_group_and_name)))
- return eps
- @functools.singledispatch
- def load(eps):
- """
- Given a Distribution.entry_points, produce EntryPoints.
- """
- groups = itertools.chain.from_iterable(
- load_group(value, group) for group, value in eps.items()
- )
- return validate(metadata.EntryPoints(groups))
- @load.register(str)
- def _(eps):
- r"""
- >>> ep, = load('[console_scripts]\nfoo=bar')
- >>> ep.group
- 'console_scripts'
- >>> ep.name
- 'foo'
- >>> ep.value
- 'bar'
- """
- return validate(metadata.EntryPoints(metadata.EntryPoints._from_text(eps)))
- load.register(type(None), lambda x: x)
- @pass_none
- def render(eps: metadata.EntryPoints):
- by_group = operator.attrgetter('group')
- groups = itertools.groupby(sorted(eps, key=by_group), by_group)
- return '\n'.join(f'[{group}]\n{render_items(items)}\n' for group, items in groups)
- def render_items(eps):
- return '\n'.join(f'{ep.name} = {ep.value}' for ep in sorted(eps))
|