Registers a dataset with segment specific hyperparameters.

    When passing keyword arguments to `register`, they are checked to be valid
    keyword arguments for the registered Dataset class constructor and are
    saved in the registry. Registered keyword arguments can be retrieved with
    the `list_datasets` function.

    All arguments that result in creation of separate datasets should be
    registered. Examples are datasets divided in different segments or
    categories, or datasets containing multiple languages.

    Once registered, an instance can be created by calling
    :func:`~gluonnlp.data.create` with the class name.

    Parameters
    ----------
    **kwargs : list or tuple of allowed argument values
        For each keyword argument, it's value must be a list or tuple of the
        allowed argument values.

    Examples
    --------
    >>> @gluonnlp.data.register(segment=['train', 'test', 'dev'])
    ... class MyDataset(gluon.data.Dataset):
    ...     def __init__(self, segment='train'):
    ...         pass
    >>> my_dataset = gluonnlp.data.create('MyDataset')
    >>> print(type(my_dataset))
    <class 'MyDataset'>

def register(class_=None, **kwargs):
    """Registers a dataset with segment specific hyperparameters.

    When passing keyword arguments to `register`, they are checked to be valid
    keyword arguments for the registered Dataset class constructor and are
    saved in the registry. Registered keyword arguments can be retrieved with
    the `list_datasets` function.

    All arguments that result in creation of separate datasets should be
    registered. Examples are datasets divided in different segments or
    categories, or datasets containing multiple languages.

    Once registered, an instance can be created by calling
    :func:`~gluonnlp.data.create` with the class name.

    Parameters
    ----------
    **kwargs : list or tuple of allowed argument values
        For each keyword argument, it's value must be a list or tuple of the
        allowed argument values.

    Examples
    --------
    >>> @gluonnlp.data.register(segment=['train', 'test', 'dev'])
    ... class MyDataset(gluon.data.Dataset):
    ...     def __init__(self, segment='train'):
    ...         pass
    >>> my_dataset = gluonnlp.data.create('MyDataset')
    >>> print(type(my_dataset))
    <class 'MyDataset'>

    """

    def _real_register(class_):
        # Assert that the passed kwargs are meaningful
        for kwarg_name, values in kwargs.items():
            try:
                real_args = inspect.getfullargspec(class_).args
            except AttributeError:
                # pylint: disable=deprecated-method
                real_args = inspect.getargspec(class_.__init__).args

            if not kwarg_name in real_args:
                raise RuntimeError(
                    ('{} is not a valid argument for {}. '
                     'Only valid arguments can be registered.').format(
                         kwarg_name, class_.__name__))

            if not isinstance(values, (list, tuple)):
                raise RuntimeError(('{} should be a list of '
                                    'valid arguments for {}. ').format(
                                        values, kwarg_name))

        # Save the kwargs associated with this class_
        _REGSITRY_NAME_KWARGS[class_] = kwargs

        register_ = registry.get_register_func(Dataset, 'dataset')
        return register_(class_)

    if class_ is not None:
        # Decorator was called without arguments
        return _real_register(class_)

    return _real_register