0.9.9 Release Notes

# Release Notes for Pyrex 0.9.9

## C++ Features

Some features for interfacing with C++ code have been introduced in this release. Structs declared with 'cdef+ struct' may have constructors and member functions, there is a 'new' operator for instantiating them, and they may be deallocated using the 'del' operator. Details may be found in the Language Overview under Using Pyrex with C++.

## Changes to Exception Semantics

The behaviour surrounding exceptions caught using a try-except statement were previously an inconsistent mixture of Pyrex and Python semantics. Attempts to make the behaviour match Python more closely were requiring the generation of increasingly convoluted and inefficient code, so I decided to backtrack and return to something simpler.
Pyrex no longer places caught exceptions into the thread state. This ensures that exceptions and tracebacks do not leak out of the except clause that caught them, unless you do something to explicitly preserve them.
It also means that you cannot retrieve an caught exception in Pyrex using sys.exc_info(). If you want to capture the exception, you need to bind it to a name in the except clause.
To capture the traceback, the syntax of the except clause has been extended to allow a third argument. For example,

    try:
      start_vehicle()
    except HovercraftError, err, tb:
      print "Can't start:", err
      traceback.print_tb(tb)

As previously, a raise statement with no arguments must be lexically enclosed in the except clause which caught the exception that you are trying to re-raise. In order to re-raise it from somewhere else, you will need to explicity communicate the exception and traceback to that place and use an ordinary raise statement.

## Planned Change to None-checking

Currently, an argument to a Python function that is declared as an extension type will, by default, be allowed to receive the value None; to prevent this, you must qualify the argument declaration with 'not None'.
This arrangement has proved to be error-prone, because it requires the programmer to be aware of the 'not None' feature and to remember to use it everywhere necessary. Failure to do so results in a Pyrex module that is prone to being crashed hard if it is passed a None value that it is not expecting.
To improve this situation, I am planning to make 'not None' the default in a future release of Pyrex. In order to allow None as a legal argument value, it will be necessary to use an 'or None' qualifier.
In release 0.9.9, the 'or None' qualifier may be used, but it is optional. In preparation for the change of default, the Pyrex compiler will issue a warning (once per run) if it encounters an extension type argument that is not qualified with either 'or None' or 'not None'. For example, if Spam and Eggs are extension types and you have a function declared as

    def frobulate(Spam s, Eggs e not None):
      ...

then in order to eliminate the warning, you will need to change it to

    def frobulate(Spam s or None, Eggs e not None):
      ...

In a later release, when 'not None' has become the default, it will be possible to drop the 'not None' qualifiers.

## Non-GC Extension Types

It is now possible to define and extension type with Python attributes that does not participate in cyclic garbage collection, using a new nogc option, for example:

    cdef class Spam [nogc]:
      """This class doesn't participate in GC even though
         it has a Python attribute."""
      object sausages

## Other New Features

Some other minor feature additions and modifications have been made.

- size_t is now a built-in type and is the type returned by the sizeof operator. Also, the sizes of size_t and Py_ssize_t are now assumed to be somewhere between long and long long.
- Operations between two int types of the same rank now return an unsigned result if either of the operands is unsigned; if the ranks differ, the result has the same type as the wider-ranked operand. I think this is the best approximation of the ANSI C rules that is possible without knowing the exact sizes of the types.
- PyString_InternFromString is now exposed under the name cintern rather than intern, because it is not a complete replacement for the Python intern function (it can't handle strings containing null bytes).
- The size check that was previously generated when importing an extension type has been disabled for the time being until I can think of something better. It was generating too many false positives, for example from different versions of numpy.
- The __fastcall calling convention option is now supported. Also, Pyrex no longer assumes that __cdecl is the default calling convention. To be considered compatible, two function types must either be declared with the same calling convention, or both must leave it unspecified.
- As I have been threatening for some time, using __new__ as the name of the initialisation method of an extension type has become an error rather than just a warning. In some future release, __new__ will re-emerge with more Python-like semantics.