skip to navigation
skip to content

Not Logged In

black-magic 0.0.5

Decorator utility that operates on black magic

Latest Version: 0.0.9

Build Status Coverage Latest Version Downloads License

Metaprogramming modules that operate on black magic!

Currently there is only one module available. However, I am all open for cool ideas.

black_magic.decorator

This is intended to become a more modern and flexible replacement for the the well known decorator module. This module benefits an API for more flexible usage. The behaviour of the decorator module can easily be duplicated.

Usage

This module exports two important functions: wraps and partial.

black_magic.decorator.wraps

You can use it just like the standard functools.wraps function:

>>> from black_magic.decorator import wraps

>>> x = []
>>> def real(a:int, b=x) -> "Returns b":
...     return b

>>> @wraps(real)
... def fake(*args, **kwargs):
...     print("Fake!")
...     return real(*args, **kwargs)

This will not only update the docstring of the fake function to look like the original but generate a wrapper function that has exactly the same signature:

>>> assert fake(1) is x   # check object-identity of default-parameter!
Fake!

>>> from inspect import signature
>>> assert signature(fake) == signature(real)

If you want to get real crazy you can even use ast.expr's:

>>> import ast
>>> fake = wraps(real)(ast.Num(n=1))
>>> fake(0)
1

WARNING: Do NOT use black_magic.decorator.wraps with functools.partial! It won't work (in most cases).

black_magic.decorator.partial

This is similar to the functools.partial function.

>>> from black_magic.decorator import partial

>>> def real(arg):
...     print(arg)
>>> partial(real, arg=0)()
0

There are some differences, though:

  • this function returns a function object which looks like the input function, except for the modified parameters.

  • all overwritten parameters are completely removed from the signature. In functools.partial this is true only for arguments bound by position.

  • the **kwargs are stripped first, then *args

    >>> partial(lambda a,b,c: (a,b,c), 2, a=1)(3)
    (1, 2, 3)
    
  • by leaving the func argument empty partial can act as decorator:

    >>> @partial(None, bar=0)
    ... def foo(bar):
    ...     print(bar)
    >>> foo()
    0
    

Under the hood

Q: This uses ugly str concat and eval code, right?

A: No, it uses abstract syntax trees to do its dynamic code generation.

Tests

This module has been tested to work on python{2.6, 2.7, 3.2, 3.3} and PyPy1.9 using Travis CI.

License

To the extent possible under law, Thomas Gläßle has waived all copyright and related or neighboring rights to black-magic. This work is published from: Germany.

To the extent possible under law, the person who associated CC0 with black-magic has waived all copyright and related or neighboring rights to black-magic.

You should have received a copy of the CC0 legalcode along with this work. If not, see http://creativecommons.org/publicdomain/zero/1.0/.

Changelog

0.0.5

  • add black_magic.decorator.partial

0.0.4

  • support any callable to be passed to ASTorator.decorate
  • convert README to .rst
 
File Type Py Version Uploaded on Size
black-magic-0.0.5.tar.gz (md5) Source 2014-02-14 12KB
  • Downloads (All Versions):
  • 95 downloads in the last day
  • 392 downloads in the last week
  • 1621 downloads in the last month