Why does Python log a DeprecationWarning saying “invalid escape sequence”?
Take this code, which prints a shruggy man:
If you run it with warnings enabled on Python 3.11, you’ll see:
$ python -W default example.py /.../example.py:1: DeprecationWarning: invalid escape sequence '\_' print("¯\_(ツ)_/¯") ¯\_(ツ)_/¯
(On Python 3.12+, you’ll see
SyntaxWarning instead, with no need to enable warnings.)
What does this mean?
Well, Python strings use backslash (
\) and the next character as an escape sequence, that represents a special character Here are some common examples:
|a single backslash|
Python’s documentation on strings has a complete table.
The combination of
\ plus a second character is called an escape sequence. The warning “invalid escape sequence” is telling you that you’ve written
\ and then an unsupported character.
Python still interprets the string as
\ plus the invalid character, hence the example shruggy emoticon displays correctly. But a future version of Python (maybe 3.13) will raise a
SyntaxError for invalid escape sequences, stopping such code from running. Then, Python will be able to add more valid escape sequences in even later versions.
To fix the issue, you will normally want to add a second
\, which is the valid escape sequecne for “a single backslash“:
No more warning:
$ python -W default example.py ¯\_(ツ)_/¯
You can also solve this by changing the string to a raw string, by adding a
Raw strings don’t use escape sequences at all, so every backslash will appear as-is. So, this change will break any valid escape sequences in the same string.
(Raw strings are particularly useful when writing regular expressions for the
re module. Regular expression syntax uses
\ as its own escape character, so using a raw string means you don’t need to double them up.)
For example, running
pyupgrade on the initial example:
$ pyupgrade example.py Rewriting example.py
…it makes the change to a raw string:
pyupgrade uses a raw string if the string only contains invalid escape sequences. If it contains any valid ones, it will instead add extra backslashes where necessary.
For example, if the string has a newline escape sequence:
…then pyupgrade only doubles up the
pyupgrade also has a nuber of other fixes to help you modernize your code.
If you aren’t ready to automatically fix your code, you can use the linter flake8 to detect invalid escape sequences early. The default configuration notes
W605 for each instance:
$ flake8 example.py example.py:1:9: W605 invalid escape sequence '\_'
You can run flake8 in your text editor, to catch issues whilst you write your code.
Improve your Django develompent experience with my new book.
One summary email a week, no spam, I pinky promise.
- Why does Python log a SyntaxWarning for ‘is’ with literals?
- Why does Python log a SyntaxWarning saying “object is not subscriptable”?
- Why does Python log a SyntaxWarning saying “assertion is always true”?
- Why does Python log a SyntaxWarning saying “list indices must be integers or slices”?
- Why does Python log a SyntaxWarning saying “object is not callable”?