Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make readline work in a python subprocess?

I have spent quite something enabling readline support in pdb on MacOS Sierra in a subprocess which I don't understand why it fails, hence the question.

Please note that I have proper readline support without adding a .pdbrc file in all my python environemnts, including python2 and 3 installations and also in virtual environments created with pipenv, venv, or pew. All work just fine.

The problem arises when I want to drop into a pdb shell in a subprocess. I use a nodejs program along with a plugin which I use to invoke AWS code locally. The first nodejs process starts the second and the second one starts a python process which I have my usual pdb code in it:

import pdb; pdb.set_trace()

However the pdb shell that I get has no readline support. I tried the following alternatives which didn't work as well:

import ipdb; ipdb.set_trace()
import rlcompleter, readline
readline.parse_and_bind('tab: complete')
readline.parse_and_bind('bind ^I rl_complete')

I also added .pdbrc file with above content (minus ipdb import) to no avail. I tried also setting PYTHONSTARTUP point to a file with this content:

import rlcompleter, readline
readline.parse_and_bind('tab: complete')

It didn't help too. People had reported that these solutions have worked for them, but they didn't have readline support to start with (which for me it works just fine without these tricks).

I also tried patching my nodejs process.env.PATH and process.env.PYTHONPATH and added directories where I have python installation which have readline support to no avail.

I appreciate if anybody can explain whether there is a fundamental difference between launching pdb from a sub-sub-...-process and directly from terminal (which in anycase it is a subprocess too). Moreover, I appreciate any suggestion that might help me solve this problem.

Update I

I noticed that even without pdb I don't get the readline support:

import code
code.interact(local=locals())

If I run the above code I get a python shell without readline support:

Python 3.7.0 (default, Jun 29 2018, 20:13:13)
[Clang 9.1.0 (clang-902.0.39.2)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)

>>>
<pointer blinks here which is strange, it should be on the line above>

Update II

Some relevant thread on the net:

  • Pipenv: https://github.com/pypa/pipenv/issues/497#issuecomment-328190362
  • Pew: https://github.com/berdario/pew/issues/150

Update III

After giving some thought to the problem and thanks to the georgexsh comment, I think my problem boils down to launching an interactive python REPL from nodejs. It must run in its own process and inputs such pressing TAB key should be sent to the python process and its stdout should be printed on the screen. In nodejs the oneliner below will do it:

require("repl").start("node> ")
like image 263
mehdix Avatar asked Nov 08 '22 02:11

mehdix


1 Answers

const ChildProcess = require('child_process');                                 

const ret = ChildProcess.spawnSync('python', [], { stdio: 'inherit' }); 

works for me.

like image 80
georgexsh Avatar answered Nov 14 '22 13:11

georgexsh