8000 Refactor Union, Tuple, and Callable by ilevkivskyi · Pull Request #308 · python/typing · GitHub
[go: up one dir, main page]

Skip to content

Refactor Union, Tuple, and Callable #308

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

Merged
merged 39 commits into from
Oct 29, 2016
Merged
Changes from 1 commit
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
e8c3ad6
Make Tuple[T, S] subcriptable and subclassable
ilevkivskyi Oct 23, 2016
cfcf81f
Make Callable[..., T] subscriptable and subclassable
ilevkivskyi Oct 23, 2016
1368e97
Make Union[T, S] subsctiptable
ilevkivskyi Oct 23, 2016
7ee4a1a
Disable plain Union and Optional as type arguments
ilevkivskyi Oct 23, 2016
5fdceba
Implement __eq__ for GenericMeta
ilevkivskyi Oct 23, 2016
f339586
Implement __eq__ for Unions
ilevkivskyi Oct 23, 2016
26f50a3
Refactor common code in __eq__ and __repr__
ilevkivskyi Oct 23, 2016
65de907
Remove redundant code
ilevkivskyi Oct 23, 2016
897de4e
Fix minor bugs + mini-refactoring
ilevkivskyi Oct 23, 2016
c687ffa
Fix repr of Callable subclasses
ilevkivskyi Oct 23, 2016
582a37f
Don't be too pedantic in GenericMeta._eval_type
ilevkivskyi Oct 23, 2016
02e6b14
Simplify __hash__ and factor out orig_chain
ilevkivskyi Oct 23, 2016
8d802cc
Remove outdated tests + be more pedanctic in _Union._eval_type
ilevkivskyi Oct 23, 2016
4e2527c
Add tests
ilevkivskyi Oct 23, 2016
92da67f
Factor out _subs_tree for Union and Generic
ilevkivskyi Oct 24, 2016
7563c92
Prohibit plain Generic[T] as type argument
ilevkivskyi Oct 24, 2016
f33545b
Correct a comment
ilevkivskyi Oct 24, 2016
4a996b2
Erase but preserve type also for Callable
ilevkivskyi Oct 24, 2016
6564742
Erase but preserve type for all generics
ilevkivskyi Oct 24, 2016
184f089
Restore original __next_in_mro__ and use more precise bases
Oct 24, 2016
b613325
Preserve __qualname__ on subscription
Oct 24, 2016
011b9d8
Add tests and factor common stuff for Union
ilevkivskyi Oct 24, 2016
52712a6
Add even more tests
ilevkivskyi Oct 24, 2016
2641151
One more test + minor code simplification
ilevkivskyi Oct 24, 2016
9f1fb98
Polishing code
ilevkivskyi Oct 25, 2016
279a67e
Minor changes
ilevkivskyi Oct 25, 2016
f173fde
Precalculate hash + refactor + more tests
ilevkivskyi Oct 25, 2016
819d472
Simplify repr for Union
ilevkivskyi Oct 25, 2016
e6f19a8
Add big test for __eq__, __repr__, and Any substitution
ilevkivskyi Oct 25, 2016
deed806
Add test to illustrate substitution
ilevkivskyi Oct 25, 2016
f6382a7
Minor change in tests
ilevkivskyi Oct 25, 2016
9bc7374
Add/expand comments and docstrings
ilevkivskyi Oct 25, 2016
c2724ce
Fix the __qualname__ in PY 3.2
ilevkivskyi Oct 25, 2016
fd3e344
Add tests to Python 2
ilevkivskyi Oct 25, 2016
cd7bbe2
Modify Union in Python 2
ilevkivskyi Oct 25, 2016
068ab5e
Update Python 2 tests
ilevkivskyi Oct 25, 2016
09c4797
Change remaining parts in Python 2
ilevkivskyi Oct 25, 2016
60303f7
Fix final test in PY 2
ilevkivskyi Oct 25, 2016
ea5dd05
Also call super().__init__ in PY 2 Generic
ilevkivskyi Oct 26, 2016
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
< 8000 input type="checkbox" name="w" id="whitespace-cb-lg" value="1" />
Diff view
Prev Previous commit
Next Next commit
Remove redundant code
  • Loading branch information
ilevkivskyi committed Oct 23, 2016
commit 65de9072034976cf639c2215a4f9671a814f2c1c
41 changes: 16 additions & 25 deletions src/typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -644,7 +644,7 @@ def _get_type_vars(self, tvars):
def __repr__(self):
if self.__origin__ is None:
return super().__repr__()
tree = self._subs_tree([], [])
tree = self._subs_tree()
if not isinstance(tree, tuple):
return repr(tree)
return self._tree_repr(tree)
Expand Down Expand Up @@ -680,7 +680,7 @@ def __getitem__(self, parameters):
("many" if alen > elen else "few", repr(self), alen, elen))
return self.__class__(parameters, origin=self, _root=True)

