#324·boltons

attrs/dataclasses-style decorator helper

Author: kurtbroseCreated Jan 25, 2023Updated Jan 25, 2023

There's probably a better name for this, but the idea is to write decorator + kwargs -- so you don't have to do @decorator() if there aren't any arguments being passed.

python
def maybe_arg_decorator(callable):
  """
  There's this fun trick that dataclasses.dataclass decorator does,
  where you can use it both directly as a decorator, or call it with kwargs and use
  that as the decorator.

  This helper converts a function with 1 positional argument and a bunch of kwargs
  into one of those.


  @maybe_arg_decorator
  def simple_decorator(decorated, a=1, b=2):
     pass

  @simple_decorator
  def thing(): pass

  @simple_decorator(a=3)
  def other_thing(): pass
  """
  @wraps(callable)
  def wrapper(decorated=None, /, **kwargs):
    if decorated:
      return callable(decorated)

    def double_wrapper(decorated, /):
      return callable(decorated, **kwargs)

    return double_wrapper

  return wrapper