diff options
author | Claudiu Popa <cpopa@cloudbasesolutions.com> | 2015-04-19 12:41:30 +0300 |
---|---|---|
committer | Claudiu Popa <cpopa@cloudbasesolutions.com> | 2015-04-19 12:41:30 +0300 |
commit | 28323597be5777e09364ef999e162417437d05fc (patch) | |
tree | 925623d891c3066d0b0036805761e9e774cfc6e1 | |
parent | 35bb01bcd89e3e35b165fab3b080722b497e084e (diff) | |
download | pylint-28323597be5777e09364ef999e162417437d05fc.tar.gz |
Look for __init__ instead of __new__ in _determine_callable_obj if __new__ comes from builtins.
Since the __new__ comes from builtins, it will not have attached any
information regarding what parameters it expects, so the check
will be useless. Retrieving __init__ in that case will at least
detect a couple of false negatives. Closes issue #429.
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | pylint/checkers/typecheck.py | 10 | ||||
-rw-r--r-- | pylint/test/functional/ctor_arguments.py | 7 | ||||
-rw-r--r-- | pylint/test/functional/ctor_arguments.txt | 2 |
4 files changed, 24 insertions, 3 deletions
@@ -57,6 +57,14 @@ ChangeLog for Pylint * Provide some hints for the bad-builtin message. Closes issue #522. + * When checking for invalid arguments to a callable, in typecheck.py, + look up for the __init__ in case the found __new__ comes from builtins. + + Since the __new__ comes from builtins, it will not have attached any + information regarding what parameters it expects, so the check + will be useless. Retrieving __init__ in that case will at least + detect a couple of false negatives. Closes issue #429. + 2015-03-14 -- 1.4.3 diff --git a/pylint/checkers/typecheck.py b/pylint/checkers/typecheck.py index 58ce4be..ef3b799 100644 --- a/pylint/checkers/typecheck.py +++ b/pylint/checkers/typecheck.py @@ -103,14 +103,18 @@ def _determine_callable(callable_obj): elif isinstance(callable_obj, astroid.Class): # Class instantiation, lookup __new__ instead. # If we only find object.__new__, we can safely check __init__ - # instead. + # instead. If __new__ belongs to builtins, then we look + # again for __init__ in the locals, since we won't have + # argument information for the builtin __new__ function. try: # Use the last definition of __new__. new = callable_obj.local_attr('__new__')[-1] except astroid.NotFoundError: new = None - if not new or new.parent.scope().name == 'object': + from_object = new and new.parent.scope().name == 'object' + from_builtins = new and new.root().name == BUILTINS + if not new or from_object or from_builtins: try: # Use the last definition of __init__. callable_obj = callable_obj.local_attr('__init__')[-1] @@ -122,7 +126,7 @@ def _determine_callable(callable_obj): if not isinstance(callable_obj, astroid.Function): raise ValueError - # both have an extra implicit 'cls'/'self' argument. + # both have an extra implicit 'cls'/'self' argument. return callable_obj, 1, 'constructor' else: raise ValueError diff --git a/pylint/test/functional/ctor_arguments.py b/pylint/test/functional/ctor_arguments.py index 7dc0a09..f052831 100644 --- a/pylint/test/functional/ctor_arguments.py +++ b/pylint/test/functional/ctor_arguments.py @@ -76,3 +76,10 @@ class ClassWithMeta(with_metaclass(Metaclass)): pass ClassWithMeta() + + +class BuiltinExc(Exception): + def __init__(self, val=True): + self.val = val + +BuiltinExc(42, 24, badarg=1) # [too-many-function-args,unexpected-keyword-arg] diff --git a/pylint/test/functional/ctor_arguments.txt b/pylint/test/functional/ctor_arguments.txt index 85cf139..817e805 100644 --- a/pylint/test/functional/ctor_arguments.txt +++ b/pylint/test/functional/ctor_arguments.txt @@ -15,3 +15,5 @@ too-many-function-args:60::Too many positional arguments for constructor call too-many-function-args:63::Too many positional arguments for constructor call no-value-for-parameter:64::No value for argument 'first_argument' in constructor call unexpected-keyword-arg:64::Unexpected keyword argument 'one' in constructor call +too-many-function-args:85::Too many positional arguments for constructor call +unexpected-keyword-arg:85::Unexpected keyword argument 'badarg' in constructor call |