summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/util.py
diff options
context:
space:
mode:
authorJason Kirtland <jek@discorporate.us>2008-01-24 00:08:40 +0000
committerJason Kirtland <jek@discorporate.us>2008-01-24 00:08:40 +0000
commitf6439ffa2c166edb2ffffc3042e20422f01803ee (patch)
tree9a26a80b93f936e54c4c3b5118745477ff144629 /lib/sqlalchemy/util.py
parent29f7a38ee075418146add1b5ce7e2f06d5fc67a1 (diff)
downloadsqlalchemy-f6439ffa2c166edb2ffffc3042e20422f01803ee.tar.gz
Corrected behavior of get_cls_kwargs and friends
Diffstat (limited to 'lib/sqlalchemy/util.py')
-rw-r--r--lib/sqlalchemy/util.py38
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):