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
にはエラー出さないで欲しいです。素直に明示的な構文だけをエラーとしてくれると非常に嬉しいのですが…。動的型付言語という性質上、難しいのかもしれません。