diff options
| author | Lele Gaifax | 2016-04-06 10:38:23 +0200 |
|---|---|---|
| committer | John Wiegley | 2016-04-26 13:50:26 -0400 |
| commit | fa7886a46ff8d611cd75eaf651944f0fbc260324 (patch) | |
| tree | 43c0df06ac3f65e2cfbca7b9e198f302bb26a2a7 | |
| parent | ccb75d72bd02885109c7c339c1f72a393a9d3d22 (diff) | |
| download | emacs-fa7886a46ff8d611cd75eaf651944f0fbc260324.tar.gz emacs-fa7886a46ff8d611cd75eaf651944f0fbc260324.zip | |
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.
| -rw-r--r-- | lisp/progmodes/python.el | 13 | ||||
| -rw-r--r-- | test/automated/python-tests.el | 56 |
2 files changed, 67 insertions, 2 deletions
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index 90097df7ef1..9c23655b911 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el | |||
| @@ -372,7 +372,10 @@ | |||
| 372 | (defconst python-rx-constituents | 372 | (defconst python-rx-constituents |
| 373 | `((block-start . ,(rx symbol-start | 373 | `((block-start . ,(rx symbol-start |
| 374 | (or "def" "class" "if" "elif" "else" "try" | 374 | (or "def" "class" "if" "elif" "else" "try" |
| 375 | "except" "finally" "for" "while" "with") | 375 | "except" "finally" "for" "while" "with" |
| 376 | ;; Python 3.5+ PEP492 | ||
| 377 | (and "async" (+ space) | ||
| 378 | (or "def" "for" "with"))) | ||
| 376 | symbol-end)) | 379 | symbol-end)) |
| 377 | (dedenter . ,(rx symbol-start | 380 | (dedenter . ,(rx symbol-start |
| 378 | (or "elif" "else" "except" "finally") | 381 | (or "elif" "else" "except" "finally") |
| @@ -383,7 +386,11 @@ | |||
| 383 | symbol-end)) | 386 | symbol-end)) |
| 384 | (decorator . ,(rx line-start (* space) ?@ (any letter ?_) | 387 | (decorator . ,(rx line-start (* space) ?@ (any letter ?_) |
| 385 | (* (any word ?_)))) | 388 | (* (any word ?_)))) |
| 386 | (defun . ,(rx symbol-start (or "def" "class") symbol-end)) | 389 | (defun . ,(rx symbol-start |
| 390 | (or "def" "class" | ||
| 391 | ;; Python 3.5+ PEP492 | ||
| 392 | (and "async" (+ space) "def")) | ||
| 393 | symbol-end)) | ||
| 387 | (if-name-main . ,(rx line-start "if" (+ space) "__name__" | 394 | (if-name-main . ,(rx line-start "if" (+ space) "__name__" |
| 388 | (+ space) "==" (+ space) | 395 | (+ space) "==" (+ space) |
| 389 | (any ?' ?\") "__main__" (any ?' ?\") | 396 | (any ?' ?\") "__main__" (any ?' ?\") |
| @@ -515,6 +522,8 @@ The type returned can be `comment', `string' or `paren'." | |||
| 515 | ;; fontified like that in order to keep font-lock consistent between | 522 | ;; fontified like that in order to keep font-lock consistent between |
| 516 | ;; Python versions. | 523 | ;; Python versions. |
| 517 | "nonlocal" | 524 | "nonlocal" |
| 525 | ;; Python 3.5+ PEP492 | ||
| 526 | (and "async" (+ space) (or "def" "for" "with")) | ||
| 518 | ;; Extra: | 527 | ;; Extra: |
| 519 | "self") | 528 | "self") |
| 520 | symbol-end) | 529 | symbol-end) |
diff --git a/test/automated/python-tests.el b/test/automated/python-tests.el index ec93c01059c..54ed92212b8 100644 --- a/test/automated/python-tests.el +++ b/test/automated/python-tests.el | |||
| @@ -614,6 +614,42 @@ something | |||
| 614 | (should (eq (car (python-indent-context)) :after-line)) | 614 | (should (eq (car (python-indent-context)) :after-line)) |
| 615 | (should (= (python-indent-calculate-indentation) 0)))) | 615 | (should (= (python-indent-calculate-indentation) 0)))) |
| 616 | 616 | ||
| 617 | (ert-deftest python-indent-after-async-block-1 () | ||
| 618 | "Test PEP492 async def." | ||
| 619 | (python-tests-with-temp-buffer | ||
| 620 | " | ||
| 621 | async def foo(a, b, c=True): | ||
| 622 | " | ||
| 623 | (should (eq (car (python-indent-context)) :no-indent)) | ||
| 624 | (should (= (python-indent-calculate-indentation) 0)) | ||
| 625 | (goto-char (point-max)) | ||
| 626 | (should (eq (car (python-indent-context)) :after-block-start)) | ||
| 627 | (should (= (python-indent-calculate-indentation) 4)))) | ||
| 628 | |||
| 629 | (ert-deftest python-indent-after-async-block-2 () | ||
| 630 | "Test PEP492 async with." | ||
| 631 | (python-tests-with-temp-buffer | ||
| 632 | " | ||
| 633 | async with foo(a) as mgr: | ||
| 634 | " | ||
| 635 | (should (eq (car (python-indent-context)) :no-indent)) | ||
| 636 | (should (= (python-indent-calculate-indentation) 0)) | ||
| 637 | (goto-char (point-max)) | ||
| 638 | (should (eq (car (python-indent-context)) :after-block-start)) | ||
| 639 | (should (= (python-indent-calculate-indentation) 4)))) | ||
| 640 | |||
| 641 | (ert-deftest python-indent-after-async-block-3 () | ||
| 642 | "Test PEP492 async for." | ||
| 643 | (python-tests-with-temp-buffer | ||
| 644 | " | ||
| 645 | async for a in sequencer(): | ||
| 646 | " | ||
| 647 | (should (eq (car (python-indent-context)) :no-indent)) | ||
| 648 | (should (= (python-indent-calculate-indentation) 0)) | ||
| 649 | (goto-char (point-max)) | ||
| 650 | (should (eq (car (python-indent-context)) :after-block-start)) | ||
| 651 | (should (= (python-indent-calculate-indentation) 4)))) | ||
| 652 | |||
| 617 | (ert-deftest python-indent-after-backslash-1 () | 653 | (ert-deftest python-indent-after-backslash-1 () |
| 618 | "The most common case." | 654 | "The most common case." |
| 619 | (python-tests-with-temp-buffer | 655 | (python-tests-with-temp-buffer |
| @@ -1493,6 +1529,26 @@ class C(object): | |||
| 1493 | (beginning-of-line) | 1529 | (beginning-of-line) |
| 1494 | (point)))))) | 1530 | (point)))))) |
| 1495 | 1531 | ||
| 1532 | (ert-deftest python-nav-beginning-of-defun-3 () | ||
| 1533 | (python-tests-with-temp-buffer | ||
| 1534 | " | ||
| 1535 | class C(object): | ||
| 1536 | |||
| 1537 | async def m(self): | ||
| 1538 | return await self.c() | ||
| 1539 | |||
| 1540 | async def c(self): | ||
| 1541 | pass | ||
| 1542 | " | ||
| 1543 | (python-tests-look-at "self.c()") | ||
| 1544 | (should (= (save-excursion | ||
| 1545 | (python-nav-beginning-of-defun) | ||
| 1546 | (point)) | ||
| 1547 | (save-excursion | ||
| 1548 | (python-tests-look-at "async def m" -1) | ||
| 1549 | (beginning-of-line) | ||
| 1550 | (point)))))) | ||
| 1551 | |||
| 1496 | (ert-deftest python-nav-end-of-defun-1 () | 1552 | (ert-deftest python-nav-end-of-defun-1 () |
| 1497 | (python-tests-with-temp-buffer | 1553 | (python-tests-with-temp-buffer |
| 1498 | " | 1554 | " |