Skip to content

Commit 5122738

Browse files
committed
Initial implementation of variants
1 parent 6d84da0 commit 5122738

File tree

2 files changed

+75
-0
lines changed

2 files changed

+75
-0
lines changed

src/variants/__init__.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# -*- coding: utf-8 -*-
2+
3+
"""Top-level package for variants."""
4+
5+
from ._variants import variants
6+
7+
__author__ = """Paul Ganssle"""
8+
__version__ = '0.1.0'
9+
10+
__all__ = ['variants']

src/variants/_variants.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# -*- coding: utf-8 -*-
2+
"""Provides the variant form decorator."""
3+
4+
import six
5+
6+
import types
7+
8+
__all__ = ['variants']
9+
10+
11+
class _StaticCallableMetaclass(type):
12+
"""Metaclass for a static callable function."""
13+
14+
def __call__(cls, *args, **kwargs):
15+
"""Rather than calling the constructor, call a static function."""
16+
return cls.__main_form__(*args, **kwargs)
17+
18+
def __repr__(cls):
19+
return cls.__func_repr__()
20+
21+
22+
def variants(f):
23+
"""
24+
Decorator to register a function that has variant forms.
25+
26+
Decorate the main form of the function with this decorator, and then
27+
subsequent variants should be declared with the same name as the original
28+
function.
29+
30+
.. example::
31+
32+
@variants
33+
def myfunc(fpath):
34+
with open(fpath, 'r') as f:
35+
do_something(f.read())
36+
37+
@myfunc.variant('from_url') as f:
38+
def myfunc(url):
39+
r = requests.get(url)
40+
do_something(r.text)
41+
"""
42+
43+
@six.add_metaclass(_StaticCallableMetaclass)
44+
class VariantFunction:
45+
__doc__ = f.__doc__
46+
47+
@staticmethod
48+
def __main_form__(*args, **kwargs):
49+
return f(*args, **kwargs)
50+
51+
@classmethod
52+
def variant(cls, func_name):
53+
def decorator(vfunc):
54+
setattr(cls, func_name, vfunc)
55+
return cls
56+
57+
return decorator
58+
59+
@classmethod
60+
def __func_repr__(cls):
61+
return '<VariantFunction {}>'.format(cls.__name__)
62+
63+
VariantFunction.__name__ = f.__name__
64+
65+
return VariantFunction

0 commit comments

Comments
 (0)