<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">Just a few notes:</div><div class="gmail_quote"><br></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">However, the fact that this works for bytestrings on Python 3 is, in my<br>
humble opinion, ridiculous:<br>
<br>
>>> np.array(b'100', 'u1') # b'100' IS NOT TEXT<br>
array(100, dtype=uint8)<br></blockquote><div><br></div><div>Yes, that is a mis-feature -- I think due to bytes and string being the same object in py2 -- so on py3, numpy continues to treat a bytes objects as also a 1-byte-per-char string, depending on context. And users want to be able to write numpy code that will run the same on py2 and py3, so we kinda need this kind of thing.</div><div><br></div><div>Makes me think that an optional "pure-py-3" mode for numpy might be a good idea. If that flag is set, your code will only run on py3 (or at least might run differently).</div><div> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span class="gmail-">> Further thoughts:<br>
> If trying to create "u1" array from a Pyhton 3 string, question is,<br>
> whether it should throw an error, I think yes,</span></blockquote><div><br></div><div>well, you can pass numbers > 255 into a u1 already:</div><div>







<p class="gmail-p1"><span class="gmail-s1">In [</span><span class="gmail-s2"><b>96</b></span><span class="gmail-s1">]: </span><span class="gmail-s3">np.array(</span><span class="gmail-s1">456</span><span class="gmail-s3">, dtype=</span><span class="gmail-s4">'u1'</span><span class="gmail-s3">)</span></p>
<p class="gmail-p1"><span class="gmail-s5">Out[</span><span class="gmail-s6"><b>96</b></span><span class="gmail-s5">]: </span><span class="gmail-s3">array(200, dtype=uint8)</span></p></div><div>and it does the wrap-around overflow thing... so why not?</div><div> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span class="gmail-">and in this case<br>
> "u4" type should be explicitly specified by initialisation, I suppose.<br>
> And e.g. translation from unicode to extended ascii (Latin1) or whatever<br>
> should be done on Python side  or with explicit translation.<br></span></blockquote><div><br></div><div>absolutely!</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">If you ask me, passing a unicode string to fromstring with sep='' (i.e.<br>
to parse binary data) should ALWAYS raise an error: the semantics only<br>
make sense for strings of bytes.<br></blockquote><div><br></div><div>exactly -- we really should have a "frombytes()" alias for fromstring() and it should only work for atual bytes objects (strings on py2, naturally).</div><div><br></div><div>and overloading fromstring() to mean both "binary dump of data" and "parse the text" due to whether the sep argument is set was always a bad idea :-(</div><div><br></div><div>.. and fromstring(s, sep=a_sep_char)</div><div> </div><div>has been semi broken (or at least not robust) forever anyway.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
Currently, there appears to be some UTF-8 conversion going on, which<br>
creates potentially unexpected results:<br>
<br>
>>> s = 'αβγδ'<br>
>>> a = np.fromstring(s, 'u1')<br>
>>> a<br>
array([206, 177, 206, 178, 206, 179, 206, 180], dtype=uint8)<br>
>>> assert len(a) * a.dtype.itemsize  == len(s)<br>
Traceback (most recent call last):<br>
  File "<stdin>", line 1, in <module><br>
AssertionError<br>
>>><br>
<br>
This is, apparently (<a href="https://github.com/numpy/numpy/issues/2152" rel="noreferrer" target="_blank">https://github.com/numpy/<wbr>numpy/issues/2152</a>), due to<br>
how the internals of Python deal with unicode strings in C code, and not<br>
due to anything numpy is doing.<br></blockquote><div><br></div><div>exactly -- py3 strings are pretty nifty implementation of unicode text -- they have nothing to do with storing binary data, and should not be used that way. There is essentially no reason you would ever want to pass the actual binary representation to any other code.</div><div><br></div><div>fromstring should be re-named frombytes, and it should raise an exception if you pass something other than a bytes object (or maybe a memoryview or other binary container?)</div><div><br></div><div>we might want to keep fromstring() for parsing strings, but only if it were fixed...</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">IMHO calling fromstring(..., sep='') with a unicode string should be<br>
deprecated and perhaps eventually forbidden. (Or fixed, but that would<br>
break backwards compatibility)</blockquote><div><br></div><div>agreed.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span class="gmail-">
> Python3 assumes 4-byte strings but in reality most of the time<br>
> we deal with 1-byte strings, so there is huge waste of resources<br>
> when dealing with 4-bytes. For many serious projects it is just not needed.<br>
<br>
</span>That's quite enough anglo-centrism, thank you. For when you need byte<br>
strings, Python 3 has a type for that. For when your strings contain<br>
text, bytes with no information on encoding are not enough.<br></blockquote><div><br></div><div>There was a big thread about this recently -- it seems to have not quite come to a conclusion. But anglo-centrism aside, there is substantial demand for a "smaller" way to store mostly-ascii text.</div><div><br></div><div>I _think_ the conversation was steering toward an encoding-specified string dtype, so us anglo-centric folks could use latin-1 or utf-8.</div><div><br></div><div>But someone would need to write the code.</div><div><br></div><div>-CHB</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span class="gmail-">> There can be some convenience methods for ascii operations,<br>
> like eg char.toupper(), but currently they don't seem to work with integer<br>
> arrays so why not make those potentially useful methots usable<br>
> and make them work on normal integer arrays?<br>
</span>I don't know what you're doing, but I don't think numpy is normally the<br>
right tool for text manipulation...<br></blockquote><div><br></div><div>I agree here. But if one were to add such a thing (vectorized string operations) -- I'd think the thing to do would be to wrap (or port) the python string methods. But it shoudl only work for actual string dtypes, of course.</div><div><br></div><div>note that another part of the discussion previously suggested that we have a dtype that wraps a native python string object -- then you'd get all for free. This is essentially an object array with strings in it, which you can do now.</div><div><br></div><div>-CHB</div><div><br></div></div><div><br></div>-- <br><div class="gmail_signature"><br>Christopher Barker, Ph.D.<br>Oceanographer<br><br>Emergency Response Division<br>NOAA/NOS/OR&R            (206) 526-6959   voice<br>7600 Sand Point Way NE   (206) 526-6329   fax<br>Seattle, WA  98115       (206) 526-6317   main reception<br><br><a href="mailto:Chris.Barker@noaa.gov" target="_blank">Chris.Barker@noaa.gov</a></div>
</div></div>