[Cython] [cython-users] Conditional import in pure Python mode

mark florisson markflorisson88 at gmail.com
Mon Apr 30 15:24:20 CEST 2012

On 30 April 2012 13:14, Ian Bell <ian.h.bell at gmail.com> wrote:
> On Sun, Apr 29, 2012 at 10:58 PM, mark florisson <markflorisson88 at gmail.com>
> wrote:
>> On 29 April 2012 01:33, Ian Bell <ian.h.bell at gmail.com> wrote:
>> > Hello Cython users,
>> >
>> > I haven't the foggiest idea how easy this would be to implement, or how
>> > to
>> > do it in the first place, but my idea is to be able to have some sort of
>> > idiom like
>> >
>> > if cython.compiled:
>> >     cython.import('from libc.math cimport sin')
>> > else:
>> >     from math import sin
>> >
>> > that would allow for a pure Python file to still have 100% CPython code
>> > in
>> > it, but when it goes through the .py+.pxd-->.pyd compilation, use the
>> > math.h
>> > version instead.  Is there any way that this could work?  I can (and
>> > will)
>> > hack together a really nasty preprocessor that can edit the .py file at
>> > Cython build time, but it is a nasty hack, and very un-Pythonic.  For
>> > me,
>> > the computational efficiency using the math.h trig functions justify a
>> > bit
>> > of nastiness.
>> >
>> > Regards,
>> > Ian
>> I think a cython.cimport would be nice. If you want to have a crack at
>> it, you may want to look in Cython/Compiler/ParseTreeTransforms.py at
>> the TransformBuiltinMethods transform, and also at the
>> Cython/Shadow.py module.
> Mark,
> Any chance you can give me a wee bit more help?  I can see how you need to
> add a cimport function in Shadow.py.  Supposing I pass it an import string
> that it will parse for the import, whereto from there?  There's quite a lot
> of code to dig through.
> Ian

Certainly, it's great to see some enthusiasm. So first, it's important
to determine how you want it. You can either simulate importing the
rightmost module from the package, or you can simulate importing
everything from the package. Personally I think if you say
cython.cimport_module("libc.stdio") you want conceptually the stdio
module to be returned. Maybe a 'cimport_star' function could cimport
everything from the scope, but I'm not sure how great an idea that is
in pure mode (likely not a good one).

So lets assume we want to use the following syntax: stdio =

In the TransformBuiltinMethods you add another case to the
visit_SimpleCallNode, which will match for the function name
"cimport_module" (which is already known to be used as an attribute of
the Cython module). TransformBuiltinMethods is a subclass of
Visitor.EnvTransform, which keeps track of the scope (e.g. if the node
is in a function, the local function scope, etc). This class is a
subclass of CythonTransform, which has a Main.Context set up in
Pipeline.py, accessible through the 'self.context' attribute.

Main.Context has methods to find and process pxd files, i.e. through
the find_pxd_file and the process_pxd methods (or maybe the
find_module method will work here).

So you want to validate that the string that gets passed to the
'cimport_module' function call is a string literal, and that this is
in fact happening from the module scope. You can then create an Entry
with an as_module attribute and put it in the current scope. The
as_module attribute holds the scope of the cimported pxd file, which
means its a "cimported module". You can do this through the
'declare_module' method of the current scope
(self.current_env().declare_module(...)) (see Symtab.py for that

I hope that helps you get set up up somewhat, don't hesitate to bug
the cython-devel mailing list with any further questions. BTW, we
probably want to formally discuss the exact syntax and semantics
before implementing it, so I think it will be a good idea to summarize
what you want and how you want it on the cython-dev mailing list. Good
luck :)

More information about the cython-devel mailing list