Skip to content

Commit

Permalink
Handle ast deprecations in Python 3.12
Browse files Browse the repository at this point in the history
  • Loading branch information
domdfcoding committed Nov 20, 2023
1 parent 579b09d commit 6b941dc
Showing 1 changed file with 27 additions and 14 deletions.
41 changes: 27 additions & 14 deletions flake8_encodings/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import ast
import configparser
import pathlib
import sys
import tempfile
from typing import TYPE_CHECKING, Callable, Iterator, List, Optional, Tuple, Type

Expand Down Expand Up @@ -92,10 +93,20 @@ def mode_is_binary(mode: ast.AST) -> Optional[bool]:

if isinstance(mode, ast.Constant): # pragma: no cover (<py38)
return 'b' in mode.value
elif isinstance(mode, ast.Str): # pragma: no cover (py38+)
return 'b' in mode.s
else:
return None
if sys.version_info < (3, 12): # pragma: no cover (py312+)
if isinstance(mode, ast.Str): # pragma: no cover (py38+)
return 'b' in mode.s

return None


if sys.version_info < (3, 12): # pragma: no cover (py312+)
_constant_nameconstant = (ast.Constant, ast.NameConstant)
_skip_312_deprecations = False
else: # pragma: no cover (<py312)
_constant_nameconstant = ast.Constant
_skip_312_deprecations = True


class Visitor(flake8_helper.Visitor):
Expand Down Expand Up @@ -135,7 +146,7 @@ def check_open_encoding(self, node: ast.Call) -> None:
if "encoding" not in kwargs:
self.report_error(node, ENC003 if unknown_mode else ENC001)

elif isinstance(kwargs["encoding"], (ast.Constant, ast.NameConstant)):
elif isinstance(kwargs["encoding"], _constant_nameconstant):
if kwargs["encoding"].value is None:
self.report_error(node, ENC004 if unknown_mode else ENC002)

Expand All @@ -157,11 +168,12 @@ def visit_Call(self, node: ast.Call) -> None: # noqa: D102
self.check_open_encoding(node)
return

if isinstance(node.func.value, ast.Str): # pragma: no cover
# Attribute on a string
return self.generic_visit(node)
if not _skip_312_deprecations: # pragma: no cover (py312+)
if isinstance(node.func.value, ast.Str): # pragma: no cover
# Attribute on a string
return self.generic_visit(node)

elif isinstance(node.func.value, ast.BinOp): # pragma: no cover
if isinstance(node.func.value, ast.BinOp): # pragma: no cover
# TODO
# Expressions such as (tmp_pathplus / "code.py").write_text(example_source)
return self.generic_visit(node)
Expand Down Expand Up @@ -226,7 +238,7 @@ def check_configparser_encoding(self, node: ast.Call) -> None:
if "encoding" not in kwargs:
self.report_error(node, ENC011)

elif isinstance(kwargs["encoding"], (ast.Constant, ast.NameConstant)):
elif isinstance(kwargs["encoding"], _constant_nameconstant):
if kwargs["encoding"].value is None:
self.report_error(node, ENC012)

Expand Down Expand Up @@ -275,7 +287,7 @@ def check_pathlib_encoding(self, node: ast.Call, method_name: str) -> None:
if "encoding" not in kwargs:
self.report_error(node, no_encoding)

elif isinstance(kwargs["encoding"], (ast.Constant, ast.NameConstant)):
elif isinstance(kwargs["encoding"], _constant_nameconstant):
if kwargs["encoding"].value is None:
self.report_error(node, encoding_none)

Expand All @@ -295,11 +307,12 @@ def visit_Call(self, node: ast.Call) -> None: # noqa: D102
self.check_open_encoding(node)
return

if isinstance(node.func.value, ast.Str): # pragma: no cover
# Attribute on a string
return self.generic_visit(node)
if not _skip_312_deprecations: # pragma: no cover (py312+)
if isinstance(node.func.value, ast.Str): # pragma: no cover
# Attribute on a string
return self.generic_visit(node)

elif isinstance(node.func.value, ast.BinOp): # pragma: no cover
if isinstance(node.func.value, ast.BinOp): # pragma: no cover
# TODO
# Expressions such as (tmp_pathplus / "code.py").write_text(example_source)
return self.generic_visit(node)
Expand Down

0 comments on commit 6b941dc

Please sign in to comment.