Skip to content

Commit 32675dd

Browse files
ilevkivskyihauntsaninja
authored andcommitted
Revert "Fix Literal strings containing pipe characters" (#17638)
Reverts #17148 (cherry picked from commit bc39f17)
1 parent 778542b commit 32675dd

15 files changed

+90
-142
lines changed

mypy/fastparse.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,14 @@ def parse_type_string(
329329
"""
330330
try:
331331
_, node = parse_type_comment(f"({expr_string})", line=line, column=column, errors=None)
332-
return RawExpressionType(expr_string, expr_fallback_name, line, column, node=node)
332+
if isinstance(node, UnboundType) and node.original_str_expr is None:
333+
node.original_str_expr = expr_string
334+
node.original_str_fallback = expr_fallback_name
335+
return node
336+
elif isinstance(node, UnionType):
337+
return node
338+
else:
339+
return RawExpressionType(expr_string, expr_fallback_name, line, column)
333340
except (SyntaxError, ValueError):
334341
# Note: the parser will raise a `ValueError` instead of a SyntaxError if
335342
# the string happens to contain things like \x00.
@@ -1046,8 +1053,6 @@ def set_type_optional(self, type: Type | None, initializer: Expression | None) -
10461053
return
10471054
# Indicate that type should be wrapped in an Optional if arg is initialized to None.
10481055
optional = isinstance(initializer, NameExpr) and initializer.name == "None"
1049-
if isinstance(type, RawExpressionType) and type.node is not None:
1050-
type = type.node
10511056
if isinstance(type, UnboundType):
10521057
type.optional = optional
10531058

mypy/semanal.py

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3437,10 +3437,10 @@ def analyze_typeddict_assign(self, s: AssignmentStmt) -> bool:
34373437
def analyze_lvalues(self, s: AssignmentStmt) -> None:
34383438
# We cannot use s.type, because analyze_simple_literal_type() will set it.
34393439
explicit = s.unanalyzed_type is not None
3440-
final_type = self.unwrap_final_type(s.unanalyzed_type)
3441-
if final_type is not None:
3440+
if self.is_final_type(s.unanalyzed_type):
34423441
# We need to exclude bare Final.
3443-
if not final_type.args:
3442+
assert isinstance(s.unanalyzed_type, UnboundType)
3443+
if not s.unanalyzed_type.args:
34443444
explicit = False
34453445

34463446
if s.rvalue:
@@ -3506,19 +3506,19 @@ def unwrap_final(self, s: AssignmentStmt) -> bool:
35063506
35073507
Returns True if Final[...] was present.
35083508
"""
3509-
final_type = self.unwrap_final_type(s.unanalyzed_type)
3510-
if final_type is None:
3509+
if not s.unanalyzed_type or not self.is_final_type(s.unanalyzed_type):
35113510
return False
3512-
if len(final_type.args) > 1:
3513-
self.fail("Final[...] takes at most one type argument", final_type)
3511+
assert isinstance(s.unanalyzed_type, UnboundType)
3512+
if len(s.unanalyzed_type.args) > 1:
3513+
self.fail("Final[...] takes at most one type argument", s.unanalyzed_type)
35143514
invalid_bare_final = False
3515-
if not final_type.args:
3515+
if not s.unanalyzed_type.args:
35163516
s.type = None
35173517
if isinstance(s.rvalue, TempNode) and s.rvalue.no_rhs:
35183518
invalid_bare_final = True
35193519
self.fail("Type in Final[...] can only be omitted if there is an initializer", s)
35203520
else:
3521-
s.type = final_type.args[0]
3521+
s.type = s.unanalyzed_type.args[0]
35223522

35233523
if s.type is not None and self.is_classvar(s.type):
35243524
self.fail("Variable should not be annotated with both ClassVar and Final", s)
@@ -4937,18 +4937,13 @@ def is_classvar(self, typ: Type) -> bool:
49374937
return False
49384938
return sym.node.fullname == "typing.ClassVar"
49394939

4940-
def unwrap_final_type(self, typ: Type | None) -> UnboundType | None:
4941-
if typ is None:
4942-
return None
4943-
typ = typ.resolve_string_annotation()
4940+
def is_final_type(self, typ: Type | None) -> bool:
49444941
if not isinstance(typ, UnboundType):
4945-
return None
4942+
return False
49464943
sym = self.lookup_qualified(typ.name, typ)
49474944
if not sym or not sym.node:
4948-
return None
4949-
if sym.node.fullname in FINAL_TYPE_NAMES:
4950-
return typ
4951-
return None
4945+
return False
4946+
return sym.node.fullname in FINAL_TYPE_NAMES
49524947

49534948
def fail_invalid_classvar(self, context: Context) -> None:
49544949
self.fail(message_registry.CLASS_VAR_OUTSIDE_OF_CLASS, context)

mypy/server/astmerge.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -507,8 +507,7 @@ def visit_typeddict_type(self, typ: TypedDictType) -> None:
507507
typ.fallback.accept(self)
508508

509509
def visit_raw_expression_type(self, t: RawExpressionType) -> None:
510-
if t.node is not None:
511-
t.node.accept(self)
510+
pass
512511

513512
def visit_literal_type(self, typ: LiteralType) -> None:
514513
typ.fallback.accept(self)

mypy/stubutil.py

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,7 @@
1717
from mypy.modulefinder import ModuleNotFoundReason
1818
from mypy.moduleinspect import InspectError, ModuleInspect
1919
from mypy.stubdoc import ArgSig, FunctionSig
20-
from mypy.types import (
21-
AnyType,
22-
NoneType,
23-
RawExpressionType,
24-
Type,
25-
TypeList,
26-
TypeStrVisitor,
27-
UnboundType,
28-
UnionType,
29-
)
20+
from mypy.types import AnyType, NoneType, Type, TypeList, TypeStrVisitor, UnboundType, UnionType
3021

3122
# Modules that may fail when imported, or that may have side effects (fully qualified).
3223
NOT_IMPORTABLE_MODULES = ()
@@ -302,11 +293,12 @@ def args_str(self, args: Iterable[Type]) -> str:
302293
The main difference from list_str is the preservation of quotes for string
303294
arguments
304295
"""
296+
types = ["builtins.bytes", "builtins.str"]
305297
res = []
306298
for arg in args:
307299
arg_str = arg.accept(self)
308-
if isinstance(arg, RawExpressionType):
309-
res.append(repr(arg.literal_value))
300+
if isinstance(arg, UnboundType) and arg.original_str_fallback in types:
301+
res.append(f"'{arg_str}'")
310302
else:
311303
res.append(arg_str)
312304
return ", ".join(res)

mypy/type_visitor.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -382,8 +382,6 @@ def visit_typeddict_type(self, t: TypedDictType) -> T:
382382
return self.query_types(t.items.values())
383383

384384
def visit_raw_expression_type(self, t: RawExpressionType) -> T:
385-
if t.node is not None:
386-
return t.node.accept(self)
387385
return self.strategy([])
388386

389387
def visit_literal_type(self, t: LiteralType) -> T:
@@ -524,8 +522,6 @@ def visit_typeddict_type(self, t: TypedDictType) -> bool:
524522
return self.query_types(list(t.items.values()))
525523

526524
def visit_raw_expression_type(self, t: RawExpressionType) -> bool:
527-
if t.node is not None:
528-
return t.node.accept(self)
529525
return self.default
530526

531527
def visit_literal_type(self, t: LiteralType) -> bool:

mypy/typeanal.py

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1107,7 +1107,6 @@ def visit_callable_type(
11071107
return ret
11081108

11091109
def anal_type_guard(self, t: Type) -> Type | None:
1110-
t = t.resolve_string_annotation()
11111110
if isinstance(t, UnboundType):
11121111
sym = self.lookup_qualified(t.name, t)
11131112
if sym is not None and sym.node is not None:
@@ -1126,7 +1125,6 @@ def anal_type_guard_arg(self, t: UnboundType, fullname: str) -> Type | None:
11261125
return None
11271126

11281127
def anal_type_is(self, t: Type) -> Type | None:
1129-
t = t.resolve_string_annotation()
11301128
if isinstance(t, UnboundType):
11311129
sym = self.lookup_qualified(t.name, t)
11321130
if sym is not None and sym.node is not None:
@@ -1144,7 +1142,6 @@ def anal_type_is_arg(self, t: UnboundType, fullname: str) -> Type | None:
11441142

11451143
def anal_star_arg_type(self, t: Type, kind: ArgKind, nested: bool) -> Type:
11461144
"""Analyze signature argument type for *args and **kwargs argument."""
1147-
t = t.resolve_string_annotation()
11481145
if isinstance(t, UnboundType) and t.name and "." in t.name and not t.args:
11491146
components = t.name.split(".")
11501147
tvar_name = ".".join(components[:-1])
@@ -1235,8 +1232,6 @@ def visit_raw_expression_type(self, t: RawExpressionType) -> Type:
12351232
# make signatures like "foo(x: 20) -> None" legal, we can change
12361233
# this method so it generates and returns an actual LiteralType
12371234
# instead.
1238-
if t.node is not None:
1239-
return t.node.accept(self)
12401235

12411236
if self.report_invalid_types:
12421237
if t.base_type_name in ("builtins.int", "builtins.bool"):
@@ -1499,7 +1494,6 @@ def analyze_callable_args(
14991494
invalid_unpacks: list[Type] = []
15001495
second_unpack_last = False
15011496
for i, arg in enumerate(arglist.items):
1502-
arg = arg.resolve_string_annotation()
15031497
if isinstance(arg, CallableArgument):
15041498
args.append(arg.typ)
15051499
names.append(arg.name)
@@ -1580,6 +1574,18 @@ def analyze_literal_type(self, t: UnboundType) -> Type:
15801574
return UnionType.make_union(output, line=t.line)
15811575

15821576
def analyze_literal_param(self, idx: int, arg: Type, ctx: Context) -> list[Type] | None:
1577+
# This UnboundType was originally defined as a string.
1578+
if isinstance(arg, UnboundType) and arg.original_str_expr is not None:
1579+
assert arg.original_str_fallback is not None
1580+
return [
1581+
LiteralType(
1582+
value=arg.original_str_expr,
1583+
fallback=self.named_type(arg.original_str_fallback),
1584+
line=arg.line,
1585+
column=arg.column,
1586+
)
1587+
]
1588+
15831589
# If arg is an UnboundType that was *not* originally defined as
15841590
# a string, try expanding it in case it's a type alias or something.
15851591
if isinstance(arg, UnboundType):
@@ -2564,8 +2570,7 @@ def visit_typeddict_type(self, t: TypedDictType) -> None:
25642570
self.process_types(list(t.items.values()))
25652571

25662572
def visit_raw_expression_type(self, t: RawExpressionType) -> None:
2567-
if t.node is not None:
2568-
t.node.accept(self)
2573+
pass
25692574

25702575
def visit_literal_type(self, t: LiteralType) -> None:
25712576
pass

0 commit comments

Comments
 (0)