[C++-sig] CallPolicies postcall not being called when an exception's raised?

Nick Rasmussen nick at ilm.com
Thu Feb 9 20:11:58 CET 2006


The docs at first glance seem to indicate that the postcall of a call
policy gets invoked even if an exception is raised:

------------------------------------------------------------------------
|x.postcall(a, r)

|convertible to |PyObject*
|
0 |0| and |PyErr_Occurred() != 0| upon failure. Must "conserve references"
even in the event of an exception. In other words, if |r| is not returned,
its reference count must be decremented; if another existing object is
returned, its reference count must be incremented.
------------------------------------------------------------------------

Which led me initially to believe that the call order looked something like:

  precall();
  handle_exception(invoke());
  postcall();

Looking at the code, however, it seems like this is what's actually
happening is:

  call() {
    precall();
    invoke();
    postcall();
  }

  handle_exception(call());

Which in retrospect makes a lot of sense if you want to ensure you don't
propagate exceptions back into the interpreter :)


For better or worse, we have a mechanism that raises c++ exceptions from
floating point exceptions.  We obviously don't want this mechanism active
inside the python interpreter, but would like to have it active when
certain functions are invoked.   Although CallPolicies are designed to
deal with object ownership issues, it seemed like a place where we could
hook entry and exit of our functions to enable and disable this exception
generation, basically:

   def("f",&f,with_fpe_exceptions_on<default_call_policies>());

But as the postcall of a policy is skipped if an exception is thrown, we're
potentially leaving the FPE->exception translation on.  My question is:

Is there a better way to hook this?

If the CallPolicies mechanism is the right thing to use for this, should
there be an additional function called when an exception's raised?

  call() {
    precall();
    try {
      invoke();
    catch(...) {
      postcall_exception();
      throw;
    }
    postcall();
  }

  handle_exception(call());


-nick



More information about the Cplusplus-sig mailing list