bug in get_cls_kwargs, affects sybase dialect

Issue #2732 resolved
Mike Bayer repo owner created an issue
from sqlalchemy.util import get_cls_kwargs
from sqlalchemy.connectors import pyodbc

class A(object):
    def __init__(self, arg1=None, arg2=None):
        pass

class B(pyodbc.PyODBCConnector, A):
    pass

class C(pyodbc.PyODBCConnector, A):
    def __init__(self, **kw):
        pass

print get_cls_kwargs(B)
print get_cls_kwargs(C)

output:

set(['supports_unicode_binds']('supports_unicode_binds'))
set(['arg2', 'supports_unicode_binds']('arg1',))

Comments (3)

  1. Mike Bayer reporter

    work in progress

    diff -r cfb0f9ca14f82c9ba06c4d5cbc992f821eb2234e lib/sqlalchemy/util/langhelpers.py
    --- a/lib/sqlalchemy/util/langhelpers.py    Wed May 15 15:46:29 2013 -0400
    +++ b/lib/sqlalchemy/util/langhelpers.py    Wed May 22 18:11:31 2013 -0400
    @@ -163,9 +163,11 @@
    
         """
    
    -    for c in cls.__mro__:
    +    mro = list(cls.__mro__)
    +    while mro:
    +        c = mro.pop(0)
             if '__init__' in c.__dict__:
    -            stack = set([c](c))
    +            stack = set([c](c))  # for very liberal, say set([cls](cls)) here
                 break
         else:
             return []
    @@ -187,6 +189,8 @@
             args.update(names)
             if has_kw:
                 stack.update(class_.__bases__)
    +            if mro:
    +                stack.add(mro.pop(0))
         args.discard('self')
         return args
    
    diff -r cfb0f9ca14f82c9ba06c4d5cbc992f821eb2234e test/base/test_utils.py
    --- a/test/base/test_utils.py   Wed May 15 15:46:29 2013 -0400
    +++ b/test/base/test_utils.py   Wed May 22 18:11:31 2013 -0400
    @@ -1084,6 +1084,10 @@
                 def __init__(self, b1, **kw):
                     pass
    
    +        class B2(B):
    +            def __init__(self, b2):
    +                pass
    +
             class AB(A, B):
                 def __init__(self, ab):
                     pass
    @@ -1101,15 +1105,24 @@
             class CBA(B, A):
                 pass
    
    +        class CB1A1(B1, A1):
    +            pass
    +
             class CAB1(A, B1):
                 pass
    
             class CB1A(B1, A):
                 pass
    
    +        class CB2A(B2, A):
    +            pass
    +
             class D(object):
                 pass
    
    +        class E(B, A):
    +            pass
    +
             def test(cls, *expected):
                 eq_(set(util.get_cls_kwargs(cls)), set(expected))
    
    @@ -1122,10 +1135,13 @@
             test(BA, 'ba', 'b', 'a')
             test(BA1, 'ba', 'b', 'a')
             test(CAB, 'a')
    -        test(CBA, 'b')
    +        test(CBA, 'b', 'a')
             test(CAB1, 'a')
    -        test(CB1A, 'b1', 'b')
    +        test(CB1A, 'b1', 'b', 'a')
    +        test(CB2A, 'b2')
    +        test(CB1A1, "a1", "b1", "b")
             test(D)
    +        test(E, "a", "b")
    
         def test_get_func_kwargs(self):
    
  2. Log in to comment