pyppin.base.flex_decorator

[View Source]

A way to simplify writing Python decorators and improve their syntax.

Functions

flex_decorator(decorator)

flex_decorator is a way to simplify writing Python decorators and improve their syntax.

pyppin.base.flex_decorator.flex_decorator(decorator: Callable) Callable[source]

flex_decorator is a way to simplify writing Python decorators and improve their syntax.

Usually, if you want to write a decorator without arguments, you have to write one kind of function, and the resulting syntax is @foo def bar(), but if you want to write a decorator that takes arguments, you have to write a completely different function, and the resulting syntax is @foo() def bar(). While there are good reasons for this to be the implementation, it’s ugly and requires both the writer and user of decorators to remember too many things.

Instead, @flex_decorator simplifies all of this. You simply need to write:

@flex_decorator
def my_decorator(target, *, arg, arg, ...):
   ... return the decorated "target"

You only write one function: it takes exactly one positional argument (the thing to be decorated), and arbitrarily many keyword arguments. You can then use the resulting decorator in two ways:

@my_decorator(arg=foo, arg=bar)
def decorated_thing(...):

or, if all of the arguments have default values, you can write:

@my_decorator
def decorated_thing(...):

This is identical to @my_decorator(), so users no longer need to remember which one to use.

Warning

There is a known conflict between this code and mypy. When you make a flex decorator and use it with parentheses, mypy will fail at the use point with “Untyped decorator makes function “my_decorator” untyped”. At the moment this requires a # type: ignore on that line. Fix in the works but this is messy and may require changes to mypy and/or Python itself to fix.