[Cython] 'with gil:' statement

Stefan Behnel stefan_ml at behnel.de
Wed Mar 16 16:14:25 CET 2011


mark florisson, 16.03.2011 11:28:
> I implemented the 'with gil:' statement
> [...]
> The 'with gil:' statement can now be used in the same way as 'with
> nogil:'. Exceptions raised from GIL blocks will be propagated if
> possible (i.e., if the return type is 'object'). Otherwise it will
> jump to the end of the function and use the usual
> __Pyx_WriteUnraisable, there's not really anything new there.

I'm not sure if this is a good idea. "nogil" blocks don't have a way to 
handle exceptions, so simply jumping out of them because an inner 'with 
gil' block raised an exception can have unexpected side effects.

Would you do the same when calling a cdef function that uses "with gil" in 
its signature? We don't currently do that, but it feels like it's the same 
situation.


> For functions declared 'nogil' that contain 'with gil:' statements, it
> will safely lock around around the initialization of any Python
> objects and set up the refnanny context (with appropriate preprocessor
> guards). At the end of the function it will safely lock around the
> teardown of the refnanny context. With 'safely' I mean that it will
> create a thread state if it was not already created and may be called
> even while the GIL is already held (using PyGILState_Ensure()). This
> means variables are declared and initialized in the same way as in
> normal GIL-holding functions (except that there is additional
> locking), and of course the GIL-checking code ensures that errors are
> issued if those variables are attempted to be used outside any GIL
> blocks.

I find that surprising semantics. So the GIL will always be acquired at 
least twice in the following example, regardless of the input?

     cdef int callme(bint flag) nogil:
          if flag:
              with gil: x = object()


> Could someone review the patch (which is attached)? Maybe check if I
> haven't missed any side cases and such?

 From a first look, the test file you added seems far too short. I would 
expect that this feature requires a lot more testing in combination with 
declared and undeclared local variables, type inference, several exception 
raising and catching situations (e.g. raise in one block, catch in an outer 
block, try-finally, ...) or looping. It may also have an impact on Vitja's 
control flow analysis branch that's worth considering.

Stefan


More information about the cython-devel mailing list