Skip to content

Add a simple REPL. - #460

Merged
jeff5 merged 7 commits into
jython:mainfrom
fwierzbicki:repl311
Nov 7, 2026
Merged

jeff5 merged 7 commits into
jython:mainfrom
fwierzbicki:repl311

Conversation

@fwierzbicki

Copy link
Copy Markdown
Member

Add a simple REPL that uses a cpython subprocess to do the compiling modeled on cpython's Lib/code.py especially InteractiveConsole

To try it out run:
./gradlew -q --console=plain core.repl

If you want history:
rlwrap ./gradlew -q --console=plain core:repl

On my mac I need to specify python3.11 (then for convenience I put it cpython=python3.11 into ~/.gradle/gradle.properties):
./gradlew -q --console=plain -Pcpython=python3.11 core:repl

rlwrap ./gradlew -q --console=plain core:repl
:core
Python 3.11.8
  Current dir = /Users/frank/src/jython/core
  templates from src/main/javaTemplate to build/generated/sources/javaTemplate/java/main
    process PyLongMethods.java
    process PyUnicodeMethods.java
    process PyFloatMethods.java
Jython 3 (prototype) using CPython compiler /Users/frank/src/cpython/python.exe
Ctrl-D to exit.
>>> a = 1
>>> a
1
>>> b = a + 1
>>> b
2
>>> 

@jeff5

jeff5 commented Oct 11, 2026

Copy link
Copy Markdown
Member

Nice idea. I suppose this gives us an interactive way to excite the interpreter without adding an example program.

As I understand it, this keeps a CPython running that is executing a script where it receives REPL input and returns marshalled code objects. It seems like this script is supplied on the command line with -c, but I'm not sure why it would have to work that way.

I haven't been able to run it on Windows. The real cause is probably a limitation on the length of a command line, as the message I get is:

Jython 3 (prototype) using CPython compiler python
Ctrl-D to exit.
  File "<string>", line 21
    print(fThe
         ^
SyntaxError: '(' was never closed

This is a truncated bit of text from `repl_compiler.py". Or it may be something to do with quote characters, given one is missing.

@jeff5 jeff5 left a comment •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice thing this, in principle. I'd have it in org.python.util I think, ISTR that's where there are things like it in Jython 2. Not running on Windows stops me poking more deeply.

Oh, and I meant to tick the request changes thing.

Comment thread .github/workflows/unit-tests.yml Resolved
Comment thread core/core.gradle Resolved
@wfouche

wfouche commented Oct 12, 2026 •

Copy link
Copy Markdown
Member

Not running on Windows stops me poking more deeply.

@jeff5 , have you tried installing WSL 3.0 with creates a lightweight Ubuntu Linux environment in Win11?

https://www.zdnet.com/article/windows-subsystem-for-linux-3-for-developers-sticking-with-microsoft/

I'm able to build and run Jython in the WSL 3.0 environment.

image

@jeff5

jeff5 commented Oct 12, 2026

Copy link
Copy Markdown
Member

I'm able to build and run Jython in the WSL 3.0 environment.

Jython 2 runs fine on Windows.

Use one name, jython.cpython, for the Gradle property and the system
property. Gradle and ReplCompiler both resolve it as jython.cpython,
then JYTHON_CPYTHON, then "python".

Run repl_compiler.py from a temp file instead of with -c. On Windows,
Java doesn't escape the double quotes in a -c argument, which
corrupted the script.

Run unit tests on Windows as well as Ubuntu, passing CPython through
JYTHON_CPYTHON to avoid quoting problems in PowerShell.
Normalise line endings in ReplTest output

println writes "\r\n" on Windows, so the expected REPL output did not
match. Compare captured output with line endings as "\n".
@fwierzbicki

Copy link
Copy Markdown
Member Author

Nice thing this, in principle. I'd have it in org.python.util I think, ISTR that's where there are things like it in Jython 2. Not running on Windows stops me poking more deeply.

Oh, and I meant to tick the request changes thing.

Moving this to org.python.util makes sense (it is indeed where that sort of thing lives in Jython 2) -- I did have to take a few things from package private to public - I know you are being super careful about what becomes public so let me know if we should do something else instead. Those newly public methods are Interpreter, its constructor, and eval().

As suggested in review. Interpreter, its constructor, and eval() become
public so that the REPL can run code from outside org.python.core.
noneOrStrError returns the TypeError and print() throws it, making
the termination clear at the call site.

Comment that displayHook is a stop-gap until there is a sys module
providing sys.displayhook and sys.stdout.
@fwierzbicki

Copy link
Copy Markdown
Member Author

Not running on Windows stops me poking more deeply.

@jeff5 , have you tried installing WSL 3.0 with creates a lightweight Ubuntu Linux environment in Win11?
That would be cheating! :)

@jeff5

jeff5 commented Oct 25, 2026

Copy link
Copy Markdown
Member

Merging #461 created a conflict, but one easy enough to rectify in the web interface, so I just did it. Merging main into #375 won't be so easy.

I'll play, but have DIY to do.

@jeff5

jeff5 commented Oct 26, 2026

Copy link
Copy Markdown
Member

That's such fun! And useful for debugging with the right wrapper. I'm looking forward to merging this from main into #375, where more of this kind of thing will work:

Jython 3 (prototype) using CPython compiler python
Ctrl-D to exit.
>>> 6*7
42
>>> dsl = str.__len__
>>> dsl.__name__
'__len__'
>>> dsl.__objclass__
AttributeError: 'wrapper_descriptor' object has no attribute '__objclass__'
>>> ("hello world" + '!').title()
AttributeError: 'str' object has no attribute 'title'
>>> import sys
org.python.base.InterpreterError: <module> at ip: 6, unknown opcode: 108
internal error: org.python.base.InterpreterError: <module> at ip: 6, unknown opcode: 108

It's very tempting to set about adding opcodes, but there are bigger fish to fry.

ctrl-D doesn't let me out on Windows. Evidently it reaches the application, and all it has to say is "that's interesting" :). But Gradle or PoSh is listening for ctrl-C:

>>> ^D
  File "<stdin>", line 1
>>>
    ^
SyntaxError: invalid non-printable character U+0004

>>> Terminate batch job (Y/N)? y

I'd merge this without, but if you wanted to honour the promise "Ctrl-D to exit", that would be nice. I'll leave a few days in case you want to add it.

@jeff5
jeff5 merged commit 5f132d5 into jython:main Nov 7, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants