Skip to content

Handle python 3.6 f-strings without error #2622

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 17 commits into from
Feb 21, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions mypy/fastparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -850,6 +850,26 @@ def visit_Str(self, n: ast3.Str) -> Union[UnicodeExpr, StrExpr]:
else:
return UnicodeExpr(n.s)

# Only available with typed_ast >= 0.6.2
if hasattr(ast3, 'JoinedStr'):
# JoinedStr(expr* values)
@with_line
def visit_JoinedStr(self, n: ast3.JoinedStr) -> Expression:
result_expression = StrExpr('') # type: Expression
for value_expr in self.translate_expr_list(n.values):
string_method = MemberExpr(value_expr, '__str__')
string_method.set_line(value_expr)
stringified_value_expr = CallExpr(string_method, [], [])
stringified_value_expr.set_line(value_expr)
result_expression = OpExpr('+', result_expression, stringified_value_expr)
result_expression.set_line(value_expr)
return result_expression

# FormattedValue(expr value)
@with_line
def visit_FormattedValue(self, n: ast3.FormattedValue) -> Expression:
return self.visit(n.value)

# Bytes(bytes s)
@with_line
def visit_Bytes(self, n: ast3.Bytes) -> Union[BytesExpr, StrExpr]:
Expand Down
43 changes: 39 additions & 4 deletions test-data/unit/check-newsyntax.test
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,46 @@ main:4: error: Unsupported target for indexed assignment
main:5: error: Type cannot be declared in assignment to non-self attribute
main:5: error: "str" has no attribute "x"

[case testNewSyntaxFstringError]
# flags: --fast-parser --python-version 3.5
f'' # E: Format strings are only supported in Python 3.6 and greater

[case testNewSyntaxAsyncComprehensionError]
# flags: --fast-parser --python-version 3.5
async def f():
results = [i async for i in aiter() if i % 2] # E: Async comprehensions are only supported in Python 3.6 and greater


[case testNewSyntaxFstringError]
# flags: --fast-parser --python-version 3.5
f'' # E: Format strings are only supported in Python 3.6 and greater

[case testNewSyntaxFStringBasics]
# flags: --fast-parser --python-version 3.6
f'foobar'
f'{"foobar"}'
f'foo{"bar"}'
f'.{1}.'
a: str
a = f'foobar'
a = f'{"foobar"}'
[builtins fixtures/primitives.pyi]

[case testNewSyntaxFStringExpressionsOk]
# flags: --fast-parser --python-version 3.6
f'.{1 + 1}.'
f'.{1 + 1}.{"foo" + "bar"}'
[builtins fixtures/primitives.pyi]

[case testNewSyntaxFStringExpressionsErrors]
# flags: --fast-parser --python-version 3.6
f'{1 + ""}'
f'.{1 + ""}'
[builtins fixtures/primitives.pyi]
[out]
main:2: error: Unsupported operand types for + ("int" and "str")
main:3: error: Unsupported operand types for + ("int" and "str")

[case testNewSyntaxFStringParseFormatOptions]
# flags: --fast-parser --python-version 3.6
value = 10.5142
width = 10
precision = 4
f'result: {value:{width}.{precision}}'
[builtins fixtures/primitives.pyi]
7 changes: 5 additions & 2 deletions test-data/unit/fixtures/primitives.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,18 @@

class object:
def __init__(self) -> None: pass
def __str__(self) -> str: pass

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

class int: pass
class int:
def __add__(self, i: int) -> int: pass
class float: pass
class complex: pass
class bool: pass
class str: pass
class str:
def __add__(self, s: str) -> str: pass
class bytes: pass
class bytearray: pass
class tuple: pass
Expand Down