pyrightを使用している際に、reportMissingSuperCallが発生したので対応していました。
error: Method "__init__" does not call the method of the same name in parent class (reportMissingSuperCall)
ただし、コード上は特に何も継承していません。
class Hoge: def __init__(self, name: str): self.name = name
このエラーメッセージを対応するために調査した内容をメモします。
環境
- Python
- 3.12
原因
掲題のとおりです。Python2ではclassを作成する際に明示的にobjectを継承する必要がありましたが、Python3からは暗黙的にobjectを継承するようになりました。
# Python3の暗黙的継承 class Hoge: def __init__(self, name: str): self.name = name # Python2の明示的継承 class Hoge(object): def __init__(self, name: str): self.name = name
ただ、具体的にPython3が暗黙的にobjectを継承しているかどうかについては、ヘルプページに記載されていませんでした。私は読み取れませんでしたがChatGPTによれば、この行が暗黙的にobjectを継承していることを示しているそうです。
Pythonのヘルプページ
Classes provide a means of bundling data and functionality together. Creating a new class creates a new type of object, allowing new instances of that type to be made. Each class instance can have attributes attached to it for maintaining its state.
- Pythonのclassのヘルプページ
ChatGPTの回答
全てのクラスが object クラスから派生するというPythonのクラス理論が「暗黙的に」言及されています
この説明は、クラスがデータと機能を結びつける手段を提供し、新しいクラスの作成が新しいオブジェクトタイプの作成を可能にすること、新しいタイプのインスタンスが作れるようになること、各クラスのインスタンスが状態を維持するための属性を割り当てることが可能であることを言います。
これらの特徴は全てのPythonクラスに共通し、これらの特徴を提供するのが object クラスということになります。したがって、全てのクラスが暗黙的に object クラスを継承していると理解して間違いないです
reportMissingSuperCallの対応
__init__は継承元となったobjectにて定義されているので、エラーメッセージにしたがって素直に呼び出しましょう。
class Hoge: def __init__(self, name: str): super().__init__() self.name = name
ソースコード
ちゃんとobjectを継承していることを確認しています。なお、このテストコードで本当に検証しきれているかは自信ないです。
終わりに
基本的にどのプログラミング言語もインスタンスの同値比較をするためにequalを持つと便利であり、そのためには基底クラスとしてequalを定義したObjectを継承していることが多いということは知っていました。
ただ、Pythonではオブジェクト指向でないためか、Objectを継承しているという認識がありませんでした。
正直なところ、暗黙的な構文はpyrightにはエラー出さないで欲しいです。素直に明示的な構文だけをエラーとしてくれると非常に嬉しいのですが…。動的型付言語という性質上、難しいのかもしれません。