I'm trying to run a basic Pexpect script:
import pexpect
ftp_process = pexpect.spawn('ftp')
ftp_process.interact()
When the code is run directly from a terminal, the code works as expected. If I run the code using PyCharm's run/debug I get the following error:
Traceback (most recent call last):
File "/path/to/code/test.py", line 3, in <module>
ftp_process.interact()
File "/usr/local/lib/python3.4/site-packages/pexpect/__init__.py", line 1645, in interact
mode = tty.tcgetattr(self.STDIN_FILENO)
termios.error: (25, 'Inappropriate ioctl for device')
It seems that how Pexpect interacts with PyCharm's run/debug window doesn't work by default. Is there some way to remedy this with a specific PyCharm setting? If not, is there some other way to work around this?
EDIT
The code above is simply a shortened example which results in the problem. The other abilities of pexpect (such as expect()
, sendline()
, etc) are still desired.
Note: This is only a workaround, but it does work.
If the script is called from a pseudo-tty by using a separate script the desired results can be achieved. For example, using pty.spawn("python my_script.py".split())
where my_script.py is the one using pexpect
.
I found it reasonable to have a single script which attempts the pexpect
calls initially within a try/except
and upon catching the error, have the script recall itself in inside a pseudo-tty.
Credit goes to J.F. Sebastian in the comments of the original question.
Try something which can allocate Pseudo TTYs. That should trick ftp
into thinking that it has a TTY (which is something that is given when you run Python REPL from the terminal). Example:
pexpect.pty.spawn('ftp')
You can also try ptyprocess although I can't vouch for it's correctness/being in a working state.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With