Skip to content

Commit 2d6f3dd

Browse files
committed
change behavior of Union w.r.t. Any; update docstrings
1 parent 2b828f1 commit 2d6f3dd

File tree

4 files changed

+20
-58
lines changed

4 files changed

+20
-58
lines changed

python2/test_typing.py

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -201,10 +201,6 @@ def test_subclass_error(self):
201201
def test_union_any(self):
202202
u = Union[Any]
203203
self.assertEqual(u, Any)
204-
u = Union[int, Any]
205-
self.assertEqual(u, Any)
206-
u = Union[Any, int]
207-
self.assertEqual(u, Any)
208204

209205
def test_union_object(self):
210206
u = Union[object]
@@ -214,12 +210,6 @@ def test_union_object(self):
214210
u = Union[object, int]
215211
self.assertEqual(u, object)
216212

217-
def test_union_any_object(self):
218-
u = Union[object, Any]
219-
self.assertEqual(u, Any)
220-
u = Union[Any, object]
221-
self.assertEqual(u, Any)
222-
223213
def test_unordered(self):
224214
u1 = Union[int, float]
225215
u2 = Union[float, int]

python2/typing.py

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -431,9 +431,13 @@ def __new__(cls, name, bases, namespace):
431431
class _Any(_FinalTypingBase):
432432
"""Special type indicating an unconstrained type.
433433
434-
- Any object is an instance of Any.
435-
- Any class is a subclass of Any.
436-
- As a special case, Any and object are subclasses of each other.
434+
- Any is compatible with every type.
435+
- Any assumed to have all methods.
436+
- All values assumed to be instances of Any.
437+
438+
Note that all the above statements are true from the point of view of
439+
static type checkers. At runtime, Any should not be used with instance
440+
or class checks.
437441
"""
438442
__metaclass__ = AnyMeta
439443
__slots__ = ()
@@ -602,16 +606,6 @@ class Manager(Employee): pass
602606
Union[Manager, int, Employee] == Union[int, Employee]
603607
Union[Employee, Manager] == Employee
604608
605-
- Corollary: if Any is present it is the sole survivor, e.g.::
606-
607-
Union[int, Any] == Any
608-
609-
- Similar for object::
610-
611-
Union[int, object] == object
612-
613-
- To cut a tie: Union[object, Any] == Union[Any, object] == Any.
614-
615609
- You cannot subclass or instantiate a union.
616610
617611
- You cannot write Union[X][Y] (what would it mean?).
@@ -650,14 +644,11 @@ def __new__(cls, parameters=None, *args, **kwds):
650644
assert not all_params, all_params
651645
# Weed out subclasses.
652646
# E.g. Union[int, Employee, Manager] == Union[int, Employee].
653-
# If Any or object is present it will be the sole survivor.
654-
# If both Any and object are present, Any wins.
655-
# Never discard type variables, except against Any.
647+
# If object is present it will be sole survivor among proper classes.
648+
# Never discard type variables.
656649
# (In particular, Union[str, AnyStr] != AnyStr.)
657650
all_params = set(params)
658651
for t1 in params:
659-
if t1 is Any:
660-
return Any
661652
if not isinstance(t1, type):
662653
continue
663654
if any(isinstance(t2, type) and issubclass(t1, t2)
@@ -730,7 +721,7 @@ def __new__(cls, name, bases, namespace):
730721
class _Optional(_FinalTypingBase):
731722
"""Optional type.
732723
733-
Optional[X] is equivalent to Union[X, type(None)].
724+
Optional[X] is equivalent to Union[X, None].
734725
"""
735726

736727
__metaclass__ = OptionalMeta

src/test_typing.py

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -202,10 +202,6 @@ def test_subclass_error(self):
202202
def test_union_any(self):
203203
u = Union[Any]
204204
self.assertEqual(u, Any)
205-
u = Union[int, Any]
206-
self.assertEqual(u, Any)
207-
u = Union[Any, int]
208-
self.assertEqual(u, Any)
209205

210206
def test_union_object(self):
211207
u = Union[object]
@@ -215,12 +211,6 @@ def test_union_object(self):
215211
u = Union[object, int]
216212
self.assertEqual(u, object)
217213

218-
def test_union_any_object(self):
219-
u = Union[object, Any]
220-
self.assertEqual(u, Any)
221-
u = Union[Any, object]
222-
self.assertEqual(u, Any)
223-
224214
def test_unordered(self):
225215
u1 = Union[int, float]
226216
u2 = Union[float, int]

src/typing.py

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -378,9 +378,13 @@ def _type_repr(obj):
378378
class _Any(_FinalTypingBase, _root=True):
379379
"""Special type indicating an unconstrained type.
380380
381-
- Any object is an instance of Any.
382-
- Any class is a subclass of Any.
383-
- As a special case, Any and object are subclasses of each other.
381+
- Any is compatible with every type.
382+
- Any assumed to have all methods.
383+
- All values assumed to be instances of Any.
384+
385+
Note that all the above statements are true from the point of view of
386+
static type checkers. At runtime, Any should not be used with instance
387+
or class checks.
384388
"""
385389

386390
__slots__ = ()
@@ -545,16 +549,6 @@ class Manager(Employee): pass
545549
Union[Manager, int, Employee] == Union[int, Employee]
546550
Union[Employee, Manager] == Employee
547551
548-
- Corollary: if Any is present it is the sole survivor, e.g.::
549-
550-
Union[int, Any] == Any
551-
552-
- Similar for object::
553-
554-
Union[int, object] == object
555-
556-
- To cut a tie: Union[object, Any] == Union[Any, object] == Any.
557-
558552
- You cannot subclass or instantiate a union.
559553
560554
- You cannot write Union[X][Y] (what would it mean?).
@@ -592,14 +586,11 @@ def __new__(cls, parameters=None, *args, _root=False):
592586
assert not all_params, all_params
593587
# Weed out subclasses.
594588
# E.g. Union[int, Employee, Manager] == Union[int, Employee].
595-
# If Any or object is present it will be the sole survivor.
596-
# If both Any and object are present, Any wins.
597-
# Never discard type variables, except against Any.
589+
# If object is present it will be sole survivor among proper classes.
590+
# Never discard type variables.
598591
# (In particular, Union[str, AnyStr] != AnyStr.)
599592
all_params = set(params)
600593
for t1 in params:
601-
if t1 is Any:
602-
return Any
603594
if not isinstance(t1, type):
604595
continue
605596
if any(isinstance(t2, type) and issubclass(t1, t2)
@@ -665,7 +656,7 @@ def __subclasscheck__(self, cls):
665656
class _Optional(_FinalTypingBase, _root=True):
666657
"""Optional type.
667658
668-
Optional[X] is equivalent to Union[X, type(None)].
659+
Optional[X] is equivalent to Union[X, None].
669660
"""
670661

671662
__slots__ = ()

0 commit comments

Comments
 (0)