11

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.

golmschenk
  • 11,736
  • 20
  • 78
  • 137
  • PyCharm must provide a pseudo-tty (pty) instead of a pipe e.g., the code runs fine from within Emacs. You could try `pty.spawn('ftp')` – jfs Aug 22 '15 at 13:42
  • @J.F.Sebastian, that is an answer, it works. – Padraic Cunningham Aug 22 '15 at 20:28
  • @J.F.Sebastian: pty works for this case, but this is really just a simplified example. I still need the power of pexpect. I don't see how to make PyCharm provide a pseudo-tty, but perhaps someone answering this question will know. – golmschenk Aug 27 '15 at 23:16
  • 1
    Try `pty.spawn("python your_script.py".split())` where *your_script.py* uses `pexpect`. – jfs Aug 27 '15 at 23:26
  • @J.F.Sebastian: This does work. It's not particularly clean (in comparison with changing some setting that might exist in the IDE or the like), but I'll see if it's the only working solution I get. – golmschenk Aug 28 '15 at 15:39
  • @J.F.Sebastian: I would prefer the bounty gets assigned to a working answer, and since this is the only one thus far it might be good to post this as an actual answer. Thanks. – golmschenk Aug 28 '15 at 15:54
  • @golmschenk: you could [post your own answer that you've tested](http://stackoverflow.com/help/self-answer) – jfs Aug 28 '15 at 17:06

3 Answers3

2

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.

golmschenk
  • 11,736
  • 20
  • 78
  • 137
1

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.

knight
  • 435
  • 5
  • 18
  • Do you know of any documentation for the `pty_spawn` function? I only see the file of this name which contains the `spawn` function I'm already using and attempting to call this function results in a `'module' object has no attribute` error. – golmschenk Aug 27 '15 at 23:04
  • Sorry, it should be `pexpect.pty.spawn`. – knight Aug 28 '15 at 02:14
  • This now does spawn the process, but other pexpect commands (expect, sendline, etc) cannot be used afterwards because it seems the program is waiting for the pty call to complete. Any thoughts on how to allow this through this approach? – golmschenk Aug 28 '15 at 15:32
  • If you want to manipulate it programmatically then I guess [ptyprocess](https://github.com/pexpect/ptyprocess) is the best way to go. – knight Aug 29 '15 at 02:02
-1

It looks like pexpect is installed correctly on your default Python installation, there may be another python instance which may not have pexpect library installed or installed correctly. In your PyCharm settings try pointing it to your default/correct python installation.

Phaneendra
  • 421
  • 4
  • 7
  • Thanks for the response, but this doesn't seem to be happening because of a problem with the Pexpect installation or which interpreter is being used by PyCharm. It appears to be an issue with how "terminal" of the run/debug of PyCharm communicates with Pexpect. – golmschenk Aug 07 '15 at 01:38