diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1e72ec5..e39b81e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,11 @@
# Change Log
+## Unreleased
+
+Bugfixes
+* Don't emit Y053 for long strings inside `Literal` slices or
+ metadata strings inside `Annotated` slices.
+
## 24.6.0
Bugfixes
diff --git a/ERRORCODES.md b/ERRORCODES.md
index 5a86af6..db82bbd 100644
--- a/ERRORCODES.md
+++ b/ERRORCODES.md
@@ -66,7 +66,7 @@ The following warnings are currently emitted by default:
| Y050 | Prefer `typing_extensions.Never` over `typing.NoReturn` for argument annotations. | Style
| Y051 | Y051 detects redundant unions between `Literal` types and builtin supertypes. For example, `Literal[5]` is redundant in the union `int \| Literal[5]`, and `Literal[True]` is redundant in the union `Literal[True] \| bool`. | Redundant code
| Y052 | Y052 disallows assignments to constant values where the assignment does not have a type annotation. For example, `x = 0` in the global namespace is ambiguous in a stub, as there are four different types that could be inferred for the variable `x`: `int`, `Final[int]`, `Literal[0]`, or `Final[Literal[0]]`. Enum members are excluded from this check, as are various special assignments such as `__all__` and `__match_args__`. | Correctness
-| Y053 | Only string and bytes literals <=50 characters long are permitted. | Style
+| Y053 | Only string and bytes literals <=50 characters long are permitted. (There are some exceptions, such as `Literal` subscripts, metadata strings inside `Annotated` subscripts, and strings passed to `@deprecated`.) | Style
| Y054 | Only numeric literals with a string representation <=10 characters long are permitted. | Style
| Y055 | Unions of the form `type[X] \| type[Y]` can be simplified to `type[X \| Y]`. Similarly, `Union[type[X], type[Y]]` can be simplified to `type[Union[X, Y]]`. | Style
| Y056 | Do not call methods such as `.append()`, `.extend()` or `.remove()` on `__all__`. Different type checkers have varying levels of support for calling these methods on `__all__`. Use `+=` instead, which is known to be supported by all major type checkers. | Correctness
diff --git a/pyi.py b/pyi.py
index 88c7b8a..370d967 100644
--- a/pyi.py
+++ b/pyi.py
@@ -1563,7 +1563,8 @@ def _visit_typing_Literal(self, node: ast.Subscript) -> None:
suggestion = f"Literal[{new_literal_slice}] | None"
self.error(analysis.none_members[0], Y061.format(suggestion=suggestion))
- self.visit(node.slice)
+ with self.long_strings_allowed.enabled():
+ self.visit(node.slice)
def _visit_slice_tuple(self, node: ast.Tuple, parent: str | None) -> None:
if parent == "Union":
@@ -1573,7 +1574,7 @@ def _visit_slice_tuple(self, node: ast.Tuple, parent: str | None) -> None:
# Allow literals, except in the first argument
if len(node.elts) > 1:
self.visit(node.elts[0])
- with self.string_literals_allowed.enabled():
+ with self.string_literals_allowed.enabled(), self.long_strings_allowed.enabled():
for elt in node.elts[1:]:
self.visit(elt)
else:
diff --git a/tests/defaults.pyi b/tests/defaults.pyi
index f7c170f..30826fb 100644
--- a/tests/defaults.pyi
+++ b/tests/defaults.pyi
@@ -1,6 +1,7 @@
import math
import os
import sys
+from typing import Annotated, Literal, TypeAlias
import _typeshed
from _typeshed import SupportsRead, SupportsWrite, sentinel
@@ -84,3 +85,10 @@ def f40(x: int, /) -> None: ...
def f41(x: int, /, y: "int") -> None: ... # Y020 Quoted annotations should never be used in stubs
def f42(x: str = "y", /) -> None: ...
def f43(x: str = os.pathsep, /) -> None: ... # Y011 Only simple default values allowed for typed arguments
+
+# Long strings inside `Literal` or `Annotated` slices are okay
+def f44(x: Literal["loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"]) -> None: ...
+def f55(x: Annotated[str, "metadataaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"]) -> None: ...
+
+X: TypeAlias = Literal["llllllllllllllllllllllllllonggggggggggggggggggggggggggggggggggggggggg"]
+Y: TypeAlias = Annotated[int, "verrrrrrrrrrrrrrrrrrrry looooooooooooooongggggggggggggggggggggggggggggggggggg"]
diff --git a/tests/pep695_py312.pyi b/tests/pep695_py312.pyi
index 0832771..6bd0575 100644
--- a/tests/pep695_py312.pyi
+++ b/tests/pep695_py312.pyi
@@ -3,7 +3,16 @@
import typing
from collections.abc import Iterator
-from typing import Any, NamedTuple, NoReturn, Protocol, Self, TypedDict
+from typing import (
+ Annotated,
+ Any,
+ Literal,
+ NamedTuple,
+ NoReturn,
+ Protocol,
+ Self,
+ TypedDict,
+)
type lowercase_alias = str | int # Y042 Type aliases should use the CamelCase naming convention
type _LooksLikeATypeVarT = str | int # Y043 Bad name for a type alias (the "T" suffix implies a TypeVar)
@@ -66,3 +75,6 @@ class _UnusedPEP695Protocol[T](Protocol): # Y046 Protocol "_UnusedPEP695Protoco
class _UnusedPEP695TypedDict[T](TypedDict): # Y049 TypedDict "_UnusedPEP695TypedDict" is not used
x: T
+
+type X = Literal["Y053 will not be emitted here despite it being a very long string literal, because it is inside a `Literal` slice"]
+type Y = Annotated[int, "look at me, very long string literal, but it's okay because it's an `Annotated` metadata string"]