From: Mike Bayer Date: Sun, 22 Dec 2013 00:51:25 +0000 (-0500) Subject: - alter the decorator function, and the newer public_factory function, X-Git-Tag: rel_0_9_0~13^2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=282a19d95251ecb033d30300b2e21ad6c57fbd77;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - 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] --- diff --git a/lib/sqlalchemy/util/langhelpers.py b/lib/sqlalchemy/util/langhelpers.py index 1a66426d06..7e261e38fe 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