78 lines
2.4 KiB
Python
78 lines
2.4 KiB
Python
import functools
|
|
import importlib
|
|
import importlib.util
|
|
import importlib.machinery
|
|
|
|
from .const import Bound, inf
|
|
from .func import iterate, open, closed, openclosed, closedopen, empty, singleton
|
|
from .io import from_string, to_string, from_data, to_data
|
|
from .dict import IntervalDict
|
|
|
|
|
|
__all__ = ["create_api"]
|
|
|
|
|
|
def partial(wrapped, *args, **kwargs):
|
|
"""
|
|
Convenient helper that combines functools.update_wrapper and
|
|
functools.partial. It has exactly the same signature than functools.partial.
|
|
"""
|
|
return functools.update_wrapper(
|
|
functools.partial(wrapped, *args, **kwargs), wrapped
|
|
)
|
|
|
|
|
|
def create_api(interval, *, interval_dict=None, name=None):
|
|
"""
|
|
Dynamically create a module whose API is similar to the one of portion, but
|
|
configured to use given Interval class. Unless specified, a new IntervalDict
|
|
subclass is automatically generated to use given Interval subclass.
|
|
|
|
This feature is experimental, and may be changed even in minor or patch
|
|
updates of portion.
|
|
|
|
:param interval: a subclass of Interval.
|
|
:param interval_dict: a subclass of IntervalDict.
|
|
:param name: the name of the new module.
|
|
"""
|
|
if name is None:
|
|
module_name = "portion_" + interval.__name__
|
|
else:
|
|
module_name = name
|
|
|
|
if interval_dict is None:
|
|
interval_dict = type(
|
|
interval.__name__ + "Dict",
|
|
(IntervalDict,),
|
|
dict(_klass=interval),
|
|
)
|
|
|
|
objects = {
|
|
"inf": inf,
|
|
"CLOSED": Bound.CLOSED,
|
|
"OPEN": Bound.OPEN,
|
|
"Interval": interval,
|
|
"open": partial(open, klass=interval),
|
|
"closed": partial(closed, klass=interval),
|
|
"openclosed": partial(openclosed, klass=interval),
|
|
"closedopen": partial(closedopen, klass=interval),
|
|
"singleton": partial(singleton, klass=interval),
|
|
"empty": partial(empty, klass=interval),
|
|
"iterate": iterate,
|
|
"from_string": partial(from_string, klass=interval),
|
|
"to_string": to_string,
|
|
"from_data": partial(from_data, klass=interval),
|
|
"to_data": to_data,
|
|
"IntervalDict": interval_dict,
|
|
}
|
|
|
|
module = importlib.util.module_from_spec(
|
|
importlib.machinery.ModuleSpec(module_name, None)
|
|
)
|
|
|
|
module.__all__ = list(objects.keys())
|
|
for name, obj in objects.items():
|
|
setattr(module, name, obj)
|
|
|
|
return module
|