38
38
StrExpr ,
39
39
TempNode ,
40
40
TupleExpr ,
41
- UnicodeExpr ,
42
41
)
43
42
from mypy .types import (
44
43
AnyType ,
65
64
from mypy .subtypes import is_subtype
66
65
from mypy .typeops import custom_special_method
67
66
68
- FormatStringExpr : _TypeAlias = Union [StrExpr , BytesExpr , UnicodeExpr ]
67
+ FormatStringExpr : _TypeAlias = Union [StrExpr , BytesExpr ]
69
68
Checkers : _TypeAlias = Tuple [Callable [[Expression ], None ], Callable [[Type ], bool ]]
70
69
MatchMap : _TypeAlias = Dict [Tuple [int , int ], Match [str ]] # span -> match
71
70
@@ -331,9 +330,6 @@ def __init__(
331
330
self .chk = chk
332
331
self .exprchk = exprchk
333
332
self .msg = msg
334
- # This flag is used to track Python 2 corner case where for example
335
- # '%s, %d' % (u'abc', 42) returns u'abc, 42' (i.e. unicode, not a string).
336
- self .unicode_upcast = False
337
333
338
334
def check_str_format_call (self , call : CallExpr , format_value : str ) -> None :
339
335
"""Perform more precise checks for str.format() calls when possible.
@@ -402,7 +398,7 @@ def check_specs_in_format_call(
402
398
expected_type : Optional [Type ] = AnyType (TypeOfAny .special_form )
403
399
else :
404
400
assert isinstance (call .callee , MemberExpr )
405
- if isinstance (call .callee .expr , ( StrExpr , UnicodeExpr ) ):
401
+ if isinstance (call .callee .expr , StrExpr ):
406
402
format_str = call .callee .expr
407
403
else :
408
404
format_str = StrExpr (format_value )
@@ -453,17 +449,16 @@ def perform_special_format_checks(
453
449
if len (c_typ .value ) != 1 :
454
450
self .msg .requires_int_or_char (call , format_call = True )
455
451
if (not spec .conv_type or spec .conv_type == "s" ) and not spec .conversion :
456
- if self .chk .options .python_version >= (3 , 0 ):
457
- if has_type_component (actual_type , "builtins.bytes" ) and not custom_special_method (
458
- actual_type , "__str__"
459
- ):
460
- self .msg .fail (
461
- 'On Python 3 formatting "b\' abc\' " with "{}" '
462
- 'produces "b\' abc\' ", not "abc"; '
463
- 'use "{!r}" if this is desired behavior' ,
464
- call ,
465
- code = codes .STR_BYTES_PY3 ,
466
- )
452
+ if has_type_component (actual_type , "builtins.bytes" ) and not custom_special_method (
453
+ actual_type , "__str__"
454
+ ):
455
+ self .msg .fail (
456
+ 'On Python 3 formatting "b\' abc\' " with "{}" '
457
+ 'produces "b\' abc\' ", not "abc"; '
458
+ 'use "{!r}" if this is desired behavior' ,
459
+ call ,
460
+ code = codes .STR_BYTES_PY3 ,
461
+ )
467
462
if spec .flags :
468
463
numeric_types = UnionType (
469
464
[self .named_type ("builtins.int" ), self .named_type ("builtins.float" )]
@@ -706,15 +701,14 @@ def check_str_interpolation(self, expr: FormatStringExpr, replacements: Expressi
706
701
self .exprchk .accept (expr )
707
702
specifiers = parse_conversion_specifiers (expr .value )
708
703
has_mapping_keys = self .analyze_conversion_specifiers (specifiers , expr )
709
- if isinstance (expr , BytesExpr ) and ( 3 , 0 ) <= self .chk .options .python_version < (3 , 5 ):
704
+ if isinstance (expr , BytesExpr ) and self .chk .options .python_version < (3 , 5 ):
710
705
self .msg .fail (
711
706
"Bytes formatting is only supported in Python 3.5 and later" ,
712
707
replacements ,
713
708
code = codes .STRING_FORMATTING ,
714
709
)
715
710
return AnyType (TypeOfAny .from_error )
716
711
717
- self .unicode_upcast = False
718
712
if has_mapping_keys is None :
719
713
pass # Error was reported
720
714
elif has_mapping_keys :
@@ -724,11 +718,7 @@ def check_str_interpolation(self, expr: FormatStringExpr, replacements: Expressi
724
718
725
719
if isinstance (expr , BytesExpr ):
726
720
return self .named_type ("builtins.bytes" )
727
- elif isinstance (expr , UnicodeExpr ):
728
- return self .named_type ("builtins.unicode" )
729
721
elif isinstance (expr , StrExpr ):
730
- if self .unicode_upcast :
731
- return self .named_type ("builtins.unicode" )
732
722
return self .named_type ("builtins.str" )
733
723
else :
734
724
assert False
@@ -815,11 +805,11 @@ def check_mapping_str_interpolation(
815
805
) -> None :
816
806
"""Check % string interpolation with names specifiers '%(name)s' % {'name': 'John'}."""
817
807
if isinstance (replacements , DictExpr ) and all (
818
- isinstance (k , (StrExpr , BytesExpr , UnicodeExpr )) for k , v in replacements .items
808
+ isinstance (k , (StrExpr , BytesExpr )) for k , v in replacements .items
819
809
):
820
810
mapping : Dict [str , Type ] = {}
821
811
for k , v in replacements .items :
822
- if self . chk . options . python_version >= ( 3 , 0 ) and isinstance (expr , BytesExpr ):
812
+ if isinstance (expr , BytesExpr ):
823
813
# Special case: for bytes formatting keys must be bytes.
824
814
if not isinstance (k , BytesExpr ):
825
815
self .msg .fail (
@@ -870,21 +860,14 @@ def check_mapping_str_interpolation(
870
860
def build_dict_type (self , expr : FormatStringExpr ) -> Type :
871
861
"""Build expected mapping type for right operand in % formatting."""
872
862
any_type = AnyType (TypeOfAny .special_form )
873
- if self .chk .options .python_version >= (3 , 0 ):
874
- if isinstance (expr , BytesExpr ):
875
- bytes_type = self .chk .named_generic_type ("builtins.bytes" , [])
876
- return self .chk .named_generic_type ("typing.Mapping" , [bytes_type , any_type ])
877
- elif isinstance (expr , StrExpr ):
878
- str_type = self .chk .named_generic_type ("builtins.str" , [])
879
- return self .chk .named_generic_type ("typing.Mapping" , [str_type , any_type ])
880
- else :
881
- assert False , "There should not be UnicodeExpr on Python 3"
882
- else :
863
+ if isinstance (expr , BytesExpr ):
864
+ bytes_type = self .chk .named_generic_type ("builtins.bytes" , [])
865
+ return self .chk .named_generic_type ("typing.Mapping" , [bytes_type , any_type ])
866
+ elif isinstance (expr , StrExpr ):
883
867
str_type = self .chk .named_generic_type ("builtins.str" , [])
884
- unicode_type = self .chk .named_generic_type ("builtins.unicode" , [])
885
- str_map = self .chk .named_generic_type ("typing.Mapping" , [str_type , any_type ])
886
- unicode_map = self .chk .named_generic_type ("typing.Mapping" , [unicode_type , any_type ])
887
- return UnionType .make_union ([str_map , unicode_map ])
868
+ return self .chk .named_generic_type ("typing.Mapping" , [str_type , any_type ])
869
+ else :
870
+ assert False , "There should not be UnicodeExpr on Python 3"
888
871
889
872
def build_replacement_checkers (
890
873
self , specifiers : List [ConversionSpecifier ], context : Context , expr : FormatStringExpr
@@ -979,29 +962,24 @@ def check_s_special_cases(self, expr: FormatStringExpr, typ: Type, context: Cont
979
962
"""Additional special cases for %s in bytes vs string context."""
980
963
if isinstance (expr , StrExpr ):
981
964
# Couple special cases for string formatting.
982
- if self .chk .options .python_version >= (3 , 0 ):
983
- if has_type_component (typ , "builtins.bytes" ):
984
- self .msg .fail (
985
- 'On Python 3 formatting "b\' abc\' " with "%s" '
986
- 'produces "b\' abc\' ", not "abc"; '
987
- 'use "%r" if this is desired behavior' ,
988
- context ,
989
- code = codes .STR_BYTES_PY3 ,
990
- )
991
- return False
992
- if self .chk .options .python_version < (3 , 0 ):
993
- if has_type_component (typ , "builtins.unicode" ):
994
- self .unicode_upcast = True
965
+ if has_type_component (typ , "builtins.bytes" ):
966
+ self .msg .fail (
967
+ 'On Python 3 formatting "b\' abc\' " with "%s" '
968
+ 'produces "b\' abc\' ", not "abc"; '
969
+ 'use "%r" if this is desired behavior' ,
970
+ context ,
971
+ code = codes .STR_BYTES_PY3 ,
972
+ )
973
+ return False
995
974
if isinstance (expr , BytesExpr ):
996
975
# A special case for bytes formatting: b'%s' actually requires bytes on Python 3.
997
- if self .chk .options .python_version >= (3 , 0 ):
998
- if has_type_component (typ , "builtins.str" ):
999
- self .msg .fail (
1000
- "On Python 3 b'%s' requires bytes, not string" ,
1001
- context ,
1002
- code = codes .STRING_FORMATTING ,
1003
- )
1004
- return False
976
+ if has_type_component (typ , "builtins.str" ):
977
+ self .msg .fail (
978
+ "On Python 3 b'%s' requires bytes, not string" ,
979
+ context ,
980
+ code = codes .STRING_FORMATTING ,
981
+ )
982
+ return False
1005
983
return True
1006
984
1007
985
def checkers_for_c_type (
@@ -1016,7 +994,7 @@ def checkers_for_c_type(
1016
994
1017
995
def check_type (type : Type ) -> bool :
1018
996
assert expected_type is not None
1019
- if self . chk . options . python_version >= ( 3 , 0 ) and isinstance (format_expr , BytesExpr ):
997
+ if isinstance (format_expr , BytesExpr ):
1020
998
err_msg = '"%c" requires an integer in range(256) or a single byte'
1021
999
else :
1022
1000
err_msg = '"%c" requires int or char'
@@ -1037,13 +1015,11 @@ def check_expr(expr: Expression) -> None:
1037
1015
if check_type (type ):
1038
1016
# Python 3 doesn't support b'%c' % str
1039
1017
if (
1040
- self .chk .options .python_version >= (3 , 0 )
1041
- and isinstance (format_expr , BytesExpr )
1018
+ isinstance (format_expr , BytesExpr )
1042
1019
and isinstance (expr , BytesExpr )
1043
1020
and len (expr .value ) != 1
1044
1021
):
1045
1022
self .msg .requires_int_or_single_byte (context )
1046
- # In Python 2, b'%c' is the same as '%c'
1047
1023
elif isinstance (expr , (StrExpr , BytesExpr )) and len (expr .value ) != 1 :
1048
1024
self .msg .requires_int_or_char (context )
1049
1025
@@ -1079,13 +1055,6 @@ def conversion_type(
1079
1055
return None
1080
1056
return self .named_type ("builtins.bytes" )
1081
1057
elif p == "a" :
1082
- if self .chk .options .python_version < (3 , 0 ):
1083
- self .msg .fail (
1084
- 'Format character "a" is only supported in Python 3' ,
1085
- context ,
1086
- code = codes .STRING_FORMATTING ,
1087
- )
1088
- return None
1089
1058
# TODO: return type object?
1090
1059
return AnyType (TypeOfAny .special_form )
1091
1060
elif p in ["s" , "r" ]:
0 commit comments