Re: [Cython] [cython-users] C++: how to handle failures of 'new'?

2012-07-03 Thread Stefan Behnel
Robert Bradshaw, 29.06.2012 11:08:
> On Thu, Jun 28, 2012 at 10:45 PM, Stefan Behnel wrote:
>> Robert Bradshaw, 28.06.2012 21:46:
>>> On Thu, Jun 28, 2012 at 11:38 AM, Stefan Behnel wrote:
 currently, when I write "new CppClass()" in Cython, it generates a straight
 call to the "new" operator. It doesn't do any error handling. And the
 current documentation doesn't even mention this case.

 Is there a "standard" way to handle this? It seems that C++ has different
 ways to deal with failures here but raises an exception by default. Would
 you declare the constructor(s) with an "except +MemoryError"? Is there a
 reason Cython shouldn't be doing this automatically (if nothing else was
 declared) ?
>>>
>>> I think it certainly makes sense to declare the default constructor as
>>> "except +" (and std::bad_alloc should become MemoryError),
>>
>> Right. The code in the constructor can raise other exceptions that must
>> also be handled properly. An explicit "except +" will handle that.
>>
>>
>>> but whether
>>> to implicitly annotate declared constructors is less clear, especially
>>> as there's no way to un-annotate them.
>>
>> I agree, but sadly, it's the default behaviour that is wrong. I'm sure we
>> made lots of users run into this trap already. I fixed the documentation
>> for now, but the bottom line is that we require users to take care of
>> proper declarations themselves. Otherwise, the code that we generate is
>> incorrect, although it's 100% certain that an allocation error can occur,
>> even if the constructor code doesn't raise any exceptions itself.
> 
> This is always the case.

Sure, we always rely on correct declarations. However, this is a case where
we *know* that bad things can happen, even if there is no declaration for
them. It would be nice to play safe by default.

IMHO, only the second best solution would be to raise a warning when we
encounter a "new" without an exception declared, so that users are urged
into writing safe code.


>> Apparently, changing the behaviour of the "new" operator requires a special
>> annotation "std::nothrow", which then returns NULL on allocation failures.
>> You can pass that from Cython by hacking up a cname, e.g.
>>
>>Rectangle "(std::nothrow) Rectangle" (int w, int h)
>>
>> I'm sure there are users out there who figured this out (I mean, I did...)
>> and use it in their code, so I agree that this isn't easy to handle because
>> Cython simply wouldn't know what the actual error behaviour is for a given
>> constructor and how to correctly detect an error.
>>
>> This problem applies only to heap allocation in that form. However, stack
>> allocation and the new exttype field allocation suffer from similar
>> problems when the default constructor raises an exception. Exttype fields
>> are a particularly nasty case because the user has no control over the
>> allocation. A C++ exception in the C++ class constructor would terminate
>> the exttype constructor unexpectedly and thus leak resources (in the best
>> case - no idea how CPython reacts if you throw a C++ exception through its
>> type instantiation code).
> 
> If the default constructor raises an exception then it should be
> declared (to not do so is an error on the users part). New raising
> bad_alloc is a bit of a special case, but doesn't appl to the stack or
> exttype allocations.

Right. In those two cases, it would definitely be the fault of the user.


>> Similarly, a C++ exception in the constructor of a stack allocated object
>> would then originate from the function entry code and potentially hit the
>> Python function wrapper etc. Again, potentially leaking resources or worse.
>>
>> To me, this sounds like we should do something about it. At least for the
>> implicit calls to the default constructor, we should generate "except +"
>> code automatically because there is no other way to handle them safely.
> 
> If no constructor is declared, it should be "except +" just to be
> safe

Ok, I'll fix it.


> but otherwise I don't see how this is any different than
> forgetting to declare exceptions on any other function. Unfortunately
> catching exceptions  (with custom per-object handling) on a set of
> stack allocated objects seems difficult if not impossible (without
> resorting to ugly hacks like using placement new everywhere).

I don't know what happens if a C++ exception is not being caught, but I
guess it would simply crash the application. That's a bit more visible than
just printing a warning when a Python exception is being ignored due to a
missing declaration. It's really unfortunate that our documentation didn't
even mention the need for this, because it's not immediately obvious that
Cython won't handle errors in "new", and testing for memory errors isn't
quite what people commonly do in their test suites.

Apart from that, I agree, users have to take care to properly declare the
API they are using.

Stefan

Re: [Cython] Cython methods for C/C++ types

2012-07-03 Thread mark florisson
On 3 July 2012 05:58, Stefan Behnel  wrote:
> Hi,
>
> the discussion on allowing for automatic user provided ways to coerce
> between Python types and C++ types got me thinking that this might hide a
> rather interesting general feature: methods for low-level types. I faintly
> remember that this idea has come up in our discussions before, but here's a
> draft CEP for it:
>
> http://wiki.cython.org/enhancements/ctypemethods
>
> Basically, it would allow writing this in .pxd files:
>
> """
> cdef extern from "...":
> cdef cppclass MyClass:
> cdef int cython_method_here(self):
> return 1
>
> ctypedef double mydouble:
> cdef double cython_method_here(self):
> return self ** 2
>
> cdef struct mystruct:
> int x, y
>
> cdef int cython_method_here(self):
> return self.x + self.y
>
> cdef union myunion:
> int a
> double b
>
> cdef int cython_method_here(self):
> return self.a if ImSureImAnInt else self.b
> """
>
> The C code for these methods would then be generated into the modules that
> use these types, similar to what we allow with "__getbuffer__()". Calls
> would be direct function calls as with "final" methods.
>
> I think it fits into what's there in a very natural way.
>
> Stefan
> ___
> cython-devel mailing list
> cython-devel@python.org
> http://mail.python.org/mailman/listinfo/cython-devel

Looks a bit like C++. I have no strong feelings either way, it would
simplify the memoryview implementation slightly, which special-cases
the memoryview struct with method attributes. I would prefer to keep
the language simple however, and have people write functions operating
on structs. It's really the same thing written differently, and
methods don't really bring an advantage since the data in the struct
cannot be hidden or readonly.
___
cython-devel mailing list
cython-devel@python.org
http://mail.python.org/mailman/listinfo/cython-devel


Re: [Cython] Cython methods for C/C++ types

