summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/util/langhelpers.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2013-12-21 19:51:25 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2013-12-21 19:51:25 -0500
commit282a19d95251ecb033d30300b2e21ad6c57fbd77 (patch)
tree190476bba4c459967870768cb53b5aa0d2f4982f /lib/sqlalchemy/util/langhelpers.py
parent730b23239365c0392077626d04246e8a62e7f40d (diff)
downloadsqlalchemy-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.py26
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