From: Olly B. <ol...@su...> - 2007-03-24 16:05:19
|
Replying to the swig-devel list, since this is discussing a change to SWIG itself... On 2007-03-09, Richard Boulton <ri...@le...> wrote: > I've recently converted a project using Swig (actually, Xapian) to use > custom exception types for the Python bindings, rather than using the > standard python exception types. I've got this all working nicely, > except for one issue: I can't make (the Python proxy classes for) my > custom exception types inherit from the standard Python Exception class > (which all exceptions thrown in python should inherit from). Looking at the python docs, the nearest to a requirement I can find is section 8.5 here: http://docs.python.org/tut/node10.html "Exceptions should typically be derived from the Exception class, either directly or indirectly." To me "should typically" suggests a somewhat weaker requirement that RFC 2119's "SHOULD" (http://www.ietf.org/rfc/rfc2119.txt) though I don't see a situation where it's useful not to follow this recommendation. It certainly seems that this is desirable default behaviour, though maybe there needs to be a way to override. > In the generated python code, I find the line: > "class Error:" > > and I would like to change this somehow to: > "class Error(Exception):" > > Is there any way to tell Swig that the proxy class for a C++ class > should inherit from a specific python class? Or is there any other way > that I can get swig to do what I want? For Xapian, we could just run sed over the wrapper code which SWIG generates to fix this up, at least for now. I don't see a nice way to do it with SWIG. It might be possible to lie to SWIG and claim the C++ Xapian::Error class inherits from an unspecified Exception class, but even if that works I think I prefer fixing up the generated code with sed. > (In theory, I wish that the %exceptionclass tag on a class would be > observed and used automatically to ensure that the corresponding proxy > class has the standard "Exception" class somewhere in it's ancestors - > but that's not currently implemented. Perhaps that would be a useful > feature for python?) This sounds good to me. What do the SWIG/Python experts think? Also, should something similar happen for any other languages? Cheers, Olly |
From: Amaury F. d'A. <ama...@gm...> - 2007-03-26 11:47:57
|
Hello, 2007/3/24, Olly Betts wrote: > Replying to the swig-devel list, since this is discussing a change to > SWIG itself... > > On 2007-03-09, Richard Boulton <ri...@le...> wrote: > > I've recently converted a project using Swig (actually, Xapian) to use > > custom exception types for the Python bindings, rather than using the > > standard python exception types. I've got this all working nicely, > > except for one issue: I can't make (the Python proxy classes for) my > > custom exception types inherit from the standard Python Exception class > > (which all exceptions thrown in python should inherit from). > > Looking at the python docs, the nearest to a requirement I can find is > section 8.5 here: > > http://docs.python.org/tut/node10.html > > "Exceptions should typically be derived from the Exception class, > either directly or indirectly." > > To me "should typically" suggests a somewhat weaker requirement that RFC > 2119's "SHOULD" (http://www.ietf.org/rfc/rfc2119.txt) though I don't > see a situation where it's useful not to follow this recommendation. It > certainly seems that this is desirable default behaviour, though maybe > there needs to be a way to override. This is not only desirable, it will be enforced in future releases of python: See http://www.python.org/dev/peps/pep-0352. > > In the generated python code, I find the line: > > "class Error:" > > > > and I would like to change this somehow to: > > "class Error(Exception):" > > > > Is there any way to tell Swig that the proxy class for a C++ class > > should inherit from a specific python class? Or is there any other way > > that I can get swig to do what I want? > > For Xapian, we could just run sed over the wrapper code which SWIG > generates to fix this up, at least for now. > > I don't see a nice way to do it with SWIG. It might be possible to > lie to SWIG and claim the C++ Xapian::Error class inherits from an > unspecified Exception class, but even if that works I think I prefer > fixing up the generated code with sed. > > > (In theory, I wish that the %exceptionclass tag on a class would be > > observed and used automatically to ensure that the corresponding proxy > > class has the standard "Exception" class somewhere in it's ancestors - > > but that's not currently implemented. Perhaps that would be a useful > > feature for python?) > > This sounds good to me. What do the SWIG/Python experts think? > You could implement this with a __metaclass__. something like this: (warning: not tested at all) %pythoncode %{ class exceptionMetaclass(type): def __init__(self, name, bases, classdict): if Exception not in bases: bases.append(Exception) type.__init__(self, name, bases, classdict) %} class Xapian::Error { %pythoncode { __metaclass__ = exceptionMetaclass } }; -- Amaury Forgeot d'Arc |
From: Olly B. <ol...@su...> - 2007-03-26 17:49:30
|
On 2007-03-26, Amaury Forgeot d'Arc <ama...@gm...> wrote: > This is not only desirable, it will be enforced in future releases of > python: > See http://www.python.org/dev/peps/pep-0352. Summarising the pertinent part of that, (in future) anything thrown as an exception in Python will need to inherit from BaseException, (and Exception is a subclass of BaseException as of Python 2.5, before that BaseException didn't exist). Given that, I think it would be reasonable for SWIG to start ensuring this is the case now (by checking the inheritance tree to see if BaseException or Exception is a parent class and adding it if not - checking both is required to work will Python < 2.5 which doesn't have BaseException). Anyone disagree? > You could implement this with a __metaclass__. something like this: > (warning: not tested at all) > > %pythoncode %{ > class exceptionMetaclass(type): > def __init__(self, name, bases, classdict): > if Exception not in bases: > bases.append(Exception) > type.__init__(self, name, bases, classdict) > %} > > class Xapian::Error > { > %pythoncode { __metaclass__ = exceptionMetaclass } > }; Thanks for the tip, though I think it's cleaner to just add the parent class directly when SWIG generates the Python code. Cheers, Olly |
From: David B. <dav...@da...> - 2007-03-26 17:59:15
|
On Mar 26, 2007, at 12:48 PM, Olly Betts wrote: > On 2007-03-26, Amaury Forgeot d'Arc <ama...@gm...> wrote: >> This is not only desirable, it will be enforced in future releases of >> python: >> See http://www.python.org/dev/peps/pep-0352. > > Summarising the pertinent part of that, (in future) anything thrown as > an exception in Python will need to inherit from BaseException, (and > Exception is a subclass of BaseException as of Python 2.5, before that > BaseException didn't exist). > > Given that, I think it would be reasonable for SWIG to start ensuring > this is the case now (by checking the inheritance tree to see if > BaseException or Exception is a parent class and adding it if not - > checking both is required to work will Python < 2.5 which doesn't have > BaseException). Anyone disagree? Nope. I think we should make all exceptions inherit from Exception--- which will at least ensure that generated code works with older versions of Python. -Dave |
From: Josh C. <jc...@nc...> - 2007-03-26 18:59:44
|
On Mon, 26 Mar 2007, Olly Betts wrote: > Given that, I think it would be reasonable for SWIG to start ensuring > this is the case now (by checking the inheritance tree to see if > BaseException or Exception is a parent class and adding it if not - > checking both is required to work will Python < 2.5 which doesn't have > BaseException). Anyone disagree? On a related note, I think it would be nice to have general methods for controlling what proxy classes inherit from. I have in mind two things: 1. A way of specifying what the ultimate base class should be, in place of object (or in place of nothing for old-style classes). This might be called %rootclass, and (like any feature) could be applied to everything or to specific classes. It can be useful to have the proxy class hierarchy (or some subset) rooted at a user-defined class. I do this to provide various help methods, such as a method to bring up a web browser with doxygen-generated help for the class. 2. A way of specifying base classes for particular classes, even if they would otherwise inherit from something other than object. Adding a Python mixin class could be useful (e.g., DictMixin provides a full dictionary interface, given a minimal set of methods). Perhaps an exception class proxy should inherit from some subclass of Exception, such as IndexError (this overlaps with (1)). There could be other reasons for manipulating the proxy class hierarchy. I could imagine %baseclasses and %addbaseclass. Josh |
From: William S F. <ws...@fu...> - 2007-03-26 20:41:05
|
Josh Cherry wrote: > > On Mon, 26 Mar 2007, Olly Betts wrote: > >> Given that, I think it would be reasonable for SWIG to start ensuring >> this is the case now (by checking the inheritance tree to see if >> BaseException or Exception is a parent class and adding it if not - >> checking both is required to work will Python < 2.5 which doesn't have >> BaseException). Anyone disagree? > > On a related note, I think it would be nice to have general methods for > controlling what proxy classes inherit from. I have in mind two things: > > 1. A way of specifying what the ultimate base class should be, in place of > object (or in place of nothing for old-style classes). This might be > called %rootclass, and (like any feature) could be applied to everything > or to specific classes. It can be useful to have the proxy class > hierarchy (or some subset) rooted at a user-defined class. I do this to > provide various help methods, such as a method to bring up a web browser > with doxygen-generated help for the class. > > 2. A way of specifying base classes for particular classes, even if they > would otherwise inherit from something other than object. Adding a Python > mixin class could be useful (e.g., DictMixin provides a full dictionary > interface, given a minimal set of methods). Perhaps an exception class > proxy should inherit from some subclass of Exception, such as IndexError > (this overlaps with (1)). There could be other reasons for manipulating > the proxy class hierarchy. I could imagine %baseclasses and > %addbaseclass. > Java and C# have control over the proxy base classes with the csinterfaces/javainterfaces and csbase/javabase typemaps with attributes controlling whether or not it will replace the C++ base class. See the docs in Java.html and examples in the test-suite directory. Any proxy mods in the Python layer might want to look at the range of Java/C# typemaps as there is full control over the Java/C# layer code. William |