flask-sqlalchemy で pyright 用のスタブファイルを作成してみた
概要
flask-sqlalchemy + pyright を使っているとデータベースのモデルからインスタンスを生成する際に pyright のエラーになります
回避方法はいろいろありますが今回は pyright 用のスタブ情報を手動で作成することで対応してみました
環境
Python 3.12.9
flask-sqlalchemy 3.1.1
pyright 1.1.396
エラーの出るファイル
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy( )
class User ( db. Model) :
id = db. Column( db. Integer, primary_key= True )
name = db. Column( db. String( 80 ) , nullable= False )
user = User( id = 1 , name= "Alice" )
これで pyright を実行すると以下のえらーになります
これをスタブを作成することで回避します
pipenv run pyright my_libs/schema.py
/path/to/my_libs/schema.py
/path/to/my_libs/schema.py:12:13 - error: No parameter named "id" (reportCallIssue)
/path/to/my_libs/schema.py:12:19 - error: No parameter named "name" (reportCallIssue)
2 errors, 0 warnings, 0 informations
スタブファイルの自動生成
これで typings 配下に以下のファイルが自動で生成されます
ls -ltR typings
total 0
drwxr-xr-x 12 user01 staff 384 3 18 10:22 flask_sqlalchemy
typings/flask_sqlalchemy:
total 120
-rw-r--r-- 1 user01 staff 171 3 18 10:22 track_modifications.pyi
-rw-r--r-- 1 user01 staff 710 3 18 10:22 table.pyi
-rw-r--r-- 1 user01 staff 1428 3 18 10:22 session.pyi
-rw-r--r-- 1 user01 staff 1870 3 18 10:22 record_queries.pyi
-rw-r--r-- 1 user01 staff 3024 3 18 10:22 query.pyi
-rw-r--r-- 1 user01 staff 5279 3 18 10:22 pagination.pyi
-rw-r--r-- 1 user01 staff 5297 3 18 10:22 model.pyi
-rw-r--r-- 1 user01 staff 14197 3 18 10:22 extension.pyi
-rw-r--r-- 1 user01 staff 321 3 18 10:22 cli.pyi
-rw-r--r-- 1 user01 staff 180 3 18 10:22 __init__.pyi
動作確認
スタブファイルを作成した状態で再度 pyright を実行しましょう
先のほどまで出ていた No parameter named "name" などのエラーが出ないことが確認できると思います
おまけ: その他の解決方法
__init__ メソッドを User モデルクラスに実装する
この方法でも pyright のエラー自体は出なくなりますがコンストラクタを生成することで初期化時の処理が変わる可能性があるのであまりおすすめはしないです
dict を使い変数展開する
User 生成時にキーワード引数ではなく辞書の展開を使ってもエラーを回避できます
params = {
"id" : 1 ,
"name" : "hawk"
}
user = User( ** params)
最後に
flask-sqlalchemy の pyright エラーに対応してみました
typings/ ディレクトリは今回は自動生成しているので git には含めないほうがいいです
手動で作成している場合は含めたほうがいいです
CI などで typings が必要な場合は毎回生成してあげるようにしましょう
おまけ: スタブファイルの手動作成(失敗編)
以下試したけどダメだったパターンです
スタブファイルはプロジェクトルートの typings というディレクトリ配下に作成します
またパッケージの階層も同じにする必要がありかつファイル名は pyi ファイルにします
mkdir typings
mkdir typings/my_libs
vim typings/my_libs/schema.pyi
from flask_sqlalchemy import SQLAlchemy
db: SQLAlchemy
class User ( ) :
id : int
name: str
def __init__ ( self, id : int , name: str ) - > None : . . .