2012-07-03 Thread mark florisson
On 3 July 2012 05:58, Stefan Behnel  wrote:
> Hi,
>
> the discussion on allowing for automatic user provided ways to coerce
> between Python types and C++ types got me thinking that this might hide a
> rather interesting general feature: methods for low-level types. I faintly
> remember that this idea has come up in our discussions before, but here's a
> draft CEP for it:
>
> http://wiki.cython.org/enhancements/ctypemethods

I see this CEP also mentions overriding C++ methods. But I think if it
doesn't support virtual methods, then overriding base class methods by
calling another function is pretty horrible.

> Basically, it would allow writing this in .pxd files:
>
> """
> cdef extern from "...":
> cdef cppclass MyClass:
> cdef int cython_method_here(self):
> return 1
>
> ctypedef double mydouble:
> cdef double cython_method_here(self):
> return self ** 2
>
> cdef struct mystruct:
> int x, y
>
> cdef int cython_method_here(self):
> return self.x + self.y
>
> cdef union myunion:
> int a
> double b
>
> cdef int cython_method_here(self):
> return self.a if ImSureImAnInt else self.b
> """
>
> The C code for these methods would then be generated into the modules that
> use these types, similar to what we allow with "__getbuffer__()". Calls
> would be direct function calls as with "final" methods.
>
> I think it fits into what's there in a very natural way.
>
> Stefan
> ___
> cython-devel mailing list
> cython-devel@python.org
> http://mail.python.org/mailman/listinfo/cython-devel
___
cython-devel mailing list
cython-devel@python.org
http://mail.python.org/mailman/listinfo/cython-devel


Re: [Cython] Exception: Tests in module 'parallel' were unexpectedly killed by signal 11

2012-07-03 Thread mark florisson
On 3 July 2012 00:04, Yaroslav Halchenko  wrote:
> please pardon my sloppy cut/paste which ruined the subject line in the
> original post ;)  So the topic is:
>
> On Mon, 02 Jul 2012, Yaroslav Halchenko wrote:
>> I was thinking about updating Debian package for cython 0.16 but ran into
>> the failing unittests so decided first to check with experts: anything 
>> obvious
>> which comes to mind from seeing those?
>
>> ...
>> compiling (c) and running sequential_parallel ... sequential_parallel.c: In 
>> function '__pyx_pf_19sequential_parallel_56test_chunksize':
>> sequential_parallel.c:12405:7: warning: variable '__pyx_t_6' set but not 
>> used [-Wunused-but-set-variable]
>> sequential_parallel.c:12404:7: warning: variable '__pyx_t_5' set but not 
>> used [-Wunused-but-set-variable]
>> sequential_parallel.c:12402:7: warning: variable '__pyx_t_3' set but not 
>> used [-Wunused-but-set-variable]
>> sequential_parallel.c: In function 
>> '__pyx_pw_19sequential_parallel_25test_nested_break_continue':
>> sequential_parallel.c:5887:29: warning: '__pyx_v_j' may be used 
>> uninitialized in this function [-Wmaybe-uninitialized]
>> sequential_parallel.c:5590:7: note: '__pyx_v_j' was declared here
>> sequential_parallel.c: In function 
>> '__pyx_f_19sequential_parallel_parallel_exc_cpdef_unnested.isra.29':
>> sequential_parallel.c:8915:3: warning: '__pyx_r' may be used uninitialized 
>> in this function [-Wmaybe-uninitialized]
>> sequential_parallel.c:8681:7: note: '__pyx_r' was declared here
>> sequential_parallel.c: In function 
>> '__pyx_f_19sequential_parallel_parallel_exc_cpdef.isra.30':
>> sequential_parallel.c:8614:3: warning: '__pyx_r' may be used uninitialized 
>> in this function [-Wmaybe-uninitialized]
>> sequential_parallel.c:8259:7: note: '__pyx_r' was declared here
>> sequential_parallel.c: In function 
>> '__pyx_pw_19sequential_parallel_33test_parallel_exc_cdef':
>> sequential_parallel.c:8222:78: warning: '__pyx_r' may be used uninitialized 
>> in this function [-Wuninitialized]
>> sequential_parallel.c:7946:7: note: '__pyx_r' was declared here
>> sequential_parallel.c:8233:69: warning: '__pyx_r' may be used uninitialized 
>> in this function [-Wuninitialized]
>> sequential_parallel.c:7578:7: note: '__pyx_r' was declared here
>> Fatal Python error: deletion of interned string failed
>> Compiling 
>> /tmp/buildd/.cython/inline/_cython_inline_a998a12d3d1450b2368ca75e07a27942.pyx
>>  because it changed.
>> Cythonizing 
>> /tmp/buildd/.cython/inline/_cython_inline_a998a12d3d1450b2368ca75e07a27942.pyx
>> ERROR
>> ...
>> ==
>> ERROR: compiling (c) and running parallel
>> --
>> Traceback (most recent call last):
>>   File "runtests.py", line 707, in run
>> self.run_tests(result)
>>   File "runtests.py", line 723, in run_tests
>> self.run_doctests(self.module, result)
>>   File "runtests.py", line 729, in run_doctests
>> run_forked_test(result, run_test, self.shortDescription(), self.fork)
>>   File "runtests.py", line 778, in run_forked_test
>> (module_name, result_code & 255))
>> Exception: Tests in module 'parallel' were unexpectedly killed by signal 11
>
>> ==
> --
> Yaroslav O. Halchenko
> Postdoctoral Fellow,   Department of Psychological and Brain Sciences
> Dartmouth College, 419 Moore Hall, Hinman Box 6207, Hanover, NH 03755
> Phone: +1 (603) 646-9834   Fax: +1 (603) 646-1419
> WWW:   http://www.linkedin.com/in/yarik
> ___
> cython-devel mailing list
> cython-devel@python.org
> http://mail.python.org/mailman/listinfo/cython-devel

Thanks for the report, I'll have a look.
___
cython-devel mailing list
cython-devel@python.org
http://mail.python.org/mailman/listinfo/cython-devel


Re: [Cython] Cython methods for C/C++ types

