Skip to content

Corrected special attributes present in object or its direct inheritors #874

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions stdlib/2/__builtin__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -30,26 +30,27 @@ class classmethod: pass # Special, only valid as a decorator.
class object:
__doc__ = ... # type: Optional[str]
__class__ = ... # type: type
__dict__ = ... # type: Dict[str, Any]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't really correct -- object itself doesn't have __dict__ and neither do classes using __slots__.

__slots__ = ... # type: Optional[Union[str, unicode, Iterable[Union[str, unicode]]]]
__module__ = ... # type: Any

def __init__(self) -> None: ...
def __new__(cls) -> Any: ...
def __setattr__(self, name: str, value: Any) -> None: ...
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Strange you're deleting these, because object does have __eq__ and __ne__.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's true for type objects like object class, but as for object() instances I'm not sure about it:

>>> object().__eq__
Traceback (most recent call last):
  ...
AttributeError: 'object' object has no attribute '__eq__'
>>> object().__ne__
Traceback (most recent call last):
  ...
AttributeError: 'object' object has no attribute '__ne__'

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, good catch. Looks like a Python 2/3 compatibility issues -- in Python 3 they exist:

>>> object().__eq__
<method-wrapper '__eq__' of object object at 0x10062e110>

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, while the methods may not exist, the operations from which they are typically used (== and !=) do work on objects.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(And I just confirmed that mypy fails simple correct code like this:

class A: pass
A() == A()

with the error

__tmp__.py:2: error: Unsupported left operand type for == ("A")

def __eq__(self, o: object) -> bool: ...
def __ne__(self, o: object) -> bool: ...
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
def __hash__(self) -> int: ...
def __format__(self, format_spec: str) -> str: ...
def __getattribute__(self, name: str) -> Any: ...
def __delattr__(self, name: str) -> None: ...
def __sizeof__(self) -> int: ...
def __reduce__(self) -> Union[str, unicode, tuple]: ...
def __reduce_ex__(self, protocol: int) -> Union[str, unicode, tuple]: ...

class type(object):
__bases__ = ... # type: Tuple[type, ...]
__name__ = ... # type: str
__module__ = ... # type: str
__dict__ = ... # type: Dict[unicode, Any]

@overload
def __init__(self, o: object) -> None: ...
Expand Down Expand Up @@ -482,6 +483,8 @@ class tuple(Sequence[_T_co], Generic[_T_co]):
def __le__(self, x: Tuple[_T_co, ...]) -> bool: ...
def __gt__(self, x: Tuple[_T_co, ...]) -> bool: ...
def __ge__(self, x: Tuple[_T_co, ...]) -> bool: ...
def __eq__(self, x: Tuple[_T_co, ...]) -> bool: ...
def __ne__(self, x: Tuple[_T_co, ...]) -> bool: ...
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is also not strictly true -- you can write (1,) == 0 and it'll just return False.

However, there's discussion in python/mypy#1271, so I'm not sure what to do.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this issue affects other type checkers as well, not just mypy, I created a typing issue where we can discuss this: python/typing#378

def __add__(self, x: Tuple[_T_co, ...]) -> Tuple[_T_co, ...]: ...
def __mul__(self, n: int) -> Tuple[_T_co, ...]: ...
def __rmul__(self, n: int) -> Tuple[_T_co, ...]: ...
Expand Down Expand Up @@ -653,12 +656,11 @@ class xrange(Sized, Iterable[int], Reversible[int]):
def __getitem__(self, i: int) -> int: ...
def __reversed__(self) -> Iterator[int]: ...

class module:
class module(object):
__name__ = ... # type: str
__file__ = ... # type: str
__dict__ = ... # type: Dict[unicode, Any]

class property:
class property(object):
def __init__(self, fget: Callable[[Any], Any] = None,
fset: Callable[[Any, Any], None] = None,
fdel: Callable[[Any], None] = None, doc: str = None) -> None: ...
Expand Down
3 changes: 1 addition & 2 deletions stdlib/2/types.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ DictType = DictionaryType = dict
class _Cell:
cell_contents = ... # type: Any

class FunctionType:
class FunctionType(object):
func_closure = ... # type: Optional[Tuple[_Cell, ...]]
func_code = ... # type: CodeType
func_defaults = ... # type: Optional[Tuple[Any, ...]]
Expand All @@ -39,7 +39,6 @@ class FunctionType:
__closure__ = func_closure
__code__ = func_code
__defaults__ = func_defaults
__dict__ = func_dict
__globals__ = func_globals
__name__ = func_name
def __call__(self, *args: Any, **kwargs: Any) -> Any: ...
Expand Down
11 changes: 6 additions & 5 deletions stdlib/3/builtins.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -34,19 +34,20 @@ class object:
__class__ = ... # type: type
__dict__ = ... # type: Dict[str, Any]
__slots__ = ... # type: Optional[Union[str, Iterable[str]]]
__module__ = ... # type: Any

def __init__(self) -> None: ...
def __new__(cls) -> Any: ...
def __setattr__(self, name: str, value: Any) -> None: ...
def __eq__(self, o: object) -> bool: ...
def __ne__(self, o: object) -> bool: ...
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
def __hash__(self) -> int: ...
def __format__(self, format_spec: str) -> str: ...
def __getattribute__(self, name: str) -> Any: ...
def __delattr__(self, name: str) -> None: ...
def __sizeof__(self) -> int: ...
def __reduce__(self) -> Union[str, tuple]: ...
def __reduce_ex__(self, protocol: int) -> Union[str, tuple]: ...

if sys.version_info >= (3, 6):
def __init_subclass__(cls) -> None: ...
Expand All @@ -56,7 +57,6 @@ class type:
__name__ = ... # type: str
__qualname__ = ... # type: str
__module__ = ... # type: str
__dict__ = ... # type: Dict[str, Any]
__mro__ = ... # type: Tuple[type, ...]

@overload
Expand Down Expand Up @@ -499,6 +499,8 @@ class tuple(Sequence[_T_co], Generic[_T_co]):
def __le__(self, x: Tuple[_T_co, ...]) -> bool: ...
def __gt__(self, x: Tuple[_T_co, ...]) -> bool: ...
def __ge__(self, x: Tuple[_T_co, ...]) -> bool: ...
def __eq__(self, x: Tuple[_T_co, ...]) -> bool: ...
def __ne__(self, x: Tuple[_T_co, ...]) -> bool: ...
def __add__(self, x: Tuple[_T_co, ...]) -> Tuple[_T_co, ...]: ...
def __mul__(self, n: int) -> Tuple[_T_co, ...]: ...
def __rmul__(self, n: int) -> Tuple[_T_co, ...]: ...
Expand Down Expand Up @@ -673,11 +675,10 @@ class range(Sequence[int]):
def __repr__(self) -> str: ...
def __reversed__(self) -> Iterator[int]: ...

class module:
class module(object):
# TODO not defined in builtins!
__name__ = ... # type: str
__file__ = ... # type: str
__dict__ = ... # type: Dict[str, Any]

class property:
def __init__(self, fget: Callable[[Any], Any] = None,
Expand Down
1 change: 0 additions & 1 deletion stdlib/3/types.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ class FunctionType:
__closure__ = ... # type: Optional[Tuple[_Cell, ...]]
__code__ = ... # type: CodeType
__defaults__ = ... # type: Optional[Tuple[Any, ...]]
__dict__ = ... # type: Dict[str, Any]
__globals__ = ... # type: Dict[str, Any]
__name__ = ... # type: str
def __call__(self, *args: Any, **kwargs: Any) -> Any: ...
Expand Down