I don't think I described my problem well.
I'm using QtConsole which gives me a nice interactive python console for my Qt application. I have no problem executing code inside the console. I can type in code or have it load a file. I can even do debugging. Using iPython through the interface is not the problem. My problem is that I do not know how to excecute code in iPython without using the console interface.
When I make my console I "push" attributes of my application to populate the local namespace in the iPython shell. Many of the objects in my application are hierarchical or composite objects. For example, I have an object called "controller" that is a model of a device my application is controlling. My controller contains a list of "channel" objects. Each of my channel objects has "feedback", "servo" and "drive" objects, and each of these objects have many attributes. Using the console I can modify these attributes by entering python expressions. This expression changes the proportional gain of one of the servo objects:
controller.channel[2].servo.proportional = 2.6
What I'm trying to do is write some "magic" functions that make it easier to navigate around. I would like it if I could do this:
ENTER controller.channel[2].servo
proportional = 2.6
integral = 0.1
error
BACK
This code should set iPython shell local variables to the attributes of the servo object. The servo object attributes are now local variables. I use the attribute/variables to set proportional and integral gains, and display the current servo error. Then I used the BACK magic command to restore the original namespace.
What the "ENTER" magic command does is evaluate the following expression (controller.channel[2].servo) which is a servo object, and push the servo.__dict__ as the "namespace" for the iPython shell. The problem is that the magic function I wrote gets "controller.channel[2].servo" as a string. I want to evaluate the expression in the iPython shell, get back the servo object, and use that to set the namespace.
I have this working without using Magic functions. When I push the namespace I add my own "built-in" functions: enter(expression) and back(). If the user types enter(controller.channel[2].servo) my console application calls this function:
def _push_context(self, context_object):
"""Push new context object onto the stack"""
self.contexts.append(context_object)
return self._restore_context()
def _pop_context(self):
"""Pop current context off the stack and restore previous context"""
if len(self.contexts) > 1:
self.contexts.pop()
return self.restore_context()
def _restore_context(self):
"""Set kernel shell namespace to reference the top context object"""
if len(self.contexts) == 0:
return None
obj = self.contexts[-1]
context = obj.__dict__.copy()
context["self"] = obj
context["enter"] = self.push_context
context["back"] = self.pop_context
self.kernel.shell.reset()
self.kernel.shell.push(context)
return obj
This works fine, but I wanted to see if I could do this with magic functions.