2021年6月20日日曜日

11: 'typeshed'レポジトリ内のmypyスタブを訂正する

<このシリーズの前の記事 | このシリーズの目次 |

'typeshed'レポジトリ内に誤りがあるかもしれません。それらを訂正する方法がここにあります。

話題


About: Pythonプログラミング言語
About: mypy

この記事の目次


開始コンテキスト


  • 読者は、Pythonプログラミング言語の基本的知識を持っている。
  • 読者は、mypyの基本的知識を持っている。

ターゲットコンテキスト



  • 読者は、'typeshed'レポジトリ内のmypyスタブを訂正する方法を知る

オリエンテーション


Pythonにてスタティックタイプチェックをmypyを用いて行なう最小限充分テクニックが、ある以前の記事にて紹介されています


本体


1: 'memoryview'のスタブが誤っているらしい、mypy 0.782現在


Hypothesizer 7
以下のコードは、mypy 0.782によってエラー判定される。

@Python ソースコード

class ClassA:
	def methodA (a_this: "ClassA", a_memoryView: memoryview) -> None:
		a_memoryView [0] = 1


メッセージは以下のものだ。

@出力
error: No overload variant of "__setitem__" of "memoryview" matches argument types "int", "int"
note: Possible overload variants:
note:     def __setitem__(self, slice, memoryview) -> None
note:     def __setitem__(self, int, bytes) -> None
note:     def __setitem__(self, slice, Sequence[bytes]) -> None

. . . 本当に?

'def __setitem__(self, int, bytes) -> None'は、私には妙に思える: 第2引数は、データ(第3引数にポイントされる)が入れられる箇所のインデックスであるはずだが、第3引数は、'bytes'であるべきなのか?その構文は、'a_memoryView [0] = b'ABC''のようなコードを広めようとしているが、それは、勿論、ランタイムエラーを引き起こすだろう。

'__setitem__(self, int, int)'が許されるべきだと私は考える。


2: 誤りがそこに入り込む可能性がある、その理由は . . .


Hypothesizer 7
誤りが'typeshed'レポジトリに入り込む可能性があるが、その理由は、そこのスタブ群は手製の後付けであることだ: それらは、ソースコードの一部ではなく、ソースコードから確定的に導出されたものでもない。


3: スタブを、上書きするスタブファイルを追加することで訂正する方法はないようだ


Hypothesizer 7
私の第1期待は、'typeshed'レポジトリに優先する正しいスタブファイルを恣意的な場所に追加できるのではないかということだった。

その方法であれば、正しいスタブを私のプロジェクトと一緒に配布できるだろう。

残念ながら、それは許されていないようだ。


4: 1つの方法: 問題のスタブファイルを直接に訂正する


Hypothesizer 7
問題のスタブファイルは、Pythonプロダクトディレクトリ内の'Lib/site-packages/mypy/typeshed'配下のテキストファイルであるので、そのファイルを直接に訂正することができる。

'memoryview'の場合、ファイルは'stdlib/2and3/builtins.pyi'である。

その方法の不利な点は、各開発環境を個別に訂正しなければならないことだ。


5: 別の方法: カスタム'typeshed'レポジトリを持つこと


Hypothesizer 7
デフォルト'typeshed'レポジトリを、恣意的な場所に追加されたファイルで上書きすることはできないが、デフォルト'typeshed'レポジトリ全体を、あるカスタム'typeshed'レポジトリ全体で置き換えることはできる。

私が行わなければならないことは、デフォルト'typeshed'レポジトリディレクトリをどこか(それがカスタム'typeshed'レポジトリディレクトリである)にコピーし、そのカスタム'typeshed'レポジトリディレクトリ配下の一部のスタブファイルを訂正し、そのカスタム'typeshed'レポジトリディレクトリを'mypy'コマンド中の'--custom-typeshed-dir'フラグで指定することである。

その方法の有利な点は、カスタム'typeshed'レポジトリを私のプロジェクトと一緒に配布できる(私のビルドスクリプトは自動的にそのカスタム'typeshed'レポジトリを使用する)ということだ。

その方法の不利な点は、そのカスタム'typeshed'レポジトリのアップデートをmypyのアップデートに合わせて維持しなければならないことだ。


6: 私のケースのためのあるダーティーな回避策


Hypothesizer 7
実のところ、私の実際のケースは、クリップボード操作のために'wx.DataObject'サブクラスを作成したときのものだった: 'GetDataHere'メソッドが'memoryview'引数を取る。

私のダーティーな回避策は、'bytearray'を'memoryview'の代わりにそこのタイプアノテーションとして使うことだが、それが機能するのは、wxPythonがmypyチェックから除外されている(wxPythonはスタブを提供していないから)ことがあるからに過ぎない。

または、より望ましくない回避策は、'Any'タイプを使うことだ、その引数へのタイプチェックを無効化して。


参考資料


<このシリーズの前の記事 | このシリーズの目次 |