Repository: python/mypy

Issue:
__ne__ doesn't allow returning NotImplemented
It seems that mypy doesn't allow `__ne__` returning `NotImplemented`, (this is allowed with `__eq__`).
And when I try explicitly adding `NotImplemented` as a possible return type, I get a run-time error:
```
  File ".../pod.py", line 65, in PlainOldData
    def __ne__(self, other: Any) -> Union[bool, NotImplemented]:
  File "/usr/lib/python3.6/typing.py", line 682, in inner
    return func(*args, **kwds)
  File "/usr/lib/python3.6/typing.py", line 800, in __getitem__
    parameters = tuple(_type_check(p, msg) for p in parameters)
  File "/usr/lib/python3.6/typing.py", line 800, in <genexpr>
    parameters = tuple(_type_check(p, msg) for p in parameters)
  File "/usr/lib/python3.6/typing.py", line 374, in _type_check
    raise TypeError(msg + " Got %.100r." % (arg,))
TypeError: Union[arg, ...]: each arg must be a type. Got NotImplemented.
```

If I change this to `def __ne__(self, other: Any) -> Union[bool, type(NotImplemented)]:`, then mypy complains: 
```
error: invalid type comment or annotation
note: Suggestion: use type[...] instead of type(...)
```

and when I try using this suggestion, I get a runtime error:
```
TypeError: 'type' object is not subscriptable
```

@gvanrossum  suggested (in [issue 1101](https://github.com/python/mypy/issues/1101#issuecomment-374685779)) that this was due to `__ne__` not being in `sharedparse.__MAGICMETHODS`; but it does appear to be there.



Discussion:
But it's not in `BINARY_MAGIC_METHODS`.
Oops. I'll put together a PR.

Resolving patch:
diff --git a/mypy/sharedparse.py b/mypy/sharedparse.py
--- a/mypy/sharedparse.py
+++ b/mypy/sharedparse.py
@@ -3,83 +3,39 @@
 """Shared logic between our three mypy parser files."""
 
 
-MAGIC_METHODS = {
+_NON_BINARY_MAGIC_METHODS = {
     "__abs__",
-    "__add__",
-    "__and__",
     "__call__",
-    "__cmp__",
     "__complex__",
     "__contains__",
     "__del__",
     "__delattr__",
     "__delitem__",
-    "__divmod__",
-    "__div__",
     "__enter__",
     "__exit__",
-    "__eq__",
-    "__floordiv__",
     "__float__",
-    "__ge__",
     "__getattr__",
     "__getattribute__",
     "__getitem__",
-    "__gt__",
     "__hex__",
-    "__iadd__",
-    "__iand__",
-    "__idiv__",
-    "__ifloordiv__",
-    "__ilshift__",
-    "__imod__",
-    "__imul__",
     "__init__",
     "__init_subclass__",
     "__int__",
     "__invert__",
-    "__ior__",
-    "__ipow__",
-    "__irshift__",
-    "__isub__",
     "__iter__",
-    "__ixor__",
-    "__le__",
     "__len__",
     "__long__",
-    "__lshift__",
-    "__lt__",
-    "__mod__",
-    "__mul__",
-    "__ne__",
     "__neg__",
     "__new__",
     "__nonzero__",
     "__oct__",
-    "__or__",
     "__pos__",
-    "__pow__",
-    "__radd__",
-    "__rand__",
-    "__rdiv__",
     "__repr__",
     "__reversed__",
-    "__rfloordiv__",
-    "__rlshift__",
-    "__rmod__",
-    "__rmul__",
-    "__ror__",
-    "__rpow__",
-    "__rrshift__",
-    "__rshift__",
-    "__rsub__",
-    "__rxor__",
     "__setattr__",
     "__setitem__",
     "__str__",
-    "__sub__",
     "__unicode__",
-    "__xor__",
 }
 
 MAGIC_METHODS_ALLOWING_KWARGS = {
@@ -89,8 +45,6 @@
     "__call__",
 }
 
-MAGIC_METHODS_POS_ARGS_ONLY = MAGIC_METHODS - MAGIC_METHODS_ALLOWING_KWARGS
-
 BINARY_MAGIC_METHODS = {
     "__add__",
     "__and__",
@@ -138,6 +92,12 @@
     "__xor__",
 }
 
+assert not (_NON_BINARY_MAGIC_METHODS & BINARY_MAGIC_METHODS)
+
+MAGIC_METHODS = _NON_BINARY_MAGIC_METHODS | BINARY_MAGIC_METHODS
+
+MAGIC_METHODS_POS_ARGS_ONLY = MAGIC_METHODS - MAGIC_METHODS_ALLOWING_KWARGS
+
 
 def special_function_elide_names(name: str) -> bool:
     return name in MAGIC_METHODS_POS_ARGS_ONLY


Test patch: