From b94e8084acd61f1881a4221ab8962c1a333b82c1 Mon Sep 17 00:00:00 2001 From: "Nathaniel J. Smith" Date: Wed, 6 May 2020 00:27:28 -0700 Subject: [PATCH 1/2] Better error messages from Final and NoPublicConstructor This is a pretty trivial change, but I noticed it while working on gh-1496 so I figured I'd just fix it. --- trio/_core/tests/test_run.py | 26 ++++++-------------------- trio/_util.py | 8 ++++++-- trio/tests/test_util.py | 10 +++------- 3 files changed, 15 insertions(+), 29 deletions(-) diff --git a/trio/_core/tests/test_run.py b/trio/_core/tests/test_run.py index fa399d93b4..e705af5c22 100644 --- a/trio/_core/tests/test_run.py +++ b/trio/_core/tests/test_run.py @@ -2155,11 +2155,7 @@ async def inner(): def test_Nursery_init(): - check_Nursery_error = pytest.raises( - TypeError, match='no public constructor available' - ) - - with check_Nursery_error: + with pytest.raises(TypeError): _core._run.Nursery(None, None) @@ -2170,23 +2166,17 @@ async def test_Nursery_private_init(): def test_Nursery_subclass(): - with pytest.raises( - TypeError, match='`Nursery` does not support subclassing' - ): + with pytest.raises(TypeError): class Subclass(_core._run.Nursery): pass def test_Cancelled_init(): - check_Cancelled_error = pytest.raises( - TypeError, match='no public constructor available' - ) - - with check_Cancelled_error: + with pytest.raises(TypeError): raise _core.Cancelled - with check_Cancelled_error: + with pytest.raises(TypeError): _core.Cancelled() # private constructor should not raise @@ -2199,18 +2189,14 @@ def test_Cancelled_str(): def test_Cancelled_subclass(): - with pytest.raises( - TypeError, match='`Cancelled` does not support subclassing' - ): + with pytest.raises(TypeError): class Subclass(_core.Cancelled): pass def test_CancelScope_subclass(): - with pytest.raises( - TypeError, match='`CancelScope` does not support subclassing' - ): + with pytest.raises(TypeError): class Subclass(_core.CancelScope): pass diff --git a/trio/_util.py b/trio/_util.py index b50a58036e..5940788859 100644 --- a/trio/_util.py +++ b/trio/_util.py @@ -216,7 +216,9 @@ def __new__(cls, name, bases, cls_namespace): for base in bases: if isinstance(base, Final): raise TypeError( - "`%s` does not support subclassing" % base.__name__ + "the {!r} class does not support subclassing".format( + base.__name__ + ) ) return super().__new__(cls, name, bases, cls_namespace) @@ -240,7 +242,9 @@ class SomeClass(metaclass=NoPublicConstructor): - TypeError if a sub class or an instance is created. """ def __call__(self, *args, **kwargs): - raise TypeError("no public constructor available") + raise TypeError( + "the {!r} class has no public constructor".format(self.__name__) + ) def _create(self, *args, **kwargs): return super().__call__(*args, **kwargs) diff --git a/trio/tests/test_util.py b/trio/tests/test_util.py index 90aec096b1..d9e97e949b 100644 --- a/trio/tests/test_util.py +++ b/trio/tests/test_util.py @@ -100,9 +100,7 @@ def test_final_metaclass(): class FinalClass(metaclass=Final): pass - with pytest.raises( - TypeError, match="`FinalClass` does not support subclassing" - ): + with pytest.raises(TypeError): class SubClass(FinalClass): pass @@ -112,12 +110,10 @@ def test_no_public_constructor_metaclass(): class SpecialClass(metaclass=NoPublicConstructor): pass - with pytest.raises(TypeError, match="no public constructor available"): + with pytest.raises(TypeError): SpecialClass() - with pytest.raises( - TypeError, match="`SpecialClass` does not support subclassing" - ): + with pytest.raises(TypeError): class SubClass(SpecialClass): pass From 4807db7db1a29dfbe6f35e5dc36e0511d14f444b Mon Sep 17 00:00:00 2001 From: "Nathaniel J. Smith" Date: Thu, 7 May 2020 14:31:43 -0700 Subject: [PATCH 2/2] Use fully-qualified names for even clearer error messages --- trio/_util.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/trio/_util.py b/trio/_util.py index 5940788859..4236d4f8cb 100644 --- a/trio/_util.py +++ b/trio/_util.py @@ -216,9 +216,7 @@ def __new__(cls, name, bases, cls_namespace): for base in bases: if isinstance(base, Final): raise TypeError( - "the {!r} class does not support subclassing".format( - base.__name__ - ) + f"{base.__module__}.{base.__qualname__} does not support subclassing" ) return super().__new__(cls, name, bases, cls_namespace) @@ -243,7 +241,7 @@ class SomeClass(metaclass=NoPublicConstructor): """ def __call__(self, *args, **kwargs): raise TypeError( - "the {!r} class has no public constructor".format(self.__name__) + f"{self.__module__}.{self.__qualname__} has no public constructor" ) def _create(self, *args, **kwargs):