Python Forum
Can a program execute code in iPython shell and get result? - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: General Coding Help (https://python-forum.io/forum-8.html)
+--- Thread: Can a program execute code in iPython shell and get result? (/thread-37479.html)



Can a program execute code in iPython shell and get result? - deanhystad - Jun-15-2022

I am playing around with iPython magic commands. I am trying to write a command to "enter" an object. When the user types:
ENTER expression
the command evaluates the expression which should return an object. The magic command then resets the shell namespace to be object.__dict__.

The function (simplified) looks like this:
def _enter_object(expression):
    object = ???(expression)
    kernel.shell.reset()
    kernel.shell.push(object.__dir__)
What I am looking for is code to evaluate "expression" in the kernel.shell context and return the value of the expression.


RE: Can a program execute code in iPython shell and get result? - Larz60+ - Jun-16-2022

If ipython is installed properly this should do it for you: hover over code you want to execute and press shift enter.

This is probably redundant, but included for those who are unfamiliar with jupyter and ipython:
Note: you also need jupyter notebook installed see: Installing Ipython which also includes instructions here for installing jupyter notebook with ipython.


RE: Can a program execute code in iPython shell and get result? - deanhystad - Jun-16-2022

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.


RE: Can a program execute code in iPython shell and get result? - Larz60+ - Jun-17-2022

OK, sorry I didn't understand. This looks intriguing, if you haven't solved it by my AM (it's 11:47 PM EDT here, and I need sleep) Perhaps I can get clever, even if you have solved it, I'd like to give it a try.