nikkie-ftnextの日記

イベントレポートや読書メモを発信

VS Codeのターミナルをカパカパする真拳

小 ネ タ で す

macOS日本語配列キーボードでは、以下を連打

Ctrl + Shift + @

カパカパ

カパカパ

食らえ!!!
(以下にGIFも用意しました)

目次

VS Codeのターミナルパネル

VS Codeの下の部分、ドキュメントによるとパネルと呼ぶようです。

User Interface」のドキュメントの「Basic Layout」より

Panel - An additional space for views below the editor region. By default, it contains output, debug information, errors and warnings, and an integrated terminal.

ドキュメント中の画像(Dの部分です)
https://github.com/microsoft/vscode-docs/blob/dca057b0c6da04c6472854c1381c863d31abcb14/docs/getstarted/images/userinterface/hero.png

このパネルには「TERMINAL」(のタブ)があります。
このパネル自体を表示したり隠したりする方法が上で紹介したCtrl + Shift + @なのです。

ショートカットキー以外の操作方法

パネルの右上にはバツ印 ✕ 1があります。
これを押してもパネルを閉じられます

私はターミナルのexitなのかと勘違いしていました。
exitではなくパネルを非表示にするだけです(ターミナルはシェルの途中から再開できます)

コマンドパレット(Shift + Cmd + P)2では、「View: Toggle Terminal」です。
コマンドパレットを使ってパネルのターミナルをカパカパできます

Toggleのショートカットキー

ショートカットキーがmacOS日本語配列キーボードでは、Ctrl + Shift + @

macOSのショートカットでは Ctrl + ` です。
https://code.visualstudio.com/shortcuts/keyboard-shortcuts-macos.pdf
日本語配列だとバッククォートは「Shift + @キー」だからでしょうか。

他のOSでも Ctrl + ` で共通です!

