@@ -316,6 +316,12 @@ def _type_repr(obj):
316
316
317
317
318
318
class _Any (Final , metaclass = TypingMeta , _root = True ):
319
+ """Special type indicating an unconstrained type.
320
+
321
+ - Any object is an instance of Any.
322
+ - Any class is a subclass of Any.
323
+ - As a special case, Any and object are subclasses of each other.
324
+ """
319
325
320
326
def __instancecheck__ (self , obj ):
321
327
raise TypeError ("Any cannot be used with isinstance()." )
@@ -438,12 +444,64 @@ def __subclasscheck__(self, cls):
438
444
AnyStr = TypeVar ('AnyStr' , bytes , str )
439
445
440
446
441
- class UnionMeta (TypingMeta ):
442
- """Metaclass for Union."""
447
+ class _Union (Final , metaclass = TypingMeta , _root = True ):
448
+ """Union type; Union[X, Y] means either X or Y.
449
+
450
+ To define a union, use e.g. Union[int, str]. Details:
451
+
452
+ - The arguments must be types and there must be at least one.
453
+
454
+ - None as an argument is a special case and is replaced by
455
+ type(None).
456
+
457
+ - Unions of unions are flattened, e.g.::
458
+
459
+ Union[Union[int, str], float] == Union[int, str, float]
460
+
461
+ - Unions of a single argument vanish, e.g.::
462
+
463
+ Union[int] == int # The constructor actually returns int
464
+
465
+ - Redundant arguments are skipped, e.g.::
466
+
467
+ Union[int, str, int] == Union[int, str]
468
+
469
+ - When comparing unions, the argument order is ignored, e.g.::
470
+
471
+ Union[int, str] == Union[str, int]
472
+
473
+ - When two arguments have a subclass relationship, the least
474
+ derived argument is kept, e.g.::
443
475
444
- def __new__ (cls , name , bases , namespace , parameters = None , _root = False ):
476
+ class Employee: pass
477
+ class Manager(Employee): pass
478
+ Union[int, Employee, Manager] == Union[int, Employee]
479
+ Union[Manager, int, Employee] == Union[int, Employee]
480
+ Union[Employee, Manager] == Employee
481
+
482
+ - Corollary: if Any is present it is the sole survivor, e.g.::
483
+
484
+ Union[int, Any] == Any
485
+
486
+ - Similar for object::
487
+
488
+ Union[int, object] == object
489
+
490
+ - To cut a tie: Union[object, Any] == Union[Any, object] == Any.
491
+
492
+ - You cannot subclass or instantiate a union.
493
+
494
+ - You cannot write Union[X][Y] (what would it mean?).
495
+
496
+ - You can use Optional[X] as a shorthand for Union[X, None].
497
+ """
498
+
499
+ def __new__ (cls , parameters = None , _root = False ):
500
+ self = object .__new__ (cls )
445
501
if parameters is None :
446
- return super ().__new__ (cls , name , bases , namespace , _root = _root )
502
+ self .__union_params__ = None
503
+ self .__union_set_params__ = None
504
+ return self
447
505
if not isinstance (parameters , tuple ):
448
506
raise TypeError ("Expected parameters=<tuple>" )
449
507
# Flatten out Union[Union[...], ...] and type-check non-Union args.
@@ -474,11 +532,6 @@ def __new__(cls, name, bases, namespace, parameters=None, _root=False):
474
532
for t1 in params :
475
533
if t1 is Any :
476
534
return Any
477
- if isinstance (t1 , TypeVar ):
478
- continue
479
- if isinstance (t1 , _TypeAlias ):
480
- # _TypeAlias is not a real class.
481
- continue
482
535
if not isinstance (t1 , type ):
483
536
continue
484
537
if any (isinstance (t2 , type ) and issubclass (t1 , t2 )
@@ -488,7 +541,6 @@ def __new__(cls, name, bases, namespace, parameters=None, _root=False):
488
541
if len (all_params ) == 1 :
489
542
return all_params .pop ()
490
543
# Create a new class with these params.
491
- self = super ().__new__ (cls , name , bases , {}, _root = True )
492
544
self .__union_params__ = tuple (t for t in params if t in all_params )
493
545
self .__union_set_params__ = frozenset (self .__union_params__ )
494
546
return self
@@ -536,79 +588,10 @@ def __instancecheck__(self, obj):
536
588
raise TypeError ("Unions cannot be used with isinstance()." )
537
589
538
590
def __subclasscheck__ (self , cls ):
539
- if cls is Any :
540
- return True
541
- if self .__union_params__ is None :
542
- return isinstance (cls , UnionMeta )
543
- elif isinstance (cls , UnionMeta ):
544
- if cls .__union_params__ is None :
545
- return False
546
- return all (issubclass (c , self ) for c in (cls .__union_params__ ))
547
- elif isinstance (cls , TypeVar ):
548
- if cls in self .__union_params__ :
549
- return True
550
- if cls .__constraints__ :
551
- return issubclass (Union [cls .__constraints__ ], self )
552
- return False
553
- else :
554
<
236B
code> - return any (issubclass (cls , t ) for t in self .__union_params__ )
555
-
556
-
557
- class Union (Final , metaclass = UnionMeta , _root = True ):
558
- """Union type; Union[X, Y] means either X or Y.
559
-
560
- To define a union, use e.g. Union[int, str]. Details:
561
-
562
- - The arguments must be types and there must be at least one.
563
-
564
- - None as an argument is a special case and is replaced by
565
- type(None).
566
-
567
- - Unions of unions are flattened, e.g.::
568
-
569
- Union[Union[int, str], float] == Union[int, str, float]
570
-
571
- - Unions of a single argument vanish, e.g.::
572
-
573
- Union[int] == int # The constructor actually returns int
574
-
575
- - Redundant arguments are skipped, e.g.::
576
-
577
- Union[int, str, int] == Union[int, str]
578
-
579
- - When comparing unions, the argument order is ignored, e.g.::
591
+ raise TypeError ("Unions cannot be used with issubclass()." )
580
592
581
- Union[int, str] == Union[str, int]
582
-
583
- - When two arguments have a subclass relationship, the least
584
- derived argument is kept, e.g.::
585
-
586
- class Employee: pass
587
- class Manager(Employee): pass
588
- Union[int, Employee, Manager] == Union[int, Employee]
589
- Union[Manager, int, Employee] == Union[int, Employee]
590
- Union[Employee, Manager] == Employee
591
-
592
- - Corollary: if Any is present it is the sole survivor, e.g.::
593
-
594
- Union[int, Any] == Any
595
-
596
- - Similar for object::
597
-
598
- Union[int, object] == object
599
-
600
- - To cut a tie: Union[object, Any] == Union[Any, object] == Any.
601
-
602
- - You cannot subclass or instantiate a union.
603
-
604
- - You cannot write Union[X][Y] (what would it mean?).
605
-
606
- - You can use Optional[X] as a shorthand for Union[X, None].
607
- """
608
593
609
- # Unsubscripted Union type has params set to None.
610
- __union_params__ = None
611
- __union_set_params__ = None
594
+ Union (Final , metaclass = UnionMeta , _root = True ):
612
595
613
596
614
597
class OptionalMeta (TypingMeta ):
0 commit comments