Python 3.10 added a match statement. When I try and type one in emacs 27.2, it does not indent it correctly, presumably because it does not yet have support for it. How do I get python-mode to indent the match statement correctly?
-
`M-x find-library RET python RET` leads you to the elisp python package. Are you comfortable to do the necessary changes? – aadcg Nov 09 '21 at 19:29
-
Please clarify what you mean by "support" the `match` statement. If you mean only support indenting it properly, the say so. – Drew Nov 09 '21 at 23:01
-
1current version support the syntax but indentation seems to be broken – rho Sep 04 '22 at 12:42
3 Answers
There is support for this in elpa python-mode
but in my case the emacs was loading the builtin python mode which does not support the match
statement.
You can tell that you are loading the builtin python-mode
in two ways.
- The status line shows
Python
instead ofPy
- If you do
C-h f python-mode RET
, then you move the cursor to thepython.el
,RET
and look the folder for the file (M-: (buffer-file-name) RET
). In my case I'm using Mac and I get this path/Applications/Emacs.app/Contents/Resources/lisp/progmodes/python.el.gz
To fix this install the package python-mode
from ELPA
M-x package-refresh-contents
M-x package-install python-mode RET
Then add (require 'python-mode)
to your .emacs
file. And restart emacs. To verify that it is working open a python file, you should see Py
instead of Python
I hope this helps

- 141
- 2
I am also using 27.2. What worked for me, clued by this question
- Update python.el to 28 (probably not necessary)
M-x find-library
, "python"- Add
"match"
andcase"
in this section:
(defmacro python-rx (&rest regexps)
"Python mode specialized rx macro.
This variant of `rx' supports common Python named REGEXPS."
`(rx-let ((block-start (seq symbol-start
(or "def" "class" "if" "elif" "else" "try"
"except" "finally" "for" "while" "with"
;; added by me for python 3.10
"match" "case"
;; Python 3.5+ PEP492
(and "async" (+ space)
(or "def" "for" "with")))
and this section:
(defvar python-font-lock-keywords-level-2
`(,@python-font-lock-keywords-level-1
,(rx symbol-start
(or
"and" "del" "from" "not" "while" "as" "elif" "global" "or" "with"
"assert" "else" "if" "pass" "yield" "break" "except" "import" "class"
"in" "raise" "continue" "finally" "is" "return" "def" "for" "lambda"
"try" "match" "case"
- Finally I deleted python.elc which was in same directory as python.el (because the unchanged .elc file will be used in preference to the .el file)

- 143
- 6
-
1What about emacs v28? When I run "find-library" "python" I get: "Can't find library: python" – Endlisnis Dec 21 '22 at 02:17
I followed the answer given by Levin Magruder. I am using Emacs 26.3. I found that, in my copy of python.el
, there was only one block which corresponded with what Levin's answer showed. So, here is what that block looked like after I made the changes:
(eval-and-compile
(defconst python-rx-constituents
`((block-start . ,(rx symbol-start
(or "def" "class" "if" "elif" "else" "try"
"except" "finally" "for" "while" "with"
;; added by bjk for Python 3.10
"match" "case"
;; Python 3.5+ PEP492
(and "async" (+ space)
(or "def" "for" "with")))
symbol-end))
[...]
Seems to work just fine. Thanks, Levin. Sorry that I don't yet have enough reputation on this SE to upvote your answer.

- 11
- 3