2012-07-03 Thread Stefan Behnel
mark florisson, 03.07.2012 12:15:
> On 3 July 2012 05:58, Stefan Behnel wrote:
>> the discussion on allowing for automatic user provided ways to coerce
>> between Python types and C++ types got me thinking that this might hide a
>> rather interesting general feature: methods for low-level types. I faintly
>> remember that this idea has come up in our discussions before, but here's a
>> draft CEP for it:
>>
>> http://wiki.cython.org/enhancements/ctypemethods
> 
> I see this CEP also mentions overriding C++ methods. But I think if it
> doesn't support virtual methods, then overriding base class methods by
> calling another function is pretty horrible.

Right, I didn't think that part through. If we don't know the real type at
compile time and get a subtype at runtime then we'll call the wrong code.

I agree that that's not a desirable feature.

Stefan
___
cython-devel mailing list
cython-devel@python.org
http://mail.python.org/mailman/listinfo/cython-devel


Re: [Cython] [cython-users] C++: how to handle failures of 'new'?

2012-07-03 Thread Dag Sverre Seljebotn

On 07/03/2012 09:14 AM, Stefan Behnel wrote:

Robert Bradshaw, 29.06.2012 11:08:

On Thu, Jun 28, 2012 at 10:45 PM, Stefan Behnel wrote:

Robert Bradshaw, 28.06.2012 21:46:

On Thu, Jun 28, 2012 at 11:38 AM, Stefan Behnel wrote:

currently, when I write "new CppClass()" in Cython, it generates a straight
call to the "new" operator. It doesn't do any error handling. And the
current documentation doesn't even mention this case.

Is there a "standard" way to handle this? It seems that C++ has different
ways to deal with failures here but raises an exception by default. Would
you declare the constructor(s) with an "except +MemoryError"? Is there a
reason Cython shouldn't be doing this automatically (if nothing else was
declared) ?


I think it certainly makes sense to declare the default constructor as
"except +" (and std::bad_alloc should become MemoryError),


Right. The code in the constructor can raise other exceptions that must
also be handled properly. An explicit "except +" will handle that.



but whether
to implicitly annotate declared constructors is less clear, especially
as there's no way to un-annotate them.


I agree, but sadly, it's the default behaviour that is wrong. I'm sure we
made lots of users run into this trap already. I fixed the documentation
for now, but the bottom line is that we require users to take care of
proper declarations themselves. Otherwise, the code that we generate is
incorrect, although it's 100% certain that an allocation error can occur,
even if the constructor code doesn't raise any exceptions itself.


This is always the case.


Sure, we always rely on correct declarations. However, this is a case where
we *know* that bad things can happen, even if there is no declaration for
them. It would be nice to play safe by default.

IMHO, only the second best solution would be to raise a warning when we
encounter a "new" without an exception declared, so that users are urged
into writing safe code.



Apparently, changing the behaviour of the "new" operator requires a special
annotation "std::nothrow", which then returns NULL on allocation failures.
You can pass that from Cython by hacking up a cname, e.g.

Rectangle "(std::nothrow) Rectangle" (int w, int h)

I'm sure there are users out there who figured this out (I mean, I did...)
and use it in their code, so I agree that this isn't easy to handle because
Cython simply wouldn't know what the actual error behaviour is for a given
constructor and how to correctly detect an error.

This problem applies only to heap allocation in that form. However, stack
allocation and the new exttype field allocation suffer from similar
problems when the default constructor raises an exception. Exttype fields
are a particularly nasty case because the user has no control over the
allocation. A C++ exception in the C++ class constructor would terminate
the exttype constructor unexpectedly and thus leak resources (in the best
case - no idea how CPython reacts if you throw a C++ exception through its
type instantiation code).


If the default constructor raises an exception then it should be
declared (to not do so is an error on the users part). New raising
bad_alloc is a bit of a special case, but doesn't appl to the stack or
exttype allocations.


Right. In those two cases, it would definitely be the fault of the user.



Similarly, a C++ exception in the constructor of a stack allocated object
would then originate from the function entry code and potentially hit the
Python function wrapper etc. Again, potentially leaking resources or worse.

To me, this sounds like we should do something about it. At least for the
implicit calls to the default constructor, we should generate "except +"
code automatically because there is no other way to handle them safely.


If no constructor is declared, it should be "except +" just to be
safe


Ok, I'll fix it.



but otherwise I don't see how this is any different than
forgetting to declare exceptions on any other function. Unfortunately
catching exceptions  (with custom per-object handling) on a set of
stack allocated objects seems difficult if not impossible (without
resorting to ugly hacks like using placement new everywhere).


I don't know what happens if a C++ exception is not being caught, but I
guess it would simply crash the application. That's a bit more visible than


Yep.


just printing a warning when a Python exception is being ignored due to a
missing declaration. It's really unfortunate that our documentation didn't
even mention the need for this, because it's not immediately obvious that
Cython won't handle errors in "new", and testing for memory errors isn't
quite what people commonly do in their test suites.

Apart from that, I agree, users have to take care to properly declare the
API they are using.


Is there any time you do NOT want a "catch (...) {}" block? I can't see 
a C++ exception propagating to Python-land doing anything useful ever.


So shouldn't we just make --cplus tur

Re: [Cython] [cython-users] C++: how to handle failures of 'new'?

2012-07-03 Thread Stefan Behnel
Dag Sverre Seljebotn, 03.07.2012 18:11:
> On 07/03/2012 09:14 AM, Stefan Behnel wrote:
>> I don't know what happens if a C++ exception is not being caught, but I
>> guess it would simply crash the application. That's a bit more visible than
> 
> Yep.
> 
>> just printing a warning when a Python exception is being ignored due to a
>> missing declaration. It's really unfortunate that our documentation didn't
>> even mention the need for this, because it's not immediately obvious that
>> Cython won't handle errors in "new", and testing for memory errors isn't
>> quite what people commonly do in their test suites.
>>
>> Apart from that, I agree, users have to take care to properly declare the
>> API they are using.
> 
> Is there any time you do NOT want a "catch (...) {}" block? I can't see a
> C++ exception propagating to Python-land doing anything useful ever.

That would have been my intuition, too.


