Set PYTHONUNBUFFERED on shell startup.

Fixes: debbugs:18595

* lisp/progmodes/python.el (python-shell-unbuffered): New var.
(python-shell-calculate-process-environment): Use it.

* test/automated/python-tests.el
(python-shell-calculate-process-environment-4)
(python-shell-calculate-process-environment-5): New tests.
(python-shell-make-comint-3): Use file-equal-p.
(python-shell-get-or-create-process-1)
(python-shell-get-or-create-process-2)
(python-shell-get-or-create-process-3): Fix interpreter for
Windows.
parent bd3625c4
2014-11-22 Fabián Ezequiel Gallina <fgallina@gnu.org>
Set PYTHONUNBUFFERED on shell startup.
* progmodes/python.el (python-shell-unbuffered): New var.
(python-shell-calculate-process-environment): Use it.
2014-11-22 Michael Albinus <michael.albinus@gmx.de>
* net/tramp.el (tramp-action-password): Clean password on subsequent
......
......@@ -94,13 +94,13 @@
;; python-shell-interpreter-args
;; "-i C:\\Python27\\Scripts\\ipython-script.py")
;; If you are experiencing missing or delayed output in your shells,
;; that's likely caused by your Operating System's pipe buffering
;; (e.g. this is known to happen running CPython 3.3.4 in Windows 7.
;; Missing or delayed output used to happen due to differences between
;; Operating Systems' pipe buffering (e.g. CPython 3.3.4 in Windows 7.
;; See URL `http://debbugs.gnu.org/cgi/bugreport.cgi?bug=17304'). To
;; fix this, using CPython's "-u" commandline argument or setting the
;; "PYTHONUNBUFFERED" environment variable should help: See URL
;; `https://docs.python.org/3/using/cmdline.html#cmdoption-u'.
;; avoid this, the `python-shell-unbuffered' defaults to non-nil and
;; controls whether `python-shell-calculate-process-environment'
;; should set the "PYTHONUNBUFFERED" environment variable on startup:
;; See URL `https://docs.python.org/3/using/cmdline.html#cmdoption-u'.
;; The interaction relies upon having prompts for input (e.g. ">>> "
;; and "... " in standard Python shell) and output (e.g. "Out[1]: " in
......@@ -1813,6 +1813,14 @@ Restart the Python shell after changing this variable for it to take effect."
:group 'python
:safe 'booleanp)
(defcustom python-shell-unbuffered t
"Should shell output be unbuffered?.
When non-nil, this may prevent delayed and missing output in the
Python shell. See commentary for details."
:type 'boolean
:group 'python
:safe 'booleanp)
(defcustom python-shell-process-environment nil
"List of environment variables for Python shell.
This variable follows the same rules as `process-environment'
......@@ -2087,6 +2095,8 @@ uniqueness for different types of configurations."
(virtualenv (if python-shell-virtualenv-path
(directory-file-name python-shell-virtualenv-path)
nil)))
(when python-shell-unbuffered
(setenv "PYTHONUNBUFFERED" "1"))
(when python-shell-extra-pythonpaths
(setenv "PYTHONPATH"
(format "%s%s%s"
......
2014-11-22 Fabián Ezequiel Gallina <fgallina@gnu.org>
* automated/python-tests.el
(python-shell-calculate-process-environment-4)
(python-shell-calculate-process-environment-5): New tests.
(python-shell-make-comint-3): Use file-equal-p.
(python-shell-get-or-create-process-1)
(python-shell-get-or-create-process-2)
(python-shell-get-or-create-process-3): Fix interpreter for
Windows (Bug#18595).
2014-11-15 Fabián Ezequiel Gallina <fgallina@gnu.org>
* automated/python-tests.el (python-indent-dedenters-8): New test
......
......@@ -1872,6 +1872,23 @@ Using `python-shell-interpreter' and
python-shell-virtualenv-path
path-separator original-path)))))
(ert-deftest python-shell-calculate-process-environment-4 ()
"Test `python-shell-unbuffered' modification."
(setenv "PYTHONUNBUFFERED")
(let* ((process-environment
(python-shell-calculate-process-environment)))
;; Defaults to t
(should python-shell-unbuffered)
(should (string= (getenv "PYTHONUNBUFFERED") "1"))))
(ert-deftest python-shell-calculate-process-environment-5 ()
(setenv "PYTHONUNBUFFERED")
"Test `python-shell-unbuffered' modification."
(let* ((python-shell-unbuffered nil)
(process-environment
(python-shell-calculate-process-environment)))
(should (not (getenv "PYTHONUNBUFFERED")))))
(ert-deftest python-shell-calculate-exec-path-1 ()
"Test `python-shell-exec-path' modification."
(let* ((original-exec-path exec-path)
......@@ -1961,8 +1978,9 @@ and `python-shell-interpreter-args' in the new shell buffer."
(should (process-live-p process))
(with-current-buffer shell-buffer
(should (eq major-mode 'inferior-python-mode))
(should (string= python-shell-interpreter
(executable-find python-tests-shell-interpreter)))
(should (file-equal-p
python-shell-interpreter
(executable-find python-tests-shell-interpreter)))
(should (string= python-shell-interpreter-args "-i"))))
(kill-buffer shell-buffer))))
......@@ -2050,12 +2068,11 @@ and `python-shell-interpreter-args' in the new shell buffer."
(skip-unless (executable-find python-tests-shell-interpreter))
(python-tests-with-temp-file
""
(let* ((python-shell-interpreter
(executable-find python-tests-shell-interpreter))
(let* ((cmd
(concat (executable-find python-tests-shell-interpreter) " -i"))
(use-dialog-box)
(dedicated-process-name (python-shell-get-process-name t))
(dedicated-process
(python-shell-get-or-create-process python-shell-interpreter t))
(dedicated-process (python-shell-get-or-create-process cmd t))
(dedicated-shell-buffer (process-buffer dedicated-process)))
(unwind-protect
(progn
......@@ -2073,12 +2090,11 @@ and `python-shell-interpreter-args' in the new shell buffer."
(skip-unless (executable-find python-tests-shell-interpreter))
(python-tests-with-temp-file
""
(let* ((python-shell-interpreter
(executable-find python-tests-shell-interpreter))
(let* ((cmd
(concat (executable-find python-tests-shell-interpreter) " -i"))
(use-dialog-box)
(process-name (python-shell-get-process-name nil))
(process
(python-shell-get-or-create-process python-shell-interpreter))
(process (python-shell-get-or-create-process cmd))
(shell-buffer (process-buffer process)))
(unwind-protect
(progn
......@@ -2088,43 +2104,42 @@ and `python-shell-interpreter-args' in the new shell buffer."
(kill-buffer shell-buffer)
;; Check there are no processes for current buffer.
(should (not (python-shell-get-process))))
(ignore-errors (kill-buffer dedicated-shell-buffer))))))
(ignore-errors (kill-buffer shell-buffer))))))
(ert-deftest python-shell-get-or-create-process-3 ()
"Check shell dedicated/global process preference."
(skip-unless (executable-find python-tests-shell-interpreter))
(python-tests-with-temp-file
""
(let* ((python-shell-interpreter
(executable-find python-tests-shell-interpreter))
(let* ((cmd
(concat (executable-find python-tests-shell-interpreter) " -i"))
(python-shell-interpreter python-tests-shell-interpreter)
(use-dialog-box)
(dedicated-process-name (python-shell-get-process-name t))
(global-process)
(dedicated-process))
(unwind-protect
(progn
;; Create global process
(run-python python-shell-interpreter nil)
(setq global-process (get-buffer-process "*Python*"))
(should global-process)
(set-process-query-on-exit-flag global-process nil)
;; Create dedicated process
(run-python python-shell-interpreter t)
(setq dedicated-process (get-process dedicated-process-name))
(should dedicated-process)
(set-process-query-on-exit-flag dedicated-process nil)
;; Prefer dedicated.
(should (equal (python-shell-get-or-create-process)
dedicated-process))
;; Kill the dedicated so the global takes over.
(kill-buffer (process-buffer dedicated-process))
;; Detect global.
(should (equal (python-shell-get-or-create-process) global-process))
;; Kill the global.
(kill-buffer (process-buffer global-process))
;; Check there are no processes for current buffer.
(should (not (python-shell-get-process))))
(ignore-errors (kill-buffer dedicated-shell-buffer))))))
(progn
;; Create global process
(run-python cmd nil)
(setq global-process (get-buffer-process "*Python*"))
(should global-process)
(set-process-query-on-exit-flag global-process nil)
;; Create dedicated process
(run-python cmd t)
(setq dedicated-process (get-process dedicated-process-name))
(should dedicated-process)
(set-process-query-on-exit-flag dedicated-process nil)
;; Prefer dedicated.
(should (equal (python-shell-get-or-create-process)
dedicated-process))
;; Kill the dedicated so the global takes over.
(kill-buffer (process-buffer dedicated-process))
;; Detect global.
(should (equal (python-shell-get-or-create-process) global-process))
;; Kill the global.
(kill-buffer (process-buffer global-process))
;; Check there are no processes for current buffer.
(should (not (python-shell-get-process)))))))
(ert-deftest python-shell-internal-get-or-create-process-1 ()
"Check internal shell process creation fallback."
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment