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) ?! -- 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/
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. 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()). --Guido van Rossum (home page: http://www.python.org/~guido/)
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/
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)) {
When you pass a class instance that doesn't support __float__, you'll get an error from the code below:
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.
Alas, I agree with this expectation, even though I believe that such code is based on a misunderstanding. :-(
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__.
Maybe, as long as we all agree that that's *exactly* what they check for, and as long as we agree that there may be overlapping areas (where two or more of these will return True). PyMapping_Check() returns true for a variety of non-mappings like strings, lists, and all classic instances. --Guido van Rossum (home page: http://www.python.org/~guido/)
[Changing PyNumber_Check() to return True for strings] Guido van Rossum wrote:
[Example switching on object types where the PyNumber_Check() preceeds the PyString_Check()]
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.
Alas, I agree with this expectation, even though I believe that such code is based on a misunderstanding. :-(
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__.
Maybe, as long as we all agree that that's *exactly* what they check for, and as long as we agree that there may be overlapping areas (where two or more of these will return True).
PyMapping_Check() returns true for a variety of non-mappings like strings, lists, and all classic instances.
Perhaps we should simply keep the existing semantics for those two APIs, that is, ensure that they return the same results for the standard builtin types as they did in Python 2.2 and below ?! This would mean that a special case would have to be added to PyNumber_Check() to have it return False for strings and Unicode. -- 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/
Maybe, as long as we all agree that that's *exactly* what they check for, and as long as we agree that there may be overlapping areas (where two or more of these will return True).
PyMapping_Check() returns true for a variety of non-mappings like strings, lists, and all classic instances.
Perhaps we should simply keep the existing semantics for those two APIs, that is, ensure that they return the same results for the standard builtin types as they did in Python 2.2 and below ?!
That's a new way of defining their semantics, but I can agree with it!
This would mean that a special case would have to be added to PyNumber_Check() to have it return False for strings and Unicode.
Somebody (MWH?) proposed to test for one or nb_int/nb_long/nb_float. That makes sense to me, and should do what you ask for. --Guido van Rossum (home page: http://www.python.org/~guido/)
participants (2)
-
Guido van Rossum
-
M.-A. Lemburg