@@ -404,14 +404,7 @@ def _is_type_or_Type(node: ast.expr) -> bool:
404404
405405
406406def _is_None (node : ast .expr ) -> bool :
407- # <=3.7: `BaseException | None` parses as:
408- # BinOp(left=Name(id='BaseException'), op=BitOr(), right=NameConstant(value=None))`
409- # >=3.8: `BaseException | None` parses as
410- # BinOp(left=Name(id='BaseException'), op=BitOr(), right=Constant(value=None))`
411- #
412- # ast.NameConstant is deprecated in 3.8+, but doesn't raise a DeprecationWarning,
413- # and the isinstance() check still works
414- return isinstance (node , ast .NameConstant ) and node .value is None
407+ return isinstance (node , ast .Constant ) and node .value is None
415408
416409
417410class ExitArgAnalysis (NamedTuple ):
@@ -553,8 +546,10 @@ def _unparse_func_node(node: ast.FunctionDef | ast.AsyncFunctionDef) -> str:
553546 return re .sub (r"\s+" , " " , unparse (node ))
554547
555548
556- def _is_list_of_str_nodes (seq : list [ast .expr | None ]) -> TypeGuard [list [ast .Str ]]:
557- return all (isinstance (item , ast .Str ) for item in seq )
549+ def _is_list_of_str_nodes (seq : list [ast .expr | None ]) -> TypeGuard [list [ast .Constant ]]:
550+ return all (
551+ isinstance (item , ast .Constant ) and type (item .value ) is str for item in seq
552+ )
558553
559554
560555def _is_bad_TypedDict (node : ast .Call ) -> bool :
@@ -582,7 +577,7 @@ def _is_bad_TypedDict(node: ast.Call) -> bool:
582577 if not _is_list_of_str_nodes (typed_dict_fields ):
583578 return False
584579
585- fieldnames = [field .s for field in typed_dict_fields ]
580+ fieldnames = [field .value for field in typed_dict_fields ]
586581
587582 return all (
588583 fieldname .isidentifier () and not iskeyword (fieldname )
@@ -740,13 +735,17 @@ def _is_valid_default_value_with_annotation(
740735
741736 # `...`, bools, None, str, bytes,
742737 # positive ints, positive floats, positive complex numbers with no real part
743- if isinstance (node , ( ast .Ellipsis , ast . NameConstant , ast . Str , ast . Bytes , ast . Num ) ):
738+ if isinstance (node , ast .Constant ):
744739 return True
745740
746741 # Negative ints, negative floats, negative complex numbers with no real part,
747742 # some constants from the math module
748743 if isinstance (node , ast .UnaryOp ) and isinstance (node .op , ast .USub ):
749- if isinstance (node .operand , ast .Num ):
744+ numeric_types = {int , float , complex }
745+ if (
746+ isinstance (node .operand , ast .Constant )
747+ and type (node .operand .value ) in numeric_types
748+ ):
750749 return True
751750 if isinstance (node .operand , ast .Attribute ) and isinstance (
752751 node .operand .value , ast .Name
@@ -762,19 +761,19 @@ def _is_valid_default_value_with_annotation(
762761 if (
763762 isinstance (node , ast .BinOp )
764763 and isinstance (node .op , (ast .Add , ast .Sub ))
765- and isinstance (node .right , ast .Num )
766- and type (node .right .n ) is complex
764+ and isinstance (node .right , ast .Constant )
765+ and type (node .right .value ) is complex
767766 ):
768767 left = node .left
769768 # ...Where the real part is positive:
770- if isinstance (left , ast .Num ) and type (left .n ) is not complex :
769+ if isinstance (left , ast .Constant ) and type (left .value ) in { int , float } :
771770 return True
772771 # ...Where the real part is negative:
773772 if (
774773 isinstance (left , ast .UnaryOp )
775774 and isinstance (left .op , ast .USub )
776- and isinstance (left .operand , ast .Num )
777- and type (left .operand .n ) is not complex
775+ and isinstance (left .operand , ast .Constant )
776+ and type (left .operand .value ) in { int , float }
778777 ):
779778 return True
780779 return False
@@ -809,10 +808,8 @@ def _is_valid_pep_604_union(node: ast.expr) -> TypeGuard[ast.BinOp]:
809808def _is_valid_default_value_without_annotation (node : ast .expr ) -> bool :
810809 """Is `node` a valid default for an assignment without an annotation?"""
811810 return (
812- isinstance (
813- node , (ast .Call , ast .Name , ast .Attribute , ast .Subscript , ast .Ellipsis )
814- )
815- or _is_None (node )
811+ isinstance (node , (ast .Call , ast .Name , ast .Attribute , ast .Subscript ))
812+ or (isinstance (node , ast .Constant ) and node .value in {None , ...})
816813 or _is_valid_pep_604_union (node )
817814 )
818815
@@ -1150,45 +1147,23 @@ def visit_Call(self, node: ast.Call) -> None:
11501147 for kw in node .keywords :
11511148 self .visit (kw )
11521149
1153- def _check_for_Y053 (self , node : ast .Constant | ast .Str | ast .Bytes ) -> None :
1154- if len (node .s ) > 50 :
1155- self .error (node , Y053 )
1156-
1157- def _check_for_Y054 (self , node : ast .Constant | ast .Num ) -> None :
1158- # The maximum character limit is arbitrary, but here's what it's based on:
1159- # Hex representation of 32-bit integers tend to be 10 chars.
1160- # So is the decimal representation
1161- # of the maximum positive signed 32-bit integer.
1162- # 0xFFFFFFFF --> 4294967295
1163- if len (str (node .n )) > 10 :
1164- self .error (node , Y054 )
1165-
1166- # 3.8+
11671150 def visit_Constant (self , node : ast .Constant ) -> None :
11681151 if isinstance (node .value , str ) and not self .string_literals_allowed .active :
11691152 self .error (node , Y020 )
11701153 elif isinstance (node .value , (str , bytes )):
1171- self ._check_for_Y053 (node )
1154+ if len (node .value ) > 50 :
1155+ self .error (node , Y053 )
11721156 elif isinstance (node .value , (int , float , complex )):
1173- self ._check_for_Y054 (node )
1174-
1175- # 3.7
1176- def visit_Str (self , node : ast .Str ) -> None :
1177- if self .string_literals_allowed .active :
1178- self ._check_for_Y053 (node )
1179- else :
1180- self .error (node , Y020 )
1181-
1182- # 3.7
1183- def visit_Bytes (self , node : ast .Bytes ) -> None :
1184- self ._check_for_Y053 (node )
1185-
1186- # 3.7
1187- def visit_Num (self , node : ast .Num ) -> None :
1188- self ._check_for_Y054 (node )
1157+ if len (str (node .value )) > 10 :
1158+ # The maximum character limit is arbitrary, but here's what it's based on:
1159+ # Hex representation of 32-bit integers tend to be 10 chars.
1160+ # So is the decimal representation
1161+ # of the maximum positive signed 32-bit integer.
1162+ # 0xFFFFFFFF --> 4294967295
1163+ self .error (node , Y054 )
11891164
11901165 def visit_Expr (self , node : ast .Expr ) -> None :
1191- if isinstance (node .value , ast .Str ):
1166+ if isinstance (node .value , ast .Constant ) and isinstance ( node . value . value , str ):
11921167 self .error (node , Y021 )
11931168 else :
11941169 self .generic_visit (node )
@@ -1288,16 +1263,12 @@ def _check_for_Y051_violations(self, analysis: UnionAnalysis) -> None:
12881263 literal_classes_present : defaultdict [str , list [_SliceContents ]]
12891264 literal_classes_present = defaultdict (list )
12901265 for literal in analysis .combined_literal_members :
1291- if isinstance (literal , ast .Str ):
1292- literal_classes_present ["str" ].append (literal )
1293- elif isinstance (literal , ast .Bytes ):
1294- literal_classes_present ["bytes" ].append (literal )
1295- elif isinstance (literal , ast .Num ):
1296- if type (literal .n ) is int :
1297- literal_classes_present ["int" ].append (literal )
1298- elif isinstance (literal , ast .NameConstant ):
1299- if type (literal .value ) is bool :
1300- literal_classes_present ["bool" ].append (literal )
1266+ interesting_builtins = {str , bytes , int , bool }
1267+ if (
1268+ isinstance (literal , ast .Constant )
1269+ and type (literal .value ) in interesting_builtins
1270+ ):
1271+ literal_classes_present [type (literal .value ).__name__ ].append (literal )
13011272 for cls , literals in literal_classes_present .items ():
13021273 if cls in analysis .builtins_classes_in_union :
13031274 first_literal_present = literals [0 ]
@@ -1460,10 +1431,9 @@ def _check_subscript_version_check(self, node: ast.Compare) -> None:
14601431 version_info = node .left
14611432 if isinstance (version_info , ast .Subscript ):
14621433 slc = version_info .slice
1463- # TODO: ast.Num works, but is deprecated
1464- if isinstance (slc , ast .Num ):
1434+ if isinstance (slc , ast .Constant ):
14651435 # anything other than the integer 0 doesn't make much sense
1466- if isinstance (slc .n , int ) and slc .n == 0 :
1436+ if isinstance (slc .value , int ) and slc .value == 0 :
14671437 must_be_single = True
14681438 else :
14691439 self .error (node , Y003 )
@@ -1474,11 +1444,11 @@ def _check_subscript_version_check(self, node: ast.Compare) -> None:
14741444 return
14751445 elif (
14761446 # allow only [:1] and [:2]
1477- isinstance (slc .upper , ast .Num )
1478- and isinstance (slc .upper .n , int )
1479- and slc .upper .n in ( 1 , 2 )
1447+ isinstance (slc .upper , ast .Constant )
1448+ and isinstance (slc .upper .value , int )
1449+ and slc .upper .value in { 1 , 2 }
14801450 ):
1481- can_have_strict_equals = slc .upper .n
1451+ can_have_strict_equals = slc .upper .value
14821452 else :
14831453 self .error (node , Y003 )
14841454 return
@@ -1501,12 +1471,17 @@ def _check_version_check(
15011471 ) -> None :
15021472 comparator = node .comparators [0 ]
15031473 if must_be_single :
1504- if not isinstance (comparator , ast .Num ) or not isinstance (comparator .n , int ):
1474+ if not isinstance (comparator , ast .Constant ) or not isinstance (
1475+ comparator .value , int
1476+ ):
15051477 self .error (node , Y003 )
15061478 elif not isinstance (comparator , ast .Tuple ):
15071479 self .error (node , Y003 )
15081480 else :
1509- if not all (isinstance (elt , ast .Num ) for elt in comparator .elts ):
1481+ if not all (
1482+ isinstance (elt , ast .Constant ) and type (elt .value ) is int
1483+ for elt in comparator .elts
1484+ ):
15101485 self .error (node , Y003 )
15111486 elif len (comparator .elts ) > 2 :
15121487 # mypy only supports major and minor version checks
@@ -1532,11 +1507,11 @@ def _check_platform_check(self, node: ast.Compare) -> None:
15321507 return
15331508
15341509 comparator = node .comparators [0 ]
1535- if isinstance (comparator , ast .Str ) :
1510+ if isinstance (comparator , ast .Constant ) and type ( comparator . value ) is str :
15361511 # other values are possible but we don't need them right now
15371512 # this protects against typos
1538- if comparator .s not in ( "linux" , "win32" , "cygwin" , "darwin" ) :
1539- self .error (node , Y008 .format (platform = comparator .s ))
1513+ if comparator .value not in { "linux" , "win32" , "cygwin" , "darwin" } :
1514+ self .error (node , Y008 .format (platform = comparator .value ))
15401515 else :
15411516 self .error (node , Y007 )
15421517
@@ -1562,8 +1537,10 @@ def visit_ClassDef(self, node: ast.ClassDef) -> None:
15621537 # empty class body should contain "..." not "pass"
15631538 if len (node .body ) == 1 :
15641539 statement = node .body [0 ]
1565- if isinstance (statement , ast .Expr ) and isinstance (
1566- statement .value , ast .Ellipsis
1540+ if (
1541+ isinstance (statement , ast .Expr )
1542+ and isinstance (statement .value , ast .Constant )
1543+ and statement .value .value is ...
15671544 ):
15681545 return
15691546 elif isinstance (statement , ast .Pass ):
@@ -1575,8 +1552,10 @@ def visit_ClassDef(self, node: ast.ClassDef) -> None:
15751552 if isinstance (statement , ast .Pass ):
15761553 self .error (statement , Y012 )
15771554 # "..." should not be used in non-empty class body
1578- elif isinstance (statement , ast .Expr ) and isinstance (
1579- statement .value , ast .Ellipsis
1555+ elif (
1556+ isinstance (statement , ast .Expr )
1557+ and isinstance (statement .value , ast .Constant )
1558+ and statement .value .value is ...
15801559 ):
15811560 self .error (statement , Y013 )
15821561
@@ -1904,11 +1883,12 @@ def _visit_function(self, node: ast.FunctionDef | ast.AsyncFunctionDef) -> None:
19041883 # normally, should just be "..."
19051884 if isinstance (statement , ast .Pass ):
19061885 self .error (statement , Y009 )
1907- # Ellipsis is fine. Str (docstrings) is not but we produce
1908- # tailored error message for it elsewhere.
1886+ # ... is fine. Docstrings are not but we produce
1887+ # tailored error message for them elsewhere.
19091888 elif not (
19101889 isinstance (statement , ast .Expr )
1911- and isinstance (statement .value , (ast .Ellipsis , ast .Str ))
1890+ and isinstance (statement .value , ast .Constant )
1891+ and isinstance (statement .value .value , (str , type (...)))
19121892 ):
19131893 self .error (statement , Y010 )
19141894
0 commit comments