Python3.11をWindowsにインストールしたらshebangに #!/usr/bin/env python3
と書いていたスクリプトの挙動がおかしくなった覚書です。
Issueはそこそこ立ってますが日本語情報がなかったので。
先に結論
-
#!/usr/bin/env
は指定名の実行ファイルをPATHから検索する - 無効化のため環境変数
PYLAUNCHER_NO_SEARCH_PATH=1
を作成(値は任意) - msysなどpython3の重複が他にないなら設定のアプリ実行エイリアスでアプリインストーラー (python.exe, python3.exe) を無効化するだけでも良い
shebangとは
スクリプトファイル一行目のこんなの↓
#!/usr/bin/env python3
本来はLinux等のシェル環境でスクリプトファイルの実行アプリケーションを指定するものです。(雑理解)
Windowsでは必要ありませんが、他の環境への移植性のために仮想的にサポートしており、 #!/usr/bin/env python3.9
のように書くとWindowsのpyランチャーがバージョンを解決してくれます。
Windowsでは下記のような書き方ができ、今までは /usr/bin/env
がUnix系環境で柔軟に対応できるため推奨されていました。[誰によって?]
#!/usr/bin/env python
#!/usr/bin/python
#!/usr/local/bin/python
#!python
起こったこと
Python3.11をインストールしたら #!/usr/bin/env python3
というshegangをつけているスクリプトがWindowsにインストールしたpythonで実行できなくなりました。
はじめはmsysのpythonで起動してしまい、そちらをPATHから外すと今度は Python
とだけ出力されてスクリプトが動作しない状態になってしまいました。
また #!/usr/bin/env python
というバージョンを全く指定しない書き方や、#!/usr/bin/python3.8
、#!python3
などenv以外の指定では今まで通り動作し、後者ではバージョン指定も効きました。
原因と解決
pyランチャーの#!/usr/bin/env
の仕様変更っぽい? (前からじゃないはず…ないよね?)
まず #!/usr/bin/env
の仕様として、「envの次のコマンドがpython
以外の場合PATHから完全一致する実行ファイルを検索する」という仕様があります。
The /usr/bin/env form of shebang line has one further special property. Before looking for installed Python interpreters, this form will search the executable PATH for a Python executable matching the name provided as the first argument. This corresponds to the behaviour of the Unix env program, which performs a PATH search. If an executable matching the first argument after the env command cannot be found, but the argument starts with python, it will be handled as described for the other virtual commands. The environment variable PYLAUNCHER_NO_SEARCH_PATH may be set (to any value) to skip this search of PATH.
多分今まではpython3等はそのまま解釈してたのを、3.11から仕様に厳格にしたのかなって感じです。過去バージョンでも同様の記載はありますがやたらと簡素なので。
インストーラでインストールされる実行ファイルは python.exe なので python3 と書くと msys 等の他の環境に含まれる実行ファイルを見に行っちゃうんですね。
この検索機能は環境変数 PYLAUNCHER_NO_SEARCH_PATH=1
を作成(値は任意)することで抑制できます。
そして他に python3.exe がない状況でも反応するものとしてWindowsのアプリインストーラーエイリアスがあります。これが 出力: Python
の正体です。
これはPythonがインストールされていないWindowsのCUIで python や python3 とタイプしたときにMicrosoft Storeへ移行しインストールを促す おせっかいな 機能で、3.11のpyランチャーはこれも拾ってしまうようです。
こちらは設定の「アプリ実行エイリアス」から無効化できます。公式インストーラでインストールした人はまず間違いなくいらない機能なので無効化してしまいましょう。