[issue3777] PyNumber_Long fails from Float

2008-09-06 Thread Barry Alan Scott

Barry Alan Scott [EMAIL PROTECTED] added the comment:

You are right that its the Py::Long( Py::Float( double( x ) ) )
that is triggering this problem.

Here is the gdb from the powerpc build that shows the
info you asked for and show res being corrupt.

I'm going to try and build a smaller version of this
problem using a minimal PyCXX module.

 import pysvn;pysvn.Client().ls('pysvn/__init__.py')

Breakpoint 1, bp () at pysvn_client_cmd_list.cpp:33
33  }
(gdb) c
Continuing.
Current language:  auto; currently c++

Breakpoint 2, pysvn_client::cmd_ls (this=0x1114830, [EMAIL PROTECTED],
[EMAIL PROTECTED]) at pysvn_client_cmd_list.cpp:138
138 Py::Long l_tmp( f_tmp );
(gdb) b PyNumber_Long
Breakpoint 5 at 0x213cfc: file Objects/abstract.c, line 1673.
(gdb) c
Continuing.

Breakpoint 5, PyNumber_Long (o=0x1809384) at Objects/abstract.c:1673
1673if (trunc_name == NULL) {
(gdb) p o
$25 = (PyObject *) 0x1809384
Current language:  auto; currently c
(gdb) p *o
$26 = {
  ob_refcnt = 1, 
  ob_type = 0x35723c
}
(gdb) p *o-ob_type
$27 = {
  ob_refcnt = 4, 
  ob_type = 0x35f0bc, 
  ob_size = 0, 
  tp_name = 0x339d98 float, 
  tp_basicsize = 16, 
  tp_itemsize = 0, 
  tp_dealloc = 0x23de30 float_dealloc, 
  tp_print = 0x23fa90 float_print, 
  tp_getattr = 0, 
  tp_setattr = 0, 
  tp_compare = 0, 
  tp_repr = 0x23fa50 float_repr, 
  tp_as_number = 0x357ab4, 
  tp_as_sequence = 0x0, 
  tp_as_mapping = 0x0, 
  tp_hash = 0x23e570 float_hash, 
  tp_call = 0, 
  tp_str = 0x23fa10 float_str, 
  tp_getattro = 0x263800 PyObject_GenericGetAttr, 
  tp_setattro = 0, 
  tp_as_buffer = 0x0, 
  tp_flags = 394747, 
  tp_doc = 0x357a4c float(x) - floating point number\n\nConvert a
string or number to a floating point number, if possible., 
  tp_traverse = 0, 
  tp_clear = 0, 
  tp_richcompare = 0x23e000 float_richcompare, 
  tp_weaklistoffset = 0, 
  tp_iter = 0, 
  tp_iternext = 0, 
  tp_methods = 0x35733c, 
  tp_members = 0x0, 
  tp_getset = 0x357300, 
  tp_base = 0x0, 
  tp_dict = 0x0, 
  tp_descr_get = 0, 
  tp_descr_set = 0, 
  tp_dictoffset = 0, 
  tp_init = 0, 
  tp_alloc = 0, 
  tp_new = 0x241a10 float_new, 
  tp_free = 0, 
  tp_is_gc = 0, 
  tp_bases = 0x0, 
  tp_mro = 0x0, 
  tp_cache = 0x0, 
  tp_subclasses = 0x0, 
  tp_weaklist = 0x0, 
  tp_del = 0, 
  tp_version_tag = 0
}
(gdb) n
1679if (o == NULL)
(gdb) 
1681m = o-ob_type-tp_as_number;
(gdb) 
1682if (m  m-nb_long) { /* This should include subclasses
of long */
(gdb) p *m
$28 = {
  nb_add = 0x242980 float_add, 
  nb_subtract = 0x242c40 float_sub, 
  nb_multiply = 0x242f00 float_mul, 
  nb_divide = 0x2431c0 float_classic_div, 
  nb_remainder = 0x243510 float_rem, 
  nb_divmod = 0x243830 float_divmod, 
  nb_power = 0x243bf0 float_pow, 
  nb_negative = 0x241d70 float_neg, 
  nb_positive = 0x241b60 float_float, 
  nb_absolute = 0x241e70 float_abs, 
  nb_nonzero = 0x23e580 float_nonzero, 
  nb_invert = 0, 
  nb_lshift = 0, 
  nb_rshift = 0, 
  nb_and = 0, 
  nb_xor = 0, 
  nb_or = 0, 
  nb_coerce = 0x241f70 float_coerce, 
  nb_int = 0x23e6e0 float_trunc, 
  nb_long = 0x23e6e0 float_trunc, 
  nb_float = 0x241b60 float_float, 
  nb_oct = 0, 
  nb_hex = 0, 
  nb_inplace_add = 0, 
  nb_inplace_subtract = 0, 
  nb_inplace_multiply = 0, 
  nb_inplace_divide = 0, 
  nb_inplace_remainder = 0, 
  nb_inplace_power = 0, 
  nb_inplace_lshift = 0, 
  nb_inplace_rshift = 0, 
  nb_inplace_and = 0, 
  nb_inplace_xor = 0, 
  nb_inplace_or = 0, 
  nb_floor_divide = 0x243b60 float_floor_div, 
  nb_true_divide = 0x244340 float_div, 
  nb_inplace_floor_divide = 0, 
  nb_inplace_true_divide = 0, 
  nb_index = 0
}
(gdb) n

Breakpoint 3, PyNumber_Long (o=0x1809384) at Objects/abstract.c:1684
1684PyObject *res = m-nb_long(o);
(gdb) s
float_trunc (v=0x1809384) at Objects/floatobject.c:1084
1084double x = PyFloat_AsDouble(v);
(gdb) p o
$29 = (PyObject *) 0x1809384
(gdb) p v
$30 = (PyObject *) 0x1809384
(gdb) n
1087(void)modf(x, wholepart);
(gdb) p x
$31 = 0
(gdb) n
1100if (LONG_MIN  wholepart  wholepart  LONG_MAX) {
(gdb) p wholepart
$32 = 4555
(gdb) n
1102return PyInt_FromLong(aslong);
(gdb) p asLong
No symbol asLong in current context.
(gdb) p aslong
No symbol aslong in current context.
(gdb) n
1105}
(gdb) n
PyNumber_Long (o=0x1809384) at Objects/abstract.c:1685
1685if (res  (!PyInt_Check(res) 
!PyLong_Check(res))) {
(gdb) p res
$33 = (PyObject *) 0x383cf0
(gdb) p *res
$34 = {
  ob_refcnt = 1362084, 
  ob_type = 0x140
}
(gdb) n

Breakpoint 4, PyNumber_Long (o=0x1809384) at Objects/abstract.c:1735
1735}
(gdb)

___
Python tracker [EMAIL PROTECTED]
http://bugs.python.org/issue3777
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue3777] PyNumber_Long fails from Float

2008-09-06 Thread Barry Alan Scott

Barry Alan Scott [EMAIL PROTECTED] added the comment:

O.k. I know what is going on.

Here is the description from abstracts.h for PyNumber_Long:

 PyAPI_FUNC(PyObject *) PyNumber_Long(PyObject *o);

   /*
 Returns the o converted to a long integer object on success,
 or NULL on failure.  This is the equivalent of the Python
 expression: long(o).

   */

Its says that I can expect a long integer. However PyNumber_long
can return an int or a long.

PyCXX checks for a long, but an int is not a long and I raise
a type error.

This is a contract break on the Python API.

The change that causes this break is in floatobject.c
From 2.5.2 code:

static PyNumberMethods float_as_number = {
...
float_int,  /*nb_int*/
float_long, /*nb_long*/

From 2.6b3 code:

static PyNumberMethods float_as_number = {
...
float_trunc,/*nb_int*/
float_trunc,/*nb_long*/

float_trunc returns either an int or a long.
Which is not what is required for the API.

Here is the same bug at the pure python level.

 $ python2.6
Python 2.6b3 (r26b3:65922, Aug 25 2008, 15:44:46) 
[GCC 4.0.1 (Apple Computer, Inc. build 5370)] on darwin
Type help, copyright, credits or license for more information.
 long(4)
4L
 long(4.3)
4
 long(6)
6L
 type(long(4.3))
type 'int'
 

Barry

___
Python tracker [EMAIL PROTECTED]
http://bugs.python.org/issue3777
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue3777] PyNumber_Long fails from Float

2008-09-04 Thread Barry Alan Scott

New submission from Barry Alan Scott [EMAIL PROTECTED]:

I am testing PySVN against python2.6b3.

I see a failure when PyNumber_Long is called with a Float.
It raises TypeError.

The same code works on 2.3, 2.4 and 2.5.

Looking with GDB I see:

(gdb) bt
#0  PyNumber_Long (o=0x1809384) at Objects/abstract.c:1735
#1  0x020f8e70 in Py::Long::Long (this=0xbfffefc8, [EMAIL PROTECTED]) at
pysvn_client_cmd_list.cpp:739

1681m = o-ob_type-tp_as_number;
1682if (m  m-nb_long) { /* This should include subclasses
of long */
1683/* Classic classes always take this branch. */
1684PyObject *res = m-nb_long(o);
1685if (res  (!PyInt_Check(res) 
!PyLong_Check(res))) {

res does not contain the value that nb_long(o) calculated.
and the if on 1685 is false so you get a type error.

I have compiled on Mac OS X 10.4 powerpc and fedora 8 x86.
Both fail in the exact same way.

If you need to reproduce you will need to build pysvn and
run a command that triggers the problem. I don't have a
smaller example.

--
components: None
messages: 72519
nosy: barry-scott
severity: normal
status: open
title: PyNumber_Long fails from Float
type: behavior
versions: Python 2.6

___
Python tracker [EMAIL PROTECTED]
http://bugs.python.org/issue3777
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue3777] PyNumber_Long fails from Float

2008-09-04 Thread Amaury Forgeot d'Arc

Amaury Forgeot d'Arc [EMAIL PROTECTED] added the comment:

Note to others: PySvn uses the PyCXX classes. The call in question is
something similar to
   Py::Long( Py::Float( double( someValue ) ) )

Barry, what is the exact error message that you get?
What do you mean by res does not contain the value that nb_long(o)
calculated ?
And what is the exact content of the o variable at the time of the
failure? (you could look for example at o-ob_type-tp_name)

--
nosy: +amaury.forgeotdarc

___
Python tracker [EMAIL PROTECTED]
http://bugs.python.org/issue3777
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com