DEV Community

Cover image for Building the Python REPL
Amal Shaji
Amal Shaji

Posted on • Originally published at amalshaji.github.io

Building the Python REPL

One of the features that come with Python is the python REPL(popularly known as the python interpreter). REPL stands for Read, Evaluate, Print, Loop. REPL enables us to write python code one line at a time. Though most python programs are run as scripts, the REPL can come in handy for quick testing of parts of code or some functions.

In this article, I will build a python REPL (a minimal one, one with fewer features). Building a REPL is not a tedious task as the python developers have done most of the work(damage)😁.

Final Product

final_demo.gif

The focus of this article will be one two built-in functions eval() and exec().

Another important thing is understanding the difference between a statement and an expression. An expression evaluates a value, but a statement does(mean) something. In Python, the following are expressions,

# python REPL

>>> 2+3
5
>>> 2*4
8
>>> "amal is great"
'amal is great'
>>> "python goes b" + "r"*20
'python goes brrrrrrrrrrrrrrrrrrrr'

# These above evaluates to a final answer, thus called expressions
Enter fullscreen mode Exit fullscreen mode

# these are statements

>>> from math import pow
>>> b = -1
>>> a = b
>>> for _ in range(10):
...     pass
...
Enter fullscreen mode Exit fullscreen mode

eval() is used for evaluating expressions. eval("some expressions as string goes here") will evaluate to whatever is input as a string.

>>> eval("2+3")
5
>>> eval("2**3")
8
>>> eval("print('python3 > python2')")
python3 > python2
Enter fullscreen mode Exit fullscreen mode

exec() is used for executing statements.

>>> exec("a=10")
>>> a
10
>>> exec("a+45")
>>> exec("b=a+45")
>>> b
55
>>> exec("from math import sqrt")
>>> sqrt(45)
6.708203932499369
Enter fullscreen mode Exit fullscreen mode

That's it, and now we can mimic the REPL with ease. First, let's create the REPL function, which executes infinitely until ctrl-c. For each loop, we'll take input and evaluate it. If the evaluation fails, we'll execute the same string. If both fail, we'll print out the error.

def repl() -> None:
    try:
        while True:
            try:
                _in = input(">> ")
                try:
                    print(eval(_in))
                except:
                    out = exec(_in)
                    if out != None:
                        print(out)
            except Exception as e:
                print(f"Error: {e}")
    except KeyboardInterrupt as e:
        print("\nExiting...")
Enter fullscreen mode Exit fullscreen mode

Program Flow

repl

Demo

demo

We have successfully re-created the REPL. But this looks very boring, let's add some colors to it.

Install colorama

pip install colorama
Enter fullscreen mode Exit fullscreen mode

Now we add RED color to errors and GREEN to successful code run. The final code is,

from colorama import Fore, init

init(autoreset=True)

success = lambda input: f"{Fore.GREEN}{input}"
failure = lambda input: f"{Fore.RED}{input}"


def repl() -> None:
    try:
        while True:
            try:
                _in = input(">>> ")
                try:
                    print(success(eval(_in)))
                except:
                    out = exec(_in)
                    if out != None:
                        print(success(out))
            except Exception as e:
                print(failure(f"Error: {e}"))
    except KeyboardInterrupt as e:
        print("\nExiting...")


if __name__ == "__main__":
    print()
    print("Welcome to python nano-REPL")
    print("crtl-c to quit")
    print()
    repl()
Enter fullscreen mode Exit fullscreen mode

init(autoreset=True) resets the style after each style change.

The above code is packaged for easy use.

Install

pip install py3repl
Enter fullscreen mode Exit fullscreen mode

Usage

# call pyrepl from the command line

pyrepl

# if this fails, try

python -m py3repl.pyrepl
Enter fullscreen mode Exit fullscreen mode

Final Demo

easter egg

Drawbacks

  • You can't navigate back and forth a line or between lines in Linux terminal(tested on WSL2)
  • Only supports single-line statements

Repo: https://github.com/amalshaji/pyrepl

There may be a lot of bugs. Please report if you find any.

Top comments (0)