How to Fix a Python “SyntaxError: invalid character” Caused by Curly Quotes

Take a break, enjoy this field.

Here’s an innocent enough looking Python file:

print(“x”)

Unfortunately if we run it, we get this error message:

$ python example.py
  File "/Users/chainz/tmp/hints/q.py", line 1
    print(“x”)
          ^
SyntaxError: invalid character '“' (U+201C)

Oh no, what’s wrong?

The problem is the code uses curly quote characters (“” and ''), but Python only supports straight quote characters ("" and ''). It’s likely the code was edited with a program that converts straight quotes to curly ones automatically, such as Microsoft Word.

(See more about curly versus straight quotes on Wikipedia.)

To fix such code, you need to convert the curly quotes back to their straight versions. You can probably do this with the find-and-replace function in your editor. Alternatively, you can use Python to perform the replacement:

filename = "example.py"
text = open(filename).read()
text = text.replace("“", '"').replace("”", '"').replace("‘", "'").replace("’", "'")
open(filename, "w").write(text)

You can save this code in a new file (e.g. fixer.py), change filename to the name of your broken file, and run python fixer.py.

Neat.

Alternative Errors

It’s also possible to encounter different error messages caused by using curly quotes. If you have an opening straight quote, but a closing curly quote, the error will be:

$ python example.py
  File "/.../example.py", line 1
    print("x”)
          ^
SyntaxError: unterminated string literal (detected at line 1)

If you use single curly quotes, the error shows those as the problematic characters:

$ python example.py
  File "/Users/chainz/tmp/hints/example.py", line 1
    print(‘x’)
          ^
SyntaxError: invalid character '‘' (U+2018)

Now you know.

Fin

May you not find any curly quotes in your code,

—Adam


Make your development more pleasant with Boost Your Django DX.


Subscribe via RSS, Twitter, or email:

One summary email a week, no spam, I pinky promise.

Related posts:

Tags: