Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using IPython interchangeably with code module if IPython exists

Tags:

python

ipython

In an existing code snippet, I have

import sys
from code import InteractiveConsole


class FileCacher:
    "Cache the stdout text so we can analyze it before returning it"
    def __init__(self):
        self.reset()

    def reset(self):
        self.out = []

    def write(self, line):
        self.out.append(line)

    def flush(self):
        output = '\n'.join(self.out)
        self.reset()
        return output


class Shell(InteractiveConsole):
    "Wrapper around Python that can filter input/output to the shell"
    def __init__(self):
        self.stdout = sys.stdout
        self.cache = FileCacher()
        InteractiveConsole.__init__(self)
        return

    def get_output(self):
        sys.stdout = self.cache

    def return_output(self):
        sys.stdout = self.stdout

    def push(self, line):
        self.get_output()
        # you can filter input here by doing something like
        # line = filter(line)
        InteractiveConsole.push(self, line)
        self.return_output()
        output = self.cache.flush()
        # you can filter the output here by doing something like
        # output = filter(output)
        print output  # or do something else with it
        return

if __name__ == '__main__':
    sh = Shell()
    sh.interact()

How do I modify this to use IPython's interactive shell if IPython is available without changing the rest of the code if possible.

I attempted swapping out line 2 from code import InteractiveConsole with from IPython.core import interactiveshell as InteractiveConsole but obviously, it's not a directly interchangeable class.

What's the best way to do this (with minimal change to the rest of the code base) with a try except and using IPython in preference over code module when IPython exists?

like image 581
Calvin Cheng Avatar asked Sep 02 '26 23:09

Calvin Cheng


1 Answers

Here's my own attempt:-

import sys
from code import InteractiveConsole

class FileCacher:
    "Cache the stdout text so we can analyze it before returning it"
    def __init__(self):
        self.reset()

    def reset(self):
        self.out = []

    def write(self, line):
        self.out.append(line)

    def flush(self):
        output = '\n'.join(self.out)
        self.reset()
        return output


class Shell(InteractiveConsole):
    "Wrapper around Python that can filter input/output to the shell"
    def __init__(self):
        self.stdout = sys.stdout
        self.cache = FileCacher()
        InteractiveConsole.__init__(self)
        return

    def get_output(self):
        sys.stdout = self.cache

    def return_output(self):
        sys.stdout = self.stdout

    def push(self, line):
        self.get_output()
        # you can filter input here by doing something like
        # line = filter(line)
        InteractiveConsole.push(self, line)
        self.return_output()
        output = self.cache.flush()
        # you can filter the output here by doing something like
        # output = filter(output)
        print output  # or do something else with it
        return

if __name__ == '__main__':
    try:
        import IPython
        IPython.embed()
    except:
        sh = Shell()
        sh.interact()

which seems to work fine but I probably lost the cache and stdout custom methods/functionalities.

Any criticism, edits and improvement suggestions welcome!

like image 66
Calvin Cheng Avatar answered Sep 04 '26 14:09

Calvin Cheng



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!