なお、New Terminalのショートカットもあります(こちらはカパカパするたびにシェルが増えていきます)

  • macOS:Ctrl + Shift + `
    • 日本語配列では Ctrl + Shift + ^ でした(Shift + ^ は ~ を打つ運指です)
  • Windows:Ctrl + Shift + `
  • Linux:Ctrl + Shift + `

コマンドパレットでは「Terminal: Create New Terminal」です。

終わりに

VS Codeのパネル(のターミナル)をカパカパする方法が分かったという小さな気づきを書きました。

  • 単に隠す:パネル右上の閉じるボタン
  • 出したり隠したり
    • コマンドパレット「View: Toggle Terminal」
    • ショートカットキー:Ctrl + `
  • 新しいターミナルを作る
    • コマンドパレット「Terminal: Create New Terminal」
    • ショートカットキー:Ctrl + Shift + `

ドキュメントでは以下の冒頭にまとまっています!

P.S. オマージュ元

ボボボーボ・ボーボボの真拳一覧 - Wikipedia

ボーボボが出した、ただCDのケースをカパカパするだけのデタラメの真拳。


  1. クローズボタンで見るような✕ですね
  2. 詳しくはこちらをどうぞ

pipx runするスクリプトを書く中でも、VS Codeによる補完のサポートを受ける

はじめに

ここすきここすきここすきここすき nikkieです。

pipx runにまつわるVS Codeの小ネタです。

目次

前回まで:pipx runはいいぞ!仮想環境レス🙌

このブログで最近取り上げていますが、pipxはPEP 723(Inline script metadata)の一部をサポートしています。

Pythonスクリプトにコメントとしてmetadataを書き、

# /// script
# dependencies = ["rich"]
# ///

pipx runで実行することで、スクリプトに必要なライブラリを仮想環境にインストールするという管理の手間をpipxにお任せできます!
仮想環境の管理から解き放たれるので、別の環境でもスクリプトを簡単に再現性高く動かせて、私にはとってもよいです。

さらに、pipxが管理する、スクリプト用の仮想環境にアクセスするには、PYTHONINSPECT=1 pipx runと実行すればよいことを見出しました。

VS Codeで補完を受けたい

すでに動くスクリプトを別の環境でも動かす場合、pipxはめちゃめちゃ力を発揮するのですが、仮想環境をpipxが管理するがゆえに開発中はやりづらさがあります。

依存するライブラリが不慣れな場合、VS Codeの補完が受けられないのがやややりづらいです   (※Copilotは元気よく提案してきます)

# /// script
# dependencies = [
#   "requests<3",
#   "rich",
# ]
# ///

import requests
from rich.pretty import pprint

importしたモジュールに黄色い線が引かれており、(requestsは該当しませんが)pprintは型がAnyとなっていて、いい感じの補完が受けられません。

PythonVS Codeの知識をつなぎ合わせて、この状態を解決していきます!

解決案:pipxが管理する仮想環境をSelect Interpreterする

macOSbrewでインストールしたpipxを使っています1

% pipx --version
1.5.0

PYTHONINSPECT環境変数を指定して上記スクリプトを実行し、対話モードに入ります。

% PYTHONINSPECT=1 pipx run ./script.py
>>>

sys.executableを確認します。
https://docs.python.org/ja/3/library/sys.html#sys.executable

Python インタプリタの実行ファイルの絶対パスを示す文字列です。

>>> import sys
>>> sys.executable
'/.../.local/pipx/.cache/2cdf4afd53bcfd9/bin/python'

これを控えたら対話モードは抜けます。
次はVS Codeの設定です。
https://code.visualstudio.com/docs/python/environments#_select-and-activate-an-environment

  • コマンドパレット(⇧⌘P2にて、「Python: Select Interpreter
  • 「Enter interpreter path...」を選び、sys.executableの値を入力

VS Codeのドキュメントは英語ではありますが、画像付きで操作が分かりやすいです)

これでpipxが管理する仮想環境に入っているライブラリがVS Codeに認識され、補完が受けられます!
見てください、pprintに色がついてます3!関数の定義も見られますよ🙌

なお、sys.executablePythonについて-m pip listとすると、pipxが仮想環境で管理してくれているライブラリが一覧できます。

手順まとめ

  1. スクリプトにdependenciesをコメントで書く
  2. 1のスクリプトPYTHONINSPECT環境変数を指定の上、pipx runで実行
  3. 対話モードでsys.executableを確認
  4. 3で確認したPythonインタプリタのパスをVS Codeの「Select Interpreter」で指定

終わりに

pipx runに寄せていく中で直面した、スクリプトを書いている最中にVS Codeの補完を十分に受けられないという課題を解決しました。
Pythonの知識とVS Codeの知識を組み合わせていったら解決に至れました。
この解決案は簡単ではないので、簡単にする方法は考えてみたいですね。

全人類よ、Pythonスクリプトの実行にはpipxを使うのです!
コメントとして依存を書くだけで仮想環境の管理から解き放たれ、とっても楽ですよ〜

この記事の元ネタ


  1. brewで入れたpipxはbrewPythonに依存するようです。一方私はpyenvで管理しています。複数のPythonから指定したいときは、pipx run --python python3.11 ./script.pyのように指定しています
  2. VS Code最下部の右側をクリックしてもSelect Interpreterできます
  3. 色が濃いのはスクショの範囲外でpprintを呼び出しているからです

そこにいるペアのCopilotを慮り、VS Codeのエディタに増えたタブを閉じる

はじめに

REFRAIN REL@TION、よすぎる... nikkieです。

先日のVS Code ConferenceからのTake awayとして、GitHub Copilotのことを考えることが増えました。
その一部をアウトプットします

目次

エディタで開いているファイルに注意を払う

VS Code Conferenceでも取り上げられた、GitHub 田中さんのスライド。

関連するファイルは常に開いておこう

なぜかというと、「現在のファイルのカーソル前後のソースコードや、別のタブで開いているファイル」が文脈となるから(田中さんスライド前のページより)

GitHub Copilot Patterns & Exercises』でも取り上げられています。

GitHub Copilot が提案に使用するファイルは、主に現在開いているファイルとそれに隣接するタブファイル(基本的には同じファイル拡張子)です。
正確な提案をするためには、関連するファイルだけを開いておくことが不可欠です。

ただし「2023年8月時点」とのことです

一人でプログラミングしているときには、多くのファイルを開いた状態でも私はそんなに気にしていませんでした。
ですが、改めてこのドキュメントを確認すると、以下が刺さりました。

「不要なファイルを閉じる」などの実践は、GitHub Copilot を使用していない場合であっても、コーディングにプラスの影響を与える可能性があります。

所作を常中させるぞ! ショートカットの確認

タブをすべて閉じる

macOSでは ⌘K + W です1
タブを右クリックすると現れる「Close All」のショートカットです。

エディタを分割して開いている場合は、アクティブになっている側が全部閉じます(なので、複数回打ち込みます)

WindowsLinuxでは、Ctrl+K Ctrl+Wのようです。

タブのピン留め

Visual Studio Codeのピン留め機能を使用すると、これらのファイルを必要に応じて簡単にアクセスし、GitHub Copilotに効率的に情報を提供できます。

ドキュメントはこちら
https://code.visualstudio.com/docs/editor/custom-layout#_pinned-tabs

  • コマンドパレット「View: Pin Editor」
    • 逆のコマンドは「View: Unpin Editor」
  • macOSでは ⌘K ⇧Enter
    • WindowsLinuxについてはショートカット一覧のPDFに見つからず、Copilotさんによると Ctrl+K Shift+Enter とのことです(真偽のほどは!?)

ピン留め操作は以下が分かりやすかったです。

ピン留めしておくと、「Close All」でも閉じないですね。
これは便利だ! もっと使っていこう

終わりに

GitHub Copilotを使い始め、「文脈」を意識するようになりました。
今回取り上げたのは、開いているファイルの整理です。
実装が小さくとも一段落ついたタイミングで、⌘K + Wでタブ(開いているファイル)を一掃します。

この「不要なファイルを閉じる」所作は、コーディングに一服を与えてくれているようです。
一瞬ですが気持ちを整えてから、Copilotと一緒に書くファイルを開いて次の小さな実装に向かいます。
Copilotを使おうと思って1週間程度ですが、まさか自分がCopilotの文脈を意識したコーディングスタイルに変わり始めるとは思いませんでしたね

VS Code⌘Kは続くキー(second key)を待つモードになるらしく、動きとして興味深いです2
今回は⌘K then Wや、⌘K then ⇧Enterの紹介でした


  1. https://code.visualstudio.com/shortcuts/keyboard-shortcuts-macos.pdf
  2. 古のEmacsを強要された記憶が蘇って、これ以上はダメーーー!!!(学生自体色々あって)

Instruction Tuningをさがして(2024年4月時点の理解まとめ)

はじめに

みなさんは、死の先には何があると思いますか?
nikkieです。

連休で「Instruction Tuning」を少し調べまして、現時点の理解をまとめます。
※間違ったことを書いていたら@ftnextまでツッコミを入れてください!(お手柔らかにお願いします🙏)

目次

実は経験のあったInstruction Tuning

調べていくうちに、過去に日経Linuxの記事に沿って経験していたと認識しました。

  • Instruction Tuningの形式のデータセットを使った
  • LLMの重みを全部更新するのではなく、LoRAで外付けした重みだけ更新(※今回PEFTは掘り下げません)

書籍や資料でインプット

今回のインプットによって、断片的に知っていた事項に繋がりが見えてきた気がします。

『大規模言語モデル入門』

「4.4 指示チューニング」を参照。

指示チューニング(instruction tuning)は、指示を含んだプロンプトと理想的な出力テキストの組で構成されるデータセットを使ったファインチューニングによって大規模言語モデルのアライメントを行う方法 (Kindle版 p.140)

松尾研 サマースクール 2023 大規模言語モデル講座 Day5

サマースクールサイトから資料をダウンロードできますが、Day5の資料はSpeaker Deckで公開されています。

様々なタスクがこの入出力形式に内包

FLAN論文で提案

Instruction Tuningの提案論文がこちら1

Google Research発の論文です。
ここで提案されたモデルがFLAN(Finetuned Language Net)

先行する論文に「Language Models are Few-Shot Learners」(2020)(GPT-3の論文)があり、プロンプトに例(few-shot)を入れることで良い性能を示すことが分かっていました。
Instruction Tuningは、言語モデルzero-shotでの性能向上手法として提案されます。

「ここ頭いいなー」と思ったんですが、「様々なタスクを指示・回答という形式に統一したデータセット」を用意してるんです!2

日経Linux記事でも指示・回答という形式で作っていました!

### 指示:
{instruction}

### 回答:

論文からFigure 2を引用します。
Instruction Tuning (C) は、あるタスクのファインチューニング (A) と、few-shotのプロンプト (B) を組み合わせたもの3と言っています。

FLANの発展(FLAN T5)

We find that instruction finetuning with the above aspects dramatically improves performance on a variety of model classes (PaLM, T5, U-PaLM), prompting setups (zero-shot, few-shot, CoT), and evaluation benchmarks (略). (Abstractより)

FLAN T5というモデルを聞いたことがあったのですが、モデルカード中の画像が論文のFigure 1なんですよね

Multi-task instruction tuning(緑)、1.8Kのタスクでデータセットを用意と、めちゃめちゃスケールさせています。

If you already know T5, FLAN-T5 is just better at everything. For the same number of parameters, these models have been fine-tuned on more than 1000 additional tasks covering also more languages.(TL;DRより)

T5を1000を超える追加タスクでファインチューンしたものが、FLAN T5!

AlpacaもInstruction Tuningで

松尾研講座資料の有効性のところに、Alpacaの文字が!

  • FLANでZero-shot性能の向上
  • Alpacaで指示応答性能の向上

Alpacaは)Meta社が開発したLLaMA 7BモデルにInstruction Tuningを適用した

https://crfm.stanford.edu/2023/03/13/alpaca.html

ちょうどNLPコロキウムでAlpacaの話を聞いて(正確には聞き流して)おり、「Instruction Tuningでできたモデルだったのか!」となりました。

ichikara-instruction!

NLP2024で複数回耳にしたichikara-instruction(データセット)。
我ながら気づくのが遅すぎたんですが、「各社Instruction Tuningをして(Alpacaのように)日本語での指示応答性能を向上させようとしていたんだなあ」と気づきました。

一例です

他にはマネーフォワードさんのhouou4

この先知りたいこと

次の論文まとめが流れてきました。

LLMを特定タスクに向けてinstruction tuningするときに関連タスクのデータも混ぜると精度向上する事があるが、instructionの文面の Encoder(論文だとSentence Transformer)での埋込のコサイン類似度の高い方から加えると良いタスクを選定できるとのこと。

日経Linux記事の例は「Linuxコマンドを答える」という1タスクなのですが、関連タスク(他の質問応答とか?)も混ぜるといいってこと
Instruction Tuning自体、複数タスク混ぜたデータセットを用意しているわけで、その中から選りすぐって使うというアプローチが提案されているのか〜

終わりに

「Instruction Tuning」で色々な事象が結びつき、ここにアウトプットしました。

  • Instruction Tuningはデータセットへのアプローチ。自然言語処理のタスクを指示と回答で同一視して混ぜる
  • Instruction Tuningで、言語モデルのzero-shot性能や指示応答性能を向上させられることがわかった
    • 言語モデルは、few-shot性能が高いことがわかっていた)
    • 日本でもichikara-instruction作成と、それを用いた各社のLLM開発

研究の流れが結びついたことで、Instruction Tuningについて手を動かしたくてうずうずしています。
データセットのアプローチだと思うので、LoRAなどのPEFT手法側からInstruction Tuningもやっているサンプルコードを探してみようかな


  1. 「Language Models are Few-Shot Learners」を意識したタイトルに思われます
  2. データセットでの工夫だから、Instruction TuningはData-centricなアプローチ、と理解していいのかな?
  3. combines appealing aspects of both the pretrain–finetune and prompting paradigms」(p.2 1.Introductionの最終段落)
  4. 事例参考 LLMのための日本語インストラクションデータ 公開ページ – RIKEN-AIP, LIAT

Apple Silicon・CPUでphi-3(Phi-3-mini-4k-instruct-gguf)を動かす

はじめに

ユーフォ3期4話、めっちゃよかった。すっごいよかった😭 nikkieです

最近登場したphi-3、気になったので触りました。

目次

届いたphi-3の興奮

Llama 3が登場したばかりですが、phi-3への興奮の声を観測1

phi-1は「Textbooks Are All You Need」論文で提案されたモデルです。
それの3代目ってことなのかな(2代目も探してみなきゃ)

phi-1 is a Transformer-based model with 1.3B parameters, (略) using a selection of “textbook quality” data from the web (6B tokens) and synthetically generated textbooks and exercises with GPT-3.5 (1B tokens)

Phi-3-mini-4k-instruct-ggufを動かす

Hugging Faceを見ると、複数の方法が案内されます。

ollamaで動かす

ノーコードで動かす方法です。

macOS向けのGUIアプリケーションからコマンドラインを設定しました2
phi-3のHugging Faceページではcurlで導入する方法も案内されています。

curl -fsSL https://ollama.com/install.sh | sh
% ollama --version
ollama version is 0.1.32

https://ollama.com/library/phi3:3.8b-mini-instruct-4k-q4_K_M を指定します。
latest, 3.8b, instruct, miniというタグもありますが、ハッシュが同一なので中身は今回指定するタグと同じと思われます。

% ollama run phi3:3.8b-mini-instruct-4k-q4_K_M
>>>

(モデル(2.3GB)がダウンロードされる待ち時間がありました)

Hugging Faceの例を入れてみます。
中世の騎士にインターネットを説明すると?

>>> How to explain Internet to a medieval knight?
Lady/Sir, imagine the world you know as our kingdom.

1600文字程度出力されました。
出力は速くてすごいですね。快適です

訳した日本語も入れたところ、体感同じ速さで日本語が返ってきました
ただ読んでみるとちょっと変なところがあります(繰り返しとか、突然の英語とか、文字化けとか)

llama-cpp-pythonを使って動かす

Pythonスクリプトからも動かしてみます。
Hugging Faceのページではllama-cpp-pythonが紹介されていました。

モデルのファイルのパスを指定するようでした。
ここで「ollamaでダウンロードしているモデルが渡せるのでは?」と企みました。
ollama runのプロンプトで/show modelfileとすると、ダウンロードしたファイルがどこにあるか分かります(FROMの行)

動作環境3

% pipx run --python python3.11 ./script_llama_cpp.py

<|user|>
How to explain Internet to a medieval knight?<|end|>
<|assistant|> To explain the concept of the Internet to a medieval knight, one must use metaphors and analogies that relate to their world. Here's how you might approach it:
(略)

量子化前のモデルをtransformersで動かす

transformersでも動かしてみます4

動作環境

  • Python 3.11.8
  • transformers 4.40.1
  • PyTorch 2.3.0

% pipx run --python python3.11 ./script_transformers.py

Good morrow, noble knight. I come before thee to share knowledge of a magical realm known as the "Internet." Imagine, if thou wilt, a vast kingdom where all the wisdom of the world is stored, and it can be accessed by any person with a device, much like a scroll or tome, but far more powerful and swift.

(略)

(下で紹介するぬこぬこさんの実装を参考にしています)

積ん読:Phi-3-mini-128k-instructもすごそう

ぬこぬこさん5が試している例、few-shotで日本語を流暢に話していました

messages = [
    {"role": "system", "content": "あなたは有益なデジタルアシスタントです。ユーザーに安全で倫理的かつ正確な情報を提供してください。"},
    {"role": "user", "content": "バナナとドラゴンフルーツを組み合わせて食べる方法を教えていただけますか?"},
    {"role": "assistant", "content": "もちろんです!バナナとドラゴンフルーツを一緒に食べる方法はいくつかあります:1. バナナとドラゴンフルーツのスムージー:バナナとドラゴンフルーツをミルクとはちみつと一緒にブレンドします。2. バナナとドラゴンフルーツのサラダ:スライスしたバナナとドラゴンフルーツをレモン汁とはちみつで和えます。"},
    {"role": "user", "content": "2x + 3 = 7 の方程式を解くことについてはどうですか?"},
]

終わりに

phi-3を触りました。
量子化したモデルをollamaやllama-cpp-pythonを介して触ったときの、テキスト生成の速さはすごかったです。

アンフェアな比較かもしれないですが、1年前に触ったOpenCALMとは出力の質が違うという体感です。
すごい時代が、来てしまいました!


  1. rasbt氏は『Python機械学習プログラミング』の著者で、勝手に師だと思っています。
  2. ロゴがかわいいですよね。もふもふ
  3. PYTHONINSPECT環境変数を指定すると、pipxが仮想環境を作る箇所でハングしているように見受けられました。なんなんだろう?
  4. NLP2024チュートリアルで知ったMPSを指定してみたのですが、macOS 12では一部機能しか使えないようでOSアップデートが促されました。このあたり理解進めながら対応したいな
  5. ぬこぬこさんの最近の記事でollamaも取り上げられています

Pythonスクリプトをpipx runで実行した後に対話モードに入るには、PYTHONINSPECT環境変数を指定する

はじめに

『ぬ』という本をつくりました! nikkieです。

pipx runを使い倒していく中で見つけたtipsを取り上げます。

目次

前回:Inline script metadata(PEP 723)を一部サポートしたpipx

詳細は上の記事を見ていただきたいのですが、かいつまんでご紹介。

Pythonスクリプトの冒頭にコメントとしてメタデータを書きます。

# /// script
# dependencies = [
#   "requests<3",
#   "rich",
# ]
# ///

このスクリプトpipx run ./script.pyと実行1すると、

  • pipxが仮想環境を管理(dependenciesに挙げたライブラリをインストール)
  • この仮想環境が有効になった状態でscript.pyが実行される

つまり、このスクリプトを書いた開発者は仮想環境を一切管理しなくていいんです(python -m venvで作る必要からありません)。
pipxが仮想環境を代わりに管理してくれます。
と っ て も 便 利 !!
スクリプトを動かすために仮想環境を作る必要がなくなり、私はめちゃめちゃ捗っています。

なお、pipx runには--python引数があり、スクリプトを実行するPythonのバージョンも指定できます。

pipx runにpython -i相当の動きをさせたい

pipx runを知るまでは、仮想環境を作り、スクリプトを少し書いてはpython -iで実行して動作確認しながら進めていました。
python-iを指定すると、「スクリプトかコマンドを実行した後にインタラクティブモードに入ります。
https://docs.python.org/ja/3/using/cmdline.html#cmdoption-i

これと同じように、pipx runでもスクリプトを少し書いた後に実行して、動作確認しながら進めたいです。
その方法を調べていて見つけたのは、PYTHONINSPECT環境変数の指定

ドキュメントによると
https://docs.python.org/ja/3/using/cmdline.html#envvar-PYTHONINSPECT

この変数に空でない文字列を設定するのは -i オプションを指定するのと等価です。

-iはインスペクトモードなのですね。

例えば、以下のように実装途中のスクリプトがあるとき、

# /// script
# dependencies = [
#   "requests<3",
#   "rich",
# ]
# ///

import requests
from rich.pretty import pprint
% PYTHONINSPECT=1 pipx run ./script.py
>>> resp = requests.get("https://peps.python.org/api/peps.json")
>>> data = resp.json()
>>> pprint([(k, v["title"]) for k, v in data.items()][:3])
[
│   ('1', 'PEP Purpose and Guidelines'),
│   ('2', 'Procedure for Adding New Modules'),
│   ('3', 'Guidelines for Handling Bug Reports')
]

dependenciesに挙げたrequestsやrichがインストールされた環境で、対話モードに入っています!

動作環境

PYTHONINSPECT環境変数の指定で、なぜうまくいくのか

pipx runの実装はpythonコマンドを呼び出しているから、という理解です。

pipx runの実装は、Windowsとそれ以外で分かれていました。
https://github.com/pypa/pipx/blob/1.5.0/src/pipx/util.py#L376-L389

  • Windows:subprocess.runでpythonコマンドを呼び出す
  • Windows以外:os.execvpeでpythonコマンドにプロセスが変わる

検証

Windows機は用意できなかったのでmacOSで検証しています。
どちらの実装の場合もPYTHONINSPECT環境変数の指定で対話モードが立ち上がることを、簡単な再現実装を用意して確認しました

.
├── src/
│   └── suburi.py
└── pyproject.toml
[project]
name = "pipx-suburi"
version = "0.1.0"

[project.scripts]
pipx-suburi = "suburi:main"

os.execvpeとPYTHONINSPECT環境変数

suburi.py

import os


def main():
    print("Start")
    env = dict(os.environ)
    os.execvpe("python", ["python", "-c", "a = 1 + 2; print('Hello World')"], env)
    print("Finish")  # この行は実行されません

python -cPythonコードを渡せます。
https://docs.python.org/ja/3/using/cmdline.html#cmdoption-c

% PYTHONINSPECT=1 pipx-suburi
Start
Hello World
>>> a
3

python -cの実行(=Hello World出力)後に対話モードに入りました。
os.execvpepythonに渡したコード中の変数aが参照できます!

["python", "-i", "-c", (略)]と変えると、pipx-suburiで対話モードに入るので、PYTHONINSPECT環境変数の指定が-iとして機能しています。

仕組みとしては、PYTHONINSPECT=1 pipx-suburiと実行したとき、envPYTHONINSPECTというキーを持ちます(breakpointを張って確認)。
この環境変数の指定がpythonコマンド実行にも引き継がれているわけです。

os.execvpe(file, args, env)のドキュメントより、関数名の命名規則について
https://docs.python.org/ja/3/library/os.html#os.execvpe

  • vは可変長個の引数(argsはリストやタプル)
  • pはfileを見つけるうえで環境変数PATHを使う
  • eは辞書型のenv引数で環境変数を定義

subprocessとPYTHONINSPECT環境変数

suburi.py

import os
import sys
import subprocess


def main():
    print("Start")
    env = dict(os.environ)
    sys.exit(
        subprocess.run(
            ["python", "-c", "a = 1 + 2; print('Hello World')"],
            env=env,
            stdout=None,
            stderr=None,
            encoding="utf-8",
            universal_newlines=True,
            check=False,
        ).returncode
    )
    print("Finish")  # この行は実行されません

引数の説明はドキュメントを参照3
https://docs.python.org/ja/3/library/subprocess.html#subprocess.run

% PYTHONINSPECT=1 pipx-suburi
Start
Hello World
>>> a
3

pipx runで発生するかは未確認ですが、subprocess版の再現実装には副作用がありました。
対話モードをexit()で抜けると

>>> exit()
Traceback (most recent call last):
  File "/.../.venv/bin/pipx-suburi", line 8, in <module>
    sys.exit(main())
             ^^^^^^
  File "/.../src/suburi.py", line 16, in main
    sys.exit(
SystemExit: 0

再度対話モードに入ります(PYTHONINSPECTが指定されているから?)

>>> exit()

もう一度exit()で抜けられます

終わりに

PYTHONINSPECT環境変数を指定してpipx runすると、pipxが管理する仮想環境でpython対話モードに入れます
PEP 723のInline script metadata(のdependencies)の恩恵にあずかって仮想環境の管理から解放されつつ、その仮想環境にも対話モードでアクセスできるという、私としては願ったり叶ったりです。神!

Pythonスクリプトの開発で、開発者が仮想環境を触らなくてよいというのは私にとっては福音です。
サーバレスにならって、スクリプト開発で仮想環境レスと言えるかも(どちらも管理からの解放)。
pipx(やPEP 723をサポートするその他のツール)に寄せていきたく、引き続き探求していきます!

もし興味を持った方がいれば、ぜひお試しあれ!
共感の声、またはnikkieのユースケースほどうまくいかなかったという苦情の共有、お待ちしています

補足:pipx runの実装読みメモ


  1. pipx runがPEP 723をサポートを知った元記事によると./script.pyが必要ということなのですが、script.pyでも動くようです(宿題事項)
  2. https://formulae.brew.sh/formula/pipx
  3. このブログでは過去にsubprocess.run()を取り上げています

登壇報告 | みんなのPython勉強会#103 にてPythonで仮想環境にライブラリをインストールするんだと(ただそれだけを)話しました #stapy

はじめに

みんなのPython勉強会#103にご参加いただき、ありがとうございました。
nikkieです。

このエントリは、タイトルが全てです。

目次

みんなのPython勉強会#103

4月回の裏テーマは、PyCon Kyushu
スピーカーの方に素振りでも話したいことでも大歓迎と募ったところ、小川さんと一緒に登壇することになりました🙌

発表「Python開発環境 基礎」

connpassより

Pythonの開発環境にライブラリをインストールしてimportできる仕組みについて(ただそれだけを)話します。

お話ししたこと

  • 仮想環境とはなにか
    • アプリーケーションごとにライブラリを分ける方法
    • インストールする場所(site-packages)をアプリーケーションごとに用意する
  • pipによる開発環境と伸びしろ
    • 最初から使える!
    • 環境の再現やライブラリの管理に伸びしろがある
  • pipのペインを解消する種々のツールの(矢継ぎ早)紹介
    • Poetry, Pipenv, Hatch, PDM, Rye, uv
    • 仮想環境の管理や環境の再現(などなど)を担ってくれる

5月のPyCon Kyushuでアップデートします!

✍️4月のstapyで話した内容

Pythonのパッケージ管理の基本をおさえる」パートの

  • パッケージをインストールするとは
  • インストールしたパッケージはPCのどこにあるのか
  • 仮想環境とは
  • なぜ仮想環境が必要なのか
  • pip freezeによる環境の再現
  • この方法はPythonチュートリアルに載っているけれど、小さな課題もある

「PyCon Kyushuでは話さないこと」も、stapyで触れていました。

  • Poetry・Pipenvなどの他のツールについて

ライブラリをインストールという限られた面で、Ryeやuvも紹介しています

終わりに

みんなのPython勉強会でPythonの仮想環境についてお話ししました。
入門者向けのハンズオンだったらできない話で、Pythonを始めている人が多数という前提で、仮想環境のディレクトリの中身やsite-packagesという仕組みを覗く話をしています。

私自身はこのあたりが魔法でした。
万人には受けないかもしれないですが、過去の私に向けた突っ込んだアウトプットは価値があると信じています(私は仕組みを知ったことでPythonの力が伸びたクチです)

タイトルの「Python開発環境 基礎」、もしかすると、話題の研修資料1の影響をサブリミナルに受けたのかもしれません。

発表をご清聴いただき、ありがとうございました。

P.S. 次回5月は9周年!

畠山さんと吉田さんを迎えて、LLM特集です!!
お待ちしています!(お友達にも教えてあげてください〜)