Don't mistakenly treat PyLong objects as PyInt objects in Python3.
This resolves issues of large integers being incorrectly treated as -1 while also having
an OverflowError set internally for converting PyLong->long and PyLong->double
Conversions from PyLong to long, unsigned long, long long, and unsigned long long now
raise OverflowError rather than TypeError when given an out of range value.
Removing unnecessary check for PyLong_AsLong when converting PyLong->unsigned long since the
call to PyLong_AsUnsignedLong will have covered this case.
* coleb-python35_dtor_exception_fix:
Add test case for Python 3.5 assertion with a pending StopIteration
Amend python_destructor_exception runtime test
Call PyErr_WriteUnraisable if a destructor sets a Python exception (-builtin)
Extended zjturner's changes to encompass all function dispatch and use PyErr_WriteUnraisable to handle exceptions during __del__.
Python - Save and restore exception state before calling destroy.
* ahnolds-python34:
Python tp_allocs -> tp_next corrections
Cosmetic correction for Python tp_version -> tp_version_tag
Add -Wmissing-field-initializers to python Travis testing
Python 3.3 builtin missing field initializers added
Adding tp_finalize field to PyTypeObject for Python 3.4 and -builtin
Adding nb_matrix_multiply and nb_inplace_matrix_multiply fields to PyNumberMethods for Python version 3.5 and up
Adding tp_finalize field to PyTypeObject for Python version 3.4 and up
Hack to use the std::array support for boost::array.
Is limited as it currently exposes some 'using' bugs in SWIG.
For example, the type system fails to see that pointers to std::array
and pointers to boost::array are the same.
This approach saves having to maintain separate boost::array support.
The 'using' bug ought to be fixed, otherwise separate boost_array.i
files could be easily made from the std_array.i files.
These work much like any of the other STL containers except Python slicing
is somewhat limited because the array is a fixed size. Only slices of
the full size are supported.
Fix error when append on a SWIG Object with -builtin:
x.append(10)
SystemError: error return without exception set
Having append and next methods on a SWIG object by default doesn't seem
right to me though.
PyObject_CallFunction has the potential to silently drop the active
exception. In cases where the user just finished iterating a
generator, StopIteration will be active. Most of the time this
is fine because destroy() won't raise an exception. On Python 3
however, and with a debug interpreter, you will get an assertion
failure inside of Python. And in the worst case scenario, if
destroy() does throw an exception, the intepreter probably won't
be able to correctly detect the end of the iteration.
* amaeldoe-master:
Add python runtime test for dynamically added attributes
Attribute of SWIG wrapped classes instances were overwritten on __init__()
Fix SwigPyObject->dict memory leak
Make __dict__ accessible for Python builtin classes
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
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==
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.
Default values are no longer generated as Python code by default.
They must be explicitly turned on using the "python:defaultargs" feature.
Closes#294Closes#296
The problems in these two issues when "python:defaultargs" is turned
on still need to be fixed and should be addressed in separate patches.
The important thing is the default code generation is now fixed.
Also fixes li_std_vector_enum testcase when run with -threads.
Patch supplied on swig-devel mailing list on 12 Sep with details...
==============================================
I just wanted to mention that I found a crash issue in bug..
I am using SWIG 2.0.11 with python and have –threads enabled. I have a C++ std::vector that I instantiate in SWIG with %template. I also have a method in a class that returns this vector. I also include std_vector.i, btw..
When I iterate like so:
children = Action.getActionList()
for child in children:
pass
Everything is fine..
When I iterate like this:
for child in Action.getActionList()
pass
Product crashes.
The problem is the following. This code gets called first:
SWIGINTERN PyObject *_wrap_delete_SwigPyIterator(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
swig::SwigPyIterator *arg1 = (swig::SwigPyIterator *) 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject * obj0 = 0 ;
if(!PyArg_UnpackTuple(args,(char *)"delete_SwigPyIterator",1,1,&obj0)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_swig__SwigPyIterator, SWIG_POINTER_DISOWN | 0 );
if (!SWIG_IsOK(res1)) {
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_SwigPyIterator" "', argument " "1"" of type '" "swig::SwigPyIterator *""'");
}
arg1 = reinterpret_cast< swig::SwigPyIterator * >(argp1);
{
SWIG_PYTHON_THREAD_BEGIN_ALLOW;
delete arg1;
SWIG_PYTHON_THREAD_END_ALLOW;
}
resultobj = SWIG_Py_Void();
return resultobj;
fail:
return NULL;
}
Note the SWIG_PYTHON_THREAD_BEGIN_ALLOW/END_ALLOW. In between those two statements, we delete arg1. That in turn will eventually end up in this code:
namespace swig {
class SwigPtr_PyObject {
protected:
PyObject *_obj;
public:
… snip! …
~SwigPtr_PyObject()
{
Py_XDECREF(_obj);
}
Uh-oh! We call Py_XDECREF when we aren’t supposed to because we are in a SWIG_PYTHON_THREAD_BEGIN_ALLOW/END_ALLOW section!
This takes care of the issue:
namespace swig {
class SwigPtr_PyObject {
protected:
PyObject *_obj;
public:
… snip! …
~SwigPtr_PyObject()
{
SWIG_PYTHON_THREAD_BEGIN_BLOCK;
Py_XDECREF(_obj);
SWIG_PYTHON_THREAD_END_BLOCK;
}
There are several other methods in this class that use the Python API, but don’t have the BEGIN/END block defined. I’m not sure if they are required for all of them, but I believe they are..
I have attached a modified pyclasses.swg with what I believe are the correct changes. This code is from 2.0.11, but as far as I can tell, it’s the same as what is in 3.0.2…
Apologies for not doing more here (making/running tests, getting it in the code repository, etc..), but I’m under some pressure to get some unrelated things done…
... if available on the version of Python that's in use. This allows
obtaining the original byte string (and potentially trying a fallback
encoding) if the bytes can't be decoded as UTF-8.
Previously, a UnicodeDecodeError would be raised with no way to treat
the data as bytes or try another codec.
- some of the %.clean rules in the test-suite Makefiles were using a single tab
as an empty rule, dangerous! I've replaced these with the safer '@exit 0'.