elpy icon indicating copy to clipboard operation
elpy copied to clipboard

C-d in pdb session causes shell exit

Open Yevgnen opened this issue 3 years ago • 1 comments

Summary

Pressing C-d in a debugger session cause the REPL process exits. The C-d is bind to comint-delchar-or-maybe-eof as default.

This happens to REPL process created by C-c C-z/elpy-shell-switch-to-shell but not C-c C-p/run-python.

This happens to a Python or iPython shell process.

This does not happen when entering exit and then RETURN in the debugger session.

Steps to reproduce

  1. Press C-c C-z(elpy-shell-switch-to-shell) in a python-mode buffer.
  2. Enter import pdb; pdb.set_trace() in the REPL buffer then ret.
  3. In the debugger session, press C-d.
  4. The debugger session exits, then the REPL process also exits.

My configuration

OS

macOS 12.0.1 (21A559)

Result of (elpy-config)

Sorry I can get this with the following messages after evaluating (elpy-config)

Elpy is creating the RPC virtualenv (’/Users/user/.emacs.d/elpy/rpc-venv’)
elpy-rpc--create-virtualenv: Doing vfork

Elpy configuration in my init.el

(use-package elpy
  :custom-face
  (elpy-codecell-boundary ((t :underline t)))

  :diminish elpy-mode
  :hook (python-mode . elpy-enable)

  :init
  (setq elpy-modules '(elpy-module-sane-defaults
                       elpy-module-folding)
        elpy-shell-command-prefix-key "C-c C-e")

  :config
  (unbind-keys :map elpy-mode-map '("C-c C-d"))

  (use-package elpy-shell
    :straight elpy
    :init (setq elpy-shell-starting-directory 'current-directory
                elpy-shell-echo-output nil)))

Yevgnen avatar Nov 24 '21 03:11 Yevgnen

The direct problem here is that Elpy connects to the Python shell via a pipe for Mac users. This was done because Python versions on MacOS that use the libedit version of readline (e.g. the default Mac Python versions) have issues operating with a pty connection (see e.g. #1671, #1550, #887).

However, the good news is that many Python versions on Mac use GNU readline instead of the libedit one (e.g. versions installed by Homebrew or Anaconda). If you are using one of these versions, there is no need to need to use a pipe instead of a pty connection.

I still need to pull together a proper pull request, but here's a simple patch. It adds a customizable variable for Mac users that allows users to toggle whether they want to use a pty connection or not. By default, a pipe is used. Add the code for the customizable variable:

(defcustom elpy-shell-darwin-use-pty nil
  "Whether to connect to the Python shell through a pseudo-terminal (pty) on MacOS.

If nil, Elpy will connect to Python through a pipe. Any non-nil
value will cause Elpy use a pty instead. This value should be set to nil when
using a Python interpreter that uses the libedit version of readline such as
the default MacOS Python interpreters.

This value is only used when `elpy-shell-get-or-create-process' creates a new
Python process."
  :type 'boolean
  :group 'elpy)

Then change this line in elpy-shell-get-or-create-process from (if (string-equal system-type "darwin") nil t)) ;; see https://github.com/jorgenschaefer/elpy/pull/1671 to (if (string-equal system-type "darwin") elpy-shell-darwin-use-pty t)) ;; see https://github.com/jorgenschaefer/elpy/pull/1671

drgillis avatar Jan 28 '22 19:01 drgillis