The way vectors are wrapped, getting an item out of a vector will return an object that is effectively a wrapped pointer, but its validity depends on the lifespan of the vector.
v = vector()
item = v[3]
del v
segfault
print item.foo
I didn't notice this being documented anywhere.
Note that this is the kind of code I was getting a crash on:
def get():
return vector()
segfault
print get()[3].foo
Python optimistically decrefs the result of get() after calling getitem but before getattr. It took me a while to understand this and realize why it was crashing.
I think the bug in all of this is that getitem does not increase the reference count of the vector instance it is a member of, and python may choose to delete the vector while objects that refer to its memory still exist.
Ideally the object wrapping the result of v[3] would hold a reference to v to prevent this dangling pointer problem.