2
2
3
3
import re
4
4
5
- from typing import cast , List , Tuple , Dict , Callable
5
+ from typing import cast , List , Tuple , Dict , Callable , Union
6
6
7
7
from mypy .types import (
8
8
Type , AnyType , TupleType , Instance , UnionType
9
9
)
10
10
from mypy .nodes import (
11
- Node , StrExpr , BytesExpr , TupleExpr , DictExpr , Context
11
+ Node , StrExpr , BytesExpr , UnicodeExpr , TupleExpr , DictExpr , Context
12
12
)
13
13
if False :
14
14
# break import cycle only needed for mypy
@@ -55,7 +55,12 @@ def __init__(self,
55
55
self .exprchk = exprchk
56
56
self .msg = msg
57
57
58
- def check_str_interpolation (self , str : StrExpr , replacements : Node ) -> Type :
58
+ # TODO: In Python 3, the bytes formatting has a more restricted set of options
59
+ # compared to string formatting.
60
+ # TODO: Bytes formatting in Python 3 is only supported in 3.5 and up.
61
+ def check_str_interpolation (self ,
62
+ str : Union [StrExpr , BytesExpr , UnicodeExpr ],
63
+ replacements : Node ) -> Type :
59
64
"""Check the types of the 'replacements' in a string interpolation
60
65
expression: str % replacements
61
66
"""
@@ -67,7 +72,15 @@ def check_str_interpolation(self, str: StrExpr, replacements: Node) -> Type:
67
72
self .check_mapping_str_interpolation (specifiers , replacements )
68
73
else :
69
74
self .check_simple_str_interpolation (specifiers , replacements )
70
- return self .named_type ('builtins.str' )
75
+
76
+ if isinstance (str , BytesExpr ):
77
+ return self .named_type ('builtins.bytes' )
78
+ elif isinstance (str , UnicodeExpr ):
79
+ return self .named_type ('builtins.unicode' )
80
+ elif isinstance (str , StrExpr ):
81
+ return self .named_type ('builtins.str' )
82
+ else :
83
+ assert False
71
84
72
85
def parse_conversion_specifiers (self , format : str ) -> List [ConversionSpecifier ]:
73
86
key_regex = r'(\(([^()]*)\))?' # (optional) parenthesised sequence of characters
0 commit comments