Created
March 20, 2014 04:47
-
-
Save matthewstory/9657448 to your computer and use it in GitHub Desktop.
unicodify and stringify decorators
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'''Decorators to convert all arguments passed to a function or method to | |
unicode or str, including default arguments''' | |
import sys | |
import functools | |
import inspect | |
def _convert_arg(arg, from_, conv, enc): | |
'''Safely convert unicode to string or string to unicode''' | |
return getattr(arg, conv)(encoding=enc) if isinstance(arg, from_) else arg | |
def _wrap_convert(from_type, fn, encoding=None): | |
'''Decorate a function converting all str arguments to unicode or | |
vice-versa''' | |
conv = 'decode' if from_type is str else 'encode' | |
encoding = encoding or sys.getdefaultencoding() | |
# override string defaults using partial | |
aspec, dflts = inspect.getargspec(fn), {} | |
if aspec.defaults: | |
for k,v in zip(aspec.args[-len(aspec.defaults):],aspec.defaults): | |
dflts[k] = _convert_arg(v, from_type, conv, encoding) | |
fn = functools.partial(fn, **dflts) | |
@functools.wraps(fn.func if isinstance(fn, functools.partial) else fn) | |
def converted(*args, **kwargs): | |
args = [_convert_arg(a, from_type, conv, encoding) for a in args] | |
for k,v in kwargs.iteritems(): | |
kwargs[k] = _convert_arg(v, from_type, conv, encoding) | |
return fn(*args, **kwargs) | |
return converted | |
def unicodify(fn=None, encoding=None): | |
'''Convert all str arguments to unicode''' | |
if fn is None: | |
return functools.partial(unicodify, encoding=encoding) | |
return _wrap_convert(str, fn, encoding=encoding) | |
def stringify(fn=None, encoding=None): | |
'''Convert all unicode arguments to str''' | |
if fn is None: | |
return functools.partial(stringify, encoding=encoding) | |
return _wrap_convert(unicode, fn, encoding=encoding) | |
__all__ = ['unicodify', 'stringify'] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment