forked from varia/varia.website
95 lines
2.2 KiB
Python
95 lines
2.2 KiB
Python
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)
|
|
)
|