]> code.delx.au - gnu-emacs/commitdiff
Add new keywords of Python 3.5
authorLele Gaifax <lele@metapensiero.it>
Wed, 6 Apr 2016 08:38:23 +0000 (10:38 +0200)
committerJorgen Schaefer <contact@jorgenschaefer.de>
Wed, 6 Apr 2016 08:51:09 +0000 (10:51 +0200)
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.

lisp/progmodes/python.el
test/lisp/progmodes/python-tests.el

index 01f7f251eddbcb80b85b08cc713c866935d31872..375b9fedc9d34446d26eb4b2cc5eb32708fd3d84 100644 (file)
   (defconst python-rx-constituents
     `((block-start          . ,(rx symbol-start
                                    (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))
       (dedenter            . ,(rx symbol-start
                                    (or "elif" "else" "except" "finally")
                                   symbol-end))
       (decorator            . ,(rx line-start (* space) ?@ (any letter ?_)
                                    (* (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__"
                                    (+ space) "==" (+ space)
                                    (any ?' ?\") "__main__" (any ?' ?\")
@@ -527,6 +534,8 @@ The type returned can be `comment', `string' or `paren'."
           ;; fontified like that in order to keep font-lock consistent between
           ;; Python versions.
           "nonlocal"
+          ;; Python 3.5+ PEP492
+          (and "async" (+ space) (or "def" "for" "with"))
           ;; Extra:
           "self")
          symbol-end)
index ec93c01059c188a64f6b6933a601d77519c9d952..54ed92212b87045a8b0df87da928fca6ae04782d 100644 (file)
@@ -614,6 +614,42 @@ something
    (should (eq (car (python-indent-context)) :after-line))
    (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 ()
   "The most common case."
   (python-tests-with-temp-buffer
@@ -1493,6 +1529,26 @@ class C(object):
                 (beginning-of-line)
                 (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 ()
   (python-tests-with-temp-buffer
    "