Skip to content

Commit

Permalink
Introduced DeprecatedMixin
Browse files Browse the repository at this point in the history
  • Loading branch information
matusvalo committed Feb 1, 2021
1 parent 8649b72 commit 5a9a6af
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 34 deletions.
4 changes: 4 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
------------------
Pylint's ChangeLog
------------------
* Introduce DeprecationMixin for reusable deprecation checks.

Closes #4049

* Bug fix for empty-comment message line number.

Closes #4009
Expand Down
1 change: 1 addition & 0 deletions pylint/checkers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
"""

from pylint.checkers.base_checker import BaseChecker, BaseTokenChecker
from pylint.checkers.deprecated import DeprecatedMixin
from pylint.checkers.mapreduce_checker import MapReduceMixin
from pylint.utils import register_plugins

Expand Down
36 changes: 36 additions & 0 deletions pylint/checkers/deprecated.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
# For details: https://github.com/PyCQA/pylint/blob/master/COPYING

"""Checker mixin for deprecated functionality."""

import abc

import astroid


class DeprecatedMixin(metaclass=abc.ABCMeta):
@abc.abstractmethod
def deprecated_methods(self):
"""Returns Iterator of deprecated methods."""

def check_deprecated_method(self, node, inferred):

if isinstance(node.func, astroid.Attribute):
func_name = node.func.attrname
elif isinstance(node.func, astroid.Name):
func_name = node.func.name
else:
# Not interested in other nodes.
return

# Reject nodes which aren't of interest to us.
acceptable_nodes = (
astroid.BoundMethod,
astroid.UnboundMethod,
astroid.FunctionDef,
)
if not isinstance(inferred, acceptable_nodes):
return
qname = inferred.qname()
if any(name in self.deprecated_methods() for name in (qname, func_name)):
self.add_message("deprecated-method", node=node, args=(func_name,))
46 changes: 12 additions & 34 deletions pylint/checkers/stdlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
from astroid.bases import Instance
from astroid.node_classes import Const

from pylint.checkers import BaseChecker, utils
from pylint.checkers import BaseChecker, DeprecatedMixin, utils
from pylint.interfaces import IAstroidChecker

OPEN_FILES = {"open", "file"}
Expand Down Expand Up @@ -80,7 +80,7 @@ def _check_mode_str(mode):
return True


class StdlibChecker(BaseChecker):
class StdlibChecker(BaseChecker, DeprecatedMixin):
__implements__ = (IAstroidChecker,)
name = "stdlib"

Expand Down Expand Up @@ -336,7 +336,7 @@ def visit_call(self, node):
self._check_env_function(node, inferred)
elif name == SUBPROCESS_RUN:
self._check_for_check_kw_in_run(node)
self._check_deprecated_method(node, inferred)
self.check_deprecated_method(node, inferred)
except astroid.InferenceError:
return

Expand All @@ -358,37 +358,6 @@ def visit_boolop(self, node):
for value in node.values:
self._check_datetime(value)

def _check_deprecated_method(self, node, inferred):
py_vers = sys.version_info[0]

if isinstance(node.func, astroid.Attribute):
func_name = node.func.attrname
elif isinstance(node.func, astroid.Name):
func_name = node.func.name
else:
# Not interested in other nodes.
return

# Reject nodes which aren't of interest to us.
acceptable_nodes = (
astroid.BoundMethod,
astroid.UnboundMethod,
astroid.FunctionDef,
)
if not isinstance(inferred, acceptable_nodes):
return

qname = inferred.qname()
if any(name in self.deprecated[0] for name in (qname, func_name)):
self.add_message("deprecated-method", node=node, args=(func_name,))
else:
for since_vers, func_list in self.deprecated[py_vers].items():
if since_vers <= sys.version_info and any(
name in func_list for name in (qname, func_name)
):
self.add_message("deprecated-method", node=node, args=(func_name,))
break

def _check_redundant_assert(self, node, infer):
if (
isinstance(infer, astroid.BoundMethod)
Expand Down Expand Up @@ -481,6 +450,15 @@ def _check_invalid_envvar_value(self, node, infer, message, call_arg, allow_none
else:
self.add_message(message, node=node, args=(name, call_arg.pytype()))

def deprecated_methods(self):
py_vers = sys.version_info[0]
deprecated_methods = set()
deprecated_methods.update(self.deprecated[0])
for since_vers, func_list in self.deprecated[py_vers].items():
if since_vers <= sys.version_info:
deprecated_methods.update(func_list)
return deprecated_methods


def register(linter):
"""required method to auto register this checker """
Expand Down

0 comments on commit 5a9a6af

Please sign in to comment.