aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/progmodes/python.el
diff options
context:
space:
mode:
authorFabián Ezequiel Gallina2014-07-19 10:13:07 -0300
committerFabián Ezequiel Gallina2014-07-19 10:13:07 -0300
commitd949ade3c101981d015b3d78d061bdff584df13a (patch)
treed5e486ede2477b8f139720eabda8f6965086daef /lisp/progmodes/python.el
parent64384ca4ded41824f30a0a2470a65160dd486207 (diff)
downloademacs-d949ade3c101981d015b3d78d061bdff584df13a.tar.gz
emacs-d949ade3c101981d015b3d78d061bdff584df13a.zip
Autodetect Python shell prompts.
* lisp/progmodes/python.el: (python-shell-interpreter-interactive-arg) (python-shell-prompt-detect-enabled) (python-shell-prompt-detect-failure-warning) (python-shell-prompt-input-regexps) (python-shell-prompt-output-regexps): New vars. (python-shell-prompt-calculated-input-regexp) (python-shell-prompt-calculated-output-regexp): New vars. (python-shell-get-process-name) (python-shell-internal-get-process-name) (python-shell-output-filter) (python-shell-completion-get-completions): Use them. (python-shell-prompt-detect) (python-shell-prompt-validate-regexps): New functions. (python-shell-prompt-set-calculated-regexps): New function. (inferior-python-mode): Use it. Also honor overriden python-shell-interpreter and python-shell-interpreter-args. (python-shell-make-comint): Honor overriden python-shell-interpreter and python-shell-interpreter-args. (python-shell-get-or-create-process): Make it testable by allowing to call run-python non-interactively. (python-util-valid-regexp-p): New function. (python-shell-prompt-regexp, python-shell-prompt-block-regexp) (python-shell-prompt-output-regexp) (python-shell-prompt-pdb-regexp): Use it as defcustom :safe. * test/automated/python-tests.el (python-shell-make-comint-1): (python-shell-make-comint-2): Fix indentation. (python-shell-make-comint-3) (python-shell-make-comint-4): New tests. (python-shell-get-or-create-process-1): Fix test. (python-shell-get-or-create-process-2) (python-shell-get-or-create-process-3): New tests. (python-shell-internal-get-or-create-process-1): Fix test. (python-shell-prompt-detect-1): New test. (python-shell-prompt-detect-2): New test. (Bug#17370) (python-shell-prompt-detect-3) (python-shell-prompt-detect-4) (python-shell-prompt-detect-5) (python-shell-prompt-detect-6) (python-shell-prompt-validate-regexps-1) (python-shell-prompt-validate-regexps-2) (python-shell-prompt-validate-regexps-3) (python-shell-prompt-validate-regexps-4) (python-shell-prompt-validate-regexps-5) (python-shell-prompt-validate-regexps-6) (python-shell-prompt-validate-regexps-7) (python-shell-prompt-set-calculated-regexps-1) (python-shell-prompt-set-calculated-regexps-2) (python-shell-prompt-set-calculated-regexps-3) (python-shell-prompt-set-calculated-regexps-4) (python-shell-prompt-set-calculated-regexps-5) (python-shell-prompt-set-calculated-regexps-6) (python-util-valid-regexp-p-1): New tests.
Diffstat (limited to 'lisp/progmodes/python.el')
-rw-r--r--lisp/progmodes/python.el316
1 files changed, 271 insertions, 45 deletions
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index 237302f0530..e49d5882a61 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -4,7 +4,7 @@
4 4
5;; Author: Fabián E. Gallina <fabian@anue.biz> 5;; Author: Fabián E. Gallina <fabian@anue.biz>
6;; URL: https://github.com/fgallina/python.el 6;; URL: https://github.com/fgallina/python.el
7;; Version: 0.24.2 7;; Version: 0.24.4
8;; Maintainer: emacs-devel@gnu.org 8;; Maintainer: emacs-devel@gnu.org
9;; Created: Jul 2010 9;; Created: Jul 2010
10;; Keywords: languages 10;; Keywords: languages
@@ -62,13 +62,28 @@
62;; (add-hook 'python-mode-hook 62;; (add-hook 'python-mode-hook
63;; (lambda () (setq forward-sexp-function nil))) 63;; (lambda () (setq forward-sexp-function nil)))
64 64
65;; Shell interaction: is provided and allows you to execute easily any 65;; Shell interaction: is provided and allows you to easily execute any
66;; block of code of your current buffer in an inferior Python process. 66;; block of code of your current buffer in an inferior Python process.
67;; This relies upon having prompts for input (e.g. ">>> " and "... "
68;; in standard Python shell) and output (e.g. "Out[1]: " in iPython)
69;; detected properly. Failing that Emacs may hang but, in the case
70;; that happens, you can recover with \\[keyboard-quit]. To avoid
71;; this issue, a two-step prompt autodetection mechanism is provided:
72;; the first step is manual and consists of a collection of regular
73;; expressions matching common prompts for Python shells stored in
74;; `python-shell-prompt-input-regexps' and
75;; `python-shell-prompt-output-regexps', and dir-local friendly vars
76;; `python-shell-prompt-regexp', `python-shell-prompt-block-regexp',
77;; `python-shell-prompt-output-regexp' which are appended to the
78;; former automatically when a shell spawns; the second step is
79;; automatic and depends on the `python-shell-prompt-detect' helper
80;; function. See its docstring for details on global variables that
81;; modify its behavior.
67 82
68;; Shell completion: hitting tab will try to complete the current 83;; Shell completion: hitting tab will try to complete the current
69;; word. Shell completion is implemented in a manner that if you 84;; word. Shell completion is implemented in a way that if you change
70;; change the `python-shell-interpreter' to any other (for example 85;; the `python-shell-interpreter' to any other (for example IPython)
71;; IPython) it should be easy to integrate another way to calculate 86;; it should be easy to integrate another way to calculate
72;; completions. You just need to specify your custom 87;; completions. You just need to specify your custom
73;; `python-shell-completion-setup-code' and 88;; `python-shell-completion-setup-code' and
74;; `python-shell-completion-string-code'. 89;; `python-shell-completion-string-code'.
@@ -79,8 +94,6 @@
79;; (setq 94;; (setq
80;; python-shell-interpreter "ipython" 95;; python-shell-interpreter "ipython"
81;; python-shell-interpreter-args "" 96;; python-shell-interpreter-args ""
82;; python-shell-prompt-regexp "In \\[[0-9]+\\]: "
83;; python-shell-prompt-output-regexp "Out\\[[0-9]+\\]: "
84;; python-shell-completion-setup-code 97;; python-shell-completion-setup-code
85;; "from IPython.core.completerlib import module_completion" 98;; "from IPython.core.completerlib import module_completion"
86;; python-shell-completion-module-string-code 99;; python-shell-completion-module-string-code
@@ -213,7 +226,9 @@
213;;; Code: 226;;; Code:
214 227
215(require 'ansi-color) 228(require 'ansi-color)
229(require 'cl-lib)
216(require 'comint) 230(require 'comint)
231(require 'json)
217 232
218;; Avoid compiler warnings 233;; Avoid compiler warnings
219(defvar view-return-to-alist) 234(defvar view-return-to-alist)
@@ -1706,33 +1721,56 @@ position, else returns nil."
1706 :type 'string 1721 :type 'string
1707 :group 'python) 1722 :group 'python)
1708 1723
1724(defcustom python-shell-interpreter-interactive-arg "-i"
1725 "Interpreter argument to force it to run interactively."
1726 :type 'string
1727 :version "24.4")
1728
1729(defcustom python-shell-prompt-detect-enabled t
1730 "Non-nil enables autodetection of interpreter prompts."
1731 :type 'boolean
1732 :safe 'booleanp
1733 :version "24.4")
1734
1735(defcustom python-shell-prompt-detect-failure-warning t
1736 "Non-nil enables warnings when detection of prompts fail."
1737 :type 'boolean
1738 :safe 'booleanp
1739 :version "24.4")
1740
1741(defcustom python-shell-prompt-input-regexps
1742 '(">>> " "\\.\\.\\. " ; Python
1743 "In \\[[0-9]+\\]: ") ; iPython
1744 "List of regular expressions matching input prompts."
1745 :type '(repeat string)
1746 :version "24.4")
1747
1748(defcustom python-shell-prompt-output-regexps
1749 '("" ; Python
1750 "Out\\[[0-9]+\\]: ") ; iPython
1751 "List of regular expressions matching output prompts."
1752 :type '(repeat string)
1753 :version "24.4")
1754
1709(defcustom python-shell-prompt-regexp ">>> " 1755(defcustom python-shell-prompt-regexp ">>> "
1710 "Regular expression matching top-level input prompt of Python shell. 1756 "Regular expression matching top level input prompt of Python shell.
1711It should not contain a caret (^) at the beginning." 1757It should not contain a caret (^) at the beginning."
1712 :type 'string 1758 :type 'string)
1713 :group 'python
1714 :safe 'stringp)
1715 1759
1716(defcustom python-shell-prompt-block-regexp "[.][.][.] " 1760(defcustom python-shell-prompt-block-regexp "\\.\\.\\. "
1717 "Regular expression matching block input prompt of Python shell. 1761 "Regular expression matching block input prompt of Python shell.
1718It should not contain a caret (^) at the beginning." 1762It should not contain a caret (^) at the beginning."
1719 :type 'string 1763 :type 'string)
1720 :group 'python
1721 :safe 'stringp)
1722 1764
1723(defcustom python-shell-prompt-output-regexp "" 1765(defcustom python-shell-prompt-output-regexp ""
1724 "Regular expression matching output prompt of Python shell. 1766 "Regular expression matching output prompt of Python shell.
1725It should not contain a caret (^) at the beginning." 1767It should not contain a caret (^) at the beginning."
1726 :type 'string 1768 :type 'string)
1727 :group 'python
1728 :safe 'stringp)
1729 1769
1730(defcustom python-shell-prompt-pdb-regexp "[(<]*[Ii]?[Pp]db[>)]+ " 1770(defcustom python-shell-prompt-pdb-regexp "[(<]*[Ii]?[Pp]db[>)]+ "
1731 "Regular expression matching pdb input prompt of Python shell. 1771 "Regular expression matching pdb input prompt of Python shell.
1732It should not contain a caret (^) at the beginning." 1772It should not contain a caret (^) at the beginning."
1733 :type 'string 1773 :type 'string)
1734 :group 'python
1735 :safe 'stringp)
1736 1774
1737(defcustom python-shell-enable-font-lock t 1775(defcustom python-shell-enable-font-lock t
1738 "Should syntax highlighting be enabled in the Python shell buffer? 1776 "Should syntax highlighting be enabled in the Python shell buffer?
@@ -1802,6 +1840,162 @@ virtualenv."
1802 :type '(alist string) 1840 :type '(alist string)
1803 :group 'python) 1841 :group 'python)
1804 1842
1843(defvar python-shell--prompt-calculated-input-regexp nil
1844 "Calculated input prompt regexp for inferior python shell.
1845Do not set this variable directly, instead use
1846`python-shell-prompt-set-calculated-regexps'.")
1847
1848(defvar python-shell--prompt-calculated-output-regexp nil
1849 "Calculated output prompt regexp for inferior python shell.
1850Do not set this variable directly, instead use
1851`python-shell-set-prompt-regexp'.")
1852
1853(defun python-shell-prompt-detect ()
1854 "Detect prompts for the current `python-shell-interpreter'.
1855When prompts can be retrieved successfully from the
1856`python-shell-interpreter' run with
1857`python-shell-interpreter-interactive-arg', returns a list of
1858three elements, where the first two are input prompts and the
1859last one is an output prompt. When no prompts can be detected
1860and `python-shell-prompt-detect-failure-warning' is non-nil,
1861shows a warning with instructions to avoid hangs and returns nil.
1862When `python-shell-prompt-detect-enabled' is nil avoids any
1863detection and just returns nil."
1864 (when python-shell-prompt-detect-enabled
1865 (let* ((process-environment (python-shell-calculate-process-environment))
1866 (exec-path (python-shell-calculate-exec-path))
1867 (python-code-file
1868 (python-shell--save-temp-file
1869 (concat
1870 "import sys\n"
1871 "ps = [getattr(sys, 'ps%s' % i, '') for i in range(1,4)]\n"
1872 ;; JSON is built manually for compatibility
1873 "ps_json = '\\n[\"%s\", \"%s\", \"%s\"]\\n' % tuple(ps)\n"
1874 "print (ps_json)\n"
1875 "sys.exit(0)\n")))
1876 (output
1877 (with-temp-buffer
1878 (call-process
1879 (executable-find python-shell-interpreter)
1880 python-code-file
1881 '(t nil)
1882 nil
1883 python-shell-interpreter-interactive-arg)
1884 (ignore-errors (delete-file python-code-file))
1885 (buffer-string)))
1886 (prompts
1887 (catch 'prompts
1888 (dolist (line (split-string output "\n" t))
1889 (let ((res
1890 ;; Check if current line is a valid JSON array
1891 (and (string= (substring line 0 2) "[\"")
1892 (ignore-errors
1893 ;; Return prompts as a list, not vector
1894 (append (json-read-from-string line) nil)))))
1895 ;; The list must contain 3 strings, where the first
1896 ;; is the input prompt, the second is the block
1897 ;; prompt and the last one is the output prompt. The
1898 ;; input prompt is the only one that can't be empty.
1899 (when (and (= (length res) 3)
1900 (cl-every #'stringp res)
1901 (not (string= (car res) "")))
1902 (throw 'prompts res))))
1903 nil)))
1904 (when (and (not prompts)
1905 python-shell-prompt-detect-failure-warning)
1906 (warn
1907 (concat
1908 "Python shell prompts cannot be detected.\n"
1909 "If your emacs session hangs when starting python shells\n"
1910 "recover with `keyboard-quit' and then try fixing the\n"
1911 "interactive flag for your interpreter by adjusting the\n"
1912 "`python-shell-interpreter-interactive-arg' or add regexps\n"
1913 "matching shell prompts in the directory-local friendly vars:\n"
1914 " + `python-shell-prompt-regexp'\n"
1915 " + `python-shell-prompt-block-regexp'\n"
1916 " + `python-shell-prompt-output-regexp'\n"
1917 "Or alternatively in:\n"
1918 " + `python-shell-prompt-input-regexps'\n"
1919 " + `python-shell-prompt-output-regexps'")))
1920 prompts)))
1921
1922(defun python-shell-prompt-validate-regexps ()
1923 "Validate all user provided regexps for prompts.
1924Signals `user-error' if any of these vars contain invalid
1925regexps: `python-shell-prompt-regexp',
1926`python-shell-prompt-block-regexp',
1927`python-shell-prompt-pdb-regexp',
1928`python-shell-prompt-output-regexp',
1929`python-shell-prompt-input-regexps',
1930`python-shell-prompt-output-regexps'."
1931 (dolist (symbol (list 'python-shell-prompt-input-regexps
1932 'python-shell-prompt-output-regexps
1933 'python-shell-prompt-regexp
1934 'python-shell-prompt-block-regexp
1935 'python-shell-prompt-pdb-regexp
1936 'python-shell-prompt-output-regexp))
1937 (dolist (regexp (let ((regexps (symbol-value symbol)))
1938 (if (listp regexps)
1939 regexps
1940 (list regexps))))
1941 (when (not (python-util-valid-regexp-p regexp))
1942 (user-error "Invalid regexp %s in `%s'"
1943 regexp symbol)))))
1944
1945(defun python-shell-prompt-set-calculated-regexps ()
1946 "Detect and set input and output prompt regexps.
1947Build and set the values for `python-shell-input-prompt-regexp'
1948and `python-shell-output-prompt-regexp' using the values from
1949`python-shell-prompt-regexp', `python-shell-prompt-block-regexp',
1950`python-shell-prompt-pdb-regexp',
1951`python-shell-prompt-output-regexp',
1952`python-shell-prompt-input-regexps',
1953`python-shell-prompt-output-regexps' and detected prompts from
1954`python-shell-prompt-detect'."
1955 (when (not (and python-shell--prompt-calculated-input-regexp
1956 python-shell--prompt-calculated-output-regexp))
1957 (let* ((detected-prompts (python-shell-prompt-detect))
1958 (input-prompts nil)
1959 (output-prompts nil)
1960 (build-regexp
1961 (lambda (prompts)
1962 (concat "^\\("
1963 (mapconcat #'identity
1964 (sort prompts
1965 (lambda (a b)
1966 (let ((length-a (length a))
1967 (length-b (length b)))
1968 (if (= length-a length-b)
1969 (string< a b)
1970 (> (length a) (length b))))))
1971 "\\|")
1972 "\\)"))))
1973 ;; Validate ALL regexps
1974 (python-shell-prompt-validate-regexps)
1975 ;; Collect all user defined input prompts
1976 (dolist (prompt (append python-shell-prompt-input-regexps
1977 (list python-shell-prompt-regexp
1978 python-shell-prompt-block-regexp
1979 python-shell-prompt-pdb-regexp)))
1980 (cl-pushnew prompt input-prompts :test #'string=))
1981 ;; Collect all user defined output prompts
1982 (dolist (prompt (cons python-shell-prompt-output-regexp
1983 python-shell-prompt-output-regexps))
1984 (cl-pushnew prompt output-prompts :test #'string=))
1985 ;; Collect detected prompts if any
1986 (when detected-prompts
1987 (dolist (prompt (butlast detected-prompts))
1988 (setq prompt (regexp-quote prompt))
1989 (cl-pushnew prompt input-prompts :test #'string=))
1990 (cl-pushnew (regexp-quote
1991 (car (last detected-prompts)))
1992 output-prompts :test #'string=))
1993 ;; Set input and output prompt regexps from collected prompts
1994 (setq python-shell--prompt-calculated-input-regexp
1995 (funcall build-regexp input-prompts)
1996 python-shell--prompt-calculated-output-regexp
1997 (funcall build-regexp output-prompts)))))
1998
1805(defun python-shell-get-process-name (dedicated) 1999(defun python-shell-get-process-name (dedicated)
1806 "Calculate the appropriate process name for inferior Python process. 2000 "Calculate the appropriate process name for inferior Python process.
1807If DEDICATED is t and the variable `buffer-file-name' is non-nil 2001If DEDICATED is t and the variable `buffer-file-name' is non-nil
@@ -1824,10 +2018,10 @@ uniqueness for different types of configurations."
1824 python-shell-internal-buffer-name 2018 python-shell-internal-buffer-name
1825 (md5 2019 (md5
1826 (concat 2020 (concat
1827 (python-shell-parse-command) 2021 python-shell-interpreter
1828 python-shell-prompt-regexp 2022 python-shell-interpreter-args
1829 python-shell-prompt-block-regexp 2023 python-shell--prompt-calculated-input-regexp
1830 python-shell-prompt-output-regexp 2024 python-shell--prompt-calculated-output-regexp
1831 (mapconcat #'symbol-value python-shell-setup-codes "") 2025 (mapconcat #'symbol-value python-shell-setup-codes "")
1832 (mapconcat #'identity python-shell-process-environment "") 2026 (mapconcat #'identity python-shell-process-environment "")
1833 (mapconcat #'identity python-shell-extra-pythonpaths "") 2027 (mapconcat #'identity python-shell-extra-pythonpaths "")
@@ -1921,12 +2115,19 @@ initialization of the interpreter via `python-shell-setup-codes'
1921variable. 2115variable.
1922 2116
1923\(Type \\[describe-mode] in the process buffer for a list of commands.)" 2117\(Type \\[describe-mode] in the process buffer for a list of commands.)"
1924 (and python-shell--parent-buffer 2118 (let ((interpreter python-shell-interpreter)
1925 (python-util-clone-local-variables python-shell--parent-buffer)) 2119 (args python-shell-interpreter-args))
1926 (setq comint-prompt-regexp (format "^\\(?:%s\\|%s\\|%s\\)" 2120 (when python-shell--parent-buffer
1927 python-shell-prompt-regexp 2121 (python-util-clone-local-variables python-shell--parent-buffer))
1928 python-shell-prompt-block-regexp 2122 ;; Users can override default values for these vars when calling
1929 python-shell-prompt-pdb-regexp)) 2123 ;; `run-python'. This ensures new values let-bound in
2124 ;; `python-shell-make-comint' are locally set.
2125 (set (make-local-variable 'python-shell-interpreter) interpreter)
2126 (set (make-local-variable 'python-shell-interpreter-args) args))
2127 (set (make-local-variable 'python-shell--prompt-calculated-input-regexp) nil)
2128 (set (make-local-variable 'python-shell--prompt-calculated-output-regexp) nil)
2129 (python-shell-prompt-set-calculated-regexps)
2130 (setq comint-prompt-regexp python-shell--prompt-calculated-input-regexp)
1930 (setq mode-line-process '(":%s")) 2131 (setq mode-line-process '(":%s"))
1931 (make-local-variable 'comint-output-filter-functions) 2132 (make-local-variable 'comint-output-filter-functions)
1932 (add-hook 'comint-output-filter-functions 2133 (add-hook 'comint-output-filter-functions
@@ -1989,10 +2190,20 @@ killed."
1989 (exec-path (python-shell-calculate-exec-path))) 2190 (exec-path (python-shell-calculate-exec-path)))
1990 (when (not (comint-check-proc proc-buffer-name)) 2191 (when (not (comint-check-proc proc-buffer-name))
1991 (let* ((cmdlist (split-string-and-unquote cmd)) 2192 (let* ((cmdlist (split-string-and-unquote cmd))
2193 (interpreter (car cmdlist))
2194 (args (cdr cmdlist))
1992 (buffer (apply #'make-comint-in-buffer proc-name proc-buffer-name 2195 (buffer (apply #'make-comint-in-buffer proc-name proc-buffer-name
1993 (car cmdlist) nil (cdr cmdlist))) 2196 interpreter nil args))
1994 (python-shell--parent-buffer (current-buffer)) 2197 (python-shell--parent-buffer (current-buffer))
1995 (process (get-buffer-process buffer))) 2198 (process (get-buffer-process buffer))
2199 ;; As the user may have overriden default values for
2200 ;; these vars on `run-python', let-binding them allows
2201 ;; to have the new right values in all setup code
2202 ;; that's is done in `inferior-python-mode', which is
2203 ;; important, especially for prompt detection.
2204 (python-shell-interpreter interpreter)
2205 (python-shell-interpreter-args
2206 (mapconcat #'identity args " ")))
1996 (with-current-buffer buffer 2207 (with-current-buffer buffer
1997 (inferior-python-mode)) 2208 (inferior-python-mode))
1998 (accept-process-output process) 2209 (accept-process-output process)
@@ -2064,8 +2275,12 @@ startup."
2064 "Return inferior Python process for current buffer." 2275 "Return inferior Python process for current buffer."
2065 (get-buffer-process (python-shell-get-buffer))) 2276 (get-buffer-process (python-shell-get-buffer)))
2066 2277
2067(defun python-shell-get-or-create-process () 2278(defun python-shell-get-or-create-process (&optional cmd dedicated show)
2068 "Get or create an inferior Python process for current buffer and return it." 2279 "Get or create an inferior Python process for current buffer and return it.
2280Arguments CMD, DEDICATED and SHOW are those of `run-python' and
2281are used to start the shell. If those arguments are not
2282provided, `run-python' is called interactively and the user will
2283be asked for their values."
2069 (let* ((dedicated-proc-name (python-shell-get-process-name t)) 2284 (let* ((dedicated-proc-name (python-shell-get-process-name t))
2070 (dedicated-proc-buffer-name (format "*%s*" dedicated-proc-name)) 2285 (dedicated-proc-buffer-name (format "*%s*" dedicated-proc-name))
2071 (global-proc-name (python-shell-get-process-name nil)) 2286 (global-proc-name (python-shell-get-process-name nil))
@@ -2074,7 +2289,11 @@ startup."
2074 (global-running (comint-check-proc global-proc-buffer-name)) 2289 (global-running (comint-check-proc global-proc-buffer-name))
2075 (current-prefix-arg 16)) 2290 (current-prefix-arg 16))
2076 (when (and (not dedicated-running) (not global-running)) 2291 (when (and (not dedicated-running) (not global-running))
2077 (if (call-interactively 'run-python) 2292 (if (if (not cmd)
2293 ;; XXX: Refactor code such that calling `run-python'
2294 ;; interactively is not needed anymore.
2295 (call-interactively 'run-python)
2296 (run-python cmd dedicated show))
2078 (setq dedicated-running t) 2297 (setq dedicated-running t)
2079 (setq global-running t))) 2298 (setq global-running t)))
2080 ;; Always prefer dedicated 2299 ;; Always prefer dedicated
@@ -2157,10 +2376,13 @@ detecting a prompt at the end of the buffer."
2157 (when (string-match 2376 (when (string-match
2158 ;; XXX: It seems on OSX an extra carriage return is attached 2377 ;; XXX: It seems on OSX an extra carriage return is attached
2159 ;; at the end of output, this handles that too. 2378 ;; at the end of output, this handles that too.
2160 (format "\r?\n\\(?:%s\\|%s\\|%s\\)$" 2379 (concat
2161 python-shell-prompt-regexp 2380 "\r?\n"
2162 python-shell-prompt-block-regexp 2381 ;; Remove initial caret from calculated regexp
2163 python-shell-prompt-pdb-regexp) 2382 (replace-regexp-in-string
2383 (rx string-start ?^) ""
2384 python-shell--prompt-calculated-input-regexp)
2385 "$")
2164 python-shell-output-filter-buffer) 2386 python-shell-output-filter-buffer)
2165 ;; Output ends when `python-shell-output-filter-buffer' contains 2387 ;; Output ends when `python-shell-output-filter-buffer' contains
2166 ;; the prompt attached at the end of it. 2388 ;; the prompt attached at the end of it.
@@ -2168,9 +2390,9 @@ detecting a prompt at the end of the buffer."
2168 python-shell-output-filter-buffer 2390 python-shell-output-filter-buffer
2169 (substring python-shell-output-filter-buffer 2391 (substring python-shell-output-filter-buffer
2170 0 (match-beginning 0))) 2392 0 (match-beginning 0)))
2171 (when (and (> (length python-shell-prompt-output-regexp) 0) 2393 (when (string-match
2172 (string-match (concat "^" python-shell-prompt-output-regexp) 2394 python-shell--prompt-calculated-output-regexp
2173 python-shell-output-filter-buffer)) 2395 python-shell-output-filter-buffer)
2174 ;; Some shells, like iPython might append a prompt before the 2396 ;; Some shells, like iPython might append a prompt before the
2175 ;; output, clean that. 2397 ;; output, clean that.
2176 (setq python-shell-output-filter-buffer 2398 (setq python-shell-output-filter-buffer
@@ -2456,11 +2678,11 @@ LINE is used to detect the context on how to complete given INPUT."
2456 ((and (> 2678 ((and (>
2457 (length python-shell-completion-module-string-code) 0) 2679 (length python-shell-completion-module-string-code) 0)
2458 (string-match 2680 (string-match
2459 (concat "^" python-shell-prompt-regexp) prompt) 2681 python-shell--prompt-calculated-input-regexp prompt)
2460 (string-match "^[ \t]*\\(from\\|import\\)[ \t]" line)) 2682 (string-match "^[ \t]*\\(from\\|import\\)[ \t]" line))
2461 'import) 2683 'import)
2462 ((string-match 2684 ((string-match
2463 (concat "^" python-shell-prompt-regexp) prompt) 2685 python-shell--prompt-calculated-input-regexp prompt)
2464 'default) 2686 'default)
2465 (t nil))) 2687 (t nil)))
2466 (completion-code 2688 (completion-code
@@ -3706,6 +3928,10 @@ returned as is."
3706 "" 3928 ""
3707 string)) 3929 string))
3708 3930
3931(defun python-util-valid-regexp-p (regexp)
3932 "Return non-nil if REGEXP is valid."
3933 (ignore-errors (string-match regexp "") t))
3934
3709 3935
3710(defun python-electric-pair-string-delimiter () 3936(defun python-electric-pair-string-delimiter ()
3711 (when (and electric-pair-mode 3937 (when (and electric-pair-mode