Varia's website
https://varia.zone
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
95 lines
2.2 KiB
95 lines
2.2 KiB
4 weeks ago
|
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)
|
||
|
)
|