Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

os.process module doesn't see to read stdout/err correctly when it stays open #20123

Open
despiegk opened this issue Dec 8, 2023 · 8 comments
Labels
Bug This tag is applied to issues which reports bugs.

Comments

@despiegk
Copy link
Contributor

despiegk commented Dec 8, 2023

Describe the bug

trying to open /opt/homebrew/bin/python3
and then write/read from the process

we can't get any output

we also tried with . is_pending() but that was blocking

Reproduction Steps

import os
import time

fn main() {
	do1() or { panic(err) }
}

fn do1() ! {

	mut p := os.new_process("/opt/homebrew/bin/python3")
	p.set_work_folder("/tmp")
	p.set_redirect_stdio()
	p.run()
	// p.set_args("")
	// time.sleep(100 * time.millisecond)
	println( "alive: ${p.is_alive()}")
	assert p.is_alive()
	p.stdin_write("print('something')\n")
	defer {
		p.wait()
		p.close()
	}

	for {
		out:=p.pipe_read(.stdout) or {""}
		if out.len>0{
			println(out)
		}
		err:=p.pipe_read(.stderr) or {""}
		if err.len>0{
			println(err)
		}
		
	}
}

Expected Behavior

to show

Python 3.11.6 (main, Oct  2 2023, 13:45:54) [Clang 15.0.0 (clang-1500.0.40.1)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>

Current Behavior

tried with and without sending to stdin

Possible Solution

No response

Additional Information/Context

No response

V version

newest

Environment details (OS name and version, etc.)

osx m.1

Note

You can use the 👍 reaction to increase the issue's priority for developers.

Please note that only the 👍 reaction to the issue itself counts as a vote.
Other reactions and those to comments will not be taken into account.

@despiegk despiegk added the Bug This tag is applied to issues which reports bugs. label Dec 8, 2023
@despiegk
Copy link
Contributor Author

despiegk commented Dec 8, 2023

see also #14486
if I did os.fd_close(p.stdio_fd[0]) then the write to stdin works but could only do it 1 time so no solution for me

and still the original output now shows

@spytheman
Copy link
Member

This works:

import os
import time

fn main() {
    python_exe := os.find_abs_path_of_executable('python3')!
    dump(python_exe)
    mut p := os.new_process(python_exe)
    p.set_args(['-i'])
    p.set_work_folder("/tmp")
    p.set_redirect_stdio()
    p.run()
    dump(p.pid)
    p.stdin_write("print('something')\n")
    mut i := 0
    for p.is_alive() {
        i++
        if oline:=p.pipe_read(.stdout) {
            println('oline: `$oline`')
        }
        if eline := p.pipe_read(.stderr) {
            eprintln('eline: `$eline`')
        }
        time.sleep(20*time.millisecond)
    }
    p.close()
    p.wait()
    dump(p.code)
}

I saw the need for -i for python in https://stackoverflow.com/questions/66763957/python-interactive-shell-not-responding-to-input-when-run-in-subprocess .

@spytheman
Copy link
Member

Passing -q may be needed as well, otherwise the first few lines will be from the python's welcome message.

@spytheman
Copy link
Member

This is with both flags:
image

@spytheman
Copy link
Member

I've added an example based on the code here in latest V: https://github.com/vlang/v/blob/master/examples/process/wrapping_interactive_python.v
image

@despiegk
Copy link
Contributor Author

despiegk commented Dec 8, 2023

amazing, thx you

any idea why is_pending() is not working ?

@spytheman
Copy link
Member

spytheman commented Dec 8, 2023

Without -i, python tries to read all the input, and only then starts to interpret it.
I.e. without it, it will block until the input stream/pipe is closed.

meanwhile, it does not output anything, and so is_pending will return false

@spytheman
Copy link
Member

spytheman commented Dec 8, 2023

From https://docs.python.org/3/using/cmdline.html#interface-options :

When called with a file name argument or with a file as standard input, it reads and executes a script from that file.

In non-interactive mode, the entire input is parsed before it is executed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug This tag is applied to issues which reports bugs.
Projects
None yet
Development

No branches or pull requests

2 participants