> So shouldn't we just make --cplus turn *all* external functions and methods
> (whether C-like or C++-like) into "except +"? (Or keep except+ for manual
> translation, but always have a catch(...)".
>
> Performance overhead is the only reason I can think of to not do this,
> although IIRC C++ catch blocks are only dealt with during stack unwinds and
> doesn't cost anything/much (?) when they're not triggered.
> 
> "except -1" should then actually mean both; "except + except -1". So it's
> more a question of just adding catch(...) *everywhere*, than making "except
> +" the default.

I have no idea if there is a performance impact, but if there isn't, always
catching all exceptions sounds like a reasonable thing to do. After all, we
have no support for catching C++ exceptions on user side.

Stefan
___
cython-devel mailing list
cython-devel@python.org
http://mail.python.org/mailman/listinfo/cython-devel


Re: [Cython] [cython-users] C++: how to handle failures of 'new'?

2012-07-03 Thread Robert Bradshaw
On Tue, Jul 3, 2012 at 9:38 AM, Stefan Behnel  wrote:
> Dag Sverre Seljebotn, 03.07.2012 18:11:
>> On 07/03/2012 09:14 AM, Stefan Behnel wrote:
>>> I don't know what happens if a C++ exception is not being caught, but I
>>> guess it would simply crash the application. That's a bit more visible than
>>
>> Yep.
>>
>>> just printing a warning when a Python exception is being ignored due to a
>>> missing declaration. It's really unfortunate that our documentation didn't
>>> even mention the need for this, because it's not immediately obvious that
>>> Cython won't handle errors in "new", and testing for memory errors isn't
>>> quite what people commonly do in their test suites.
>>>
>>> Apart from that, I agree, users have to take care to properly declare the
>>> API they are using.
>>
>> Is there any time you do NOT want a "catch (...) {}" block? I can't see a
>> C++ exception propagating to Python-land doing anything useful ever.
>
> That would have been my intuition, too.

If it's actually embedded, with the main driver in C++, one might want
it to propagate up.

>> So shouldn't we just make --cplus turn *all* external functions and methods
>> (whether C-like or C++-like) into "except +"? (Or keep except+ for manual
>> translation, but always have a catch(...)".
>>
>> Performance overhead is the only reason I can think of to not do this,
>> although IIRC C++ catch blocks are only dealt with during stack unwinds and
>> doesn't cost anything/much (?) when they're not triggered.
>>
>> "except -1" should then actually mean both; "except + except -1". So it's
>> more a question of just adding catch(...) *everywhere*, than making "except
>> +" the default.
>
> I have no idea if there is a performance impact, but if there isn't, always
> catching all exceptions sounds like a reasonable thing to do. After all, we
> have no support for catching C++ exceptions on user side.

This is a bit like following every C call with "except *" (though the
performance ratios are unclear). It just seems a lot to wrap every
single line of a non-trivial C++ using function with try..catch
blocks. I also don't think this would play well with Pynac (from Sage)
which is a C++ library with Cython callbacks that may call back into
the library and raise C++ exceptions (but that does feel a bit risky
anyways).

- Robert
___
cython-devel mailing list
cython-devel@python.org
http://mail.python.org/mailman/listinfo/cython-devel


Re: [Cython] [cython-users] C++: how to handle failures of 'new'?

2012-07-03 Thread Stefan Behnel
Robert Bradshaw, 03.07.2012 19:58:
> On Tue, Jul 3, 2012 at 9:38 AM, Stefan Behnel wrote:
>> Dag Sverre Seljebotn, 03.07.2012 18:11:
>>> On 07/03/2012 09:14 AM, Stefan Behnel wrote:
 I don't know what happens if a C++ exception is not being caught, but I
 guess it would simply crash the application. That's a bit more visible than
>>>
>>> Yep.
>>>
 just printing a warning when a Python exception is being ignored due to a
 missing declaration. It's really unfortunate that our documentation didn't
 even mention the need for this, because it's not immediately obvious that
 Cython won't handle errors in "new", and testing for memory errors isn't
 quite what people commonly do in their test suites.

 Apart from that, I agree, users have to take care to properly declare the
 API they are using.
>>>
>>> Is there any time you do NOT want a "catch (...) {}" block? I can't see a
>>> C++ exception propagating to Python-land doing anything useful ever.
>>
>> That would have been my intuition, too.
> 
> If it's actually embedded, with the main driver in C++, one might want
> it to propagate up.

But what kind of a propagation would that be? On the way out, it could
induce anything, from side effects to resource leaks to crashes, depending
on what the state of the surrounding code is. It would leave the whole
system in an unpredictable state. I cannot imagine anyone really wanting this.


>>> So shouldn't we just make --cplus turn *all* external functions and methods
>>> (whether C-like or C++-like) into "except +"? (Or keep except+ for manual
>>> translation, but always have a catch(...)".
>>>
>>> Performance overhead is the only reason I can think of to not do this,
>>> although IIRC C++ catch blocks are only dealt with during stack unwinds and
>>> doesn't cost anything/much (?) when they're not triggered.
>>>
>>> "except -1" should then actually mean both; "except + except -1". So it's
>>> more a question of just adding catch(...) *everywhere*, than making "except
>>> +" the default.
>>
>> I have no idea if there is a performance impact, but if there isn't, always
>> catching all exceptions sounds like a reasonable thing to do. After all, we
>> have no support for catching C++ exceptions on user side.
> 
> This is a bit like following every C call with "except *" (though the
> performance ratios are unclear). It just seems a lot to wrap every
> single line of a non-trivial C++ using function with try..catch
> blocks.

But if users are correct about their declarations, we'd end up with the
same thing. I think it's worth a try.

Stefan
___
cython-devel mailing list
cython-devel@python.org
http://mail.python.org/mailman/listinfo/cython-devel


Re: [Cython] [cython-users] C++: how to handle failures of 'new'?

2012-07-03 Thread Robert Bradshaw
On Tue, Jul 3, 2012 at 11:11 AM, Stefan Behnel  wrote:
> Robert Bradshaw, 03.07.2012 19:58:
>> On Tue, Jul 3, 2012 at 9:38 AM, Stefan Behnel wrote:
>>> Dag Sverre Seljebotn, 03.07.2012 18:11:
 On 07/03/2012 09:14 AM, Stefan Behnel wrote:
> I don't know what happens if a C++ exception is not being caught, but I
> guess it would simply crash the application. That's a bit more visible 
> than

 Yep.

> just printing a warning when a Python exception is being ignored due to a
> missing declaration. It's really unfortunate that our documentation didn't
> even mention the need for this, because it's not immediately obvious that
> Cython won't handle errors in "new", and testing for memory errors isn't
> quite what people commonly do in their test suites.
>
> Apart from that, I agree, users have to take care to properly declare the
> API they are using.

 Is there any time you do NOT want a "catch (...) {}" block? I can't see a
 C++ exception propagating to Python-land doing anything useful ever.
>>>
>>> That would have been my intuition, too.
>>
>> If it's actually embedded, with the main driver in C++, one might want
>> it to propagate up.
>
> But what kind of a propagation would that be? On the way out, it could
> induce anything, from side effects to resource leaks to crashes, depending
> on what the state of the surrounding code is. It would leave the whole
> system in an unpredictable state. I cannot imagine anyone really wanting this.
>
>
 So shouldn't we just make --cplus turn *all* external functions and methods
 (whether C-like or C++-like) into "except +"? (Or keep except+ for manual
 translation, but always have a catch(...)".

 Performance overhead is the only reason I can think of to not do this,
 although IIRC C++ catch blocks are only dealt with during stack unwinds and
 doesn't cost anything/much (?) when they're not triggered.

 "except -1" should then actually mean both; "except + except -1". So it's
 more a question of just adding catch(...) *everywhere*, than making "except
 +" the default.
>>>
>>> I have no idea if there is a performance impact, but if there isn't, always
>>> catching all exceptions sounds like a reasonable thing to do. After all, we
>>> have no support for catching C++ exceptions on user side.
>>
>> This is a bit like following every C call with "except *" (though the
>> performance ratios are unclear). It just seems a lot to wrap every
>> single line of a non-trivial C++ using function with try..catch
>> blocks.
>
> But if users are correct about their declarations, we'd end up with the
> same thing. I think it's worth a try.

Most C++ code (that I've ever run into) doesn't use exceptions,
because exception handling is so broken in C++ anyways.

- Robert
___
cython-devel mailing list
cython-devel@python.org
http://mail.python.org/mailman/listinfo/cython-devel


Re: [Cython] [cython-users] C++: how to handle failures of 'new'?

2012-07-03 Thread Dag Sverre Seljebotn

On 07/03/2012 08:23 PM, Robert Bradshaw wrote:

On Tue, Jul 3, 2012 at 11:11 AM, Stefan Behnel  wrote:

Robert Bradshaw, 03.07.2012 19:58:

On Tue, Jul 3, 2012 at 9:38 AM, Stefan Behnel wrote:

Dag Sverre Seljebotn, 03.07.2012 18:11:

On 07/03/2012 09:14 AM, Stefan Behnel wrote:

I don't know what happens if a C++ exception is not being caught, but I
guess it would simply crash the application. That's a bit more visible than


Yep.


just printing a warning when a Python exception is being ignored due to a
missing declaration. It's really unfortunate that our documentation didn't
even mention the need for this, because it's not immediately obvious that
Cython won't handle errors in "new", and testing for memory errors isn't
quite what people commonly do in their test suites.

Apart from that, I agree, users have to take care to properly declare the
API they are using.


Is there any time you do NOT want a "catch (...) {}" block? I can't see a
C++ exception propagating to Python-land doing anything useful ever.


That would have been my intuition, too.


If it's actually embedded, with the main driver in C++, one might want
it to propagate up.


But what kind of a propagation would that be? On the way out, it could
induce anything, from side effects to resource leaks to crashes, depending
on what the state of the surrounding code is. It would leave the whole
system in an unpredictable state. I cannot imagine anyone really wanting this.



So shouldn't we just make --cplus turn *all* external functions and methods
(whether C-like or C++-like) into "except +"? (Or keep except+ for manual
translation, but always have a catch(...)".

Performance overhead is the only reason I can think of to not do this,
although IIRC C++ catch blocks are only dealt with during stack unwinds and
doesn't cost anything/much (?) when they're not triggered.

"except -1" should then actually mean both; "except + except -1". So it's
more a question of just adding catch(...) *everywhere*, than making "except
+" the default.


I have no idea if there is a performance impact, but if there isn't, always
catching all exceptions sounds like a reasonable thing to do. After all, we
have no support for catching C++ exceptions on user side.


This is a bit like following every C call with "except *" (though the
performance ratios are unclear). It just seems a lot to wrap every
single line of a non-trivial C++ using function with try..catch
blocks.


It seems "a lot" of just what exactly? Generated code? Binary size? Time 
spent in GCC parser?


Though I guess one might want to try to pull out the try-catch to at 
least only one per code line rather than one per SimpleCallNode.


"except *" only has a point when calling functions using the CPython 
API, but most external C functions are pure C, not 
CPython-API-using-functions. OTOH, all external C++ functions are C++ :-)


(Also, if we wrote Cython from scratch now I'm pretty sure the "except 
*" defaults would be a tad different.)




But if users are correct about their declarations, we'd end up with the
same thing. I think it's worth a try.


Most C++ code (that I've ever run into) doesn't use exceptions,
because exception handling is so broken in C++ anyways.


Except for the fact that any code touching "new" could be raising 
exceptions? That propagates.


There is a lot of C++ code out there using exceptions. I'd guess that 
both mathematical code and Google-written code is unlike most C++ code 
out there :-) Many C++ programmers go on and on about RAII and auto_ptrs 
and so on, and that doesn't have much point unless you throw an 
exception now and then (OK, there's the occasional return statement 
where it matters well).


Dag
___
cython-devel mailing list
cython-devel@python.org
http://mail.python.org/mailman/listinfo/cython-devel


Re: [Cython] [cython-users] C++: how to handle failures of 'new'?

2012-07-03 Thread Dag Sverre Seljebotn

On 07/03/2012 08:23 PM, Robert Bradshaw wrote:

On Tue, Jul 3, 2012 at 11:11 AM, Stefan Behnel  wrote:

Robert Bradshaw, 03.07.2012 19:58:

On Tue, Jul 3, 2012 at 9:38 AM, Stefan Behnel wrote:

Dag Sverre Seljebotn, 03.07.2012 18:11:

On 07/03/2012 09:14 AM, Stefan Behnel wrote:

I don't know what happens if a C++ exception is not being caught, but I
guess it would simply crash the application. That's a bit more visible than


Yep.


just printing a warning when a Python exception is being ignored due to a
missing declaration. It's really unfortunate that our documentation didn't
even mention the need for this, because it's not immediately obvious that
Cython won't handle errors in "new", and testing for memory errors isn't
quite what people commonly do in their test suites.

Apart from that, I agree, users have to take care to properly declare the
API they are using.


Is there any time you do NOT want a "catch (...) {}" block? I can't see a
C++ exception propagating to Python-land doing anything useful ever.


That would have been my intuition, too.


If it's actually embedded, with the main driver in C++, one might want
it to propagate up.


But what kind of a propagation would that be? On the way out, it could
induce anything, from side effects to resource leaks to crashes, depending
on what the state of the surrounding code is. It would leave the whole
system in an unpredictable state. I cannot imagine anyone really wanting this.



So shouldn't we just make --cplus turn *all* external functions and methods
(whether C-like or C++-like) into "except +"? (Or keep except+ for manual
translation, but always have a catch(...)".

Performance overhead is the only reason I can think of to not do this,
although IIRC C++ catch blocks are only dealt with during stack unwinds and
doesn't cost anything/much (?) when they're not triggered.

"except -1" should then actually mean both; "except + except -1". So it's
more a question of just adding catch(...) *everywhere*, than making "except
+" the default.


I have no idea if there is a performance impact, but if there isn't, always
catching all exceptions sounds like a reasonable thing to do. After all, we
have no support for catching C++ exceptions on user side.


This is a bit like following every C call with "except *" (though the
performance ratios are unclear). It just seems a lot to wrap every
single line of a non-trivial C++ using function with try..catch
blocks.


But if users are correct about their declarations, we'd end up with the
same thing. I think it's worth a try.


Most C++ code (that I've ever run into) doesn't use exceptions,
because exception handling is so broken in C++ anyways.


Did you mean that most C++ code doesn't use try/except? That's true, but 
my experience is that throw is used.


Dag
___
cython-devel mailing list
cython-devel@python.org
http://mail.python.org/mailman/listinfo/cython-devel


Re: [Cython] [cython-users] C++: how to handle failures of 'new'?

2012-07-03 Thread Robert Bradshaw
On Tue, Jul 3, 2012 at 11:43 AM, Dag Sverre Seljebotn
 wrote:
> On 07/03/2012 08:23 PM, Robert Bradshaw wrote:
>>
>> On Tue, Jul 3, 2012 at 11:11 AM, Stefan Behnel
>> wrote:
>>>
>>> Robert Bradshaw, 03.07.2012 19:58:

 On Tue, Jul 3, 2012 at 9:38 AM, Stefan Behnel wrote:
>
> Dag Sverre Seljebotn, 03.07.2012 18:11:
>>
>> On 07/03/2012 09:14 AM, Stefan Behnel wrote:
>>>
>>> I don't know what happens if a C++ exception is not being caught, but
>>> I
>>> guess it would simply crash the application. That's a bit more
>>> visible than
>>
>>
>> Yep.
>>
>>> just printing a warning when a Python exception is being ignored due
>>> to a
>>> missing declaration. It's really unfortunate that our documentation
>>> didn't
>>> even mention the need for this, because it's not immediately obvious
>>> that
>>> Cython won't handle errors in "new", and testing for memory errors
>>> isn't
>>> quite what people commonly do in their test suites.
>>>
>>> Apart from that, I agree, users have to take care to properly declare
>>> the
>>> API they are using.
>>
>>
>> Is there any time you do NOT want a "catch (...) {}" block? I can't
>> see a
>> C++ exception propagating to Python-land doing anything useful ever.
>
>
> That would have been my intuition, too.


 If it's actually embedded, with the main driver in C++, one might want
 it to propagate up.
>>>
>>>
>>> But what kind of a propagation would that be? On the way out, it could
>>> induce anything, from side effects to resource leaks to crashes,
>>> depending
>>> on what the state of the surrounding code is. It would leave the whole
>>> system in an unpredictable state. I cannot imagine anyone really wanting
>>> this.
>>>
>>>
>> So shouldn't we just make --cplus turn *all* external functions and
>> methods
>> (whether C-like or C++-like) into "except +"? (Or keep except+ for
>> manual
>> translation, but always have a catch(...)".
>>
>> Performance overhead is the only reason I can think of to not do this,
>> although IIRC C++ catch blocks are only dealt with during stack
>> unwinds and
>> doesn't cost anything/much (?) when they're not triggered.
>>
>> "except -1" should then actually mean both; "except + except -1". So
>> it's
>> more a question of just adding catch(...) *everywhere*, than making
>> "except
>> +" the default.
>
>
> I have no idea if there is a performance impact, but if there isn't,
> always
> catching all exceptions sounds like a reasonable thing to do. After
> all, we
> have no support for catching C++ exceptions on user side.


 This is a bit like following every C call with "except *" (though the
 performance ratios are unclear). It just seems a lot to wrap every
 single line of a non-trivial C++ using function with try..catch
 blocks.
>
>
> It seems "a lot" of just what exactly? Generated code? Binary size? Time
> spent in GCC parser?

All of the above. And we should take a look at the runtime overhead
(which is hopefully nil, but who knows.)

> Though I guess one might want to try to pull out the try-catch to at least
> only one per code line rather than one per SimpleCallNode.

Or even higher, if possible. It's still a lot.

> "except *" only has a point when calling functions using the CPython API,
> but most external C functions are pure C, not CPython-API-using-functions.
> OTOH, all external C++ functions are C++ :-)

Fair point.

> (Also, if we wrote Cython from scratch now I'm pretty sure the "except *"
> defaults would be a tad different.)

For sure.

>>> But if users are correct about their declarations, we'd end up with the
>>> same thing. I think it's worth a try.
>>
>>
>> Most C++ code (that I've ever run into) doesn't use exceptions,
>> because exception handling is so broken in C++ anyways.
>
>
> Except for the fact that any code touching "new" could be raising
> exceptions? That propagates.

I would guess most of the time people don't bother catching these and
let the program die, as there's often no sane recovery (the same as
MemoryErrors in Python, though I guess C++ is less often used from an
event loop).

> There is a lot of C++ code out there using exceptions. I'd guess that both
> mathematical code and Google-written code is unlike most C++ code out there
> :-) Many C++ programmers go on and on about RAII and auto_ptrs and so on,
> and that doesn't have much point unless you throw an exception now and then
> (OK, there's the occasional return statement where it matters well).

True, I've seen a small subset of the C++ code that's out there. Maybe
numerical computations use it a lot?

+1 to making catch-everywhere a directive at least. Lets see what the
impact is before we decide to make it the default.

- Robert
___
cyth

Re: [Cython] [cython-users] C++: how to handle failures of 'new'?

2012-07-03 Thread Dag Sverre Seljebotn

On 07/03/2012 09:15 PM, Robert Bradshaw wrote:

On Tue, Jul 3, 2012 at 11:43 AM, Dag Sverre Seljebotn
  wrote:

On 07/03/2012 08:23 PM, Robert Bradshaw wrote:


On Tue, Jul 3, 2012 at 11:11 AM, Stefan Behnel
wrote:


Robert Bradshaw, 03.07.2012 19:58:


On Tue, Jul 3, 2012 at 9:38 AM, Stefan Behnel wrote:


Dag Sverre Seljebotn, 03.07.2012 18:11:


On 07/03/2012 09:14 AM, Stefan Behnel wrote:


I don't know what happens if a C++ exception is not being caught, but
I
guess it would simply crash the application. That's a bit more
visible than



Yep.


just printing a warning when a Python exception is being ignored due
to a
missing declaration. It's really unfortunate that our documentation
didn't
even mention the need for this, because it's not immediately obvious
that
Cython won't handle errors in "new", and testing for memory errors
isn't
quite what people commonly do in their test suites.

Apart from that, I agree, users have to take care to properly declare
the
API they are using.



Is there any time you do NOT want a "catch (...) {}" block? I can't
see a
C++ exception propagating to Python-land doing anything useful ever.



That would have been my intuition, too.



If it's actually embedded, with the main driver in C++, one might want
it to propagate up.



But what kind of a propagation would that be? On the way out, it could
induce anything, from side effects to resource leaks to crashes,
depending
on what the state of the surrounding code is. It would leave the whole
system in an unpredictable state. I cannot imagine anyone really wanting
this.



So shouldn't we just make --cplus turn *all* external functions and
methods
(whether C-like or C++-like) into "except +"? (Or keep except+ for
manual
translation, but always have a catch(...)".

Performance overhead is the only reason I can think of to not do this,
although IIRC C++ catch blocks are only dealt with during stack
unwinds and
doesn't cost anything/much (?) when they're not triggered.

"except -1" should then actually mean both; "except + except -1". So
it's
more a question of just adding catch(...) *everywhere*, than making
"except
+" the default.



I have no idea if there is a performance impact, but if there isn't,
always
catching all exceptions sounds like a reasonable thing to do. After
all, we
have no support for catching C++ exceptions on user side.



This is a bit like following every C call with "except *" (though the
performance ratios are unclear). It just seems a lot to wrap every
single line of a non-trivial C++ using function with try..catch
blocks.



It seems "a lot" of just what exactly? Generated code? Binary size? Time
spent in GCC parser?


All of the above. And we should take a look at the runtime overhead
(which is hopefully nil, but who knows.)


Though I guess one might want to try to pull out the try-catch to at least
only one per code line rather than one per SimpleCallNode.


Or even higher, if possible. It's still a lot.


"except *" only has a point when calling functions using the CPython API,
but most external C functions are pure C, not CPython-API-using-functions.
OTOH, all external C++ functions are C++ :-)


Fair point.


(Also, if we wrote Cython from scratch now I'm pretty sure the "except *"
defaults would be a tad different.)


For sure.


But if users are correct about their declarations, we'd end up with the
same thing. I think it's worth a try.



Most C++ code (that I've ever run into) doesn't use exceptions,
because exception handling is so broken in C++ anyways.



Except for the fact that any code touching "new" could be raising
exceptions? That propagates.


I would guess most of the time people don't bother catching these and
let the program die, as there's often no sane recovery (the same as
MemoryErrors in Python, though I guess C++ is less often used from an
event loop).


The point is to provide the user with the stack trace of exactly where 
you ran out of memory. Even if you can't follow it deep into C++-land, 
the Python-side stack trace can be a worth a lot.





There is a lot of C++ code out there using exceptions. I'd guess that both
mathematical code and Google-written code is unlike most C++ code out there
:-) Many C++ programmers go on and on about RAII and auto_ptrs and so on,
and that doesn't have much point unless you throw an exception now and then
(OK, there's the occasional return statement where it matters well).


True, I've seen a small subset of the C++ code that's out there. Maybe
numerical computations use it a lot?


One library I'm using for distributed dense linear algebra (Elemental) 
does. Numerical computations libraries are very different from one another.


Dag
___
cython-devel mailing list
cython-devel@python.org
http://mail.python.org/mailman/listinfo/cython-devel


Re: [Cython] [cython-users] C++: how to handle failures of 'new'?

2012-07-03 Thread Dag Sverre Seljebotn

On 07/03/2012 10:39 PM, Dag Sverre Seljebotn wrote:

On 07/03/2012 09:15 PM, Robert Bradshaw wrote:

On Tue, Jul 3, 2012 at 11:43 AM, Dag Sverre Seljebotn
 wrote:

On 07/03/2012 08:23 PM, Robert Bradshaw wrote:


On Tue, Jul 3, 2012 at 11:11 AM, Stefan Behnel
wrote:


Robert Bradshaw, 03.07.2012 19:58:


On Tue, Jul 3, 2012 at 9:38 AM, Stefan Behnel wrote:


Dag Sverre Seljebotn, 03.07.2012 18:11:


On 07/03/2012 09:14 AM, Stefan Behnel wrote:


I don't know what happens if a C++ exception is not being
caught, but
I
guess it would simply crash the application. That's a bit more
visible than



Yep.


just printing a warning when a Python exception is being
ignored due
to a
missing declaration. It's really unfortunate that our
documentation
didn't
even mention the need for this, because it's not immediately
obvious
that
Cython won't handle errors in "new", and testing for memory errors
isn't
quite what people commonly do in their test suites.

Apart from that, I agree, users have to take care to properly
declare
the
API they are using.



Is there any time you do NOT want a "catch (...) {}" block? I can't
see a
C++ exception propagating to Python-land doing anything useful
ever.



That would have been my intuition, too.



If it's actually embedded, with the main driver in C++, one might
want
it to propagate up.



But what kind of a propagation would that be? On the way out, it could
induce anything, from side effects to resource leaks to crashes,
depending
on what the state of the surrounding code is. It would leave the whole
system in an unpredictable state. I cannot imagine anyone really
wanting
this.



So shouldn't we just make --cplus turn *all* external functions and
methods
(whether C-like or C++-like) into "except +"? (Or keep except+ for
manual
translation, but always have a catch(...)".

Performance overhead is the only reason I can think of to not do
this,
although IIRC C++ catch blocks are only dealt with during stack
unwinds and
doesn't cost anything/much (?) when they're not triggered.

"except -1" should then actually mean both; "except + except
-1". So
it's
more a question of just adding catch(...) *everywhere*, than making
"except
+" the default.



I have no idea if there is a performance impact, but if there isn't,
always
catching all exceptions sounds like a reasonable thing to do. After
all, we
have no support for catching C++ exceptions on user side.



This is a bit like following every C call with "except *" (though the
performance ratios are unclear). It just seems a lot to wrap every
single line of a non-trivial C++ using function with try..catch
blocks.



It seems "a lot" of just what exactly? Generated code? Binary size? Time
spent in GCC parser?


All of the above. And we should take a look at the runtime overhead
(which is hopefully nil, but who knows.)


Though I guess one might want to try to pull out the try-catch to at
least
only one per code line rather than one per SimpleCallNode.


Or even higher, if possible. It's still a lot.


"except *" only has a point when calling functions using the CPython
API,
but most external C functions are pure C, not
CPython-API-using-functions.
OTOH, all external C++ functions are C++ :-)


Fair point.


(Also, if we wrote Cython from scratch now I'm pretty sure the
"except *"
defaults would be a tad different.)


For sure.


But if users are correct about their declarations, we'd end up with
the
same thing. I think it's worth a try.



Most C++ code (that I've ever run into) doesn't use exceptions,
because exception handling is so broken in C++ anyways.



Except for the fact that any code touching "new" could be raising
exceptions? That propagates.


I would guess most of the time people don't bother catching these and
let the program die, as there's often no sane recovery (the same as
MemoryErrors in Python, though I guess C++ is less often used from an
event loop).


The point is to provide the user with the stack trace of exactly where
you ran out of memory. Even if you can't follow it deep into C++-land,
the Python-side stack trace can be a worth a lot.


Note that I think (I just skimmed gcc documentation) the abort will 
happen the moment you pop back to a C function (unless you compile the C 
code with -fexceptions). I.e. once you're back in the CPython eval loop 
you die, it doesn't propagate back to main(). That means you could crash 
in a lot of callback cases too; your expectation of some kind of 
propagation for callbacks is only true if there's C++ all the way 
(according to my skimming, anyway).


Dag






There is a lot of C++ code out there using exceptions. I'd guess that
both
mathematical code and Google-written code is unlike most C++ code out
there
:-) Many C++ programmers go on and on about RAII and auto_ptrs and so
on,
and that doesn't have much point unless you throw an exception now
and then
(OK, there's the occasional return statement where it matters well).


True, I've seen a small subset of the C++ code 

Re: [Cython] [cython-users] C++: how to handle failures of 'new'?

2012-07-03 Thread Sturla Molden

Den 03.07.2012 20:43, skrev Dag Sverre Seljebotn:


Except for the fact that any code touching "new" could be raising 
exceptions? That propagates.


There is a lot of C++ code out there using exceptions. I'd guess that 
both mathematical code and Google-written code is unlike most C++ code 
out there :-) Many C++ programmers go on and on about RAII and 
auto_ptrs and so on, and that doesn't have much point unless you throw 
an exception now and then (OK, there's the occasional return statement 
where it matters well).




Usually there is just one C++ exception to care about: std::bad_alloc. 
It is important to know that it can be raised almost anywhere in C++ 
code that are using the STL.


The majority of C++ programs never attempt to catch std::bad_alloc. 
Instead a program will set a global handler routine using 
std::set_new_handler. Usually a callback for memory failure will just 
display an error message and call std::exit with status 
std::EXIT_FAILURE. ||


When interfacing from Python I think a std::bad_alloc should be 
translated to a MemoryError exception if possible.  Though others might 
argue that one should never try to recover from a memory failure. 
Arguably, recovering std::bad_alloc might not be possible if the heap is 
exhausted.


Sturla





___
cython-devel mailing list
cython-devel@python.org
http://mail.python.org/mailman/listinfo/cython-devel


Re: [Cython] [cython-users] C++: how to handle failures of 'new'?

2012-07-03 Thread Stefan Behnel
Sturla Molden, 04.07.2012 02:58:
> Den 03.07.2012 20:43, skrev Dag Sverre Seljebotn:
>> Except for the fact that any code touching "new" could be raising
>> exceptions? That propagates.
>>
>> There is a lot of C++ code out there using exceptions. I'd guess that
>> both mathematical code and Google-written code is unlike most C++ code
>> out there :-) Many C++ programmers go on and on about RAII and auto_ptrs
>> and so on, and that doesn't have much point unless you throw an exception
>> now and then (OK, there's the occasional return statement where it
>> matters well).
> 
> Usually there is just one C++ exception to care about: std::bad_alloc. It
> is important to know that it can be raised almost anywhere in C++ code that
> are using the STL.
> 
> The majority of C++ programs never attempt to catch std::bad_alloc. Instead
> a program will set a global handler routine using std::set_new_handler.

Interesting. Doesn't make much sense to do that in Cython, though (and
users wouldn't like it if they intend to use it themselves).


> Usually a callback for memory failure will just display an error message
> and call std::exit with status std::EXIT_FAILURE. ||
> 
> When interfacing from Python I think a std::bad_alloc should be translated
> to a MemoryError exception if possible.  Though others might argue that one
> should never try to recover from a memory failure. Arguably, recovering
> std::bad_alloc might not be possible if the heap is exhausted.

Usually, the intention is more to exit gracefully, i.e. to pass through all
finally clauses, than to actually handle the error and continue. And I
would expect that going back along that path would eventually free up some
memory, so that this should actually work in most cases.

Also, the allocation may have failed on a larger block of memory, which is
then unused when the exception gets raised and can be used by cleanup code.
I really don't think the world is all that dark here.

Stefan
___
cython-devel mailing list
cython-devel@python.org
http://mail.python.org/mailman/listinfo/cython-devel