Page 1 of 2
I can’t interact with micropython by Popen
Posted: Fri Apr 24, 2020 3:18 am
by rockindy
Hi,
I tried to use Popen of python2/3 to interact with micropyton unix port, but will be blocked by proc.stdout.readline() function:
Code: Select all
proc = subprocess.Popen(['./micropython', '-i'],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
proc.stdin.write(b'2+2\n')
proc.stdin.flush()
proc.stdout.readline()
Dose anyone has any idea?
Thanks.
Re: I can’t interact with micropython by Popen
Posted: Fri Apr 24, 2020 5:26 am
by pythoncoder
MicroPython is primarily intended to run on microcontrollers where there is no underlying OS. A lot of CPython's functionality assumes an OS and is unsupported.
Re: I can’t interact with micropython by Popen
Posted: Fri Apr 24, 2020 7:11 am
by stijn
IIRC there is (or was) a way to do this: in the past I've played around with a Jupyter kernel for the unix and windows ports. Don't remember which one though, but in my memory it used Popen or pexpect.ReplWrapper or something like that.
Still, question is: what do you really want to do? Because the code you show could be done using subprocess.check_output or so.
Re: I can’t interact with micropython by Popen
Posted: Fri Apr 24, 2020 7:17 am
by Christian Walther
This
is CPython.
Apparently micropython does not run the REPL when stdin is not from a terminal, which means that
- input is only compiled at EOF, not line-wise,
- you need to use print() to see output.
This works for me:
Code: Select all
>>> proc = subprocess.Popen(['./micropython', '-i'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
>>> proc.stdin.write(b'print(2+2)\n')
11
>>> proc.stdin.close()
>>> proc.stdout.read()
b'4\n'
>>> proc.stderr.read()
b''
Re: I can’t interact with micropython by Popen
Posted: Mon Apr 27, 2020 3:52 am
by rockindy
Hi,
Thanks for your replies.
I want to let user interacts with MicroPython REPL via gui widget, so I need to pipe the stdin/stdout.
@Christian Walther your way works but can only write the stdin once.
Finally I found a way to do it.
For whom encountered the same problem, you can modify the main.c of unix port to solve it:
Code: Select all
--- a/ports/unix/main.c
+++ b/ports/unix/main.c
@@ -657,7 +657,8 @@ MP_NOINLINE int main_(int argc, char **argv) {
inspect = true;
}
if (ret == NOTHING_EXECUTED || inspect) {
- if (isatty(0)) {
+ if (1) {
prompt_read_history();
ret = do_repl();
prompt_write_history();
Re: I can’t interact with micropython by Popen
Posted: Mon Apr 27, 2020 2:34 pm
by dhylands
The way that python and bash does it is to provide a -i or --interactive option which tells it to stick around and do interactive things.
Otherwise if you just wanted to run a script with redirected input it would print a prompt and try to listen to stdin which wouldn't be the intended behaviour.
So changing it to be "if isatty(stdin) || -i flag was specified" would be a solution which you would likely get merged.
Re: I can’t interact with micropython by Popen
Posted: Mon Apr 27, 2020 5:33 pm
by Christian Walther
And "-i flag was specified" is exactly the variable
inspect used one line above, so the changed line is
You’ll probably also want to adjust the
print_help() text. (CPython’s says “forces a prompt even if stdin does not appear to be a terminal”.)
Re: I can’t interact with micropython by Popen
Posted: Tue Apr 28, 2020 3:05 am
by rockindy
In the current code, once you redirect stdin, it won't call do_repl().
And I don't know how to tell the redirection is from '<' or from Popen.
My suggestion is once you set -i flag, it will always call do_repl().
And if you want to run script from a file, just use '<' without -i flag.
Re: I can’t interact with micropython by Popen
Posted: Tue Apr 28, 2020 1:12 pm
by Christian Walther
rockindy wrote: ↑Tue Apr 28, 2020 3:05 am
And I don't know how to tell the redirection is from '<' or from Popen.
Why would you need to?
My suggestion is once you set -i flag, it will always call do_repl().
That much is common between dhylands’ solution and yours. What’s different is what happens when you don’t set the -i flag.
And if you want to run script from a file, just use '<' without -i flag.
That’s what works in dhylands’ solution but not in yours.
(At least that’s my understanding just from reading the code, I haven’t actually tested it.)
(You may be talking past each other with respect to whether you are talking about “micropython script.py < inputfile” or “micropython < script.py”.)
Re: I can’t interact with micropython by Popen
Posted: Wed Apr 29, 2020 6:38 am
by rockindy
Sorry, I think I misunderstood dhylands' post.
The correct understanding is:
Code: Select all
if (ret == NOTHING_EXECUTED || inspect) {
- if (isatty(0)) {
+ if (isatty(0) || inspect) {
prompt_read_history();
With this patch, it should work as excepted.
Thank you
@dhylands and
@Christian Walther.