Closed gilch closed 3 years ago
From the Python docs on sys.ps1
and ps2
:
Their initial values in this case are '>>> ' and '... '. If a non-string object is assigned to either variable, its str() is re-evaluated each time the interpreter prepares to read a new interactive command; this can be used to implement a dynamic prompt.
Looks like input()
calls str()
on its prompt object, so this is more dynamic than I thought. Any class with a __str__
override could call .get()
on a contextvar. Still doesn't cooperate that well if some other code tries to assign that though.
I also found a better place to override the prompt: the raw_input()
method. I initially glossed over this because I thought it was only for getting input, but it also outputs the prompts. Monkeypatching will not be required.
Not a new issue, but I'm writing it down so I don't forget to address it. I knew this was going to happen when I wrote the REPL code, but couldn't see a good way to avoid it at the time. Python's REPL prompts are stored in
sys.ps1
andsys.ps2
. Lissp's REPL is based oncode.InteractiveConsole
and overwrites these to be the Lissp prompts, because the superclass reads them from there. An unfortunate design flaw.That means that if you start a
code.interact()
session from within the Lissp REPL, you keep getting the Lissp prompts, which is confusing. It's nice to be able to drop into Python from the same environment, so it could come up. The resulting Python console is perfectly functional, so perhaps this is a minor issue.The methods are also too large to override easily, short of copy/pasting library code. The best available approach may be monkeypatching with
unittest.mock.patch
as briefly and as close to use as possible. It's times like this when I wish Python had dynamic variables like Lisp. Contextvars come close, but they're not a drop-in replacement for a global, since you still have to call the.get()
method to dereference. Monkeypatching like this is somewhat brittle, but using the prompts fromsys
is documented behavior in thecode
module, so this case should work.