Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Unified Diff: third_party/pylint/checkers/base.py

Issue 876793002: pylint: upgrade to 1.4.1 (Closed) Base URL: https://chromium.googlesource.com/chromium/tools/depot_tools.git@master
Patch Set: Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « third_party/pylint/__pkginfo__.py ('k') | third_party/pylint/checkers/classes.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/pylint/checkers/base.py
diff --git a/third_party/pylint/checkers/base.py b/third_party/pylint/checkers/base.py
index 8198d1647f93a7a4ef0e00dd4c03fe6f5d36f917..750d661f669e0597bc8534e757643ef9f1fdcfd2 100644
--- a/third_party/pylint/checkers/base.py
+++ b/third_party/pylint/checkers/base.py
@@ -45,6 +45,7 @@ from pylint.checkers.utils import (
has_known_bases,
NoSuchArgumentError,
is_import_error,
+ unimplemented_abstract_methods,
)
@@ -148,8 +149,7 @@ if sys.version_info < (3, 0):
PROPERTY_CLASSES = set(('__builtin__.property', 'abc.abstractproperty'))
else:
PROPERTY_CLASSES = set(('builtins.property', 'abc.abstractproperty'))
-ABC_METHODS = set(('abc.abstractproperty', 'abc.abstractmethod',
- 'abc.abstractclassmethod', 'abc.abstractstaticmethod'))
+
def _determine_function_name_type(node):
"""Determine the name type whose regex the a function's name should match.
@@ -179,26 +179,17 @@ def _determine_function_name_type(node):
return 'attr'
return 'method'
-def decorated_with_abc(func):
- """ Determine if the `func` node is decorated
- with `abc` decorators (abstractmethod et co.)
- """
- if func.decorators:
- for node in func.decorators.nodes:
- try:
- infered = next(node.infer())
- except InferenceError:
- continue
- if infered and infered.qname() in ABC_METHODS:
- return True
-def has_abstract_methods(node):
+
+def _has_abstract_methods(node):
"""
- Determine if the given `node` has
- abstract methods, defined with `abc` module.
+ Determine if the given `node` has abstract methods.
+
+ The methods should be made abstract by decorating them
+ with `abc` decorators.
"""
- return any(decorated_with_abc(meth)
- for meth in node.methods())
+ return len(unimplemented_abstract_methods(node)) > 0
+
def report_by_type_stats(sect, stats, old_stats):
"""make a report of
@@ -298,7 +289,7 @@ class BasicErrorChecker(_BasicChecker):
'duplicate-argument-name',
'Duplicate argument names in function definitions are syntax'
' errors.'),
- 'E0110': ('Abstract class with abstract methods instantiated',
+ 'E0110': ('Abstract class %r with abstract methods instantiated',
'abstract-class-instantiated',
'Used when an abstract class with `abc.ABCMeta` as metaclass '
'has abstract methods and is instantiated.'),
@@ -398,17 +389,21 @@ class BasicErrorChecker(_BasicChecker):
return
# __init__ was called
metaclass = infered.metaclass()
- abstract_methods = has_abstract_methods(infered)
+ abstract_methods = _has_abstract_methods(infered)
if metaclass is None:
# Python 3.4 has `abc.ABC`, which won't be detected
# by ClassNode.metaclass()
for ancestor in infered.ancestors():
if ancestor.qname() == 'abc.ABC' and abstract_methods:
- self.add_message('abstract-class-instantiated', node=node)
+ self.add_message('abstract-class-instantiated',
+ args=(infered.name, ),
+ node=node)
break
return
if metaclass.qname() == 'abc.ABCMeta' and abstract_methods:
- self.add_message('abstract-class-instantiated', node=node)
+ self.add_message('abstract-class-instantiated',
+ args=(infered.name, ),
+ node=node)
def _check_else_on_loop(self, node):
"""Check that any loop with an else clause has a break statement."""
@@ -676,7 +671,13 @@ functions, methods
variable names, max locals
"""
self.stats[node.is_method() and 'method' or 'function'] += 1
+ self._check_dangerous_default(node)
+
+ def _check_dangerous_default(self, node):
# check for dangerous default values as arguments
+ is_iterable = lambda n: isinstance(n, (astroid.List,
+ astroid.Set,
+ astroid.Dict))
for default in node.args.defaults:
try:
value = next(default.infer())
@@ -685,21 +686,30 @@ functions, methods
if (isinstance(value, astroid.Instance) and
value.qname() in DEFAULT_ARGUMENT_SYMBOLS):
+
if value is default:
msg = DEFAULT_ARGUMENT_SYMBOLS[value.qname()]
- elif type(value) is astroid.Instance:
- if isinstance(default, astroid.CallFunc):
- # this argument is direct call to list() or dict() etc
+ elif type(value) is astroid.Instance or is_iterable(value):
+ # We are here in the following situation(s):
+ # * a dict/set/list/tuple call which wasn't inferred
+ # to a syntax node ({}, () etc.). This can happen
+ # when the arguments are invalid or unknown to
+ # the inference.
+ # * a variable from somewhere else, which turns out to be a list
+ # or a dict.
+ if is_iterable(default):
+ msg = value.pytype()
+ elif isinstance(default, astroid.CallFunc):
msg = '%s() (%s)' % (value.name, value.qname())
else:
- # this argument is a variable from somewhere else which turns
- # out to be a list or dict
msg = '%s (%s)' % (default.as_string(), value.qname())
else:
# this argument is a name
msg = '%s (%s)' % (default.as_string(),
DEFAULT_ARGUMENT_SYMBOLS[value.qname()])
- self.add_message('dangerous-default-value', node=node, args=(msg,))
+ self.add_message('dangerous-default-value',
+ node=node,
+ args=(msg, ))
@check_messages('unreachable', 'lost-exception')
def visit_return(self, node):
« no previous file with comments | « third_party/pylint/__pkginfo__.py ('k') | third_party/pylint/checkers/classes.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698