2016-05-31 4 views
5

私はPython 3.5.1と新しくリリースされたMyPy v0.4.1静的型アナライザを使用しています。__eq__の引数型を定義するとMyPy型のエラーが発生するのはなぜですか?

test.py: note: In class "MyObject": 
test.py:5: error: Argument 1 of "__eq__" incompatible with supertype "object" 
mypy test.py次のエラーが生成型チェッカー実行

class MyObject(object): 
    def __init__(self, value: int=5) -> None: 
     self.value = value 

    def __eq__(self, other: MyObject) -> bool: 
     return self.value == other.value 

は、私はエラーを再現するために必要な、この最も簡単なPythonクラスにまで減少してきたいくつかのより複雑なコードを持っています

私の理論はthese docsに基づいています。オブジェクトの__eq____neq__にはすでに定義された型があり、これらはサブクラスのこれらの型の再定義と衝突します。私の質問は、__eq__が私の選択したタイプでタイプチェックされていることを確認するためにこれらのタイプを定義する方法です。

答えて

4

==は、あなたのタイプのオブジェクトだけでなく、任意の他のオブジェクトを使用することになっています。それは他のオブジェクトを認識しない場合、それはNotImplementedを返す必要があります:

class MyObject(object): 
    def __init__(self, value: int=5) -> None: 
     self.value = value 

    def __eq__(self, other: object) -> bool: 
     if not isinstance(other, MyObject): 
      return NotImplemented 
     return self.value == other.value 

をまた、あなたは自身の身体の内側型ヒントをMyObjectを参照する必要がある場合、あなたは、'MyObject'代わりMyObjectの文字列を使用する必要があります。 MyObjectはまだ存在しません。

+0

Re:自分の体の中の「MyObject」を参照すると、引用符を使わずにコード内のどこかで行っています。私はMyPyからエラーを受け取りません:https://github.com/pirate/py-data/blob/ master/recursive_descent_parser.py#L78 –

+1

@NickSweeting:あなたはそれを実行しましたか? [あなたがそれを実行しようとするとエラーが発生するはずです] – user2357112

+0

ああ、thanks @ user2357112、私はそれを試してみて、実際にはそれを無視してしまいました。それを文字列に変更しました。 –

2

あなたのドキュメントの読解は正しいです - 方法(__eq__)に、既に基底クラス(object)にあるものと同じ署名を与える必要があります。

その理由は、あなたのMyObjectobjectのサブタイプであるため、MyObjectは、そのコードが他のobjectとそれを比較することができることを意味している... objectを期待しているどこにでも渡すことができ、かつ正当な方法はありませんということです型チェッカーが不平を言うために。そのため、あなたの__eq__には、objectが必要です。あなたは何ができるか

タイプをチェックして返す(または例外を送出)、メソッドのボディに右フロント次第です:

if not isinstance(other, MyObject): 
    return False 

はその後those docs sayとして、Mypyはそのチェックの後に十分なスマートです、それはotherMyObjectであることを認識し、それに従って処理します。

関連する問題