[Python-Dev] Re: PyNumber_Check()

M.-A. Lemburg mal@lemburg.com
Mon, 18 Nov 2002 18:40:50 +0100


Guido van Rossum wrote:
>>gvanrossum@projects.sourceforge.net wrote:
>>
>>>*** NEWS	18 Nov 2002 16:19:39 -0000	1.526
>>>--- NEWS	18 Nov 2002 16:27:16 -0000	1.527
>>>***************
>>>*** 694,698 ****
>>>  - PyNumber_Check() now returns true for string and unicode objects.
>>>    This is a result of these types having a partially defined
>>>!   tp_as_number slot.
>>>  
>>>  - The string object's layout has changed: the pointer member
>>>--- 694,700 ----
>>>  - PyNumber_Check() now returns true for string and unicode objects.
>>>    This is a result of these types having a partially defined
>>>!   tp_as_number slot.  (This is not a feature, but an indication that
>>>!   PyNumber_check() is not very useful to determine numeric behavior.
>>>!   It may be deprecated.)
>>
>>Perhaps PyNumber_Check() should check that at least
>>one of nb_int, nb_long, nb_float is available (in addition to the
>>tp_as_number slot) ?!
> 
> 
> No, I think PyNumber_Check() should be deprecated.  I don't think
> there's a valid use case for it.  If you really want a fuzzy
> definition like "at least one of nb_int, nb_long, nb_float is
> available", you can test for that yourself -- IMO that doesn't really
> make it a number.

Hmm, I use it in mxODBC to switch on Python object types.
The above change causes the semantics to change as well:

             ...
	    else if (PyNumber_Check(v)) {
		if (mxODBC_DateStructFromFloat(dbcs, v, param, row)) {
		    if (!PyErr_Occurred())
			PyErr_Format(PyExc_TypeError,
	   "parameter %i in row %i must be a mxODBC date float",
				     column, row);
		    goto onError;
		}
	    }
	    else if (PyString_Check(v)) {
		param->data = (SQLPOINTER)(PyString_AS_STRING(v));
		param->data_len = strlen(PyString_AS_STRING(v));
		param->ctype = SQL_C_CHAR;
	    }

With the new semantics, the PyNumber_Check() test would
succeed for strings, making the second test a no-op.

I would expect that this kind of switching on types is
not uncommon for code which works in polymorphic ways.

> PyNumber_Check() comes from an old era, when the presence or absence
> of the as_number "extension" to the type object was thought to be
> useful.  If I had to do it over, I wouldn't provide PyNumber_Check()
> at all (nor PySequence_Check() nor PyMapping_Check()).

Ok, but why not fix those APIs to mean something more
useful than deprecating them ? E.g. I would expect that
a number is usable as input to float(), int() or long()
and that a mapping knows at least about __getitem__.

-- 
Marc-Andre Lemburg
CEO eGenix.com Software GmbH
_______________________________________________________________________
eGenix.com -- Makers of the Python mx Extensions: mxDateTime,mxODBC,...
Python Consulting:                               http://www.egenix.com/
Python Software:                    http://www.egenix.com/files/python/