loading...
Cover image for Building the Python REPL

Building the Python REPL

amalshaji profile image Amal Shaji Originally published at amalshaji.github.io ・3 min read

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

# these are statements

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

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

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

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...")

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

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()

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

The above code is packaged for easy use.

Install

pip install py3repl

Usage

# call pyrepl from the command line

pyrepl

# if this fails, try

python -m py3repl.pyrepl

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.

Discussion

pic
Editor guide