diff options
author | Jason Kirtland <jek@discorporate.us> | 2008-01-24 00:08:40 +0000 |
---|---|---|
committer | Jason Kirtland <jek@discorporate.us> | 2008-01-24 00:08:40 +0000 |
commit | f6439ffa2c166edb2ffffc3042e20422f01803ee (patch) | |
tree | 9a26a80b93f936e54c4c3b5118745477ff144629 /lib/sqlalchemy/util.py | |
parent | 29f7a38ee075418146add1b5ce7e2f06d5fc67a1 (diff) | |
download | sqlalchemy-f6439ffa2c166edb2ffffc3042e20422f01803ee.tar.gz |
Corrected behavior of get_cls_kwargs and friends
Diffstat (limited to 'lib/sqlalchemy/util.py')
-rw-r--r-- | lib/sqlalchemy/util.py | 38 |
1 files changed, 28 insertions, 10 deletions
diff --git a/lib/sqlalchemy/util.py b/lib/sqlalchemy/util.py index 4f30f76ba..bdcaf37f0 100644 --- a/lib/sqlalchemy/util.py +++ b/lib/sqlalchemy/util.py @@ -4,8 +4,9 @@ # This module is part of SQLAlchemy and is released under # the MIT License: http://www.opensource.org/licenses/mit-license.php -import itertools, sys, warnings, sets, weakref +import inspect, itertools, sets, sys, warnings, weakref import __builtin__ +types = __import__('types') from sqlalchemy import exceptions @@ -181,20 +182,37 @@ class ArgSingleton(type): return instance def get_cls_kwargs(cls): - """Return the full set of legal kwargs for the given `cls`.""" + """Return the full set of inherited kwargs for the given `cls`. + + Probes a class's __init__ method, collecting all named arguments. If the + __init__ defines a **kwargs catch-all, then the constructor is presumed to + pass along unrecognized keywords to it's base classes, and the collection + process is repeated recursively on each of the bases. + """ - kw = [] for c in cls.__mro__: - cons = c.__init__ - if hasattr(cons, 'func_code'): - for vn in cons.func_code.co_varnames: - if vn != 'self': - kw.append(vn) - return kw + if '__init__' in c.__dict__: + stack = [c] + break + else: + return [] + + args = Set() + while stack: + class_ = stack.pop() + ctr = class_.__dict__.get('__init__', False) + if not ctr or not isinstance(ctr, types.FunctionType): + continue + names, _, has_kw, _ = inspect.getargspec(ctr) + args |= Set(names) + if has_kw: + stack.extend(class_.__bases__) + args.discard('self') + return list(args) def get_func_kwargs(func): """Return the full set of legal kwargs for the given `func`.""" - return [vn for vn in func.func_code.co_varnames] + return inspect.getargspec(func)[0] # from paste.deploy.converters def asbool(obj): |