From: Josh C. <jc...@nc...> - 2008-01-18 22:16:57
|
On Fri, 18 Jan 2008, William S Fulton wrote: > The current implementation accepts a vector<int> for a vector<double>, so it has > an implicit conversion from one type to the other. This is bit of a surprise as > there is no such implicit conversion for this in C++. The conversion isn't > implemented in the types table, but through the swig::asptr template. From what > I can make out, it calls PySequence_Check and if it passes then attempts to > convert each of the elements into the appropriate C++ element type. What it is > trying to do is convert any Python type that could be a sequence. Surely this is > a bug? Not necessarily. It is not unreasonable to accept any Python sequence type (I confess I don't know exactly what that means) that contains the right kind of elements. Why restrict things to Python lists and tuples? If somebody writes a Python type that can be indexed or iterated over, there is utility in accepting it. At least the argument can be made, and that's how things often wind up working in Python. On the other hand, if this feature is omitted, the caller can pass list(x) rather than x. > I'm not entirely sure how the PySequence_Check works, but it looks like > PySequence_Check succeeds if __getitem__ exists in the object's class. > This includes Python strings btw, so an attempt is made to convert a string into > a vector!! Might work for vector<char>, but otherwise it seems daft to me. Or a vector of an integral type. Or floating point. Should a Python list of characters, like ['a', 'x'], be acceptable for vector<int>? I don't know; maybe. > This means that if an overloaded method contains one of the STL containers, an > attempt is made to convert the elements in any object that has a __getitem__. > Surely this is plain wrong as well as being very inefficient? Inefficient how? When it succeeds or when it fails? > I can understand > trying to convert intrinsic python sequences like lists, but not all the swig > proxy classes, irrelevant of type. How about modifying this to skip the sequence > check if not the correct swig/C++ type? That way Python lists could still be > used for std::vector. Seems reasonable, though one could argue that accepting vector<int> for vector<double> (passed by value or const&) is no stranger than accepting a python list of integers. > Maybe the check should be just for Python List and Tuple > types only, using PyList_Check and PyTuple_Check? I think the stl support used to do that. That's what I do in my own version of stl support. It does limit what Python containers can be passed. > We can also remove SWIG_TYPECHECK_POINTER and friends to remove the erroneous > warnings without any consequence. A list<double> will no longer automatically > work for a vector<double> etc, but I feel that is to be expected. Users can > always customise otherwise if needed. Do you mean SWIG_TYPECHECK_VECTOR and friends? I think the list<double> -> vector<double> conversion is unrelated to the precedences. These issues touch on a long discussion we had about performance problems with the stl support (http://www.nabble.com/Performance-bug-in-pycontainers.swg-to10671251.html). At least for Python, things were ridiculously slow; things that should have been O(1) were O(n) or O(n^2). As far as I know this hasn't been fixed. It's related to accepting Python lists and other sequences, but better code would accept them without imposing a penalty when a wrapped object of the right type is passed. Josh |