`pipenv shell` breaks bash `suspend` (job control)
Issue description
When inside a bash shell spawned from pipenv shell, using suspend (bash builtin to give back control to parent shell from subshell, this is like using ^Z) does not give back control to parent shell (the one running pipenv shell).
The issue does not occur when using pipenv run bash.
Expected result
Being able to supend my shell from inside a pipenv subshell like when using pipenv run.
Actual result
$ pipenv shell
Loading .env environment variables...
Loading .env environment variables...
Launching subshell in virtual environment...
[max@work-laptop-max] $ . /home/max/.local/share/virtualenvs/document_sync_job-ykvVh148/bin/activate
[max@work-laptop-max] $
ps -x --forest
13135 pts/0 Ss 0:00 | \_ /bin/bash
13847 pts/0 S+ 0:00 | \_ /usr/bin/python /usr/bin/pipenv shell
13848 pts/1 Ss+ 0:00 | \_ /bin/bash -i
$ suspend
^C^C^C^C^Z^Z^Z
ps -x --forest
13135 pts/0 Ss 0:00 | \_ /bin/bash
13847 pts/0 S+ 0:00 | \_ /usr/bin/python /usr/bin/pipenv shell
13848 pts/1 Ts+ 0:00 | \_ /bin/bash -i
(T = stopped by job control signal, S = interruptible sleep (from man ps))
Compare to pipenv run bash:
14015 pts/0 Ss 0:00 | \_ /bin/bash
14191 pts/0 S+ 0:00 | \_ /usr/bin/bash
(I presume this is using exec instead of fork)
pipenv shell should either do the same thing as pipenv run (but maybe there is need for some cleanup on exit ?) or check for sigstop on the child process and stop itself, then resume child when itself resumed. (Just ideas)
Steps to replicate
Any Pipfile + the commands described in the previous section.
$ pipenv --support
Pipenv version: '2022.9.8'
Pipenv location: '/usr/lib/python3.10/site-packages/pipenv'
Python location: '/usr/bin/python'
OS Name: 'posix'
User pip version: '22.2.2'
user Python installations found:
3.10.7:/usr/bin/python3.10.7:/usr/bin/python33.8.13:/home/max/.pyenv/versions/3.8.13/bin/python3.8
PEP 508 Information:
{'implementation_name': 'cpython',
'implementation_version': '3.10.7',
'os_name': 'posix',
'platform_machine': 'x86_64',
'platform_python_implementation': 'CPython',
'platform_release': '5.19.8-arch1-1',
'platform_system': 'Linux',
'platform_version': '#1 SMP PREEMPT_DYNAMIC Thu, 08 Sep 2022 18:07:42 +0000',
'python_full_version': '3.10.7',
'python_version': '3.10',
'sys_platform': 'linux'}
System environment variables:
SHELLCOLORTERMSSH_AUTH_SOCKEDITORPWDLOGNAMESYSTEMD_EXEC_PIDHOMELANGXDG_CURRENT_DESKTOPSWAYSOCKWAYLAND_DISPLAYINVOCATION_IDMANAGERPIDTERMUSERDISPLAYSHLVLXDG_RUNTIME_DIRJOURNAL_STREAMBROWSERPATHDBUS_SESSION_BUS_ADDRESSMAIL_PIP_DISABLE_PIP_VERSION_CHECKPIP_PYTHON_PATHPYTHONDONTWRITEBYTECODEPYTHONFINDER_IGNORE_UNSUPPORTED
Pipenv–specific environment variables:
Debug–specific environment variables:
PATH:/usr/local/bin:/usr/binSHELL:/bin/bashEDITOR:vimLANG:en_US.UTF-8PWD:/home/max
That is an interesting issue to work on.
pipenv shell calls pexpect, so the issue is maybe related to pexpect or to how we use pexpect, follow from here:
https://github.com/pypa/pipenv/blob/114eb8f80a63e519fe9d12ac9e7cb60444cf47c0/pipenv/core.py#L2424
pipenv run calls os.execve in
https://github.com/pypa/pipenv/blob/114eb8f80a63e519fe9d12ac9e7cb60444cf47c0/pipenv/core.py#L2579
This makes me wonder if we can even drop pexpect and every time the user runs pipenv shell start the correct shell with the correct environment...