diff options
author | Claudiu Popa <pcmanticore@gmail.com> | 2017-04-13 13:03:41 +0300 |
---|---|---|
committer | Claudiu Popa <pcmanticore@gmail.com> | 2017-04-13 13:04:46 +0300 |
commit | bf3e06fcb86fef4d0273ba40f8254377a050aa00 (patch) | |
tree | d52027be112c175d5dd6a5fba8e9dea835c6ea93 | |
parent | 67b1508d91ae2983aa9b6c2ead374a6cb5ff3e3e (diff) | |
download | pylint-git-bf3e06fcb86fef4d0273ba40f8254377a050aa00.tar.gz |
We don't emit by default ``no-member`` if we have opaque inference objects in the inference results
This is controlled through the new flag ``--ignore-on-opaque-inference``, which is by
default True. The inference can return multiple potential results while
evaluating a Python object, but some branches might not be evaluated, which
results in partial inference. In that case, it might be useful to still emit
no-member and other checks for the rest of the inferred objects.
-rw-r--r-- | ChangeLog | 11 | ||||
-rw-r--r-- | doc/whatsnew/1.7.rst | 8 | ||||
-rw-r--r-- | pylint/checkers/typecheck.py | 39 | ||||
-rw-r--r-- | pylint/test/functional/member_checks.py | 2 | ||||
-rw-r--r-- | pylint/test/functional/member_checks.txt | 1 | ||||
-rw-r--r-- | pylint/test/functional/member_checks_opaque.py | 6 | ||||
-rw-r--r-- | pylint/test/functional/member_checks_opaque.rc | 2 | ||||
-rw-r--r-- | pylint/test/functional/member_checks_opaque.txt | 1 |
8 files changed, 54 insertions, 16 deletions
@@ -6,10 +6,19 @@ What's New in Pylint 1.7? ========================= Release date: tba + * Don't emit missing-final-newline or trailing-whitespace for formfeeds (page breaks). Close #1218 and #1219 - + + * Don't emit by default no-member if we have opaque inference objects in the inference results + + This is controlled through the new flag ignore-on-opaque-inference, which is by + default True. The inference can return multiple potential results while + evaluating a Python object, but some branches might not be evaluated, which + results in partial inference. In that case, it might be useful to still emit + no-member and other checks for the rest of the inferred objects. + * Added new message `assign-to-new-keyword` to warn about assigning to names which will become a keyword in future Python releases. diff --git a/doc/whatsnew/1.7.rst b/doc/whatsnew/1.7.rst index 219691760..662323536 100644 --- a/doc/whatsnew/1.7.rst +++ b/doc/whatsnew/1.7.rst @@ -596,6 +596,14 @@ New checkers Other Changes ============= +* We don't emit by default ``no-member`` if we have opaque inference objects in the inference results + + This is controlled through the new flag ``--ignore-on-opaque-inference``, which is by + default True. The inference can return multiple potential results while + evaluating a Python object, but some branches might not be evaluated, which + results in partial inference. In that case, it might be useful to still emit + no-member and other checks for the rest of the inferred objects. + * Namespace packages are now supported by pylint. This includes both explicit namespace packages and implicit namespace packages, supported in Python 3 through PEP 420. diff --git a/pylint/checkers/typecheck.py b/pylint/checkers/typecheck.py index 89f5b34c4..a504c1c40 100644 --- a/pylint/checkers/typecheck.py +++ b/pylint/checkers/typecheck.py @@ -474,7 +474,17 @@ class TypeChecker(BaseChecker): msgs = MSGS priority = -1 # configuration options - options = (('ignore-mixin-members', + options = (('ignore-on-opaque-inference', + {'default': True, 'type': 'yn', 'metavar': '<y_or_n>', + 'help': 'This flag controls whether pylint should warn about ' + 'no-member and similar checks whenever an opaque object ' + 'is returned when inferring. The inference can return ' + 'multiple potential results while evaluating a Python object, ' + 'but some branches might not be evaluated, which results in ' + 'partial inference. In that case, it might be useful to still emit ' + 'no-member and other checks for the rest of the inferred objects.'} + ), + ('ignore-mixin-members', {'default' : True, 'type' : 'yn', 'metavar': '<y_or_n>', 'help' : 'Tells whether missing members accessed in mixin \ class should be ignored. A mixin class is detected if its name ends with \ @@ -610,22 +620,26 @@ accessed. Python regular expressions are accepted.'} return try: - infered = list(node.expr.infer()) + inferred = list(node.expr.infer()) except exceptions.InferenceError: return + # list of (node, nodename) which are missing the attribute missingattr = set() - inference_failure = False - for owner in infered: - # skip yes object - if owner is astroid.YES: - inference_failure = True - continue - if isinstance(owner, astroid.nodes.Unknown): - inference_failure = True - continue + non_opaque_inference_results = [ + owner for owner in inferred + if owner is not astroid.Uninferable + and not isinstance(owner, astroid.nodes.Unknown) + ] + if (len(non_opaque_inference_results) != len(inferred) + and self.config.ignore_on_opaque_inference): + # There is an ambiguity in the inference. Since we can't + # make sure that we won't emit a false positive, we just stop + # whenever the inference returns an opaque inference object. + return + for owner in non_opaque_inference_results: name = getattr(owner, 'name', None) if _is_owner_ignored(owner, name, self.config.ignored_classes, self.config.ignored_modules): @@ -666,7 +680,6 @@ accessed. Python regular expressions are accepted.'} if actual in done: continue done.add(actual) - confidence = INFERENCE if not inference_failure else INFERENCE_FAILURE if self.config.missing_member_hint: hint = _missing_member_hint(owner, node.attrname, @@ -678,7 +691,7 @@ accessed. Python regular expressions are accepted.'} self.add_message('no-member', node=node, args=(owner.display_type(), name, node.attrname, hint), - confidence=confidence) + confidence=INFERENCE) @check_messages('assignment-from-no-return', 'assignment-from-none') def visit_assign(self, node): diff --git a/pylint/test/functional/member_checks.py b/pylint/test/functional/member_checks.py index 86dcc0d0a..cb5f2313c 100644 --- a/pylint/test/functional/member_checks.py +++ b/pylint/test/functional/member_checks.py @@ -83,7 +83,7 @@ class Getattribute(object): print(object.__init__) print(property.__init__) -print(Client().set_later.lower()) # [no-member] +print(Client().set_later.lower()) print(Mixin().nanana()) print(Getattr().nananan()) print(Getattribute().batman()) diff --git a/pylint/test/functional/member_checks.txt b/pylint/test/functional/member_checks.txt index f599da943..bf5f2c2c8 100644 --- a/pylint/test/functional/member_checks.txt +++ b/pylint/test/functional/member_checks.txt @@ -7,7 +7,6 @@ no-member:55:Client.test_bt_types:Instance of 'tuple' has no 'append' member:INF no-member:57:Client.test_bt_types:Instance of 'str' has no 'loower' member; maybe 'lower'?:INFERENCE no-member:59:Client.test_bt_types:Instance of 'int' has no 'whatever' member:INFERENCE no-member:65:Client.test_no_false_positives:Super of 'Client' has no 'misssing' member:INFERENCE -no-member:86::Instance of 'int' has no 'lower' member:INFERENCE_FAILURE no-member:97::Instance of 'Client' has no 'indeed' member:INFERENCE no-member:104::Class 'Client' has no 'missing' member:INFERENCE no-member:110::Class 'Client' has no 'missing' member:INFERENCE diff --git a/pylint/test/functional/member_checks_opaque.py b/pylint/test/functional/member_checks_opaque.py new file mode 100644 index 000000000..d5e71a775 --- /dev/null +++ b/pylint/test/functional/member_checks_opaque.py @@ -0,0 +1,6 @@ +# pylint: disable=missing-docstring + +import json + + +json.loads('bar').get('baz') # [no-member] diff --git a/pylint/test/functional/member_checks_opaque.rc b/pylint/test/functional/member_checks_opaque.rc new file mode 100644 index 000000000..025cd2a0f --- /dev/null +++ b/pylint/test/functional/member_checks_opaque.rc @@ -0,0 +1,2 @@ +[TYPECHECK] +ignore-on-opaque-inference=n diff --git a/pylint/test/functional/member_checks_opaque.txt b/pylint/test/functional/member_checks_opaque.txt new file mode 100644 index 000000000..68af2e6b9 --- /dev/null +++ b/pylint/test/functional/member_checks_opaque.txt @@ -0,0 +1 @@ +no-member:6::Instance of 'bool' has no 'get' member:INFERENCE |