[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