Add new keywords of Python 3.5

Python 3.5, released in mid September 2015, introduced a few new
keywords to better support asynchronous code, "async" and "await"
in particular. See https://www.python.org/dev/peps/pep-0492/ for
details. (Bug#21783)
* lisp/progmodes/python.el (python-rx-constituents): Add async
def/for/with as block-start and async def as defun.
* lisp/progmodes/python.el (python-font-lock-keywords): Add async
def/for/with as keyword.
* test/automated/python-tests.el (python-indent-after-async-block-1,
python-indent-after-async-block-2, python-indent-after-async-block-3,
python-nav-beginning-of-defun-3): New tests to test indentation and
navigation for the async keyword.
This commit is contained in:
Lele Gaifax 2016-04-06 10:38:23 +02:00 committed by John Wiegley
parent ccb75d72bd
commit fa7886a46f
2 changed files with 67 additions and 2 deletions

View file

@ -372,7 +372,10 @@
(defconst python-rx-constituents (defconst python-rx-constituents
`((block-start . ,(rx symbol-start `((block-start . ,(rx symbol-start
(or "def" "class" "if" "elif" "else" "try" (or "def" "class" "if" "elif" "else" "try"
"except" "finally" "for" "while" "with") "except" "finally" "for" "while" "with"
;; Python 3.5+ PEP492
(and "async" (+ space)
(or "def" "for" "with")))
symbol-end)) symbol-end))
(dedenter . ,(rx symbol-start (dedenter . ,(rx symbol-start
(or "elif" "else" "except" "finally") (or "elif" "else" "except" "finally")
@ -383,7 +386,11 @@
symbol-end)) symbol-end))
(decorator . ,(rx line-start (* space) ?@ (any letter ?_) (decorator . ,(rx line-start (* space) ?@ (any letter ?_)
(* (any word ?_)))) (* (any word ?_))))
(defun . ,(rx symbol-start (or "def" "class") symbol-end)) (defun . ,(rx symbol-start
(or "def" "class"
;; Python 3.5+ PEP492
(and "async" (+ space) "def"))
symbol-end))
(if-name-main . ,(rx line-start "if" (+ space) "__name__" (if-name-main . ,(rx line-start "if" (+ space) "__name__"
(+ space) "==" (+ space) (+ space) "==" (+ space)
(any ?' ?\") "__main__" (any ?' ?\") (any ?' ?\") "__main__" (any ?' ?\")
@ -515,6 +522,8 @@ The type returned can be `comment', `string' or `paren'."
;; fontified like that in order to keep font-lock consistent between ;; fontified like that in order to keep font-lock consistent between
;; Python versions. ;; Python versions.
"nonlocal" "nonlocal"
;; Python 3.5+ PEP492
(and "async" (+ space) (or "def" "for" "with"))
;; Extra: ;; Extra:
"self") "self")
symbol-end) symbol-end)

View file

@ -614,6 +614,42 @@ something
(should (eq (car (python-indent-context)) :after-line)) (should (eq (car (python-indent-context)) :after-line))
(should (= (python-indent-calculate-indentation) 0)))) (should (= (python-indent-calculate-indentation) 0))))
(ert-deftest python-indent-after-async-block-1 ()
"Test PEP492 async def."
(python-tests-with-temp-buffer
"
async def foo(a, b, c=True):
"
(should (eq (car (python-indent-context)) :no-indent))
(should (= (python-indent-calculate-indentation) 0))
(goto-char (point-max))
(should (eq (car (python-indent-context)) :after-block-start))
(should (= (python-indent-calculate-indentation) 4))))
(ert-deftest python-indent-after-async-block-2 ()
"Test PEP492 async with."
(python-tests-with-temp-buffer
"
async with foo(a) as mgr:
"
(should (eq (car (python-indent-context)) :no-indent))
(should (= (python-indent-calculate-indentation) 0))
(goto-char (point-max))
(should (eq (car (python-indent-context)) :after-block-start))
(should (= (python-indent-calculate-indentation) 4))))
(ert-deftest python-indent-after-async-block-3 ()
"Test PEP492 async for."
(python-tests-with-temp-buffer
"
async for a in sequencer():
"
(should (eq (car (python-indent-context)) :no-indent))
(should (= (python-indent-calculate-indentation) 0))
(goto-char (point-max))
(should (eq (car (python-indent-context)) :after-block-start))
(should (= (python-indent-calculate-indentation) 4))))
(ert-deftest python-indent-after-backslash-1 () (ert-deftest python-indent-after-backslash-1 ()
"The most common case." "The most common case."
(python-tests-with-temp-buffer (python-tests-with-temp-buffer
@ -1493,6 +1529,26 @@ class C(object):
(beginning-of-line) (beginning-of-line)
(point)))))) (point))))))
(ert-deftest python-nav-beginning-of-defun-3 ()
(python-tests-with-temp-buffer
"
class C(object):
async def m(self):
return await self.c()
async def c(self):
pass
"
(python-tests-look-at "self.c()")
(should (= (save-excursion
(python-nav-beginning-of-defun)
(point))
(save-excursion
(python-tests-look-at "async def m" -1)
(beginning-of-line)
(point))))))
(ert-deftest python-nav-end-of-defun-1 () (ert-deftest python-nav-end-of-defun-1 ()
(python-tests-with-temp-buffer (python-tests-with-temp-buffer
" "