self.assertIsInstance(Foo(), ProtocolWithMixedMembers)
self.assertNotIsInstance(42, ProtocolWithMixedMembers)
+ def test_protocol_issubclass_error_message(self):
+ class Vec2D(Protocol):
+ x: float
+ y: float
+
+ def square_norm(self) -> float:
+ return self.x ** 2 + self.y ** 2
+
+ self.assertEqual(Vec2D.__protocol_attrs__, {'x', 'y', 'square_norm'})
+ expected_error_message = (
+ "Protocols with non-method members don't support issubclass()."
+ " Non-method members: 'x', 'y'."
+ )
+ with self.assertRaisesRegex(TypeError, re.escape(expected_error_message)):
+ issubclass(int, Vec2D)
+
class GenericTests(BaseTestCase):
not cls.__callable_proto_members_only__
and cls.__dict__.get("__subclasshook__") is _proto_hook
):
+ non_method_attrs = sorted(
+ attr for attr in cls.__protocol_attrs__
+ if not callable(getattr(cls, attr, None))
+ )
raise TypeError(
- "Protocols with non-method members don't support issubclass()"
+ "Protocols with non-method members don't support issubclass()."
+ f" Non-method members: {str(non_method_attrs)[1:-1]}."
)
if not getattr(cls, '_is_runtime_protocol', False):
raise TypeError(