These are a few utility decorators I wrote on a tangent for a Python 2 project I was working on. The exceptions raised mirror, as closely as possible, the ones raised by functions in Python 3 that use the keyword-only arguments syntax.
They don't disallow positional arguments, but they can require/restrict keyword arguments.  You could create another decorator that disallowed positional arguments.
import functools
def original_wrapped_function(f):
    try:
        while True:
            f = f.__wrapped__
    except AttributeError:
        return f
def restrict_kwargs(*allowed_keywords):
    def restrict_kwargs_decorator(func):
        @functools.wraps(original_wrapped_function(func))
        def restrict_wrapper(*args, **kwargs):
            for keyword in kwargs:
                if keyword not in allowed_keywords:
                    msg = "%s() got an unexpected keyword argument '%s'"
                    raise TypeError(msg % (func.__name__, keyword))
            return func(*args, **kwargs)
        restrict_wrapper.__wrapped__ = func
        return restrict_wrapper
    return restrict_kwargs_decorator
def require_kwargs(*required_keywords):
    def require_kwargs_decorator(func):
        @functools.wraps(original_wrapped_function(func))
        def require_wrapper(*args, **kwargs):
            missing_keywords = []
            for keyword in required_keywords:
                if keyword not in kwargs:
                    missing_keywords.append(keyword)
            if missing_keywords:
                func_name = func.__name__
                count = len(missing_keywords)
                if count == 1:
                    arg_word = 'argument'
                    missing_keywords_str = "'%s'" % missing_keywords[0]
                else:
                    arg_word = 'arguments'
                    and_join_str = ' and ' if count == 2 else ', and '
                    missing_keywords_str = ', '.join(
                        ("'%s'" % mk) for mk in missing_keywords[:-1])
                    missing_keywords_str = and_join_str.join((
                        missing_keywords_str, ("'%s'" % missing_keywords[-1])))
                msg = "%s() missing %d required keyword-only %s: %s"
                raise TypeError(msg % (func_name, count, arg_word,
                                       missing_keywords_str))
            return func(*args, **kwargs)
        require_wrapper.__wrapped__ = func
        return require_wrapper
    return require_kwargs_decorator
def exact_kwargs(*exact_keywords):
    def exact_kwargs_decorator(func):
        @restrict_kwargs(*exact_keywords)
        @require_kwargs(*exact_keywords)
        @functools.wraps(original_wrapped_function(func))
        def exact_wrapper(*args, **kwargs):
            return func(*args, **kwargs)
        exact_wrapper.__wrapped__ = func
        return exact_wrapper
    return exact_kwargs_decorator
Some examples:
>>> @restrict_kwargs('five', 'six')
... def test_restrict_kwargs(arg1, arg2, *moreargs, **kwargs):
...     return (arg1, arg2, moreargs, kwargs)
... 
>>> 
>>> @require_kwargs('five', 'six')
... def test_require_kwargs(arg1, arg2, *moreargs, **kwargs):
...     return (arg1, arg2, moreargs, kwargs)
... 
>>> 
>>> @exact_kwargs('five', 'six')
... def test_exact_kwargs(arg1, arg2, *moreargs, **kwargs):
...     return (arg1, arg2, moreargs, kwargs)
... 
>>> 
>>> 
>>> 
>>> test_restrict_kwargs(1, 2, 3, 4, five=5)
(1, 2, (3, 4), {'five': 5})
>>> 
>>> test_restrict_kwargs(1, 2, 3, 4, five=5, six=6)
(1, 2, (3, 4), {'six': 6, 'five': 5})
>>> 
>>> test_restrict_kwargs(1, 2, 3, 4, five=5, six=6, seven=7)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "SO_31939890.py", line 19, in restrict_wrapper
    raise TypeError(msg % (func.__name__, keyword))
TypeError: test_restrict_kwargs() got an unexpected keyword argument 'seven'
>>> 
>>> 
>>> 
>>> test_require_kwargs(1, 2, 3, 4, five=5)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "SO_31939890.py", line 49, in require_wrapper
    missing_keywords_str))
TypeError: test_require_kwargs() missing 1 required keyword-only argument: 'six'
>>> 
>>> test_require_kwargs(1, 2, 3, 4, five=5, six=6)
(1, 2, (3, 4), {'six': 6, 'five': 5})
>>> 
>>> test_require_kwargs(1, 2, 3, 4, five=5, six=6, seven=7)
(1, 2, (3, 4), {'seven': 7, 'six': 6, 'five': 5})
>>> 
>>> 
>>> 
>>> test_exact_kwargs(1, 2, 3, 4, five=5)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "SO_31939890.py", line 20, in restrict_wrapper
    return func(*args, **kwargs)
  File "SO_31939890.py", line 49, in require_wrapper
    missing_keywords_str))
TypeError: test_exact_kwargs() missing 1 required keyword-only argument: 'six'
>>> 
>>> test_exact_kwargs(1, 2, 3, 4, five=5, six=6)
(1, 2, (3, 4), {'six': 6, 'five': 5})
>>> 
>>> test_exact_kwargs(1, 2, 3, 4, five=5, six=6, seven=7)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "SO_31939890.py", line 19, in restrict_wrapper
    raise TypeError(msg % (func.__name__, keyword))
TypeError: test_exact_kwargs() got an unexpected keyword argument 'seven'
>>>