File tree Expand file tree Collapse file tree 5 files changed +56
-2
lines changed Expand file tree Collapse file tree 5 files changed +56
-2
lines changed Original file line number Diff line number Diff line change 1
- # Unreleased
1
+ # Release 4.15.0rc1 (August 18, 2025)
2
2
3
+ - Add the ` @typing_extensions.disjoint_base ` decorator, as specified
4
+ in PEP 800. Patch by Jelle Zijlstra.
3
5
- Add ` typing_extensions.type_repr ` , a backport of
4
6
[ ` annotationlib.type_repr ` ] ( https://docs.python.org/3.14/library/annotationlib.html#annotationlib.type_repr ) ,
5
7
introduced in Python 3.14 (CPython PR [ #124551 ] ( https://github.com/python/cpython/pull/124551 ) ,
Original file line number Diff line number Diff line change @@ -705,6 +705,17 @@ Decorators
705
705
Inheriting from a deprecated class now also raises a runtime
706
706
:py:exc: `DeprecationWarning `.
707
707
708
+ .. decorator :: disjoint_base
709
+
710
+ See :pep: `800 `. A class decorator that marks a class as a "disjoint base", meaning that
711
+ child classes of the decorated class cannot inherit from other disjoint bases that are not
712
+ parent classes of the decorated class.
713
+
714
+ This helps type checkers to detect unreachable code and to understand when two types
715
+ can overlap.
716
+
717
+ .. versionadded :: 4.15.0
718
+
708
719
.. decorator :: final
709
720
710
721
See :py:func: `typing.final ` and :pep: `591 `. In ``typing `` since 3.8.
Original file line number Diff line number Diff line change @@ -6,7 +6,7 @@ build-backend = "flit_core.buildapi"
6
6
# Project metadata
7
7
[project ]
8
8
name = " typing_extensions"
9
- version = " 4.14.1 "
9
+ version = " 4.15.0rc1 "
10
10
description = " Backported and Experimental Type Hints for Python 3.9+"
11
11
readme = " README.md"
12
12
requires-python = " >=3.9"
Original file line number Diff line number Diff line change 84
84
clear_overloads ,
85
85
dataclass_transform ,
86
86
deprecated ,
87
+ disjoint_base ,
87
88
evaluate_forward_ref ,
88
89
final ,
89
90
get_annotations ,
@@ -6670,6 +6671,18 @@ def cached(self): ...
6670
6671
self .assertIs (True , Methods .cached .__final__ )
6671
6672
6672
6673
6674
+ class DisjointBaseTests (BaseTestCase ):
6675
+ def test_disjoint_base_unmodified (self ):
6676
+ class C : ...
6677
+ self .assertIs (C , disjoint_base (C ))
6678
+
6679
+ def test_dunder_disjoint_base (self ):
6680
+ @disjoint_base
6681
+ class C : ...
6682
+
6683
+ self .assertIs (C .__disjoint_base__ , True )
6684
+
6685
+
6673
6686
class RevealTypeTests (BaseTestCase ):
6674
6687
def test_reveal_type (self ):
6675
6688
obj = object ()
Original file line number Diff line number Diff line change 71
71
'clear_overloads' ,
72
72
'dataclass_transform' ,
73
73
'deprecated' ,
74
+ 'disjoint_base' ,
74
75
'Doc' ,
75
76
'evaluate_forward_ref' ,
76
77
'get_overloads' ,
@@ -321,6 +322,33 @@ class Other(Leaf): # Error reported by type checker
321
322
return f
322
323
323
324
325
+ if hasattr (typing , "disjoint_base" ): # 3.15
326
+ disjoint_base = typing .disjoint_base
327
+ else :
328
+ def disjoint_base (cls ):
329
+ """This decorator marks a class as a disjoint base.
330
+
331
+ Child classes of a disjoint base cannot inherit from other disjoint bases that are
332
+ not parent classes of the disjoint base.
333
+
334
+ For example:
335
+
336
+ @disjoint_base
337
+ class Disjoint1: pass
338
+
339
+ @disjoint_base
340
+ class Disjoint2: pass
341
+
342
+ class Disjoint3(Disjoint1, Disjoint2): pass # Type checker error
343
+
344
+ Type checkers can use knowledge of disjoint bases to detect unreachable code
345
+ and determine when two types can overlap.
346
+
347
+ See PEP 800."""
348
+ cls .__disjoint_base__ = True
349
+ return cls
350
+
351
+
324
352
def IntVar (name ):
325
353
return typing .TypeVar (name )
326
354
You can’t perform that action at this time.
0 commit comments