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
Diff view
Prev Previous commit
Next Next commit
Simplify __hash__ and factor out orig_chain
  • Loading branch information
ilevkivskyi committed Oct 23, 2016
commit 02e6b14f522f933e18b5948976d07e627d73fb05
64 changes: 32 additions & 32 deletions src/typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,16 @@ def remove_dups(params):
return params


def _orig_chain(cls):
# Make of chain of origins (i.e. cls -> cls.__origin__)
current = cls.__origin__
orig_chain = []
while current.__origin__ is not None:
orig_chain.append(current)
current = current.__origin__
return orig_chain


def _tp_cache(func):
cached = functools.lru_cache()(func)
@functools.wraps(func)
Expand Down Expand Up @@ -686,12 +696,11 @@ def __getitem__(self, parameters):
return self.__class__(parameters, origin=self, _root=True)

def _subs_tree(self, tvars=None, args=None):
# This is an adapted equivalent of code in GenericMeta (removing duplicates).
current = self.__origin__
orig_chain = []
while current.__origin__ is not None:
orig_chain.append(current)
current = current.__origin__
# This is an adapted equivalent of code in GenericMeta,
# but removing duplicate args and flattens Union's.
if self is Union:
return (Union,)
orig_chain = _orig_chain(self)
tree_args = []
for arg in self.__args__:
tree_args.append(_replace_arg(arg, tvars, args))
Expand All @@ -701,25 +710,20 @@ def _subs_tree(self, tvars=None, args=None):
new_tree_args.append(_replace_arg(arg, cls.__parameters__,
tree_args))
tree_args = new_tree_args
tree_args = remove_dups(flat_union(tree_args))
res = ((orig_chain[-1].__origin__ if orig_chain
else self.__origin__),) + tuple(tree_args)
if len(res) == 2:
return res[1]
return res
tree_args = tuple(remove_dups(flat_union(tree_args)))
if len(tree_args) == 1:
return tree_args[0] # Union of a single type is that type
return (Union,) + tree_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 self is other
if self.__origin__:
return self._subs_tree() is other
return NotImplemented
return frozenset(self._subs_tree()) == frozenset(other._subs_tree())
return self._subs_tree() == other

def __hash__(self):
return hash((type(self).__name__,
frozenset(self._subs_tree()) if self.__origin__ else ()))
if self is Union:
return hash(frozenset((_Union,)))
return hash(frozenset(self._subs_tree()))

def __instancecheck__(self, obj):
raise TypeError("Unions cannot be used with isinstance().")
Expand Down Expand Up @@ -952,14 +956,9 @@ def _tree_repr(self, tree):
return super().__repr__() + '[%s]' % ', '.join(arg_list)

def _subs_tree(self, tvars=None, args=None):
# Construct the chain of __origin__'s.
current = self.__origin__
if current is None:
if self.__origin__ is None:
return self
orig_chain = []
while current.__origin__ is not None:
orig_chain.append(current)
current = current.__origin__
orig_chain = _orig_chain(self)
# Replace type variables in __args__ if asked ...
tree_args = ()
for arg in self.__args__:
Expand All @@ -970,18 +969,19 @@ def _subs_tree(self, tvars=None, args=None):
for i, arg in enumerate(cls.__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
return (_gorg(self),) + 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()
else:
if self.__origin__ is None or other.__origin__ is None:
return self is other
return self._subs_tree() == other._subs_tree()

def __hash__(self):
return hash((self.__name__, self._subs_tree() if self.__origin__ else ()))
if self.__origin__ is None:
return hash((self.__name__,))
return hash(self._subs_tree())

@_tp_cache
def __getitem__(self, params):
Expand Down
0