1. NodeBox 1
    1. Homepage
    2. NodeBox 3Node-based app for generative design and data visualization
    3. NodeBox OpenGLHardware-accelerated cross-platform graphics library
    4. NodeBox 1Generate 2D visuals using Python code (Mac OS X only)
  2. Gallery
  3. Documentation
  4. Forum
  5. Blog

ximport inside imported modules

Posted by Josh Caswell on Jun 19, 2009

I'm having a great deal of difficulty with importing a module. It surprises me that I haven't run into this before, but here it is:

I have a module in ~/Library/Application Support/NodeBox, which I am importing into my script using ximport(). This module itself needs to use other modules in the same folder, including the colors library. At least one of these second set of modules needs access to the current context, _ctx, and therefore needs to be imported with ximport(). However, when I put

colors = ximport("colors")
helpermodule = ximport("helpermodule")
at the top of mymodule, I get a NameError that 'ximport' is not defined. Importing ximport itself from nodebox.graphics obviously doesn't work, because it's a method of Context, not a top-level function. So apparently you can't use ximport() inside a module until after you have ximport()'d the module?

In order to work around the NameError, I copied and pasted some of the code from helpermodule, so that the functions I need from it are now at top level in mymodule. Needless to say, this is a clumsy and annoying workaround.

The key function in mymodule calls stroke(), and after removing the ximport() calls, I get another
NameError: global name 'stroke' is not defined
. The same continues for fill, random, and rect, all of which are called within the function inside mymodule, that is, not until:
mymodule.myfunc()
is executed in my top level script. Shouldn't mymodule, having been ximport()'d, have access to those functions by that time? I thought that was the point of ximport().

I have worked around this problem by qualifying these calls as
_ctx.stroke()
and so forth.

I've combed the forum here, documentation, etc., and I can't figure this out. Is it in fact impossible to use ximport() inside a module? This really limits module usage, because any auxiliary modules cannot have drawing routines; they won't have access to _ctx. Also, are stroke(), fill(), etc. only available unqualified when in a top-level script?

Any pointers would be greatly appreciated. Hope I'm not just missing something simple and stupid.


 
Posted by Stefan on Jun 19, 2009

ximport actually adds _ctx to the namespace of the module it imports, but it only can do so after the module has been imported. In your, by then, imported module you can access ximport by calling _ctx.ximport. But you can only do that from within a function or so, not at the top level because _ctx isn't known by the module (yet). Is this making any sense?



Posted by Josh Caswell on Jun 22, 2009

Yep, that makes perfect sense. It actually occurred to me the next day -- putting calls to ximport inside a setup function in the first imported module, then having to call that setup() in the script. And no way to access what are usually global functions without qualification in modules. It's kind of a bummer: Python's pretty flexible about making modules usable either as libraries or scripts, but this means you have to pick one or the other, or just get in the habit of writing _ctx.fill() all the time.

Anyways, thanks for the reply, Stefan!