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

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

Issue 753543006: pylint: upgrade to 1.4.0 (Closed) Base URL: https://chromium.googlesource.com/chromium/tools/depot_tools.git@master
Patch Set: Created 6 years 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/checkers/strings.py ('k') | third_party/pylint/checkers/utils.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/pylint/checkers/typecheck.py
diff --git a/third_party/pylint/checkers/typecheck.py b/third_party/pylint/checkers/typecheck.py
index fb8f3c6e769c5217992bb7d82e4e5fb2d0dd1368..10b9f8669fb9353ab9e4766e5174a6ef5a257078 100644
--- a/third_party/pylint/checkers/typecheck.py
+++ b/third_party/pylint/checkers/typecheck.py
@@ -23,23 +23,21 @@ import astroid
from astroid import InferenceError, NotFoundError, YES, Instance
from astroid.bases import BUILTINS
-from pylint.interfaces import IAstroidChecker
+from pylint.interfaces import IAstroidChecker, INFERENCE, INFERENCE_FAILURE
from pylint.checkers import BaseChecker
-from pylint.checkers.utils import safe_infer, is_super, check_messages
+from pylint.checkers.utils import (
+ safe_infer, is_super,
+ check_messages, decorated_with_property)
MSGS = {
'E1101': ('%s %r has no %r member',
'no-member',
- 'Used when a variable is accessed for an unexistent member.'),
+ 'Used when a variable is accessed for an unexistent member.',
+ {'old_names': [('E1103', 'maybe-no-member')]}),
'E1102': ('%s is not callable',
'not-callable',
'Used when an object being called has been inferred to a non \
callable object'),
- 'E1103': ('%s %r has no %r member (but some types could not be inferred)',
- 'maybe-no-member',
- 'Used when a variable is accessed for an unexistent member, but \
- astroid was not able to interpret all possible types of this \
- variable.'),
'E1111': ('Assigning to function call which doesn\'t return',
'assignment-from-no-return',
'Used when an assignment is done on a function call but the \
@@ -56,11 +54,6 @@ MSGS = {
'too-many-function-args',
'Used when a function call passes too many positional \
arguments.'),
- 'E1122': ('Duplicate keyword argument %r in %s call',
- 'duplicate-keyword-arg',
- 'Used when a function call passes the same keyword argument \
- multiple times.',
- {'maxversion': (2, 6)}),
'E1123': ('Unexpected keyword argument %r in %s call',
'unexpected-keyword-arg',
'Used when a function call passes a keyword argument that \
@@ -192,7 +185,7 @@ accessed. Python regular expressions are accepted.'}
def visit_delattr(self, node):
self.visit_getattr(node)
- @check_messages('no-member', 'maybe-no-member')
+ @check_messages('no-member')
def visit_getattr(self, node):
"""check that the accessed attribute exists
@@ -254,6 +247,20 @@ accessed. Python regular expressions are accepted.'}
# explicit skipping of module member access
if owner.root().name in self.config.ignored_modules:
continue
+ if isinstance(owner, astroid.Class):
+ # Look up in the metaclass only if the owner is itself
+ # a class.
+ # TODO: getattr doesn't return by default members
+ # from the metaclass, because handling various cases
+ # of methods accessible from the metaclass itself
+ # and/or subclasses only is too complicated for little to
+ # no benefit.
+ metaclass = owner.metaclass()
+ try:
+ if metaclass and metaclass.getattr(node.attrname):
+ continue
+ except NotFoundError:
+ pass
missingattr.add((owner, name))
continue
# stop on the first found
@@ -270,13 +277,11 @@ accessed. Python regular expressions are accepted.'}
if actual in done:
continue
done.add(actual)
- if inference_failure:
- msgid = 'maybe-no-member'
- else:
- msgid = 'no-member'
- self.add_message(msgid, node=node,
+ confidence = INFERENCE if not inference_failure else INFERENCE_FAILURE
+ self.add_message('no-member', node=node,
args=(owner.display_type(), name,
- node.attrname))
+ node.attrname),
+ confidence=confidence)
@check_messages('assignment-from-no-return', 'assignment-from-none')
def visit_assign(self, node):
@@ -333,43 +338,17 @@ accessed. Python regular expressions are accepted.'}
except astroid.NotFoundError:
return
- stop_checking = False
for attr in attrs:
if attr is astroid.YES:
continue
- if stop_checking:
- break
if not isinstance(attr, astroid.Function):
continue
# Decorated, see if it is decorated with a property
- if not attr.decorators:
- continue
- for decorator in attr.decorators.nodes:
- if not isinstance(decorator, astroid.Name):
- continue
- try:
- for infered in decorator.infer():
- property_like = False
- if isinstance(infered, astroid.Class):
- if (infered.root().name == BUILTINS and
- infered.name == 'property'):
- property_like = True
- else:
- for ancestor in infered.ancestors():
- if (ancestor.name == 'property' and
- ancestor.root().name == BUILTINS):
- property_like = True
- break
- if property_like:
- self.add_message('not-callable', node=node,
- args=node.func.as_string())
- stop_checking = True
- break
- except InferenceError:
- pass
- if stop_checking:
- break
+ if decorated_with_property(attr):
+ self.add_message('not-callable', node=node,
+ args=node.func.as_string())
+ break
@check_messages(*(list(MSGS.keys())))
def visit_callfunc(self, node):
@@ -383,11 +362,7 @@ accessed. Python regular expressions are accepted.'}
num_positional_args = 0
for arg in node.args:
if isinstance(arg, astroid.Keyword):
- keyword = arg.arg
- if keyword in keyword_args:
- self.add_message('duplicate-keyword-arg', node=node,
- args=(keyword, 'function'))
- keyword_args.add(keyword)
+ keyword_args.add(arg.arg)
else:
num_positional_args += 1
@@ -549,7 +524,6 @@ accessed. Python regular expressions are accepted.'}
# slice or instances with __index__.
parent_type = safe_infer(node.parent.value)
-
if not isinstance(parent_type, (astroid.Class, astroid.Instance)):
return
@@ -578,13 +552,10 @@ accessed. Python regular expressions are accepted.'}
if not isinstance(itemmethod, astroid.Function):
return
-
if itemmethod.root().name != BUILTINS:
return
-
if not itemmethod.parent:
return
-
if itemmethod.parent.name not in SEQUENCE_TYPES:
return
@@ -595,7 +566,6 @@ accessed. Python regular expressions are accepted.'}
index_type = node
else:
index_type = safe_infer(node)
-
if index_type is None or index_type is astroid.YES:
return
@@ -607,7 +577,6 @@ accessed. Python regular expressions are accepted.'}
elif isinstance(index_type, astroid.Instance):
if index_type.pytype() in (BUILTINS + '.int', BUILTINS + '.slice'):
return
-
try:
index_type.getattr('__index__')
return
@@ -625,7 +594,6 @@ accessed. Python regular expressions are accepted.'}
continue
index_type = safe_infer(index)
-
if index_type is None or index_type is astroid.YES:
continue
« no previous file with comments | « third_party/pylint/checkers/strings.py ('k') | third_party/pylint/checkers/utils.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698