[C++-sig] wrapped std::vector slice affecting items in a python list
talljimbo at gmail.com
Fri Aug 12 21:30:58 CEST 2011
On 08/12/2011 04:28 AM, babak wrote:
> I've come across some unusual behaviour that I was hoping some one might be
> able to explain to me.
> In python I have a list and a wrapped std::vector<MyCustomType> (using the
> vector_indexing_suite) where the list contains the items in the vector. If I
> slice insert items into the vector then the items in the python list change.
> The attached example illustrates this.
> Is this behaviour expected ?
> I'm quite confused as to what's going on so any help clarifying this would
> be greatly appreciated.
> http://boost.2283326.n4.nabble.com/file/n3738972/test.py test.py
> http://boost.2283326.n4.nabble.com/file/n3738972/source.cpp source.cpp
Some of the stuff vector_indexing_suite is sufficiently complex that at
least I'd say this behavior is not unexpected. After all, when you
slice a Python list, and modify the elements in the sliced bit, you
modify the original list as well (unless your elements are immutable
things like strings or numbers, and in that case you aren't really
modifying them, you're replacing them).
I think the thing you get back from slicing a std::vector is probably a
proxy object designed to have exactly that behavior (note: I haven't
checked; that's just how I'd have implemented it).
In any case, I'd recommend against wrapping a std::vector of a mutable
C++ type directly in Python. It's almost always unsafe, because any
operation on the vector that invalidates iterators will destroy the
elements of the vector, even if there are Python objects that point to
those elements elsewhere with nonzero reference counts. It's much safer
to use a vector of shared_ptr, or always convert to Python lists and
avoid vector_indexing_suite. This isn't a Boost.Python-specific
problem, it's an inherent incompatibility between C++'s value-based
containers and Python's shared-reference ones.
More information about the Cplusplus-sig