Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Structure sub-subclass does not initialize with base class positional arguments #49292

Closed
jaraco opened this issue Jan 24, 2009 · 6 comments
Closed
Assignees
Labels
topic-ctypes type-bug An unexpected behavior, bug, or error

Comments

@jaraco
Copy link
Member

jaraco commented Jan 24, 2009

BPO 5042
Nosy @theller, @jaraco
Files
  • ctypes subclassing issues.py: problem description and demo workaround script
  • init.c
  • ctypes-structinit.patch
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = 'https://github.com/theller'
    closed_at = <Date 2009-09-18.19:48:44.414>
    created_at = <Date 2009-01-24.16:04:18.593>
    labels = ['ctypes', 'type-bug']
    title = 'Structure sub-subclass does not initialize with base class positional arguments'
    updated_at = <Date 2009-09-18.19:48:44.413>
    user = 'https://github.com/jaraco'

    bugs.python.org fields:

    activity = <Date 2009-09-18.19:48:44.413>
    actor = 'theller'
    assignee = 'theller'
    closed = True
    closed_date = <Date 2009-09-18.19:48:44.414>
    closer = 'theller'
    components = ['ctypes']
    creation = <Date 2009-01-24.16:04:18.593>
    creator = 'jaraco'
    dependencies = []
    files = ['12845', '14920', '14921']
    hgrepos = []
    issue_num = 5042
    keywords = ['patch']
    message_count = 6.0
    messages = ['80457', '92792', '92793', '92794', '92816', '92838']
    nosy_count = 2.0
    nosy_names = ['theller', 'jaraco']
    pr_nums = []
    priority = 'normal'
    resolution = 'fixed'
    stage = None
    status = 'closed'
    superseder = None
    type = 'behavior'
    url = 'https://bugs.python.org/issue5042'
    versions = ['Python 2.6', 'Python 3.1', 'Python 2.7', 'Python 3.2']

    @jaraco
    Copy link
    Member Author

    jaraco commented Jan 24, 2009

    When trying to create a sub-subclass of a ctypes.Structure, the behavior
    is not as expected.

    An executable example that describes the problem in detail and
    demonstrates the issue is available at
    http://paste.turbogears.org/paste/29555 and also attached.

    The failing behavior is near the beginning, following the description.

    Three unsuccessful workarounds follow.

    The expected behavior is found at the end, where a final workaround has
    been implemented.

    Can this behavior be improved in subsequent releases of ctypes? If not,
    can ctypes at least support the workaround natively (perhaps by
    providing a method in the Structure class that performs the workaround
    and can be called by a sub-subclass during __init__)?

    @jaraco jaraco added topic-ctypes type-bug An unexpected behavior, bug, or error labels Jan 24, 2009
    @theller
    Copy link

    theller commented Sep 17, 2009

    The problem is the implementation of the current __init__ method, in
    Modules/_ctypes/_ctypes.c, line 4024. Rewritten in Python, and slightly
    simplified it looks like this:

        def __init__(self, *args, **kw):
            """The current BUGGY __init__ method"""
            names = [f[0] for f in self._fields_]
            for n, v in zip(names, args):
                setattr(self, n, v)
            for n, v in kw.iteritems():
                setattr(self, n, v)

    It assigns positional parameters to the names found in the _fields_ list
    of the subclass, but it should look up all the _fields_ definitions in
    all the superclasses, too. Working pseudo Python code:

        def __init__(self, *args, **kw):
            """This is how the Structure's __init__method SHOULD be"""
            if args:
                names = []
                for tp in self.__class__.mro()[2::-1]:
                    for n, _ in tp._fields_:
                        names.append(n)
                for n, v in zip(names, args):
                    setattr(self, n, v)
            for n, v in kw.iteritems():
                setattr(self, n, v)

    Now, I don't really want to write the above code in C ;-).

    @jaraco
    Copy link
    Member Author

    jaraco commented Sep 17, 2009

    Heh. Me neither.

    Is it possible to use something like Cython to generate the C code?

    @jaraco
    Copy link
    Member Author

    jaraco commented Sep 17, 2009

    That was easier than I thought. The generated code is _ugly_ but it did
    seem to be able to generate it.

    I created init.pyx

    {{{
    class X(object):
    def __init__(self, *args, **kw):
    """This is how the Structure's __init__method SHOULD be"""
    if args:
    names = []
    for tp in self.__class__.mro()[2::-1]:
    for n, _ in tp._fields_:
    names.append(n)
    for n, v in zip(names, args):
    setattr(self, n, v)
    for n, v in kw.iteritems():
    setattr(self, n, v)
    }}}

    Then, ran cython init.pyx and got the attached file.

    Is that any help?

    @theller
    Copy link

    theller commented Sep 18, 2009

    Is that any help?
    Not really ;-).

    Here is a patch I just wrote - it must still be checked for correctness,
    and tests for it must be added. I hope the comment in the code explains
    how it works. ctypes-structinit.patch

    @theller
    Copy link

    theller commented Sep 18, 2009

    I've commited a slightly changed patch plus a test.

    trunk: 74917, py3k: 74918, release26-maint: 74919, release31-maint: 74920.

    @theller theller closed this as completed Sep 18, 2009
    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    topic-ctypes type-bug An unexpected behavior, bug, or error
    Projects
    None yet
    Development

    No branches or pull requests

    2 participants