[Numpy-tickets] [NumPy] #598: incorrect behaviour with ( "%d"%a[i]) on uint64

NumPy numpy-tickets@scipy....
Wed Oct 24 11:12:44 CDT 2007


#598: incorrect behaviour with ( "%d"%a[i]) on uint64
--------------------------+-------------------------------------------------
 Reporter:  gregsmith_to  |        Owner:  somebody
     Type:  defect        |       Status:  reopened
 Priority:  normal        |    Milestone:  1.0.4   
Component:  Other         |      Version:  1.0.2   
 Severity:  normal        |   Resolution:          
 Keywords:                |  
--------------------------+-------------------------------------------------
Changes (by gregsmith_to):

  * status:  closed => reopened
  * resolution:  invalid =>

Comment:

 OK, I downloaded 1.0.3.1 on 2.5/Win32 and confirmed the error. Are you
 sure that the rhs of % was a scalar when you tried it? Because "%d"%x will
 only raise that TypeError after trying {{{x.__int__(),}}} and if that
 doesn't work for numpy scalars, numpy won't work.
 {{{
 Python 2.5 (r25:51908, Sep 19 2006, 09:52:17) [MSC v.1310 32 bit (Intel)]
 on win32
 Type "copyright", "credits" or "license()" for more information.
 {yada yada}

 IDLE 1.2
 >>> import numpy; numpy.__version__
 '1.0.3.1'
 >>> a = numpy.zeros(5,numpy.uint64)
 >>> a[0] = -1
 >>> a
 array([18446744073709551615,                    0,                    0,
                           0,                    0], dtype=uint64)
 >>> "%d"%a[0]
 '-1'
 >>>
 }}}

 There seem to have been a number of issues related to problems in getting
 numpy.*int* objects to behave consistently with python integers (e.g.
 'hex()' conversion), and I wanted to suggest an approach. Rather that re-
 implementing the {{{__hex__}}} and {{{__oct__}}} methods etc, those
 methods could all construct a Python 'long' (or float or complex) object
 from the numpy scalar in  a common way, and then basically get the
 corresponding method of the new object and call that. So
 {{{a[0].__hex__()}}} would essentially call
 {{{a[0].__long__().__hex__()}}}, {{{a[0].__str__()}}} would call
 {{{a[0].__long__().__str__()}}}, etc. The only difference between the
 various array types  would be the conversion. This guarantees consistent
 behaviour even if the Python conversion changes.

 You could even put something in getattr to cover all cases uniformly for
 scalars; if someone tries to get unknown attribute {{{a[0].__foobar__}}}
 of a scalar uint64, you would attempt to {{{getattr( a[0].__long__(),
 '__foobar__')}}} and if that succeeds, return that object.  That by itself
 would cover all the {{{__str__, __hex__, __oct__}}} etc, but adding them
 as actual methods is polite so that they appear in dir(). This allows
 numpy to support future methods added to the python integer types, without
 modification.

 I've used this 'subclass by proxy' approach to make a certain library's
 C++ array class appear to act as a numpy array, and it works very well.

-- 
Ticket URL: <http://scipy.org/scipy/numpy/ticket/598#comment:4>
NumPy <http://projects.scipy.org/scipy/numpy>
The fundamental package needed for scientific computing with Python.


More information about the Numpy-tickets mailing list