Skip to main content

🗃 dek - the decorator-decorator 🗃

dek decorates your decorators to diminish defects and drudgery.

Writing a Python decorator which takes no parameters isn't hard.

But writing a decorator with parameters is less easy - and more work if you want to decorate classes, like unittest.mock.patch does.

dek is a decorator for decorators that does this deftly with a single tiny function.

Example 1: a simple decorator with dek

TASK: write a decorator before that prints a function's name and its arguments before it executes.

With dek, it's a few lines:

import dek

@dek
def before(pfunc):
    print(pfunc)
    return pfunc()

Done! To use your new decorator:

@before
def phone(two, four=4):
    print('Calling', two + two, four * four)

one(32, four=3)

# That prints something like:
#
# functools.partial(<function phone at 0x7fafa8072b00>, 32, four=3)
# Calling 64 9

pfunc is a functools.partial, which represents the function call that dek intercepted. Your code can call pfunc as often as you like, or add or change parameters.

Example 2: same, without dek

import functools

def before(func):
    @functools.wraps(func)
    def wrapped(*args, **kwargs):
        print(func, args, kwargs)
        return func(*args, **kwargs)

    return wrapped

With dek it's a bit less work, but the real advantage comes when you have a decorator with a parameter.

Example 3: a decorator with a single optional parameter

Write a decorator before that prints a function's name, arguments and a label before it executes.

With dek, it's a trivial change from the previous solution.

import dek

@dek
def before(pfunc, label='dull'):
    print(label, pfunc.func, *pfunc.args)
    return pfunc()

@before
def add(x, y):
    return x + y

@before(label='Exciting!')
def times(x, y):
    return x * y

print('Result', add(2, times(2, 3)))

# Prints:
#   Exciting! times 2 3
#   dull add 2 6
#   Result 8

Example 4: same, without dek

Without dek it's actual work that's easy to get wrong.

import functools

def before(func=None, label='dull'):
    if func is not None:
        @functools.wraps(func)
        def wrapped(*args, **kwargs):
            print(label, func.__name, *args)
            return func(*args, **kwargs)

        return wrapped

    return functools.partial(before, label=label)

Example 5: Deferred mode

For finer control over function signatures there is deferred mode, which lets you select what sort of signature you want to expose with a wrapped function that you create.

@dek(defer=True)
def before(func, label='debug'):
    def wrapped(foo, bar):
        print(label, foo, bar)
        return func(foo, bar)

    return wrapped

Example 6: Decorating a class

If you need to decorate methods on a class, there's a methods parameter to select which methods get decorated.

import dek

@dek(methods='test')
def before(pfunc):
    print('HERE', *pfunc.args)
    return pfunc()

@before
class Class:
    def test_one(self):
        return 1

    def test_two(self):
        return 2

    def three(self):  # This won't get decorated
        return 1


# Test at the command line:
>>> cl = Class()
>>> cl.test_one(), cl.test_two(), cl.three()
HERE 1
HERE 2
(1, 2, 3)

NOTES:

This article talks more about decorators that take parameters and about dek in general.

For your advanced decorator desires, the PyPi module decorator does not duplicate duties that dek does, but does pretty anything else you could conceive of in a decorator library.

API Documentation

Metadata

Release files for dek 1.6.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for dek 1.6.0
File Size Uploaded Provenance Actions
dek-1.6.0.tar.gz 18.3 kB Without provenance Details for dek-1.6.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for dek 1.6.0
File Interpreter ABI Platform Actions
dek-1.6.0-py3-none-any.whl Python 3 none any Details for dek-1.6.0-py3-none-any.whl

Total release size: 24.7 kB

Release files / dek-1.6.0.tar.gz

Download URL dek-1.6.0.tar.gz
Size 18.3 kB
Tags Source
SHA-256 checksum
How to use checksums
acc14bff3820dd54c8f46ed45b3498cee874c43c3e8a886998da2f36336ea667
BLAKE2b-256 checksum
How to use checksums
e89d8e772b75234db35c0cf6d307e2eeff05150e1e33fc867014820e3179afd5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.10.12 {"installer":{"name":"uv","version":"0.10.12","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / dek-1.6.0-py3-none-any.whl

Download URL dek-1.6.0-py3-none-any.whl
Size 6.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
847b00007e0e36177c0262901b56de31de13d2a27f6f76a5ec6af4d17aa355f6
BLAKE2b-256 checksum
How to use checksums
73189d0bb764907b4e320b755b77a6f69a14f0053fc8c4973ebb443e27b1f2c6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.10.12 {"installer":{"name":"uv","version":"0.10.12","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Security for dek 1.6.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page