結論

SyntaxError: invalid syntax は「Python の文法として読めない行がある」ときに、プログラムを1行も実行する前に出るエラーです。多いのはコロン(:)の書き忘れ・括弧の閉じ忘れ・= と == の取り違えと、pip install を Python の中(>>>)で打った場合です。^ の印の場所で見つからなければ、1つ上の行を見ます。

この記事でわかること

  • invalid syntax の原因10系統と、原因ごとのエラー原文・直したあとの出力
  • Python 3.8〜3.15 でエラー文がどう変わったか(同じ49本のコードで比較)
  • エラーの行がずれるときの探し方と、構文エラーをまとめて見つける方法

2026年11月5日更新|Python 3.8.20・3.10.22・3.11.18・3.12.3・3.13.18・3.14.10・3.15.2 で実行確認

この記事で実際に動かしたもの:構文エラーになるコード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」は「閉じる記号が来ないままファイルが終わった」という意味です。

1

最後の行(エラーの種類)を読む

invalid syntax のあとに expected ':'・Perhaps you forgot a comma? などのヒントがあれば、まずそのとおりに直す。

3.10 以降はヒントが多い

2

^ の場所を見る

印の付いた語の前後に、コロン・カンマ・引用符の抜けや = の誤りが無いか見る。

多くはこれで見つかる

3

1つ上の行を見る

印の場所に誤りが無ければ、上の行の括弧 ( [ { と引用符が閉じているか数える。

3.8・3.9 で特に多い

4

Python の版を確かめる

誤りが無いのに出るなら、新しい版の構文を以前の版で動かしている。python3 --version で版を見る。

match・type・t文字列など

5

エラー文の最後の行で検索する

ファイル名を除いた最後の行(例: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 でした。

1

Python を抜ける

exit() と打つか、Ctrl+D(Windows は Ctrl+Z のあと Enter)。プロンプトが >>> から $ や C:\> に戻ればターミナル。

抜けたか目で確かめる

2

ターミナルで打ち直す

python3 -m pip install requests のように python3 -m pip の形で打つと、今の python3 に入る。手元では python3 -m pip --version が pip 26.2.1 ... (python 3.13) と版まで表示した。

Windows は py -m pip

3

スクリプトもターミナルで動かす

python3 hello.py はターミナルで打つ。手元では hello と表示された。

>>> の中では動かない

4

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. 1エラー文の最後の行を読むinvalid syntax のあとのヒントを最優先
  2. 2^ の場所と、その1つ上の行を見る括弧・引用符・コロン・カンマ
  3. 3Python のコードか確かめる>>>・pip・python3・他の言語の書き方
  4. 4Python の版を確かめるpython3 --version と、構文が使える版
  5. 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期連続の黒字決算。

ABOUT RJC RJCがどんな会社か知る 考え方、研修、働き方、福利厚生、社員の前職まで。RJCのことが丸わかり! RJC丸わかりページへ JOB DESCRIPTION 仕事内容・待遇を見てみる 仕事内容、給与・待遇、選考の流れ。経験者も未経験も!応募前に知りたいこと、まとめました! 募集要項を見る ENTRY エントリーする エントリーは1〜2分・履歴書不要です。まずは話を聞いてみたい、という方でも歓迎です! エントリーフォームへ

成長のヒミツ、 ぜんぶ丸わかり