[Numpy-discussion] Changes in PyArray_FromAny between 1.5.x and 1.6.x

Nathaniel Smith njs at pobox.com
Tue Jun 5 11:34:41 EDT 2012


On Mon, Jun 4, 2012 at 10:12 PM, Dag Sverre Seljebotn
<d.s.seljebotn at astro.uio.no> wrote:
> On 06/04/2012 09:06 PM, Mike Hansen wrote:
>> On Mon, May 28, 2012 at 3:15 AM, Mike Hansen<mhansen at gmail.com>  wrote:
>>> In trying to upgrade NumPy within Sage, we notices some differences in
>>> behavior between 1.5 and 1.6.  In particular, in 1.5, we have
>>>
>>> sage: f = 0.5
>>> sage: f.__array_interface__
>>> {'typestr': '=f8'}
>>> sage: numpy.array(f)
>>> array(0.5)
>>> sage: numpy.array(float(f))
>>> array(0.5)
>>>
>>> In 1.6, we get the following,
>>>
>>> sage: f = 0.5
>>> sage: f.__array_interface__
>>> {'typestr': '=f8'}
>>> sage: numpy.array(f)
>>> array(0.500000000000000, dtype=object)
>>>
>>> This seems to be do to the changes in PyArray_FromAny introduced in
>>> https://github.com/mwhansen/numpy/commit/2635398db3f26529ce2aaea4028a8118844f3c48
>>> .  In particular, _array_find_type used to be used to query our
>>> __array_interface__ attribute, and it no longer seems to work.  Is
>>> there a way to get the old behavior with the current code?
>
> No idea. If you want to spend the time to fix this properly, you could
> implement PEP 3118 and use that instead to export your array data (which
> can be done from Cython using __getbuffer__ on a Cython class).

I don't think that would work, because looking more closely, I don't
think they're actually doing anything like what
__array_interface__/PEP3118 are designed for. They just have some
custom class ("sage.rings.real_mpfr.RealLiteral", I guess an arbitrary
precision floating point of some sort?), and they want instances that
are passed to np.array() to be automatically coerced to another type
(float64) by default. But there's no buffer sharing or anything like
that going on at all. Mike, does that sound right?

This automagic coercion seems... in very dubious taste to me. (Why
does creating an array object imply that you want to throw away
precision? You can already throw away precision explicitly by doing
np.array(f, dtype=float).) But if this automatic coercion feature is
useful, then wouldn't it be better to have a different interface
instead of kluging it into __array_interface__, like we should check
for an attribute called __numpy_preferred_dtype__ or something?

-n



More information about the NumPy-Discussion mailing list