diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2013-12-21 19:51:25 -0500 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2013-12-21 19:51:25 -0500 |
commit | 282a19d95251ecb033d30300b2e21ad6c57fbd77 (patch) | |
tree | 190476bba4c459967870768cb53b5aa0d2f4982f /lib/sqlalchemy/util/langhelpers.py | |
parent | 730b23239365c0392077626d04246e8a62e7f40d (diff) | |
download | sqlalchemy-282a19d95251ecb033d30300b2e21ad6c57fbd77.tar.gz |
- alter the decorator function, and the newer public_factory function,
to use a named def instead of a lambda. this so that TypeError on wrong
arguments are more legible. [ticket:2884]
Diffstat (limited to 'lib/sqlalchemy/util/langhelpers.py')
-rw-r--r-- | lib/sqlalchemy/util/langhelpers.py | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/lib/sqlalchemy/util/langhelpers.py b/lib/sqlalchemy/util/langhelpers.py index 1a66426d0..7e261e38f 100644 --- a/lib/sqlalchemy/util/langhelpers.py +++ b/lib/sqlalchemy/util/langhelpers.py @@ -99,14 +99,21 @@ def decorator(target): metadata = dict(target=targ_name, fn=fn_name) metadata.update(format_argspec_plus(spec, grouped=False)) - - code = 'lambda %(args)s: %(target)s(%(fn)s, %(apply_kw)s)' % ( - metadata) - decorated = eval(code, {targ_name: target, fn_name: fn}) + metadata['name'] = fn.__name__ + code = """\ +def %(name)s(%(args)s): + return %(target)s(%(fn)s, %(apply_kw)s) +""" % metadata + decorated = _exec_code_in_env(code, + {targ_name: target, fn_name: fn}, + fn.__name__) decorated.__defaults__ = getattr(fn, 'im_func', fn).__defaults__ return update_wrapper(decorated, fn) return update_wrapper(decorate, target) +def _exec_code_in_env(code, env, fn_name): + exec(code, env) + return env[fn_name] def public_factory(target, location): """Produce a wrapping function for the given cls or classmethod. @@ -127,11 +134,18 @@ def public_factory(target, location): doc = "This function is mirrored; see :func:`~%s` "\ "for a description of arguments." % location + location_name = location.split(".")[-1] spec = compat.inspect_getfullargspec(fn) del spec[0][0] metadata = format_argspec_plus(spec, grouped=False) - code = 'lambda %(args)s: cls(%(apply_kw)s)' % metadata - decorated = eval(code, {'cls': callable_, 'symbol': symbol}) + metadata['name'] = location_name + code = """\ +def %(name)s(%(args)s): + return cls(%(apply_kw)s) +""" % metadata + env = {'cls': callable_, 'symbol': symbol} + exec(code, env) + decorated = env[location_name] decorated.__doc__ = fn.__doc__ if compat.py2k or hasattr(fn, '__func__'): fn.__func__.__doc__ = doc |