目次
- 目次
- 用語確認:importしただけなのに、SyntaxError
- 事件現場
- Python 3.7以降でasyncが予約語に
- asyncが予約語、OSSに見つけた事象
- 終わりに
- P.S. 構造的パターンマッチとソフトキーワード
用語確認:importしただけなのに、SyntaxError
組み込み例外のドキュメントより
https://docs.python.org/ja/3/library/exceptions.html#SyntaxError
SyntaxErrorは
パーザが構文エラーに遭遇した場合に送出されます。
この例外は import 文、 (略) で (対話的な実行時にも) 起こる可能性があります。
import文はこちら
https://docs.python.org/ja/3/reference/simple_stmts.html#import
事件現場
素晴らしいスクリプトを書きました、async.pyに
def awesome() -> None: print("Awesome ✨")
importしてみます。
% python3.12 # Python 3.12.6 >>> import async File "<stdin>", line 1 import async ^^^^^ SyntaxError: invalid syntax
スクリプトとしては実行できます
% python3.12 -i async.py >>> awesome() Awesome ✨
Python 3.7以降でasync
が予約語に
「SyntaxError: invalid syntax」は、async
が予約語だからです。
Python 3.7から予約語です。
https://docs.python.org/ja/3/whatsnew/3.7.html#summary-release-highlights
async と await は予約されたキーワードになりました。
https://docs.python.org/ja/3/whatsnew/3.7.html#changes-in-python-behavior
async and await names are now reserved keywords. Code using these names as identifiers will now raise a SyntaxError.
予約語のドキュメント
https://docs.python.org/ja/3/reference/lexical_analysis.html#keywords
以下の識別子は、予約語、または Python 言語における キーワード (keyword) として使われ、通常の識別子として使うことはできません。
importはimport <通常の識別子>
となるため、通常の識別子に予約語のasync
が来られず、SyntaxErrorという理解です。
同じ理由で、関数名にも使えませんね。
>>> def async(): File "<stdin>", line 1 def async(): ^^^^^ SyntaxError: invalid syntax
Python 3.7より前は予約語ではないのでimportできます。
% docker run --rm -it --platform linux/x86_64 -v $PWD/async.py:/work/async.py -w /work python:3.6 python >>> import async >>> async.awesome() Awesome ✨
% docker run --rm -it --platform linux/x86_64 -v $PWD/async.py:/work/async.py -w /work python:3.7 python >>> import async File "<stdin>", line 1 import async ^ SyntaxError: invalid syntax
async
が予約語、OSSに見つけた事象
知っている中から2つ紹介
(1) Celery
from . import async, base
(async.pyのimport)でSyntaxErrorが送出されています。
asynchronous.pyにrenameして修正しています。
(2) Sphinx
私が報告していました。
関数の引数にasync
が使われていて、SyntaxErrorが送出されました
終わりに
importしただけなのにSyntaxError、予約語をimportしていたためでした。
予約語は関数名や仮引数に使ってもSyntaxErrorです。
学び:予約語は、通常の識別子として使えません。
P.S. 構造的パターンマッチとソフトキーワード
Python 3.10で追加された「構造的パターンマッチ」
https://docs.python.org/ja/3/whatsnew/3.10.html#pep-634-structural-pattern-matching
こちらに使うmatch
やcase
ですが、予約語ではなく、ソフトキーワードとして導入されています。
https://docs.python.org/ja/3/reference/lexical_analysis.html#soft-keywords
Some identifiers are only reserved under specific contexts. These are known as soft keywords.
As soft keywords, their use in the grammar is possible while still preserving compatibility with existing code that uses these names as identifier names.
async
と同様キーワードとして追加すると影響は大きかったと思います(re.match()などにも影響)。
ソフトキーワードという意思決定の背景が少しだけ分かった気がします。