@@ -1696,6 +1696,12 @@ class NT(NamedTuple):
16961696 y : int
16971697
16981698
1699+ skip_if_py312b1 = skipIf (
1700+ sys .version_info == (3 , 12 , 0 , 'beta' , 1 ),
1701+ "CPython had a bug in 3.12.0b1"
1702+ )
1703+
1704+
16991705class ProtocolTests (BaseTestCase ):
17001706 def test_runtime_alias (self ):
17011707 self .assertIs (runtime , runtime_checkable )
@@ -2267,10 +2273,56 @@ class Foo: ...
22672273 del f .x
22682274 self .assertNotIsInstance (f , HasX )
22692275
2270- @skipIf (
2271- sys .version_info == (3 , 12 , 0 , 'beta' , 1 ),
2272- "CPython had a bug in 3.12.0b1"
2273- )
2276+ @skip_if_py312b1
2277+ def test_runtime_checkable_generic_non_protocol (self ):
2278+ # Make sure this doesn't raise AttributeError
2279+ with self .assertRaisesRegex (
2280+ TypeError ,
2281+ "@runtime_checkable can be only applied to protocol classes" ,
2282+ ):
2283+ @runtime_checkable
2284+ class Foo (Generic [T ]): ...
2285+
2286+ def test_runtime_checkable_generic (self ):
2287+ @runtime_checkable
2288+ class Foo (Protocol [T ]):
2289+ def meth (self ) -> T : ...
2290+
2291+ class Impl :
2292+ def meth (self ) -> int : ...
2293+
2294+ self .assertIsSubclass (Impl , Foo )
2295+
2296+ class NotImpl :
2297+ def method (self ) -> int : ...
2298+
2299+ self .assertNotIsSubclass (NotImpl , Foo )
2300+
2301+ if sys .version_info >= (3 , 12 ):
2302+ exec (textwrap .dedent (
2303+ """
2304+ @skip_if_py312b1
2305+ def test_pep695_generics_can_be_runtime_checkable(self):
2306+ @runtime_checkable
2307+ class HasX(Protocol):
2308+ x: int
2309+
2310+ class Bar[T]:
2311+ x: T
2312+ def __init__(self, x):
2313+ self.x = x
2314+
2315+ class Capybara[T]:
2316+ y: str
2317+ def __init__(self, y):
2318+ self.y = y
2319+
2320+ self.assertIsInstance(Bar(1), HasX)
2321+ self.assertNotIsInstance(Capybara('a'), HasX)
2322+ """
2323+ ))
2324+
2325+ @skip_if_py312b1
22742326 def test_protocols_isinstance_generic_classes (self ):
22752327 T = TypeVar ("T" )
22762328
0 commit comments