Some random thoughts on this:
This is basically two orthogonal things (as given in two seperaate examples):
a) Automatic inclusion of .h-files "as if they were pxd files" (or, making pxds
unecessary). This has very wide uses.
b) Automatic generation of wrappers for cpp classes.
I think a) has a very wide circle of potential users, and perhaps getting this
integrated first could be a first goal here?
As for syntax, here's another idea (not that I'm against the original proposal):
For a):
from "myheader.h" cimport foo
(or from cython.cheaders.myheader, or similar)
I.e. the .h-file acts exactly like a pxd file. This should integrate very
nicely with existing codebases (i.e. some pxds could simply be deleted and the
import changed and things would still work the same :-) ).
This has some problems with performance obviously - only the necesarry symbols
should go from .h to "implicit pxd" stage. It looks like this is in place
though from the other syntax, and now that type symbol resolution is postponed
to after parsing (yey!) this could even work with a normal "cimport
'myheader.h' as mylib; mylib.foo(...)"...
For b), I'm thinking something like:
from "mylib.h" cimport MyCppClass
cdef class MyCyClass(MyCppClass):
pass
i.e. you can "inherit" from the C++ class in Cython. This also provides a nice
syntax right away for extending the wrapper with more stuff in addition to the
automatic part.
Finally, thoughts on integration with Cython: The first thing to do after a
successful integration of what exists now, would be looking at producing a
"tree preprocessor" rather than file preprocessor. I.e. in whatever code exists
now it should be rather simple to emit the nodes of Nodes.py rather than Cython
code strings, which should give a performance boost and make things less
complex overall.
As for pyparsing, I note my disagreement with Robert. I don't think it would
hurt to add another dependency as long as it is an optional for optional
features, at least if switching parser is nontrivial.
Dag Sverre Seljebotn
-----Original Message-----
From: Robert Bradshaw <[EMAIL PROTECTED]>
Date: Sunday, Oct 19, 2008 5:53 am
Subject: Re: [Cython] How do I write C++ shadow classes..
To: [EMAIL PROTECTED]: [email protected]
On Oct 17, 2008, at 11:15 PM, Andrey Ivanov wrote:
>
>> Hello Cython developers,
>
>> recently I started to refactor my C++/Python project, where I used
> a SWIG tool
> to build extention, and I discovered that Pyrex/Cython tool is much
> more faster
> and eats less memory. But there are some cons, it cannot create
> shadow C++
> classes automaticly, so user must write them by hands. Of course
> this is needed
> base functionality for such tools, but it is not what developers
> want (lazy,
> like me :) ).
>
>Actually, a lot of people do want this, but it's just that there are
>other things we want more, and we have limited time :). Personally, I
>tend to wrap more C than C++ code, and find the interface I want to
>provide to Python is not necessarily the "raw" interface as given by
>the underlying library, but this would certainly come in handy. And
>it could certainly be useful for C as well as C++.
>
>> So I've decided make an addition to Cython tool to provide such
> functionality.
> Because I'm not very experienced in how Pyrex/Cython works (and
> there are some
> specific, because tool must parse .h) I've decided to write
> preprocessor wich
> would roll out simple modified 'extern from' construction. It
> integrates with
> Cython in Utils.py module (by ihooks) and provides preprocessed
> files instead
> of original ones.
>
>Hopefully you'll be able to contribute directly to Cython itself. My
>one concern is that I don't want to add pyparsing as a dependancy,
>but the parser we ship with should be flexible enough for our needs.
>
>> There are a few constructions parsed by preprocessor
>
>I'm not quite sure exactly what you're explaining here--is the part
>above the line your input, and the part below autogenerated?
>
>> (I called it ccython because of lack of imagination):
>
>> cdef extern from "China.hpp" import Dress, Phone:
> pass
> -------------------------
> cdef extern from "China.hpp":
> ctypedef struct c_Dress "Dress":
> void tearAtaTouch();
> c_Dress *new_Dress "new Dress" ()
> void del_Dress "delete" (c_Dress * ptr)
> ctypedef struct c_Phone "Phone":
> void ring();
> int break(int days);
> c_Phone *new_Phone "new Phone" ()
> void del_Phone "delete" (c_Phone * ptr)
> etc.. all classes specified in import list will be imported, also
> using of * is
> possible. And:
>
>> cdef class Phone import *:
> pass
> -------------------------
> cdef class Phone:
> cdef c_Phone *thisptr
> def __cinit__(self): new_Phone()
>
>I assume you mean "self. thisptr = new_Phone()
>
>> def __dealloc__(self): del_Phone(self.thisptr)
> def ring(self): self.thisptr.break()
>
>and self.thisptr.ring()
>
>> def break(self, days): return self.thisptr.break(days)
>
>> (all like in C++ example on cython.org)
> also instead of pass other methods can be specified by hands. Only
> specified .h
> file and specified class definition parsed, but there is a
> possibility to use
> 'gcc -E' output (all included) and look at all class hierarchy.
>
>Yes, gcc -E would certainly be useful in many cases--we certainly
>don't want to be doing our own macro expansion and all.
>
>>
> I used pyparsing module to parse .pyx and .h files. Now tool is in
> pre-alpha,
> so I have some question:
> - how it corellate with Cython developers goals? Does exist a
> little chance for
> such features to be implemented in original Cython (my project is
> only a little
> test).
>
>The only reason it's not there is because no one's stepped up to do
>it. Now it looks like you have :).
>
>> - is that syntax good ?
>
>I like the "cdef extern from 'file.h' import ..." syntax, though
>perhaps instead of automatically mangling names one should write
>"import Phone as c_Phone." The "cdef class Phone import *:" seems a
>bit odd though... A while back we talked about supporting auto-
>generated methods (e.g. for pickling, comparison, str, ...) and your
>auto-generated class seems like a candidate for the same syntax.
>Should "new" and "delete" be added as
>
>> - what should I do with arguments of C++ class types? (create
> shadows for them!)
>
>If we end up creating shadows for everything, then that will slow
>things down immensely. This is one of the reasons SWIG is slow, and
>although I think Cython wrappings could be a lot tighter, if we're
>just passing a bunch of Python objects around there's a limit to how
>fast you can be. It could be possible to make cpdef functions and
>only wrap/unwrap things as they pass into Python land (via shadows or
>ctypes or a CObjects)? Would such shadow types be compatible across
>modules?
>
>> Now TODO list looks like:
> - parse C preprocessed files instead of headers (may be done by
> pythonic tools
> or just 'gcc -E')
> - add import lists for extern structs (I not intends to spam local
> scope with
> identifiers what I've never seen)
> - resolve conflicts with already declared names (how?)
>
>I think this should just be an error... Eventually, polymorphism
>would be a very nice thing to have in Cython.
>
>> - look through all class tree for public methods and attributes
>
>Yep. How to handle class inheritance (and the ensuing type
>compatibility) is another big question.
>
>- Robert
>
>
>_______________________________________________
>Cython-dev mailing list
>[email protected]
>http://codespeak.net/mailman/listinfo/cython-dev
>
_______________________________________________
Cython-dev mailing list
[email protected]
http://codespeak.net/mailman/listinfo/cython-dev