Skip to content

Commit fe1056b

Browse files
Adrien ChauveJukkaL
Adrien Chauve
authored andcommitted
Handle python 3.6 f-strings without error (#2622)
Linked to #2265
1 parent 1ed4cb6 commit fe1056b

File tree

3 files changed

+64
-6
lines changed

3 files changed

+64
-6
lines changed

mypy/fastparse.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -850,6 +850,26 @@ def visit_Str(self, n: ast3.Str) -> Union[UnicodeExpr, StrExpr]:
850850
else:
851851
return UnicodeExpr(n.s)
852852

853+
# Only available with typed_ast >= 0.6.2
854+
if hasattr(ast3, 'JoinedStr'):
855+
# JoinedStr(expr* values)
856+
@with_line
857+
def visit_JoinedStr(self, n: ast3.JoinedStr) -> Expression:
858+
result_expression = StrExpr('') # type: Expression
859+
for value_expr in self.translate_expr_list(n.values):
860+
string_method = MemberExpr(value_expr, '__str__')
861+
string_method.set_line(value_expr)
862+
stringified_value_expr = CallExpr(string_method, [], [])
863+
stringified_value_expr.set_line(value_expr)
864+
result_expression = OpExpr('+', result_expression, stringified_value_expr)
865+
result_expression.set_line(value_expr)
866+
return result_expression
867+
868+
# FormattedValue(expr value)
869+
@with_line
870+
def visit_FormattedValue(self, n: ast3.FormattedValue) -> Expression:
871+
return self.visit(n.value)
872+
853873
# Bytes(bytes s)
854874
@with_line
855875
def visit_Bytes(self, n: ast3.Bytes) -> Union[BytesExpr, StrExpr]:

test-data/unit/check-newsyntax.test

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,11 +99,46 @@ main:4: error: Unsupported target for indexed assignment
9999
main:5: error: Type cannot be declared in assignment to non-self attribute
100100
main:5: error: "str" has no attribute "x"
101101

102-
[case testNewSyntaxFstringError]
103-
# flags: --fast-parser --python-version 3.5
104-
f'' # E: Format strings are only supported in Python 3.6 and greater
105-
106102
[case testNewSyntaxAsyncComprehensionError]
107103
# flags: --fast-parser --python-version 3.5
108104
async def f():
109105
results = [i async for i in aiter() if i % 2] # E: Async comprehensions are only supported in Python 3.6 and greater
106+
107+
108+
[case testNewSyntaxFstringError]
109+
# flags: --fast-parser --python-version 3.5
110+
f'' # E: Format strings are only supported in Python 3.6 and greater
111+
112+
[case testNewSyntaxFStringBasics]
113+
# flags: --fast-parser --python-version 3.6
114+
f'foobar'
115+
f'{"foobar"}'
116+
f'foo{"bar"}'
117+
f'.{1}.'
118+
a: str
119+
a = f'foobar'
120+
a = f'{"foobar"}'
121+
[builtins fixtures/primitives.pyi]
122+
123+
[case testNewSyntaxFStringExpressionsOk]
124+
# flags: --fast-parser --python-version 3.6
125+
f'.{1 + 1}.'
126+
f'.{1 + 1}.{"foo" + "bar"}'
127+
[builtins fixtures/primitives.pyi]
128+
129+
[case testNewSyntaxFStringExpressionsErrors]
130+
# flags: --fast-parser --python-version 3.6
131+
f'{1 + ""}'
132+
f'.{1 + ""}'
133+
[builtins fixtures/primitives.pyi]
134+
[out]
135+
main:2: error: Unsupported operand types for + ("int" and "str")
136+
main:3: error: Unsupported operand types for + ("int" and "str")
137+
138+
[case testNewSyntaxFStringParseFormatOptions]
139+
# flags: --fast-parser --python-version 3.6
140+
value = 10.5142
141+
width = 10
142+
precision = 4
143+
f'result: {value:{width}.{precision}}'
144+
[builtins fixtures/primitives.pyi]

test-data/unit/fixtures/primitives.pyi

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,18 @@
22

33
class object:
44
def __init__(self) -> None: pass
5+
def __str__(self) -> str: pass
56

67
class type:
78
def __init__(self, x) -> None: pass
89

9-
class int: pass
10+
class int:
11+
def __add__(self, i: int) -> int: pass
1012
class float: pass
1113
class complex: pass
1214
class bool: pass
13-
class str: pass
15+
class str:
16+
def __add__(self, s: str) -> str: pass
1417
class bytes: pass
1518
class bytearray: pass
1619
class tuple: pass

0 commit comments

Comments
 (0)