[Python-Dev] PyRange_New() alternative?
Tim Peters
tim.peters at gmail.com
Fri Jun 23 10:40:12 CEST 2006
[Ralf W. Grosse-Kunstleve]
> Thanks! This does the trick for me:
>
> #if PY_VERSION_HEX >= 0x02030000
> PyObject_CallFunction(
> (PyObject*) &PyRange_Type, "lll", start, start+len*step, step)
Note that this is extremely lax about possible overflow in the
arithmetic. For that reason it can't be recommend for general use.
> #else
> PyRange_New(start, len, step, 1)
> #endif
>
> I've tested this with Python 2.2.3, 2.3.4, 2.4.3, 2.5b1. Python 2.2.3 (RedHat
> WS 3) compiles the PyRange_Type call, but there is a runtime error:
>
> TypeError: cannot create 'xrange' instances
Sorry, I didn't follow that. The only mention of PyRange_Type in the
#if'ed code above is in a block that looks like it should be entirely
ignored in a 2.2.3 Python (provided you're using the right header
files and the C compiler isn't broken).
> I am compiling the code above with a C++ compiler (in the context of
> Boost.Python). Newer g++ versions unfortunatly produce a warning if -Wall is
> specified:
>
> warning: dereferencing type-punned pointer will break strict-aliasing rules
>
> This refers to the (PyObject*) &PyRange_Type cast.
> I believe the warning is bogus, but people still get upset about it (google the
> C++-SIG archive).
Compile all of Python that way, and you'll probably see more of those
than you can count ;-) Python is normally compiled with, and is
_intended_ to be compiled with,
-fno-strict-aliasing
If you didn't do that, try it.
> Is there a chance that PyRange_New() could be resurrected,
> with the fragment above (plus additional overflow check for start+len*step) as
> the implementation? That would fix the problems of the old implementation,
> there would be no reason to have the cast in C++, no frustrated end-users, and
> one change less to document.
The deprecation of PyRange_New was duly announced in the NEWS file for
Python 2.4:
"""
What's New in Python 2.4 (release candidate 1)
==============================================
*Release date: 18-NOV-2004*
...
C API
-----
- The PyRange_New() function is deprecated.
"""
Since it was never documented to begin with, it was a "use at your own
risk" thing anyway. As you're currently it's only known user
throughout all of history :-), if you do all the work of
rehabilitating it, I'd be at best a weak -1 anyway: one of the
problems with PyRange_New was that its signature was wildly different
than the builtin range()'s. That made it a poor API for "surprise,
surprise!" reasons alone. That was a mistake, and I'd rather
inconvenience you than pass that mistake on to our precious children
;-)
OTOH, I'd have no objection to a new C API function with a (start,
stop, step) signature.
More information about the Python-Dev
mailing list