I am running into some unexpected errors when using stl_input_iterator. I have 
a fairly simple converter registered to convert an iterable list of values 
(custom enum) to a unordered_set. The code looks like this:

struct advicetype_set_from_python {
        advicetype_set_from_python() {
                converter::registry::push_back(&convertible, &construct, 
type_id<std::unordered_set<AdviceType>>());
        }

        static void* convertible(PyObject *obj) {
                if (obj==Py_None)
                        return obj;

                PyObject* iter = PyObject_GetIter(obj);
                if (iter==NULL) {
                        throw_error_already_set();
                        return 0;
                }
                Py_DECREF(iter);
                return obj;
        }

        static void construct(PyObject* obj, 
converter::rvalue_from_python_stage1_data *data) {
                std::unordered_set<AdviceType> result;
                if (obj!=Py_None) {
                        object o = object(handle<>(obj));
                        stl_input_iterator<AdviceType> begin(o), end;
                        result.insert(begin, end);
                }
                void *storage = 
((converter::rvalue_from_python_storage<std::unordered_set<AdviceType>>*)data)->storage.bytes;
                new (storage) std::unordered_set<AdviceType>(result);
                data->convertible = storage;
        }
};

When using this code we were seeing segfaults due to what appears to be invalid 
reference counters. Since I suspected a problem in this convertor I wrote a 
simple test which triggers the converter a number of times:

for i in range(5000):
    my_func({AdviceType.one, AdviceType.two})

Which had an interesting result: the tests immediately aborted with a "Fatal 
Python error: GC object already tracked" error. Commenting out the contents of 
the if-statement in construct() made the problem go away, which makes we think 
the bug is in the stl_input_iterator used there. Am I doing something wrong 
here, or is this a boost bug? FWIW I am seeing this under both Boost 1.48 on an 
Ubuntu 12.04 machine and Boost 1.52 on OSX 10.8.

I am not sure if this is related, but clang outputs an interesting warning for 
the in-place new that is required here:

warning: cast from 'converter::rvalue_from_python_stage1_data *' to 
'converter::rvalue_from_python_storage<std::unordered_set<AdviceType> > *' 
increases required alignment
      from 8 to 16 [-Wcast-align]
                        void *storage = 
((converter::rvalue_from_python_storage<std::unordered_set<AdviceType>>*)data)->storage.bytes;


Wichert.
_______________________________________________
Cplusplus-sig mailing list
Cplusplus-sig@python.org
http://mail.python.org/mailman/listinfo/cplusplus-sig

Reply via email to