3838import ast
3939import configparser
4040import pathlib
41+ import sys
4142import tempfile
4243from typing import TYPE_CHECKING , Callable , Iterator , List , Optional , Tuple , Type
4344
@@ -92,10 +93,20 @@ def mode_is_binary(mode: ast.AST) -> Optional[bool]:
9293
9394 if isinstance (mode , ast .Constant ): # pragma: no cover (<py38)
9495 return 'b' in mode .value
95- elif isinstance (mode , ast .Str ): # pragma: no cover (py38+)
96- return 'b' in mode .s
9796 else :
98- return None
97+ if sys .version_info < (3 , 12 ): # pragma: no cover (py312+)
98+ if isinstance (mode , ast .Str ): # pragma: no cover (py38+)
99+ return 'b' in mode .s
100+
101+ return None
102+
103+
104+ if sys .version_info < (3 , 12 ): # pragma: no cover (py312+)
105+ _constant_nameconstant = (ast .Constant , ast .NameConstant )
106+ _skip_312_deprecations = False
107+ else : # pragma: no cover (<py312)
108+ _constant_nameconstant = ast .Constant
109+ _skip_312_deprecations = True
99110
100111
101112class Visitor (flake8_helper .Visitor ):
@@ -135,7 +146,7 @@ def check_open_encoding(self, node: ast.Call) -> None:
135146 if "encoding" not in kwargs :
136147 self .report_error (node , ENC003 if unknown_mode else ENC001 )
137148
138- elif isinstance (kwargs ["encoding" ], ( ast . Constant , ast . NameConstant ) ):
149+ elif isinstance (kwargs ["encoding" ], _constant_nameconstant ):
139150 if kwargs ["encoding" ].value is None :
140151 self .report_error (node , ENC004 if unknown_mode else ENC002 )
141152
@@ -157,11 +168,12 @@ def visit_Call(self, node: ast.Call) -> None: # noqa: D102
157168 self .check_open_encoding (node )
158169 return
159170
160- if isinstance (node .func .value , ast .Str ): # pragma: no cover
161- # Attribute on a string
162- return self .generic_visit (node )
171+ if not _skip_312_deprecations : # pragma: no cover (py312+)
172+ if isinstance (node .func .value , ast .Str ): # pragma: no cover
173+ # Attribute on a string
174+ return self .generic_visit (node )
163175
164- elif isinstance (node .func .value , ast .BinOp ): # pragma: no cover
176+ if isinstance (node .func .value , ast .BinOp ): # pragma: no cover
165177 # TODO
166178 # Expressions such as (tmp_pathplus / "code.py").write_text(example_source)
167179 return self .generic_visit (node )
@@ -226,7 +238,7 @@ def check_configparser_encoding(self, node: ast.Call) -> None:
226238 if "encoding" not in kwargs :
227239 self .report_error (node , ENC011 )
228240
229- elif isinstance (kwargs ["encoding" ], ( ast . Constant , ast . NameConstant ) ):
241+ elif isinstance (kwargs ["encoding" ], _constant_nameconstant ):
230242 if kwargs ["encoding" ].value is None :
231243 self .report_error (node , ENC012 )
232244
@@ -275,7 +287,7 @@ def check_pathlib_encoding(self, node: ast.Call, method_name: str) -> None:
275287 if "encoding" not in kwargs :
276288 self .report_error (node , no_encoding )
277289
278- elif isinstance (kwargs ["encoding" ], ( ast . Constant , ast . NameConstant ) ):
290+ elif isinstance (kwargs ["encoding" ], _constant_nameconstant ):
279291 if kwargs ["encoding" ].value is None :
280292 self .report_error (node , encoding_none )
281293
@@ -295,11 +307,12 @@ def visit_Call(self, node: ast.Call) -> None: # noqa: D102
295307 self .check_open_encoding (node )
296308 return
297309
298- if isinstance (node .func .value , ast .Str ): # pragma: no cover
299- # Attribute on a string
300- return self .generic_visit (node )
310+ if not _skip_312_deprecations : # pragma: no cover (py312+)
311+ if isinstance (node .func .value , ast .Str ): # pragma: no cover
312+ # Attribute on a string
313+ return self .generic_visit (node )
301314
302- elif isinstance (node .func .value , ast .BinOp ): # pragma: no cover
315+ if isinstance (node .func .value , ast .BinOp ): # pragma: no cover
303316 # TODO
304317 # Expressions such as (tmp_pathplus / "code.py").write_text(example_source)
305318 return self .generic_visit (node )
0 commit comments