def _subs_tree(self, tvars, args):
def _subs_tree(self, tvars=None, args=None):
# This is an adapted equivalent of code in GenericMeta (removing duplicates).
current = self.__origin__
orig_chain = []
Expand All @@ -689,12 +689,12 @@ def _subs_tree(self, tvars, args):
current = current.__origin__
tree_args = []
for arg in self.__args__:
tree_args.append(_replace_arg_nos(arg, tvars, args))
tree_args.append(_replace_arg(arg, tvars, args))
tree_args = remove_dups(tree_args)
for cls in orig_chain:
new_tree_args = []
for i, arg in enumerate(cls.__args__):
new_tree_args.append(_replace_arg_nos(arg, cls.__parameters__,
new_tree_args.append(_replace_arg(arg, cls.__parameters__,
tree_args))
tree_args = remove_dups(new_tree_args)
res = ((orig_chain[-1].__origin__ if orig_chain
Expand All @@ -706,16 +706,15 @@ def _subs_tree(self, tvars, args):
def __eq__(self, other):
if isinstance(other, _Union):
if self.__origin__ and other.__origin__:
return (frozenset(self._subs_tree([], []))
== frozenset(other._subs_tree([], [])))
return frozenset(self._subs_tree()) == frozenset(other._subs_tree())
return self is other
if self.__origin__:
return self._subs_tree([], []) is other
return self._subs_tree() is other
return NotImplemented

def __hash__(self):
return hash((type(self).__name__,
frozenset(self._subs_tree([], [])) if self.__origin__ else ()))
frozenset(self._subs_tree()) if self.__origin__ else ()))

def __instancecheck__(self, obj):
raise TypeError("Unions cannot be used with isinstance().")
Expand Down Expand Up @@ -768,16 +767,8 @@ def _geqv(a, b):


def _replace_arg(arg, tvars, args):
if hasattr(arg, '_subs_repr'):
return arg._subs_repr(tvars, args)
if isinstance(arg, TypeVar):
for i, tvar in enumerate(tvars):
if arg == tvar:
return args[i]
return _type_repr(arg)


def _replace_arg_nos(arg, tvars, args):
if tvars is None:
return arg
if hasattr(arg, '_subs_tree'):
return arg._subs_tree(tvars, args)
if isinstance(arg, TypeVar):
Expand Down Expand Up @@ -946,7 +937,7 @@ def _eval_type(self, globalns, localns):
def __repr__(self):
if self.__origin__ is None:
return super().__repr__()
return self._tree_repr(self._subs_tree([], []))
return self._tree_repr(self._subs_tree())

def _tree_repr(self, tree):
arg_list = []
Expand All @@ -959,7 +950,7 @@ def _tree_repr(self, tree):
arg_list.append(arg[0]._tree_repr(arg))
return super().__repr__() + '[%s]' % ', '.join(arg_list)

def _subs_tree(self, tvars, args):
def _subs_tree(self, tvars=None, args=None):
# Construct the chain of __origin__'s.
current = self.__origin__
if current is None:
Expand All @@ -971,25 +962,25 @@ def _subs_tree(self, tvars, args):
# Replace type variables in __args__ if asked ...
tree_args = ()
for arg in self.__args__:
tree_args += (_replace_arg_nos(arg, tvars, args),)
tree_args += (_replace_arg(arg, tvars, args),)
# ... then continue replacing down the origin chain.
for cls in orig_chain:
new_tree_args = ()
for i, arg in enumerate(cls.__args__):
new_tree_args += (_replace_arg_nos(arg, cls.__parameters__, tree_args),)
new_tree_args += (_replace_arg(arg, cls.__parameters__, tree_args),)
tree_args = new_tree_args
return ((orig_chain[-1].__origin__ if orig_chain else self.__origin__),) + tree_args

def __eq__(self, other):
if not isinstance(other, GenericMeta):
return NotImplemented
if self.__origin__ is not None and other.__origin__ is not None:
return self._subs_tree([], []) == other._subs_tree([], [])
return self._subs_tree() == other._subs_tree()
else:
return self is other

def __hash__(self):
return hash((self.__name__, self._subs_tree([], []) if self.__origin__ else ()))
return hash((self.__name__, self._subs_tree() if self.__origin__ else ()))

@_tp_cache
def __getitem__(self, params):
Expand Down Expand Up @@ -1166,7 +1157,7 @@ class CallableMeta(GenericMeta):
def __repr__(self):
if self.__origin__ is None:
return super().__repr__()
return self._tree_repr(self._subs_tree([], []))
return self._tree_repr(self._subs_tree())

def _tree_repr(self, tree):
arg_list = []
Expand Down
0