<br><br><div class="gmail_quote">On Thu, Apr 24, 2008 at 7:11 PM, Charles R Harris <<a href="mailto:charlesr.harris@gmail.com">charlesr.harris@gmail.com</a>> wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<br><br><div class="gmail_quote"><div><div></div><div class="Wj3C7c">On Thu, Apr 24, 2008 at 5:58 PM, Robert Kern <<a href="mailto:robert.kern@gmail.com" target="_blank">robert.kern@gmail.com</a>> wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">

<div><div></div><div>On Thu, Apr 24, 2008 at 5:37 PM, Charles R Harris<br>
<<a href="mailto:charlesr.harris@gmail.com" target="_blank">charlesr.harris@gmail.com</a>> wrote:<br>
> Hi,<br>
><br>
> I've been looking into ticket #736 and playing with some things. In<br>
> arrayobject.c starting at line 8534 I added a check for strings.<br>
><br>
>         if (PyString_Check(op)) {<br>
>             r = Array_FromPyScalar(op, newtype);<br>
>          }<br>
>         if (PySequence_Check(op)) {<br>
>             PyObject *thiserr = NULL;<br>
><br>
>             /* necessary but not sufficient */<br>
>             Py_INCREF(newtype);<br>
>             r = Array_FromSequence(op, newtype, flags & FORTRAN,<br>
>                                     min_depth, max_depth);<br>
>             if (r == NULL && (thiserr=PyErr_Occurred())) {<br>
>                 if (PyErr_GivenExceptionMatches(thiserr,<br>
>                                                 PyExc_MemoryError)) {<br>
>                      return NULL;<br>
>                 }<br>
><br>
> I think there may be a failure to decrement the reference to newtype unless<br>
> Array_FromSequence does that (nasty side effect);<br>
><br>
> Anyway, the added check for a string fixes the conversion problem for such<br>
> things as int32('123'). There remains a problem with array('123',<br>
> dtype=int32) and with array(['123','123'], dtype=int32), but I think I can<br>
> track those down. The question is, will changing the current behavior so<br>
> that strings get converted to numbers cause problems with other programs out<br>
> there. I suspect I also need to check that strings are converted this way<br>
> only when the type is explicitly given, not detected.<br>
<br>
</div></div>Seems to work for me.<br>
<br>
In [5]: array([124, '123', '123'])<br>
Out[5]:<br>
array(['124', '123', '123'],<br>
      dtype='|S4')</blockquote><div> </div></div></div><div>Sure, but you didn't specify the type, so numpy determined that it was numpy string type. Wrong test. Try<br><br><span style="font-family: courier new,monospace;">In [1]: array(['123'], dtype=int32)</span><br style="font-family: courier new,monospace;">

<span style="font-family: courier new,monospace;">Out[1]: array([[1, 2, 3]])</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">In [2]: a = ones(3, dtype=int32)</span><br style="font-family: courier new,monospace;">

<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">In [3]: a[...] = '123'</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;">

<span style="font-family: courier new,monospace;">In [4]: a</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">Out[4]: array([1, 2, 3])</span><br style="font-family: courier new,monospace;">

<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">In [5]: a[...] = int32('123')</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;">

<span style="font-family: courier new,monospace;">In [6]: a</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">Out[6]: array([123, 123, 123])</span><br><br>So on and so forth. The problem is this bit of code (among others)<br>

<br><span style="font-family: courier new,monospace;">    stop_at_string = ((type == PyArray_OBJECT) ||</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">                      (type == PyArray_STRING &&</span><br style="font-family: courier new,monospace;">

<span style="font-family: courier new,monospace;">                       typecode->type == PyArray_STRINGLTR) ||</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">                      (type == PyArray_UNICODE) ||</span><br style="font-family: courier new,monospace;">

<span style="font-family: courier new,monospace;">                      (type == PyArray_VOID));</span><br style="font-family: courier new,monospace;"><br><br>The question is, how do we interpret a string when the type is specified? I think in that case we should try to convert the string to the relevant type, just as we cast numbers to the relevant type. So we should always stop at string.<br>

</div></div></blockquote><div><br>Setting stop_at_string = 1 fixes all the problems I can see, but introduces one new one:<br><br>Traceback (most recent call last):<br>  File "/usr/lib/python2.5/site-packages/numpy/core/tests/test_regression.py", line 537, in check_numeric_carray_compare<br>
    assert_equal(np.array([ 'X' ], 'c'),'X')<br>ValueError: setting an array element with a sequence<br><br>on the other hand array(['X']) == 'X' works fine, so I don't know what's going on with the 'c' type.<br>
<br>Chuck<br></div></div><br>