From 728da9c1ba7fa2a6eb3442eb599d0b38e6529492 Mon Sep 17 00:00:00 2001 From: Xavier Francisco <98830734+XF-FW@users.noreply.github.com> Date: Wed, 4 Jan 2023 11:57:42 -0100 Subject: [PATCH] [Fix] Allow StrPromise to be used in exceptions (#297) Co-authored-by: Xavier Francisco --- rest_framework-stubs/exceptions.pyi | 3 ++- scripts/typecheck_tests.py | 6 +++--- tests/typecheck/test_exceptions.yml | 9 +++++++++ 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/rest_framework-stubs/exceptions.pyi b/rest_framework-stubs/exceptions.pyi index 7dcaf8f57..9af1352f3 100644 --- a/rest_framework-stubs/exceptions.pyi +++ b/rest_framework-stubs/exceptions.pyi @@ -4,6 +4,7 @@ from typing import Any from typing_extensions import TypeAlias from django.http import HttpRequest, JsonResponse +from django_stubs_ext import StrOrPromise from rest_framework.renderers import BaseRenderer from rest_framework.request import Request @@ -15,7 +16,7 @@ class ErrorDetail(str): code: str | None def __new__(cls, string: str, code: str | None = ...): ... -_Detail: TypeAlias = str | list[Any] | dict[str, Any] +_Detail: TypeAlias = StrOrPromise | list[Any] | dict[str, Any] class APIException(Exception): status_code: int diff --git a/scripts/typecheck_tests.py b/scripts/typecheck_tests.py index 2e05a5f7b..0eac263b2 100644 --- a/scripts/typecheck_tests.py +++ b/scripts/typecheck_tests.py @@ -106,7 +106,7 @@ "Dict entry", '"FieldValues"', 'base class "Field" defined the type as "bool"', - 'Invalid index type "int" for "Union[str, List[Any], Dict[str, Any]]"; expected type "str"', + 'Invalid index type "int" for "Union[str, _StrPromise, List[Any], Dict[str, Any]]"; expected type "str"', 'Item "str" of "Union[str, Any]" has no attribute "code"', 'Argument "default" to "CharField" has incompatible type', '"MultipleChoiceField" has no attribute "partial"', @@ -152,7 +152,7 @@ 'Cannot assign multiple types to name "composed_perm" without an explicit "Type[...]" annotation', ], "test_relations.py": [ - 'Invalid index type "int" for "Union[str, List[Any], Dict[str, Any]]"; expected type "str"', + 'Invalid index type "int" for "Union[str, _StrPromise, List[Any], Dict[str, Any]]"; expected type "str"', 'Argument "queryset" to "HyperlinkedRelatedField" has incompatible type', 'Incompatible return value type (got "None", expected "HttpResponseBase', 'Argument 2 to "re_path" has incompatible type "Callable[[], None]"; expected "Callable[..., HttpResponseBase]"', # noqa: E501 @@ -217,7 +217,7 @@ 'Argument 1 to "to_internal_value" of "Field" has incompatible type "object"', ], "test_validation_error.py": [ - 'Argument "detail" to "ValidationError" has incompatible type "Tuple[str, str]"; expected "Optional[Union[str, List[Any], Dict[str, Any]]]"', # noqa: E501 + 'Argument "detail" to "ValidationError" has incompatible type "Tuple[str, str]"; expected "Optional[Union[Union[str, _StrPromise], List[Any], Dict[str, Any]]]"', # noqa: E501 ], "test_validators.py": [ 'Argument "queryset" to "BaseUniqueForValidator" has incompatible type "object";' diff --git a/tests/typecheck/test_exceptions.yml b/tests/typecheck/test_exceptions.yml index 0c1a4704e..c17849318 100644 --- a/tests/typecheck/test_exceptions.yml +++ b/tests/typecheck/test_exceptions.yml @@ -15,3 +15,12 @@ status_code = 200 default_detail = {"ok": "everything"} default_code = "ok" +- case: test_exception_declaration_lazystr + main: | + from django.utils.translation import gettext_lazy as _ + from rest_framework import exceptions + + class MyException(exceptions.APIException): + status_code = 200 + default_detail = _("Está tudo bem") + default_code = "ok"