[Python-Dev] PyRange_New() alternative? (original) (raw)

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 PYVERSIONHEX >= 0x02030000 PyObjectCallFunction( (PyObject*) &PyRangeType, "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 PyRangeNew(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 PyRangeType 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*) &PyRangeType 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 PyRangeNew() 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

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