- Python
SyntaxError: invalid syntaxの直し方|Python49例
結論
SyntaxError: invalid syntax は「Python の文法として読めない行がある」ときに、プログラムを1行も実行する前に出るエラーです。多いのはコロン(:)の書き忘れ・括弧の閉じ忘れ・= と == の取り違えと、pip install を Python の中(>>>)で打った場合です。^ の印の場所で見つからなければ、1つ上の行を見ます。
この記事でわかること
- invalid syntax の原因10系統と、原因ごとのエラー原文・直したあとの出力
- Python 3.8〜3.15 でエラー文がどう変わったか(同じ49本のコードで比較)
- エラーの行がずれるときの探し方と、構文エラーをまとめて見つける方法
この記事で実際に動かしたもの:構文エラーになるコード49本と直したコード20本を、Python 3.8・3.10・3.11・3.12・3.13・3.14・3.15 の7つの版で1本ずつ実行し、表示を比べました。
flowchart TD
E[SyntaxError] --> C{pip・python<br>を打った?}
C -->|はい| T[ターミナルで]
C -->|いいえ| M{ヒントは?}
M -->|ある| H[ヒントで直す]
M -->|ない| U[^ の行と<br>1つ上の行]
U --> V[Python の<br>版を確認]
やりたいことごとに、いちばん早い方法を先にまとめます。
| やりたいこと | いちばん早い方法 | 詳しい節 |
|---|---|---|
| SyntaxError: invalid syntax の意味を知りたい | Python の文法として読めない行がある。実行前に止まる | エラーの意味 |
| どこが間違いか知りたい | ^ の場所と、その1つ上の行を見る |
^の位置の読み方 |
pip install で出た |
exit() で Python を抜け、ターミナル(コマンドプロンプト)で打つ |
pip・pythonを>>>の中で打った |
| if・for・def の行で出た | 行の最後に : を付ける |
コロン・括弧・引用符 |
| エラーの行に誤りが見当たらない | 上の行の括弧 ( [ { が閉じているか数える |
^の位置の読み方 |
| 人のコードやサンプルで出た | python3 --version で版を確かめる(match は 3.10、type は 3.12 から) |
新しい構文と版 |
| ネットのコードをコピーして出た | 先頭の >>>・print "..."(Python 2)を直す |
Python 2のコード |
| 全部のファイルをまとめて調べたい | python3 -m compileall -q . |
構文エラーをまとめて見つける |
確認環境:Ubuntu 24.04.5 LTS の上で、Python 3.11.18・3.12.3・3.13.18(OS のパッケージ)と、uv 0.13.7(PyPI の最新版を作業用の仮想環境に導入)で取得した Python 3.8.20・3.10.22・3.14.10・3.15.2 を使いました。3.14 は実行を終えてから削除し、3.15 を入れて同じコードを実行しています。構文エラーになるコード49本を各版で python -I ファイル名 として実行し、エラー文の原文を取り、直したコードの出力も同じ版で取りました。Python 3.9 は実行していません。>>> の中での表示は、標準入力から対話モードに流して確かめています。版ごとの変更点は Python 公式ドキュメントの「What's New」(3.10・3.12・3.14)、エラーの属性は「組み込み例外」、矢印の読み方はチュートリアル「エラーと例外」、版のサポート状況は Python Developer's Guide で確かめました。Windows の py コマンド・VS Code・Jupyter は公式ドキュメントの範囲で、手元では動かしていません。図は mermaid 11 で描画を確かめています(確認日 2026年11月5日)。
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「SyntaxError: invalid syntaxの直し方|Python49例」
SyntaxError: invalid syntaxの意味(いつ・なぜ出るか)
この節では、エラー文の日本語訳と、このエラーが「実行前」に出るという特徴が分かります。
「SyntaxError: invalid syntax」を日本語にすると「構文エラー:文法が正しくありません」です。構文(syntax)は、プログラムの書き方の決まりのことです。Python 公式ドキュメントは SyntaxError を次のように説明しています。
Raised when the parser encounters a syntax error.(パーサーが構文の誤りに出会ったときに送出される)
パーサーは、ファイル全体を読んで「Python の文として意味が通るか」を確かめる部分です。この確認は実行より前に行われるため、エラーより上の行も1行も動きません。手元で、1行目に print("start")、4行目に閉じ忘れの括弧を置いたファイルを動かすと、「start」は表示されませんでした。
print("start")
for i in range(3):
print(i)
print("end"
File "/srv/s4/r17/t298/s/c51_runs_nothing.py", line 4
print("end"
^
SyntaxError: '(' was never closed
「途中まで動いてから止まった」なら構文エラーではありません。構文エラーは、python ファイル名 を実行したとき・import したとき・exec() や eval() に文字列を渡したとき・>>> に打ち込んだときに出ます。
構文エラー(SyntaxError)
ファイルを読んだ時点で止まる
1行も実行されない(print も出ない)
Traceback の行が無いことが多い
直すのは書き方
実行時のエラー(TypeError など)
動かしている途中で止まる
エラーより前の行は実行済み
「Traceback (most recent call last):」から始まる
直すのは値や処理の流れ
エラー文の4行の読み方
表示は4行で1組です。手元の Python 3.13 でコロンを書き忘れたときは次のとおりでした。
File "/srv/s4/r17/t298/s/c01_colon.py", line 2
if x == 1
^
SyntaxError: expected ':'
| 行 | 書いてあること | 見るところ |
|---|---|---|
| 1行目 | ファイル名と行番号(line 2) | エディタでその行を開く |
| 2行目 | 問題の行のコード | 書いたとおりか見比べる |
| 3行目 | ^ の印 |
パーサーが「ここで読めなくなった」場所 |
| 4行目 | エラーの種類と説明 | invalid syntax のあとにヒントが続くか |
同じコードを Python 3.8 で動かすと、4行目は SyntaxError: invalid syntax だけでした。3.10 以降は多くの場面で「何が足りないか」まで書かれるので、版が新しいほど直しやすくなります(版ごとの違いは後の節にまとめました)。
^の位置の読み方と、エラーの行がずれる理由
この節では、^ が誤りの場所を指さないときに、どこを探せばよいかが分かります。
Python 公式のチュートリアルは、矢印について次のように書いています。
Note that this is not always the place that needs to be fixed.(これが必ずしも直すべき場所とは限らない)
^ は「パーサーが読めなくなった場所」で、「書き間違えた場所」とは限りません。典型が括弧の閉じ忘れです。1行目で閉じ忘れたコードを Python 3.8 で動かすと、エラーは2行目を指しました。
total = sum([1, 2, 3]
print(total)
File "c02_paren_next.py", line 2
print(total)
^
SyntaxError: invalid syntax
括弧が閉じていないので、Python は「1行目の式がまだ続いている」と考えて2行目まで読み、そこで初めて読めなくなります。同じコードを Python 3.10 以降で動かすと、閉じていない括弧そのものを指しました。
File "/srv/s4/r17/t298/s/c02_paren_next.py", line 1
total = sum([1, 2, 3]
^
SyntaxError: '(' was never closed
行がずれる代表的な場面は次の3つです。どれも「エラーの行より上」に原因があります。
| 書き間違い | Python 3.8 の表示 | Python 3.10 以降の表示 |
|---|---|---|
| 括弧の閉じ忘れ(次の行あり) | 次の行で invalid syntax |
開いた括弧の行で '(' was never closed |
| 括弧の閉じ忘れ(ファイルの最後) | 最後の空行で unexpected EOF while parsing |
開いた括弧の行で '[' was never closed |
| 三重引用符 """ の閉じ忘れ | ファイルの最後で EOF while scanning triple-quoted string literal |
開いた行で unterminated triple-quoted string literal (detected at line 4) |
3.8 の「unexpected EOF while parsing」は「閉じる記号が来ないままファイルが終わった」という意味です。
最後の行(エラーの種類)を読む
invalid syntax のあとに expected ':'・Perhaps you forgot a comma? などのヒントがあれば、まずそのとおりに直す。
^ の場所を見る
印の付いた語の前後に、コロン・カンマ・引用符の抜けや = の誤りが無いか見る。
1つ上の行を見る
印の場所に誤りが無ければ、上の行の括弧 ( [ { と引用符が閉じているか数える。
Python の版を確かめる
誤りが無いのに出るなら、新しい版の構文を以前の版で動かしている。python3 --version で版を見る。
エラー文の最後の行で検索する
ファイル名を除いた最後の行(例:SyntaxError: expected ':')で検索すると、同じ原因の解説が見つかりやすい。
invalid syntaxの原因一覧(10系統)
この節では、このエラーになる原因の全体像と、手元の Python 3.13 での表示が分かります。
手元で再現した原因を10系統にまとめました。3.13 の表示に「invalid syntax」以外の文が出るものは、その文がそのまま直し方を示しています。
| 原因 | 例 | Python 3.13 の表示 |
|---|---|---|
| 1. コロンの書き忘れ | if x == 1 |
expected ':' |
| 2. 括弧の閉じ忘れ | sum([1, 2, 3] |
'(' was never closed |
| 3. 引用符の閉じ忘れ | print("hello) |
unterminated string literal |
| 4. = と == の取り違え | if x = 1: |
Maybe you meant '==' or ':=' |
| 5. 予約語を名前に使った・綴りの誤り | class = "A"・de test(): |
invalid syntax |
| 6. カンマの書き忘れ | [1 2 3] |
Perhaps you forgot a comma? |
| 7. Python 2 のコード | print "hello" |
Missing parentheses in call to 'print' |
| 8. 他の言語の書き方 | i++・&&・//・? : |
invalid syntax |
| 9. pip・python を >>> の中で打った | pip install requests |
invalid syntax |
| 10. 新しい構文を以前の版で動かした | match・type・t"..." |
以前の版で invalid syntax |
3.13 でも「invalid syntax」だけが出る原因(5・8・9・10)は、Python がヒントを出せない種類です。表示がそっけないときほど、「そもそも Python のコードか」「この版で使える書き方か」を疑うと早く見つかります。なお、全角スペースや全角の括弧が原因の invalid character・invalid non-printable character は、関連記事「SyntaxError: invalid characterの直し方|全角スペース」で扱っています。
原因1〜3:コロン・括弧・引用符の書き忘れ
この節では、もっとも多い3つの書き忘れの原文と、直したあとの出力が分かります。
原因1:if・for・def・class の行末のコロン
if・elif・else・for・while・def・class・try・except・with の行は、最後に : が要ります。Python 3.10 以降は expected ':' と、印も行末を指しました。
def total(a, b)
return a + b
File "/srv/s4/r17/t298/s/c32_def_colon.py", line 1
def total(a, b)
^
SyntaxError: expected ':'
for でも同じで、for i in range(3) は 3.8 では invalid syntax、3.10 以降は expected ':' でした。コロンを付けた if x == 1: は、3.8・3.13・3.15 のどれでも one と表示されました。
JavaScript などの癖で else if と書いた場合も、3.13 では expected ':' になり、印は else の直後を指しました。Python では elif と書きます。直したコードは big と表示されました。
File "/srv/s4/r17/t298/s/c20_elseif.py", line 4
else if x > 1:
^^
SyntaxError: expected ':'
原因2:括弧の閉じ忘れ
前の節のとおり、3.10 以降は '(' was never closed・'[' was never closed・'{' was never closed と、開いた括弧を指します。辞書を複数行で書いて閉じ忘れたときも、3.8 は3行目の print(data) を指し、3.10 以降は1行目の { を指しました。sum([1, 2, 3]) と閉じると、出力は 6 でした。
原因3:引用符の閉じ忘れと、文字列の中の引用符
閉じ忘れは、3.8 では EOL while scanning string literal(行の終わりまで文字列が続いた)、3.10 以降は unterminated string literal (detected at line 1) でした。
File "/srv/s4/r17/t298/s/c19_string.py", line 1
print("hello)
^
SyntaxError: unterminated string literal (detected at line 1)
文字列の中に同じ引用符を入れた print("He said "hi" to me") は、版で表示が大きく変わりました。
| 版 | 表示 |
|---|---|
| 3.8 | SyntaxError: invalid syntax |
| 3.13 | SyntaxError: invalid syntax. Perhaps you forgot a comma? |
| 3.15 | SyntaxError: invalid syntax. Is this intended to be part of the string? |
3.13 の「カンマを忘れた?」は的外れに見えますが、Python からは "He said " と hi と " to me" の3つが並んでいるように読めるためです。外側を ' にした print('He said "hi" to me') は、どの版でも He said "hi" to me と表示されました。
文字列の中に " を入れる
"He said "hi" to me"。外側と同じ引用符で文字列が途中で終わる' にする('He said "hi" to me')か、\" と書く覚え方:外と中で引用符の種類を変える
原因4〜6:=と==・予約語・キーワードの綴り・カンマ
この節では、比べる記号・使えない名前・綴りの誤り・カンマ抜けの原文と直し方が分かります。
原因4:if の中の = と ==
比べるときは ==、代入は = です。3.10 以降は、何を書くつもりだったかまで示しました。
File "/srv/s4/r17/t298/s/c04_eq.py", line 2
if x = 1:
^^^^^
SyntaxError: invalid syntax. Maybe you meant '==' or ':=' instead of '='?
:= は代入しながら値を使う「セイウチ演算子」(3.8 から)で、if (n := len(a)) > 3: は 3.8 でも 4 と表示されました。関数の呼び出しに代入した f() = 2 は、3.13 で cannot assign to function call here. Maybe you meant '==' instead of '='? でした。
原因5:予約語を名前に使った・キーワードの綴り
class・def・import・async などの予約語(キーワード)は、変数名・関数名・モジュール名に使えません。手元の Python 3.13 では keyword.kwlist に35語が入っていました。
['False', 'None', 'True', 'and', 'as', 'assert', 'async', 'await', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']
class = "A" と import async は、3.8〜3.15 のすべてで invalid syntax だけでした。class_ = "A" のように後ろに _ を付けるのが慣例で、直したコードは A と表示されました。True = 1 は cannot assign to True と別の文になります。
match・case・type・_ は「ソフトキーワード」で、文の形のときだけ特別な意味になり、変数名には使えます(3.13 の keyword.softkwlist は ['_', 'case', 'match', 'type']、3.15.2 では 'lazy' が加わっていました)。
キーワードの綴りの誤りは、3.14 から候補が出るようになりました。
File "/srv/s4/r17/t298/s/c27_while_typo.py", line 1
whille True:
^^^^^^
SyntaxError: invalid syntax. Did you mean 'while'?
同じ whille True: と de test(): は、3.13 までは invalid syntax だけで、3.14・3.15 では Did you mean 'while'?・Did you mean 'def'? と出ました。
原因6:カンマの書き忘れ
リスト・辞書・関数の引数でカンマが抜けると、3.10 以降は Perhaps you forgot a comma? になりました。[1 2 3]・print(1 2)・{"a": 1 "b": 2} のどれも同じ表示です。
File "/srv/s4/r17/t298/s/c30_dict.py", line 1
x = {"a": 1 "b": 2}
^^^^^
SyntaxError: invalid syntax. Perhaps you forgot a comma?
注意したいのは、文字列どうしはカンマが無くてもエラーにならないことです。print("a" "b") は ab と表示され、つながった1つの文字列として扱われました。["東京" "大阪"] は要素が1つのリストになるため、エラーが出ないまま結果だけが変わります。
原因7・8:Python 2のコードと、他の言語の書き方
この節では、ネットの以前のコードや、JavaScript・Java の癖で出る invalid syntaxが分かります。
原因7:Python 2 の print と except
2020年1月にサポートが終わった Python 2 の書き方は、Python 3 では構文エラーになります。いちばん多いのが括弧の無い print です。
File "/srv/s4/r17/t298/s/c07_print2.py", line 1
print "hello"
^^^^^^^^^^^^^
SyntaxError: Missing parentheses in call to 'print'. Did you mean print(...)?
3.8 では Did you mean print("hello")? と直した形まで表示されました。print("hello") にすると hello と出ます。
もう1つが except ValueError, e: です。ここで版による落とし穴を見つけました。
| 版 | except ValueError, e: の結果 |
|---|---|
| 3.8 | SyntaxError: invalid syntax |
| 3.10〜3.13 | SyntaxError: multiple exception types must be parenthesized |
| 3.14・3.15 | 構文エラーにならず、例外が起きたときに NameError: name 'e' is not defined |
3.14 から、as を使わないときは except TimeoutError, ConnectionRefusedError: のように括弧なしで複数の例外を並べられるようになりました(PEP 758)。そのため Python 2 の except ValueError, e: は「ValueError と e の2つを捕まえる」と読まれ、例外が起きるまでエラーになりません。例外が起きない入力では ok と最後まで動きました。
Traceback (most recent call last):
File "/srv/s4/r17/t298/s/c17_except_py2.py", line 2, in <module>
int("a")
~~~^^^^^
ValueError: invalid literal for int() with base 10: 'a'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/srv/s4/r17/t298/s/c17_except_py2.py", line 3, in <module>
except ValueError, e:
^
NameError: name 'e' is not defined
except ValueError as e: に直すと、どの版でも caught: invalid literal for int() with base 10: 'a' と表示されました。複数の例外を捕まえて名前も付けるときは、3.14 以降も except (ValueError, TypeError) as e: と括弧が要ります。
原因8:他の言語の書き方
JavaScript・Java・C の書き方は、どの版でも invalid syntax だけでした。ヒントが出ないので、表で覚えておくと早く直せます。
| 書いたもの | Python での書き方 | 直した出力 |
|---|---|---|
i++ |
i += 1 |
1 |
if a && b: |
if a and b:(|| は or、! は not) |
1 |
// コメント |
# コメント(// は切り捨ての割り算) |
― |
a > 0 ? "pos" : "neg" |
"pos" if a > 0 else "neg" |
pos |
n = 010(8進数のつもり) |
0o10(10進の10なら 10) |
8 10 |
n = 010 だけは、3.8 から leading zeros in decimal integer literals are not permitted; use an 0o prefix for octal integers と直し方まで表示されました。
原因9:pip installやpythonを>>>の中で打った
この節では、ターミナルで打つコマンドを Python の中で打ったときの原文と、抜け方が分かります。
初めて Python を使う人に特に多いのがこの原因です。python と打って >>> が出た状態は「Python の中」で、ここには Python のコードしか書けません。pip install や python3 hello.py はターミナル(Windows ならコマンドプロンプトや PowerShell)で打つコマンドです。手元の Python 3.13 の対話モードでは次のようになりました。
>>> File "<stdin>", line 1
pip install requests
^^^^^^^
SyntaxError: invalid syntax
>>> File "<stdin>", line 1
python3 hello.py
^^^^^
SyntaxError: invalid syntax
ファイル名が <stdin>(標準入力)になっているのが「Python の中で打った」目印です。pip という名前の次に install が来る形は Python の文法に無いため、印は2語目を指します。3.8〜3.15 のすべてで、ヒントの無い invalid syntax でした。
Python を抜ける
exit() と打つか、Ctrl+D(Windows は Ctrl+Z のあと Enter)。プロンプトが >>> から $ や C:\> に戻ればターミナル。
ターミナルで打ち直す
python3 -m pip install requests のように python3 -m pip の形で打つと、今の python3 に入る。手元では python3 -m pip --version が pip 26.2.1 ... (python 3.13) と版まで表示した。
スクリプトもターミナルで動かす
python3 hello.py はターミナルで打つ。手元では hello と表示された。
Jupyter なら %pip
ノートブックのセルでは %pip install requests。IPython 公式ドキュメントは %pip を「今のカーネルの中で pip を動かす」と説明している。
サンプルの >>> print(1) を、>>> ごとファイルに貼った場合も、3.13 は1行目の >> を指して invalid syntax でした。ドキュメントの >>> と ... は「Python の中で打った」という印で、コードの一部ではありません。pip と仮想環境の使い分けは、関連記事「uv venvとuvの使い方|仮想環境の作成・有効化とpipとの速さ比較」で扱っています。
原因10:新しい構文を以前の版のPythonで動かした
この節では、書き方は正しいのに invalid syntax になるときに、版を確かめる方法が分かります。
コードに誤りが無いのに invalid syntax が出るなら、Python の版が古すぎる可能性があります。同じファイルを版ごとに動かした結果です(○は正しく動いた、×は構文エラー)。
| 構文 | 使える版 | 3.8 | 3.11 | 3.13 |
|---|---|---|---|---|
:=(セイウチ演算子) |
3.8〜 | ○ | ○ | ○ |
match・case |
3.10〜 | × | ○ | ○ |
with (A() as a, B() as b): |
3.10〜(公式) | × | ○ | ○ |
| f文字列の中で同じ引用符 | 3.12〜 | × | × | ○ |
type UserId = int |
3.12〜 | × | × | ○ |
def first[T](xs: list[T]) |
3.12〜 | × | × | ○ |
except A, B:(括弧なし) |
3.14〜 | × | × | × |
t"..."(テンプレート文字列) |
3.14〜 | × | × | × |
括弧なしの except と t 文字列は、3.14・3.15 では正しく動きました(t 文字列は Template(strings=('hi ', ''), ...) を返しました)。match を 3.8 で動かすと、印は match の次の語を指しました。
File "c13_match.py", line 2
match cmd:
^
SyntaxError: invalid syntax
3.11 で def first[T](...) を動かすと expected '(' と出て、「括弧を書き忘れた」ように見えました。ヒントが出ていても、新しい構文では的外れなことがあります。match 文の書き方は、関連記事「Python match caseの使い方|パターン全種の早見表と注意点」で扱っています。
f文字列の書き方の誤りと版の違い
f文字列の { を閉じ忘れた f"{name" は、3.8〜3.15 のどれも f-string: expecting '}' でした。版で結果が分かれたのは、中で同じ引用符を使ったときです。
d = {"k": 1}
print(f"{d["k"]}")
File "/srv/s4/r17/t298/s/c09_fstring_quote.py", line 2
print(f"{d["k"]}")
^
SyntaxError: f-string: unmatched '['
これは 3.11 の表示で、3.12・3.13・3.15 では 1 と表示されました(3.12 で f文字列の解析が変わった PEP 701)。3.11 以前でも動かすなら f"{d['k']}" と中の引用符を変えます。直したコードは 3.8 でも 1 でした。f文字列の書式は、関連記事「Python f-string書式指定|全項目の早見表と実行結果・3.14対応」で扱っています。
自分の Python の版を確かめる
python3 --version
python3 -c "import sys; print(sys.version_info[:3])"
Python 3.13.18
(3, 13, 18)
type UserId = int を以前の版向けに書き直すときは、3.10 以降なら from typing import TypeAlias と UserId: TypeAlias = int が使えます。ただし 3.8 で動かすと ImportError: cannot import name 'TypeAlias' from 'typing' になったので、3.8・3.9 では UserId = int と書きます。Python Developer's Guide によると、2026年11月5日時点で 3.10 以前はサポートが終わっており(3.8 は2024年10月、3.9 は2025年10月、3.10 は2026年10月)、新しい版に上げるのも直し方の1つです。版の切り替えは uv で行えます。
Pythonの版ごとのエラー文の違い(3.8〜3.15で比較)
この節では、同じ間違いが版によってどう表示されるかと、ヒントが増えた度合いが分かります。
3.8 で構文エラー(SyntaxError・IndentationError)になる49本のコードを各版で動かし、表示が「invalid syntax」だけだった本数を数えました(3.14 は 3.15 と同じ表示だったため省いています)。
| 版 | invalid syntax だけ | 具体的なヒントあり | 構文エラーにならない |
|---|---|---|---|
| 3.8.20 | 33本 | 16本 | 0本 |
| 3.10.22 | 17本 | 30本 | 2本 |
| 3.11.18 | 16本 | 31本 | 2本 |
| 3.12.3 | 15本 | 29本 | 5本 |
| 3.13.18 | 15本 | 29本 | 5本 |
| 3.15.2 | 10本 | 31本 | 8本 |
「構文エラーにならない」は、新しい版でその書き方が正しい構文になったものです(match・with の括弧・f文字列の引用符・type・型パラメーター・括弧なし except・t 文字列。Python 2 の except は 3.14 以降で実行時の NameError に変わります)。3.15 でも invalid syntax だけだった10本は、予約語を名前にしたもの・pip や python3 のコマンド・>>> を貼ったもの・++ && // ? : などの他の言語の書き方・exec に渡した文字列でした。新しい版でもヒントが出ないときは、「Python のコードではないもの」が混ざっていると考えると近道です。
13.10:場所とヒントが大きく改善
expected ':'・'(' was never closed・Perhaps you forgot a comma?・Maybe you meant '==' がこの版から。印も ^^^^^ と範囲で付くようになった。
23.12:f文字列と引数の文言
f文字列の中で同じ引用符が使えるようになり、def f(a=1, b): の表示が parameter without a default follows parameter with a default に変わった。
33.14:綴りの候補と専用の文
Did you mean 'while'? の候補、'elif' block follows an 'else' block、Is this intended to be part of the string? などが加わった。
3.14 で加わった文は、手元の 3.15.2 で次のとおり出ました(3.13 では3つとも invalid syntax だけでした)。
| 書いたもの | 3.15 の表示 |
|---|---|
| else のあとに elif | 'elif' block follows an 'else' block |
print("He said "hi" to me") |
Is this intended to be part of the string? |
x if c else pass |
expected expression after 'else', but statement is given |
構文エラーをまとめて見つける(py_compile・compileall・ast)
この節では、実行せずに構文だけを確かめる方法と、版を指定して確かめる方法が分かります。
構文エラーはファイルを実行しなくても見つけられます。標準の py_compile は1ファイル、compileall はフォルダーの中の全ファイルを調べます。2つの誤りを入れたフォルダーで試しました。
python3 -m compileall -q .
*** Error compiling './pkg/bad1.py'...
File "./pkg/bad1.py", line 2
if x == 1
^
SyntaxError: expected ':'
*** Error compiling './pkg/bad2.py'...
File "./pkg/bad2.py", line 1
items = [1, 2
^
SyntaxError: '[' was never closed
終了コードは1で、CI(自動テスト)に入れると誤りのあるコードを取り込む前に止められます。同じフォルダーを 3.11 で調べると、3.12 からの type N = int を書いた3つ目のファイルも invalid syntax として見つかりました。本番で使う版で compileall を動かすと、「手元では動くのに本番で構文エラー」を防げます。なお compileall は .pyc ファイルを作るので、作りたくないときは PYTHONPYCACHEPREFIX で置き場所を変えます。
行と列を一覧にする(ast.parse)
標準の ast を使うと、行・列をそろえて一覧にできます。
import ast, sys, pathlib
for p in sorted(pathlib.Path(sys.argv[1]).rglob("*.py")):
try:
ast.parse(p.read_text(encoding="utf-8"), filename=str(p))
except SyntaxError as e:
print(f"{p}:{e.lineno}:{e.offset}: {e.msg} (end {e.end_lineno}:{e.end_offset})")
pkg/bad1.py:2:10: expected ':' (end 2:11)
pkg/bad2.py:1:9: '[' was never closed (end 1:0)
end_lineno と end_offset は 3.10 で加わった属性で、3.8 で同じコードを動かすと AttributeError: 'SyntaxError' object has no attribute 'end_lineno' になりました。3.8 でも使うなら lineno・offset・msg だけにします。
ast.parse の feature_version を使うと、新しい Python のまま「以前の版で通るか」を確かめられます。3.13 で試すと、版を名指しした分かりやすい文が出ました。
| コード | feature_version | 表示 |
|---|---|---|
| match 文 | (3, 9) | Pattern matching is only supported in Python 3.10 and greater |
type N = int |
(3, 11) | Type statement is only supported in Python 3.12 and greater |
def f[T](x: T) |
(3, 11) | Type parameter lists are only supported in Python 3.12 and greater |
ただし、f文字列の中の同じ引用符と with の括弧は feature_version で指定しても通ってしまいました。最終的な確認は、その版の Python 本体で compileall を動かすのが確実です。
OS・環境別の確かめ方(Windows・Mac・Linux・Jupyter・VS Code)
この節では、環境ごとに「どの Python で動いているか」を確かめる方法が分かります。
invalid syntax の原因が「版」や「打つ場所」にあるときは、環境ごとに確かめ方が違います。Windows・VS Code・Jupyter は公式ドキュメントで確かめた範囲です。
| 環境 | 版の確かめ方 | 注意点 |
|---|---|---|
| Windows | py list(以前からの py -0p も可)で一覧、py -V:3.12 ファイル名 で版を指定 |
コマンドプロンプト・PowerShell で打つ。>>> の中ではない |
| Mac・Linux | python3 --version・which python3 |
python と python3 で別の版を指すことがある |
| Jupyter | セルで import sys; print(sys.version) |
pip はセルで %pip install |
| VS Code | 画面下のステータスバーの版の表示、またはコマンドパレットの「Python: Select Interpreter」 | 選んだインタープリターで実行・デバッグされる |
| 仮想環境(venv・uv) | 有効にしてから python --version |
有効にする前後で版が変わる |
よくあるエラー/つまずき
この節では、invalid syntax と似たエラー・警告の原文と、見分け方が分かります。
構文の誤りでも、invalid syntax 以外の文になるものがあります。手元で出した原文を並べます。
| 表示(原文) | 意味 | 直し方 |
|---|---|---|
IndentationError: expected an indented block after 'for' statement on line 2 |
for の次の行が字下げされていない | 次の行を4文字下げる |
IndentationError: unindent does not match any outer indentation level |
else などの字下げが上の行とそろっていない | if と同じ位置にそろえる |
SyntaxError: invalid non-printable character U+3000 |
全角スペースが入っている(3.8 は invalid character in identifier) |
半角スペースに置き換える |
SyntaxError: unexpected character after line continuation character |
行末の \ のあとに空白がある |
\ を行の最後にするか括弧で囲む |
SyntaxError: 'return' outside function |
関数の外に return がある | 字下げを見直し、関数の中に入れる |
SyntaxError: cannot assign to True |
True・False・None に代入した | 別の名前にする |
SyntaxError: non-default argument follows default argument |
既定値ありの引数の後ろに既定値なしを置いた(3.12 以降は文言が変わる) | 既定値なしの引数を前に |
IndentationError は SyntaxError の仲間(サブクラス)で、字下げの誤りだけを表します。タブとスペースの混在を含めて、関連記事「IndentationError・TabErrorの直し方|Python」で扱っています。
SyntaxWarning は止まらない
警告(SyntaxWarning)はエラーではなく、プログラムは最後まで動きます。手元では次の3つが出ました。
| 書いたもの | 表示 | 出た版 |
|---|---|---|
re.findall("\d+", ...) |
SyntaxWarning: invalid escape sequence '\d' |
3.12・3.13(3.14 は文が詳しくなる) |
if x is 1: |
SyntaxWarning: "is" with 'int' literal. Did you mean "=="? |
3.8 から(文言は版で違う) |
| finally の中の return | SyntaxWarning: 'return' in a 'finally' block |
3.14 から |
3.12 の What's New には、無効なエスケープは将来 SyntaxError になると書かれています。正規表現は r"\d+" と raw 文字列で書いておくと、版が上がっても止まりません。
- 1if・for・def・class の行末に : があるか3.10 以降は expected ':' と出る。3.8・3.9 では invalid syntax だけ
- 2上の行の括弧と引用符が閉じているかエラーの行に誤りが無いときは、まず上の行を数える
- 3Python の中(>>>)でコマンドを打っていないかpip・python3 はターミナルで。ファイル名が <stdin> なら Python の中
- 4コピーしたコードに Python 2 や他の言語の書き方が無いかprint "..."・except X, e・++・&&・// を探す
- 5動かしている Python の版で使える構文かpython3 --version を確かめ、match は 3.10、type は 3.12 から
判断表:invalid syntaxの直し方の選び方
この節では、表示と状況ごとに、どこを見てどう直すかの一覧が分かります。
| 表示・状況 | 見るところ | 直し方 |
|---|---|---|
expected ':' |
印の付いた行の最後 | : を付ける。else if は elif |
'(' was never closed・unexpected EOF |
印の付いた括弧から下 | 閉じ括弧を足す |
Perhaps you forgot a comma? |
印の範囲の要素の間 | カンマを足す。文字列の中の引用符も疑う |
Maybe you meant '==' |
if・while の条件 | == にする |
invalid syntax だけで、ファイル名が <stdin> |
打った場所 | exit() で抜けてターミナルで打つ |
invalid syntax だけで、印の場所に誤りが無い |
1つ上の行・Python の版 | 括弧を数え、python3 --version を確かめる |
| 人のコードで出る・自分の環境だけで出る | 構文の使える版 | 版を上げるか、以前の版の書き方に直す |
| フォルダー全体を確かめたい | 本番と同じ版 | python -m compileall -q . を CI で動かす |
- 1エラー文の最後の行を読むinvalid syntax のあとのヒントを最優先
- 2^ の場所と、その1つ上の行を見る括弧・引用符・コロン・カンマ
- 3Python のコードか確かめる>>>・pip・python3・他の言語の書き方
- 4Python の版を確かめるpython3 --version と、構文が使える版
- 5まとめて確かめるcompileall を本番と同じ版で
よくある質問
この節では、SyntaxError: invalid syntax について検索されることの多い疑問への答えが分かります。
Q. SyntaxError: invalid syntax の日本語の意味は?
A. 「構文エラー:文法が正しくありません」という意味です。Python の決まりとして読めない行があることを表します。
Q. エラーの行を見ても間違いが無いのはなぜ?
A. ^ は「読めなくなった場所」で、原因はその上の行にあることが多いためです。特に括弧の閉じ忘れは、Python 3.8 では次の行を指しました。
Q. pip install requests で invalid syntax になるのはなぜ?
A. Python の中(>>>)で打っているためです。exit() で抜けて、ターミナルで python3 -m pip install requests と打ちます。
Q. 同じコードが友人の PC では動くのはなぜ?
A. Python の版が違う可能性が高いです。match は 3.10、type 文は 3.12、括弧なしの except は 3.14 から使えます。
Q. Python 3.8 と 3.13 でエラー文が違うのはなぜ?
A. 3.10 でエラー文が大きく改善されたためです。手元の49本では、invalid syntax だけの表示が 3.8 の33本から 3.13 で15本に減りました。
Q. 変数名に class や import を使えない?
A. 使えません。予約語(35語)は名前にできないので、class_ のように _ を付けます。match・type は変数名にも使えます。
Q. Jupyter で pip install を打つと invalid syntax になるのは?
A. セルは Python のコードとして実行されるためです。%pip install requests と書きます。
Q. 構文エラーを実行前に見つける方法は?
A. python3 -m py_compile ファイル名、フォルダーなら python3 -m compileall -q . で、実行せずに構文だけを確かめられます。
Q. IndentationError や invalid character とは別のエラー?
A. どちらも SyntaxError の仲間です。字下げの誤りは IndentationError、全角スペースなどは invalid character / invalid non-printable character と表示されます。
まとめ
この節では、記事の要点を5つに絞った振り返りが分かります。
- 意味:Python の文法として読めない行がある。実行前に止まるので、エラーより上の行も動かない。
- 探し方:最後の行のヒント →
^の場所 → 1つ上の行の括弧・引用符、の順に見る。 - 多い原因:コロン・括弧・引用符・カンマの書き忘れ、
=と==、予約語、>>>の中でのpip install。 - 版:3.10 以降はヒントが増え、3.14 からは綴りの候補も出る。新しい構文(match・type・t 文字列)は以前の版では invalid syntax になる。
- 予防:本番と同じ版で
python -m compileall -q .を動かし、エラーを共有するときは版も添える。
参考・出典
この節では、この記事で確かめた公式の資料(確認日 2026年11月5日)が分かります。
- Python 公式ドキュメント「Errors and Exceptions」8.1 Syntax Errors:https://docs.python.org/3/tutorial/errors.html
- Python 公式ドキュメント「Built-in Exceptions」SyntaxError・IndentationError・TabError:https://docs.python.org/3/library/exceptions.html
- Python 公式ドキュメント「What's New In Python 3.10」Better error messages・PEP 634:https://docs.python.org/3/whatsnew/3.10.html
- Python 公式ドキュメント「What's New In Python 3.12」PEP 701・PEP 695・SyntaxWarning:https://docs.python.org/3/whatsnew/3.12.html
- Python 公式ドキュメント「What's New In Python 3.14」PEP 758・PEP 750・PEP 765・エラー文の改善:https://docs.python.org/3/whatsnew/3.14.html
- Python 公式ドキュメント「Using Python on Windows」:https://docs.python.org/3/using/windows.html
- Python Developer's Guide「Status of Python versions」:https://devguide.python.org/versions/
- IPython 公式ドキュメント「Built-in magic commands」%pip:https://ipython.readthedocs.io/en/stable/interactive/magics.html
- Visual Studio Code 公式ドキュメント「Python environments in VS Code」:https://code.visualstudio.com/docs/python/environments
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「SyntaxError: invalid syntaxの直し方|Python49例」
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。