5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Python】エラーに関するドキュメントがないことに耐えられなかったので`cpython`にコントリビュートしたら、プロダクションコードも変更することになったお話

Posted at

きっかけ

私は以前、Pythonの各ライブラリ型情報をまとめているtypeshedに、ctypesの内部実装_ctypesに定義された_ctypes.COMErrorの型情報を追加するPRをopenしてmergeされました。

このCOMErrorは発生時スタックトレースに現れてキャッチされなければシステムを停止させる例外、つまり事実上パブリックな例外であるにも関わらず、どのような理由でエラーが起きるのか、エラーの各属性が何を意味するかなどはドキュメントで言及されておらず、仕様が不明瞭なものでした。

公式のドキュメントが存在しないことにより、この例外は私がメンテナンスしているcomtypesのカスタム例外であると勘違いされることが多く、似通った内容のIssueがopenして質問と回答が繰り返され、メンテナーやコミュニティが疲弊する要素の一つとなっていました。

この状況を改善すべく、私はPythonのドキュメントに_ctypes.COMErrorに関する記述を追加しようと考えました。

_ctypes.COMErrorとは

COMErrorは、Pythonのctypesモジュールを使用してCOM (Component Object Model) オブジェクトと連携する際に発生するエラーです。

COMErrorは、COM関連のエラー情報を保持するためのいくつかのフィールドを持っています。

  • hresult: COMメソッドの実行結果を示す数値コードであるHRESULT値を表します
  • text: エラーメッセージ
  • details: 長さ5で構成されるタプルです
    • インデックス0: descr。テキストによる説明
    • インデックス1: source。エラーを発生させたクラスまたはアプリケーションの(言語依存の)ProgID
    • インデックス2: helpfile。ヘルプファイルのパス
    • インデックス3: helpcontext。ヘルプコンテキストの識別子
    • インデックス4: progid。エラーを定義したインターフェースのProgID

これらのフィールドを通じて、COMエラーの詳細な情報を取得し、エラーの原因を特定することができます。

OSErrorとの違い

COMメソッドの定義方法によっては、OSErrorCOMErrorの代わりに投げられることがあります。
OSErrorは、オペレーティングシステムに関連するエラー、例えばファイルが見つからない、ネットワークに接続できないなどの場合に発生します。

ctypesでCOMオブジェクトのメソッドを呼び出す際、PYFUNCTYPEを使って関数プロトタイプを作成し、そのプロトタイプからメソッド呼び出しを行うための関数を生成します。
プロトタイプから関数を生成する際にIID(COMインターフェースを一意に識別するためのGUID(Globally Unique Identifier))を指定しなければ、COMErrorOSErrorの代わりに投げられます。

PR mergeまでの顛末

まず、私はPythonのIssueトラッカーにCOMErrorに関するドキュメントを追加したい旨を報告しました。

しかし、Issueではあまり議論は起こりませんでした。そこで、私は反対意見がないものと判断し、プロダクションコードを変更することなくドキュメントだけを変更するPull Requestを送りました。

すると、PRを提出してから議論が始まりました。議論の中で他の開発者から「"プライベート"な要素に対してドキュメントを追加するだけでなく、COMErrorctypesへインポートしてパブリックにした方がいい」という提案があり、私もその提案に賛同しました。

Pull Requestは、他の開発者によるレビューを経て、最終的にmergeされました。

現在の状況

現在では、ctypes.COMErrorとしてこのエラーはパブリックになり、Pythonのドキュメントにもctypes.COMErrorに関する記述が追加されました。

Python 3.14ベータ版も2025/4/7にリリースされたため、特に問題がなければファイナルリリースにも上記は含まれる予定です。

その後

この件を通じて、私はOSSへのコントリビューションの難しさ、そして楽しさを学びました。

当初はドキュメントの追加だけで良いと考えていましたが、他の開発者との議論を通じて、より良い解決策を見つけることができました。

また、Pull Requestを送る際には、コードの品質だけでなく、ドキュメントの整備やテストの追加なども行う必要があり、OSSへのコントリビューションは簡単なことでもありません。

しかし、自分の書いたコードがPythonのプロダクションコードとなり、多くのユーザーが利用するようになるのは、非常にやりがいのある経験でした。

この記事が、OSSへのコントリビューションに興味を持つ方にとって、少しでも参考になれば幸いです。

5
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?