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

Make __dict__ accessible for Python builtin classes #320

Merged
merged 3 commits into from Apr 11, 2015

Commits on Apr 10, 2015

  1. Make __dict__ accessible for Python builtin classes

    Attribute set within instance of a SWIG Python wrapped class are
    stored in SwigPyObject->dict, which tp_dictoffset slot is pointing to.
    
    However, SWIG wrapped classes did not have a __dict__ attribute.
    Inheriting subclasses did not get the attribute either because the
    SWIG wrapped classes initialize the tp_dictoffset slot:
    
    From http://bugs.python.org/issue16272:
    
    "If a type defines a nonzero tp_dictoffset, that type is responsible for
    defining a `__dict__` slot as part of the tp_getset structures. Failure to
    do so will result in the dict being inaccessible from Python via
    `obj.__dict__` from instances of the type or subtypes."
    
    Provide a SwigPyObject_get___dict__() function to retrieve the dict
    attribute or create it when it does not exist yet (it is normally
    created when setting attribute set), and a PyGetSetDef entry pointing
    to this function.
    amaeldoe committed Apr 10, 2015
    Copy the full SHA
    92b88db View commit details
    Browse the repository at this point in the history
  2. Fix SwigPyObject->dict memory leak

    The following patch attempt to fix a memory leak happening when a
    random class attribute is set. The internal instance dictionary is
    created but never freed.
    
    This fixes the problem for me, although I am not sure the patch
    is correct.
    
    <code>
     p = MySWIGClass()
     p.random_attribute = 0
    </code>
    
    Valgrind report:
    ==18267== 280 bytes in 1 blocks are definitely lost in loss record 1,372 of 1,780
    ==18267==    at 0x4A0645D: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==18267==    by 0x3A90A885DC: PyObject_Malloc (in /usr/lib64/libpython2.7.so.1.0)
    ==18267==    by 0x3A90B101A8: _PyObject_GC_Malloc (in /usr/lib64/libpython2.7.so.1.0)
    ==18267==    by 0x3A90B102AC: _PyObject_GC_New (in /usr/lib64/libpython2.7.so.1.0)
    ==18267==    by 0x3A90A80943: PyDict_New (in /usr/lib64/libpython2.7.so.1.0)
    ==18267==    by 0x3A90A6E8FC: PyFrame_New (in /usr/lib64/libpython2.7.so.1.0)
    ==18267==    by 0x3A90AE1A65: PyEval_EvalCodeEx (in /usr/lib64/libpython2.7.so.1.0)
    ==18267==    by 0x3A90AE088E: PyEval_EvalFrameEx (in /usr/lib64/libpython2.7.so.1.0)
    ==18267==    by 0x3A90AE21DC: PyEval_EvalCodeEx (in /usr/lib64/libpython2.7.so.1.0)
    ==18267==    by 0x3A90AE22E1: PyEval_EvalCode (in /usr/lib64/libpython2.7.so.1.0)
    ==18267==    by 0x3A90AFB71E: ??? (in /usr/lib64/libpython2.7.so.1.0)
    ==18267==    by 0x3A90AFC8DD: PyRun_FileExFlags (in /usr/lib64/libpython2.7.so.1.0)
    ==18267==
    amaeldoe committed Apr 10, 2015
    Copy the full SHA
    3983d7b View commit details
    Browse the repository at this point in the history
  3. Attribute of SWIG wrapped classes instances were overwritten on __ini…

    …t__()
    
    When a SWIG classes instances is initialized, its internal dictionary was
    reset to NULL, which result in the loss of any attribute that might have
    been set for the instance.
    
    Only initialize the internal dictionary on actual PyObject creation.
    
    class Test(MySwigWrappedClass):
            def __init__(self):
                    self.val = "Random Value"
                    MySwigWrappedClass.__init__(self)
    
    p = Test()
    print hasattr(p, "val") # Should return True, but used to return False
    amaeldoe committed Apr 10, 2015
    Copy the full SHA
    327d7c9 View commit details
    Browse the repository at this point in the history