Returns an object to use as entry point when calling ``registry.solve_resource``.

    When calling ``registry.solve_resource`` on a "root" resource, we don't have any value.
    This function will create a object to use as a first value and is used to specify which
    entry points are allowed at the first level of a dataql query.

    Example
    -------

    >>> from datetime import date, timedelta
    >>> registry = Registry()
    >>> registry.register(date, ['strftime'])
    >>> entry_points = EntryPoints(registry,
    ...     today=date(2015, 6, 1),
    ...     in_days=lambda days: date(2015, 6, 1)+timedelta(days=days))
    >>> from dataql.resources import *
    >>> resource = Field('today', filters=[
    ...     Filter('today'),
    ...     Filter('strftime', args=[PosArg('%F')]),
    ... ])
    >>> registry.solve_resource(entry_points, resource)
    '2015-06-01'
    >>> registry.solve_resource(entry_points, Field('tomorrow', filters=[
    ...     Filter('in_days', args=[NamedArg('days', '=', 1)]),
    ...     Filter('strftime', args=[PosArg('%F')]),
    ... ]))
    '2015-06-02'

    Notes
    -----
    The name of this function is intentionally made to resemble a class, as it returns an instance
    of a class named ``EntryPoints``.

def EntryPoints(registry, **kwargs):
    """Returns an object to use as entry point when calling ``registry.solve_resource``.

    When calling ``registry.solve_resource`` on a "root" resource, we don't have any value.
    This function will create a object to use as a first value and is used to specify which
    entry points are allowed at the first level of a dataql query.

    Example
    -------

    >>> from datetime import date, timedelta
    >>> registry = Registry()
    >>> registry.register(date, ['strftime'])
    >>> entry_points = EntryPoints(registry,
    ...     today=date(2015, 6, 1),
    ...     in_days=lambda days: date(2015, 6, 1)+timedelta(days=days))
    >>> from dataql.resources import *
    >>> resource = Field('today', filters=[
    ...     Filter('today'),
    ...     Filter('strftime', args=[PosArg('%F')]),
    ... ])
    >>> registry.solve_resource(entry_points, resource)
    '2015-06-01'
    >>> registry.solve_resource(entry_points, Field('tomorrow', filters=[
    ...     Filter('in_days', args=[NamedArg('days', '=', 1)]),
    ...     Filter('strftime', args=[PosArg('%F')]),
    ... ]))
    '2015-06-02'

    Notes
    -----
    The name of this function is intentionally made to resemble a class, as it returns an instance
    of a class named ``EntryPoints``.

    """

    # We convert functions to staticmethod as they will be held by a class and
    # we don't want them to expect a ``self`` or ``cls`` argument.
    attrs = {k: (staticmethod(v) if isfunction(v) else v) for k, v in kwargs.items()}

    klass = type('EntryPoints', (BaseEntryPoints, ), attrs)
    registry.register(klass, kwargs.keys())
    return klass()