8th day of python challenges 111-117
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
""" This should not warn about `prop` being abstract in Child """
|
||||
# pylint: disable=too-few-public-methods, no-absolute-import,metaclass-assignment, useless-object-inheritance
|
||||
|
||||
import abc
|
||||
|
||||
class Parent(object):
|
||||
"""Abstract Base Class """
|
||||
__metaclass__ = abc.ABCMeta
|
||||
|
||||
@property
|
||||
@abc.abstractmethod
|
||||
def prop(self):
|
||||
""" Abstract """
|
||||
|
||||
class Child(Parent):
|
||||
""" No warning for the following. """
|
||||
prop = property(lambda self: 1)
|
||||
@@ -0,0 +1,20 @@
|
||||
"""Don't warn if the class is instantiated in its own body."""
|
||||
# pylint: disable=missing-docstring, useless-object-inheritance
|
||||
|
||||
|
||||
import abc
|
||||
|
||||
import six
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class Ala(object):
|
||||
|
||||
@abc.abstractmethod
|
||||
def bala(self):
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def portocala(cls):
|
||||
instance = cls()
|
||||
return instance
|
||||
@@ -0,0 +1,82 @@
|
||||
"""Check that instantiating a class with
|
||||
`abc.ABCMeta` as metaclass fails if it defines
|
||||
abstract methods.
|
||||
"""
|
||||
|
||||
# pylint: disable=too-few-public-methods, missing-docstring, useless-object-inheritance
|
||||
# pylint: disable=no-absolute-import, metaclass-assignment
|
||||
# pylint: disable=abstract-method, import-error, wildcard-import
|
||||
|
||||
import abc
|
||||
from abc import ABCMeta
|
||||
from lala import Bala
|
||||
|
||||
|
||||
class GoodClass(object):
|
||||
__metaclass__ = abc.ABCMeta
|
||||
|
||||
class SecondGoodClass(object):
|
||||
__metaclass__ = abc.ABCMeta
|
||||
|
||||
def test(self):
|
||||
""" do nothing. """
|
||||
|
||||
class ThirdGoodClass(object):
|
||||
__metaclass__ = abc.ABCMeta
|
||||
|
||||
def test(self):
|
||||
raise NotImplementedError()
|
||||
|
||||
class FourthGoodClass(object):
|
||||
__metaclass__ = ABCMeta
|
||||
|
||||
class BadClass(object):
|
||||
__metaclass__ = abc.ABCMeta
|
||||
|
||||
@abc.abstractmethod
|
||||
def test(self):
|
||||
""" do nothing. """
|
||||
|
||||
class SecondBadClass(object):
|
||||
__metaclass__ = abc.ABCMeta
|
||||
|
||||
@property
|
||||
@abc.abstractmethod
|
||||
def test(self):
|
||||
""" do nothing. """
|
||||
|
||||
class ThirdBadClass(object):
|
||||
__metaclass__ = ABCMeta
|
||||
|
||||
@abc.abstractmethod
|
||||
def test(self):
|
||||
pass
|
||||
|
||||
class FourthBadClass(ThirdBadClass):
|
||||
pass
|
||||
|
||||
|
||||
class SomeMetaclass(object):
|
||||
__metaclass__ = ABCMeta
|
||||
|
||||
@abc.abstractmethod
|
||||
def prop(self):
|
||||
pass
|
||||
|
||||
class FifthGoodClass(SomeMetaclass):
|
||||
"""Don't consider this abstract if some attributes are
|
||||
there, but can't be inferred.
|
||||
"""
|
||||
prop = Bala # missing
|
||||
|
||||
|
||||
def main():
|
||||
""" do nothing """
|
||||
GoodClass()
|
||||
SecondGoodClass()
|
||||
ThirdGoodClass()
|
||||
FourthGoodClass()
|
||||
BadClass() # [abstract-class-instantiated]
|
||||
SecondBadClass() # [abstract-class-instantiated]
|
||||
ThirdBadClass() # [abstract-class-instantiated]
|
||||
FourthBadClass() # [abstract-class-instantiated]
|
||||
@@ -0,0 +1,2 @@
|
||||
[testoptions]
|
||||
max_pyver=3.0
|
||||
@@ -0,0 +1,4 @@
|
||||
abstract-class-instantiated:79:main:Abstract class 'BadClass' with abstract methods instantiated
|
||||
abstract-class-instantiated:80:main:Abstract class 'SecondBadClass' with abstract methods instantiated
|
||||
abstract-class-instantiated:81:main:Abstract class 'ThirdBadClass' with abstract methods instantiated
|
||||
abstract-class-instantiated:82:main:Abstract class 'FourthBadClass' with abstract methods instantiated
|
||||
@@ -0,0 +1,128 @@
|
||||
"""Check that instantiating a class with
|
||||
`abc.ABCMeta` as metaclass fails if it defines
|
||||
abstract methods.
|
||||
"""
|
||||
|
||||
# pylint: disable=too-few-public-methods, missing-docstring
|
||||
# pylint: disable=abstract-method, import-error, useless-object-inheritance
|
||||
|
||||
import abc
|
||||
import weakref
|
||||
from lala import Bala
|
||||
|
||||
|
||||
class GoodClass(object, metaclass=abc.ABCMeta):
|
||||
pass
|
||||
|
||||
class SecondGoodClass(object, metaclass=abc.ABCMeta):
|
||||
def test(self):
|
||||
""" do nothing. """
|
||||
|
||||
class ThirdGoodClass(object, metaclass=abc.ABCMeta):
|
||||
""" This should not raise the warning. """
|
||||
def test(self):
|
||||
raise NotImplementedError()
|
||||
|
||||
class BadClass(object, metaclass=abc.ABCMeta):
|
||||
@abc.abstractmethod
|
||||
def test(self):
|
||||
""" do nothing. """
|
||||
|
||||
class SecondBadClass(object, metaclass=abc.ABCMeta):
|
||||
@property
|
||||
@abc.abstractmethod
|
||||
def test(self):
|
||||
""" do nothing. """
|
||||
|
||||
class ThirdBadClass(SecondBadClass):
|
||||
pass
|
||||
|
||||
|
||||
class Structure(object, metaclass=abc.ABCMeta):
|
||||
@abc.abstractmethod
|
||||
def __iter__(self):
|
||||
pass
|
||||
@abc.abstractmethod
|
||||
def __len__(self):
|
||||
pass
|
||||
@abc.abstractmethod
|
||||
def __contains__(self, _):
|
||||
pass
|
||||
@abc.abstractmethod
|
||||
def __hash__(self):
|
||||
pass
|
||||
|
||||
class Container(Structure):
|
||||
def __contains__(self, _):
|
||||
pass
|
||||
|
||||
class Sizable(Structure):
|
||||
def __len__(self):
|
||||
pass
|
||||
|
||||
class Hashable(Structure):
|
||||
__hash__ = 42
|
||||
|
||||
|
||||
class Iterator(Structure):
|
||||
def keys(self): # pylint: disable=no-self-use
|
||||
return iter([1, 2, 3])
|
||||
|
||||
__iter__ = keys
|
||||
|
||||
class AbstractSizable(Structure):
|
||||
@abc.abstractmethod
|
||||
def length(self):
|
||||
pass
|
||||
__len__ = length
|
||||
|
||||
class NoMroAbstractMethods(Container, Iterator, Sizable, Hashable):
|
||||
pass
|
||||
|
||||
class BadMroAbstractMethods(Container, Iterator, AbstractSizable):
|
||||
pass
|
||||
|
||||
class SomeMetaclass(metaclass=abc.ABCMeta):
|
||||
|
||||
@abc.abstractmethod
|
||||
def prop(self):
|
||||
pass
|
||||
|
||||
class FourthGoodClass(SomeMetaclass):
|
||||
"""Don't consider this abstract if some attributes are
|
||||
there, but can't be inferred.
|
||||
"""
|
||||
prop = Bala # missing
|
||||
|
||||
|
||||
def main():
|
||||
""" do nothing """
|
||||
GoodClass()
|
||||
SecondGoodClass()
|
||||
ThirdGoodClass()
|
||||
FourthGoodClass()
|
||||
weakref.WeakKeyDictionary()
|
||||
weakref.WeakValueDictionary()
|
||||
NoMroAbstractMethods()
|
||||
|
||||
BadMroAbstractMethods() # [abstract-class-instantiated]
|
||||
BadClass() # [abstract-class-instantiated]
|
||||
SecondBadClass() # [abstract-class-instantiated]
|
||||
ThirdBadClass() # [abstract-class-instantiated]
|
||||
|
||||
|
||||
if 1: # pylint: disable=using-constant-test
|
||||
class FourthBadClass(object, metaclass=abc.ABCMeta):
|
||||
|
||||
def test(self):
|
||||
pass
|
||||
else:
|
||||
class FourthBadClass(object, metaclass=abc.ABCMeta):
|
||||
|
||||
@abc.abstractmethod
|
||||
def test(self):
|
||||
pass
|
||||
|
||||
|
||||
def main2():
|
||||
FourthBadClass() # [abstract-class-instantiated]
|
||||
@@ -0,0 +1,2 @@
|
||||
[testoptions]
|
||||
min_pyver=3.0
|
||||
@@ -0,0 +1,5 @@
|
||||
abstract-class-instantiated:108:main:Abstract class 'BadMroAbstractMethods' with abstract methods instantiated
|
||||
abstract-class-instantiated:109:main:Abstract class 'BadClass' with abstract methods instantiated
|
||||
abstract-class-instantiated:110:main:Abstract class 'SecondBadClass' with abstract methods instantiated
|
||||
abstract-class-instantiated:111:main:Abstract class 'ThirdBadClass' with abstract methods instantiated
|
||||
abstract-class-instantiated:128:main2:Abstract class 'FourthBadClass' with abstract methods instantiated
|
||||
@@ -0,0 +1,19 @@
|
||||
"""
|
||||
Check that instantiating a class with `abc.ABCMeta` as ancestor fails if it
|
||||
defines abstract methods.
|
||||
"""
|
||||
|
||||
# pylint: disable=too-few-public-methods, missing-docstring, no-init
|
||||
|
||||
import abc
|
||||
|
||||
|
||||
|
||||
class BadClass(abc.ABC):
|
||||
@abc.abstractmethod
|
||||
def test(self):
|
||||
pass
|
||||
|
||||
def main():
|
||||
""" do nothing """
|
||||
BadClass() # [abstract-class-instantiated]
|
||||
@@ -0,0 +1,2 @@
|
||||
[testoptions]
|
||||
min_pyver=3.4
|
||||
@@ -0,0 +1 @@
|
||||
abstract-class-instantiated:19:main:Abstract class 'BadClass' with abstract methods instantiated
|
||||
@@ -0,0 +1,90 @@
|
||||
"""Test abstract-method warning."""
|
||||
from __future__ import print_function
|
||||
|
||||
# pylint: disable=missing-docstring, no-init, no-self-use
|
||||
# pylint: disable=too-few-public-methods, useless-object-inheritance
|
||||
import abc
|
||||
|
||||
class Abstract(object):
|
||||
def aaaa(self):
|
||||
"""should be overridden in concrete class"""
|
||||
raise NotImplementedError()
|
||||
|
||||
def bbbb(self):
|
||||
"""should be overridden in concrete class"""
|
||||
raise NotImplementedError()
|
||||
|
||||
|
||||
class AbstractB(Abstract):
|
||||
"""Abstract class.
|
||||
|
||||
this class is checking that it does not output an error msg for
|
||||
unimplemeted methods in abstract classes
|
||||
"""
|
||||
def cccc(self):
|
||||
"""should be overridden in concrete class"""
|
||||
raise NotImplementedError()
|
||||
|
||||
class Concrete(Abstract): # [abstract-method]
|
||||
"""Concrete class"""
|
||||
|
||||
def aaaa(self):
|
||||
"""overidden form Abstract"""
|
||||
|
||||
|
||||
class Structure(object):
|
||||
__metaclass__ = abc.ABCMeta
|
||||
|
||||
@abc.abstractmethod
|
||||
def __iter__(self):
|
||||
pass
|
||||
@abc.abstractmethod
|
||||
def __len__(self):
|
||||
pass
|
||||
@abc.abstractmethod
|
||||
def __contains__(self, _):
|
||||
pass
|
||||
@abc.abstractmethod
|
||||
def __hash__(self):
|
||||
pass
|
||||
|
||||
|
||||
# +1: [abstract-method, abstract-method, abstract-method]
|
||||
class Container(Structure):
|
||||
def __contains__(self, _):
|
||||
pass
|
||||
|
||||
|
||||
# +1: [abstract-method, abstract-method, abstract-method]
|
||||
class Sizable(Structure):
|
||||
def __len__(self):
|
||||
pass
|
||||
|
||||
|
||||
# +1: [abstract-method, abstract-method, abstract-method]
|
||||
class Hashable(Structure):
|
||||
__hash__ = 42
|
||||
|
||||
|
||||
# +1: [abstract-method, abstract-method, abstract-method]
|
||||
class Iterator(Structure):
|
||||
def keys(self):
|
||||
return iter([1, 2, 3])
|
||||
|
||||
__iter__ = keys
|
||||
|
||||
|
||||
class AbstractSizable(Structure):
|
||||
@abc.abstractmethod
|
||||
def length(self):
|
||||
pass
|
||||
__len__ = length
|
||||
|
||||
|
||||
class GoodComplexMRO(Container, Iterator, Sizable, Hashable):
|
||||
pass
|
||||
|
||||
|
||||
# +1: [abstract-method, abstract-method, abstract-method]
|
||||
class BadComplexMro(Container, Iterator, AbstractSizable):
|
||||
pass
|
||||
@@ -0,0 +1,2 @@
|
||||
[testoptions]
|
||||
max_pyver=3.0
|
||||
@@ -0,0 +1,16 @@
|
||||
abstract-method:28:Concrete:"Method 'bbbb' is abstract in class 'Abstract' but is not overridden"
|
||||
abstract-method:53:Container:"Method '__hash__' is abstract in class 'Structure' but is not overridden"
|
||||
abstract-method:53:Container:"Method '__iter__' is abstract in class 'Structure' but is not overridden"
|
||||
abstract-method:53:Container:"Method '__len__' is abstract in class 'Structure' but is not overridden"
|
||||
abstract-method:59:Sizable:"Method '__contains__' is abstract in class 'Structure' but is not overridden"
|
||||
abstract-method:59:Sizable:"Method '__hash__' is abstract in class 'Structure' but is not overridden"
|
||||
abstract-method:59:Sizable:"Method '__iter__' is abstract in class 'Structure' but is not overridden"
|
||||
abstract-method:65:Hashable:"Method '__contains__' is abstract in class 'Structure' but is not overridden"
|
||||
abstract-method:65:Hashable:"Method '__iter__' is abstract in class 'Structure' but is not overridden"
|
||||
abstract-method:65:Hashable:"Method '__len__' is abstract in class 'Structure' but is not overridden"
|
||||
abstract-method:70:Iterator:"Method '__contains__' is abstract in class 'Structure' but is not overridden"
|
||||
abstract-method:70:Iterator:"Method '__hash__' is abstract in class 'Structure' but is not overridden"
|
||||
abstract-method:70:Iterator:"Method '__len__' is abstract in class 'Structure' but is not overridden"
|
||||
abstract-method:89:BadComplexMro:"Method '__hash__' is abstract in class 'Structure' but is not overridden"
|
||||
abstract-method:89:BadComplexMro:"Method '__len__' is abstract in class 'AbstractSizable' but is not overridden"
|
||||
abstract-method:89:BadComplexMro:"Method 'length' is abstract in class 'AbstractSizable' but is not overridden"
|
||||
@@ -0,0 +1,88 @@
|
||||
"""Test abstract-method warning."""
|
||||
from __future__ import print_function
|
||||
|
||||
# pylint: disable=missing-docstring, no-init, no-self-use
|
||||
# pylint: disable=too-few-public-methods, useless-object-inheritance
|
||||
import abc
|
||||
|
||||
class Abstract(object):
|
||||
def aaaa(self):
|
||||
"""should be overridden in concrete class"""
|
||||
raise NotImplementedError()
|
||||
|
||||
def bbbb(self):
|
||||
"""should be overridden in concrete class"""
|
||||
raise NotImplementedError()
|
||||
|
||||
|
||||
class AbstractB(Abstract):
|
||||
"""Abstract class.
|
||||
|
||||
this class is checking that it does not output an error msg for
|
||||
unimplemeted methods in abstract classes
|
||||
"""
|
||||
def cccc(self):
|
||||
"""should be overridden in concrete class"""
|
||||
raise NotImplementedError()
|
||||
|
||||
class Concrete(Abstract): # [abstract-method]
|
||||
"""Concrete class"""
|
||||
|
||||
def aaaa(self):
|
||||
"""overidden form Abstract"""
|
||||
|
||||
|
||||
class Structure(object, metaclass=abc.ABCMeta):
|
||||
@abc.abstractmethod
|
||||
def __iter__(self):
|
||||
pass
|
||||
@abc.abstractmethod
|
||||
def __len__(self):
|
||||
pass
|
||||
@abc.abstractmethod
|
||||
def __contains__(self, _):
|
||||
pass
|
||||
@abc.abstractmethod
|
||||
def __hash__(self):
|
||||
pass
|
||||
|
||||
|
||||
# +1: [abstract-method, abstract-method, abstract-method]
|
||||
class Container(Structure):
|
||||
def __contains__(self, _):
|
||||
pass
|
||||
|
||||
|
||||
# +1: [abstract-method, abstract-method, abstract-method]
|
||||
class Sizable(Structure):
|
||||
def __len__(self):
|
||||
pass
|
||||
|
||||
|
||||
# +1: [abstract-method, abstract-method, abstract-method]
|
||||
class Hashable(Structure):
|
||||
__hash__ = 42
|
||||
|
||||
|
||||
# +1: [abstract-method, abstract-method, abstract-method]
|
||||
class Iterator(Structure):
|
||||
def keys(self):
|
||||
return iter([1, 2, 3])
|
||||
|
||||
__iter__ = keys
|
||||
|
||||
|
||||
class AbstractSizable(Structure):
|
||||
@abc.abstractmethod
|
||||
def length(self):
|
||||
pass
|
||||
__len__ = length
|
||||
|
||||
|
||||
class GoodComplexMRO(Container, Iterator, Sizable, Hashable):
|
||||
pass
|
||||
|
||||
|
||||
# +1: [abstract-method, abstract-method, abstract-method]
|
||||
class BadComplexMro(Container, Iterator, AbstractSizable):
|
||||
pass
|
||||
@@ -0,0 +1,2 @@
|
||||
[testoptions]
|
||||
min_pyver=3.0
|
||||
@@ -0,0 +1,16 @@
|
||||
abstract-method:28:Concrete:"Method 'bbbb' is abstract in class 'Abstract' but is not overridden"
|
||||
abstract-method:51:Container:"Method '__hash__' is abstract in class 'Structure' but is not overridden"
|
||||
abstract-method:51:Container:"Method '__iter__' is abstract in class 'Structure' but is not overridden"
|
||||
abstract-method:51:Container:"Method '__len__' is abstract in class 'Structure' but is not overridden"
|
||||
abstract-method:57:Sizable:"Method '__contains__' is abstract in class 'Structure' but is not overridden"
|
||||
abstract-method:57:Sizable:"Method '__hash__' is abstract in class 'Structure' but is not overridden"
|
||||
abstract-method:57:Sizable:"Method '__iter__' is abstract in class 'Structure' but is not overridden"
|
||||
abstract-method:63:Hashable:"Method '__contains__' is abstract in class 'Structure' but is not overridden"
|
||||
abstract-method:63:Hashable:"Method '__iter__' is abstract in class 'Structure' but is not overridden"
|
||||
abstract-method:63:Hashable:"Method '__len__' is abstract in class 'Structure' but is not overridden"
|
||||
abstract-method:68:Iterator:"Method '__contains__' is abstract in class 'Structure' but is not overridden"
|
||||
abstract-method:68:Iterator:"Method '__hash__' is abstract in class 'Structure' but is not overridden"
|
||||
abstract-method:68:Iterator:"Method '__len__' is abstract in class 'Structure' but is not overridden"
|
||||
abstract-method:87:BadComplexMro:"Method '__hash__' is abstract in class 'Structure' but is not overridden"
|
||||
abstract-method:87:BadComplexMro:"Method '__len__' is abstract in class 'AbstractSizable' but is not overridden"
|
||||
abstract-method:87:BadComplexMro:"Method 'length' is abstract in class 'AbstractSizable' but is not overridden"
|
||||
@@ -0,0 +1,40 @@
|
||||
# pylint: disable=missing-docstring,too-few-public-methods,invalid-name
|
||||
# pylint: disable=attribute-defined-outside-init, useless-object-inheritance
|
||||
|
||||
class Aaaa(object):
|
||||
"""class with attributes defined in wrong order"""
|
||||
|
||||
def __init__(self):
|
||||
var1 = self._var2 # [access-member-before-definition]
|
||||
self._var2 = 3
|
||||
self._var3 = var1
|
||||
|
||||
|
||||
class Bbbb(object):
|
||||
A = 23
|
||||
B = A
|
||||
|
||||
def __getattr__(self, attr):
|
||||
try:
|
||||
return self.__repo
|
||||
except AttributeError:
|
||||
self.__repo = attr
|
||||
return attr
|
||||
|
||||
|
||||
def catchme(self, attr):
|
||||
"""no AttributeError catched"""
|
||||
try:
|
||||
return self._repo # [access-member-before-definition]
|
||||
except ValueError:
|
||||
self._repo = attr
|
||||
return attr
|
||||
|
||||
|
||||
class Mixin(object):
|
||||
|
||||
def test_mixin(self):
|
||||
"""Don't emit access-member-before-definition for mixin classes."""
|
||||
if self.already_defined:
|
||||
# pylint: disable=attribute-defined-outside-init
|
||||
self.already_defined = None
|
||||
@@ -0,0 +1,2 @@
|
||||
access-member-before-definition:8:Aaaa.__init__:Access to member '_var2' before its definition line 9
|
||||
access-member-before-definition:28:Bbbb.catchme:Access to member '_repo' before its definition line 30
|
||||
@@ -0,0 +1,21 @@
|
||||
# pylint: disable=too-few-public-methods, print-statement, useless-object-inheritance
|
||||
"""test access to __name__ gives undefined member on new/old class instances
|
||||
but not on new/old class object
|
||||
"""
|
||||
from __future__ import print_function
|
||||
|
||||
class Aaaa:
|
||||
"""old class"""
|
||||
def __init__(self):
|
||||
print(self.__name__) # [no-member]
|
||||
print(self.__class__.__name__)
|
||||
|
||||
class NewClass(object):
|
||||
"""new class"""
|
||||
|
||||
def __new__(cls, *args, **kwargs):
|
||||
print('new', cls.__name__)
|
||||
return object.__new__(cls, *args, **kwargs)
|
||||
|
||||
def __init__(self):
|
||||
print('init', self.__name__) # [no-member]
|
||||
@@ -0,0 +1,2 @@
|
||||
no-member:10:Aaaa.__init__:Instance of 'Aaaa' has no '__name__' member:INFERENCE
|
||||
no-member:21:NewClass.__init__:Instance of 'NewClass' has no '__name__' member:INFERENCE
|
||||
@@ -0,0 +1,59 @@
|
||||
# pylint: disable=too-few-public-methods, W0231, print-statement, useless-object-inheritance
|
||||
# pylint: disable=no-classmethod-decorator
|
||||
"""Test external access to protected class members."""
|
||||
from __future__ import print_function
|
||||
|
||||
class MyClass(object):
|
||||
"""Class with protected members."""
|
||||
_cls_protected = 5
|
||||
|
||||
def __init__(self, other):
|
||||
MyClass._cls_protected = 6
|
||||
self._protected = 1
|
||||
self.public = other
|
||||
self.attr = 0
|
||||
|
||||
def test(self):
|
||||
"""Docstring."""
|
||||
self._protected += self._cls_protected
|
||||
print(self.public._haha) # [protected-access]
|
||||
|
||||
def clsmeth(cls):
|
||||
"""Docstring."""
|
||||
cls._cls_protected += 1
|
||||
print(cls._cls_protected)
|
||||
clsmeth = classmethod(clsmeth)
|
||||
|
||||
def _private_method(self):
|
||||
"""Doing nothing."""
|
||||
|
||||
|
||||
class Subclass(MyClass):
|
||||
"""Subclass with protected members."""
|
||||
|
||||
def __init__(self):
|
||||
MyClass._protected = 5
|
||||
super(Subclass, self)._private_method()
|
||||
|
||||
INST = Subclass()
|
||||
INST.attr = 1
|
||||
print(INST.attr)
|
||||
INST._protected = 2 # [protected-access]
|
||||
print(INST._protected) # [protected-access]
|
||||
INST._cls_protected = 3 # [protected-access]
|
||||
print(INST._cls_protected) # [protected-access]
|
||||
|
||||
|
||||
class Issue1031(object):
|
||||
"""Test for GitHub issue 1031"""
|
||||
_attr = 1
|
||||
|
||||
def correct_access(self):
|
||||
"""Demonstrates correct access"""
|
||||
return type(self)._attr
|
||||
|
||||
def incorrect_access(self):
|
||||
"""Demonstrates incorrect access"""
|
||||
if self._attr == 1:
|
||||
return type(INST)._protected # [protected-access]
|
||||
return None
|
||||
@@ -0,0 +1,6 @@
|
||||
protected-access:19:MyClass.test:Access to a protected member _haha of a client class
|
||||
protected-access:41::Access to a protected member _protected of a client class
|
||||
protected-access:42::Access to a protected member _protected of a client class
|
||||
protected-access:43::Access to a protected member _cls_protected of a client class
|
||||
protected-access:44::Access to a protected member _cls_protected of a client class
|
||||
protected-access:58:Issue1031.incorrect_access:Access to a protected member _protected of a client class
|
||||
@@ -0,0 +1,20 @@
|
||||
# pylint:disable=W0105, W0511
|
||||
"""Test for backslash escapes in byte vs unicode strings"""
|
||||
|
||||
# Would be valid in Unicode, but probably not what you want otherwise
|
||||
BAD_UNICODE = b'\u0042' # [anomalous-unicode-escape-in-string]
|
||||
BAD_LONG_UNICODE = b'\U00000042' # [anomalous-unicode-escape-in-string]
|
||||
# +1:[anomalous-unicode-escape-in-string]
|
||||
BAD_NAMED_UNICODE = b'\N{GREEK SMALL LETTER ALPHA}'
|
||||
|
||||
GOOD_UNICODE = u'\u0042'
|
||||
GOOD_LONG_UNICODE = u'\U00000042'
|
||||
GOOD_NAMED_UNICODE = u'\N{GREEK SMALL LETTER ALPHA}'
|
||||
|
||||
|
||||
# Valid raw strings
|
||||
RAW_BACKSLASHES = r'raw'
|
||||
RAW_UNICODE = ur"\u0062\n"
|
||||
|
||||
# In a comment you can have whatever you want: \ \\ \n \m
|
||||
# even things that look like bad strings: "C:\Program Files"
|
||||
@@ -0,0 +1,2 @@
|
||||
[testoptions]
|
||||
max_pyver=3.0
|
||||
@@ -0,0 +1,3 @@
|
||||
anomalous-unicode-escape-in-string:5::"Anomalous Unicode escape in byte string: '\u'. String constant might be missing an r or u prefix."
|
||||
anomalous-unicode-escape-in-string:6::"Anomalous Unicode escape in byte string: '\U'. String constant might be missing an r or u prefix."
|
||||
anomalous-unicode-escape-in-string:8::"Anomalous Unicode escape in byte string: '\N'. String constant might be missing an r or u prefix."
|
||||
@@ -0,0 +1,19 @@
|
||||
# pylint:disable=W0105, W0511
|
||||
"""Test for backslash escapes in byte vs unicode strings"""
|
||||
|
||||
# Would be valid in Unicode, but probably not what you want otherwise
|
||||
BAD_UNICODE = b'\u0042' # [anomalous-unicode-escape-in-string]
|
||||
BAD_LONG_UNICODE = b'\U00000042' # [anomalous-unicode-escape-in-string]
|
||||
# +1:[anomalous-unicode-escape-in-string]
|
||||
BAD_NAMED_UNICODE = b'\N{GREEK SMALL LETTER ALPHA}'
|
||||
|
||||
GOOD_UNICODE = u'\u0042'
|
||||
GOOD_LONG_UNICODE = u'\U00000042'
|
||||
GOOD_NAMED_UNICODE = u'\N{GREEK SMALL LETTER ALPHA}'
|
||||
|
||||
|
||||
# Valid raw strings
|
||||
RAW_BACKSLASHES = r'raw'
|
||||
|
||||
# In a comment you can have whatever you want: \ \\ \n \m
|
||||
# even things that look like bad strings: "C:\Program Files"
|
||||
@@ -0,0 +1,2 @@
|
||||
[testoptions]
|
||||
min_pyver=3.0
|
||||
@@ -0,0 +1,3 @@
|
||||
anomalous-unicode-escape-in-string:5::"Anomalous Unicode escape in byte string: '\u'. String constant might be missing an r or u prefix."
|
||||
anomalous-unicode-escape-in-string:6::"Anomalous Unicode escape in byte string: '\U'. String constant might be missing an r or u prefix."
|
||||
anomalous-unicode-escape-in-string:8::"Anomalous Unicode escape in byte string: '\N'. String constant might be missing an r or u prefix."
|
||||
@@ -0,0 +1,217 @@
|
||||
# pylint: disable=too-few-public-methods, no-absolute-import,missing-docstring,import-error,wrong-import-position
|
||||
# pylint: disable=wrong-import-order, useless-object-inheritance
|
||||
|
||||
def decorator(fun):
|
||||
"""Decorator"""
|
||||
return fun
|
||||
|
||||
|
||||
class DemoClass(object):
|
||||
"""Test class for method invocations."""
|
||||
|
||||
@staticmethod
|
||||
def static_method(arg):
|
||||
"""static method."""
|
||||
return arg + arg
|
||||
|
||||
@classmethod
|
||||
def class_method(cls, arg):
|
||||
"""class method"""
|
||||
return arg + arg
|
||||
|
||||
def method(self, arg):
|
||||
"""method."""
|
||||
return (self, arg)
|
||||
|
||||
@decorator
|
||||
def decorated_method(self, arg):
|
||||
"""decorated method."""
|
||||
return (self, arg)
|
||||
|
||||
|
||||
def function_1_arg(first_argument):
|
||||
"""one argument function"""
|
||||
return first_argument
|
||||
|
||||
def function_3_args(first_argument, second_argument, third_argument):
|
||||
"""three arguments function"""
|
||||
return first_argument, second_argument, third_argument
|
||||
|
||||
def function_default_arg(one=1, two=2):
|
||||
"""fonction with default value"""
|
||||
return two, one
|
||||
|
||||
|
||||
function_1_arg(420)
|
||||
function_1_arg() # [no-value-for-parameter]
|
||||
function_1_arg(1337, 347) # [too-many-function-args]
|
||||
|
||||
function_3_args(420, 789) # [no-value-for-parameter]
|
||||
# +1:[no-value-for-parameter,no-value-for-parameter,no-value-for-parameter]
|
||||
function_3_args()
|
||||
function_3_args(1337, 347, 456)
|
||||
function_3_args('bab', 'bebe', None, 5.6) # [too-many-function-args]
|
||||
|
||||
function_default_arg(1, two=5)
|
||||
function_default_arg(two=5)
|
||||
|
||||
function_1_arg(bob=4) # [unexpected-keyword-arg,no-value-for-parameter]
|
||||
function_default_arg(1, 4, coin="hello") # [unexpected-keyword-arg]
|
||||
|
||||
function_default_arg(1, one=5) # [redundant-keyword-arg]
|
||||
|
||||
# Remaining tests are for coverage of correct names in messages.
|
||||
LAMBDA = lambda arg: 1
|
||||
|
||||
LAMBDA() # [no-value-for-parameter]
|
||||
|
||||
def method_tests():
|
||||
"""Method invocations."""
|
||||
demo = DemoClass()
|
||||
demo.static_method() # [no-value-for-parameter]
|
||||
DemoClass.static_method() # [no-value-for-parameter]
|
||||
|
||||
demo.class_method() # [no-value-for-parameter]
|
||||
DemoClass.class_method() # [no-value-for-parameter]
|
||||
|
||||
demo.method() # [no-value-for-parameter]
|
||||
DemoClass.method(demo) # [no-value-for-parameter]
|
||||
|
||||
demo.decorated_method() # [no-value-for-parameter]
|
||||
DemoClass.decorated_method(demo) # [no-value-for-parameter]
|
||||
|
||||
# Test a regression (issue #234)
|
||||
import sys
|
||||
|
||||
class Text(object):
|
||||
""" Regression """
|
||||
|
||||
if sys.version_info > (3,):
|
||||
def __new__(cls):
|
||||
""" empty """
|
||||
return object.__new__(cls)
|
||||
else:
|
||||
def __new__(cls):
|
||||
""" empty """
|
||||
return object.__new__(cls)
|
||||
|
||||
Text()
|
||||
|
||||
class TestStaticMethod(object):
|
||||
|
||||
@staticmethod
|
||||
def test(first, second=None, **kwargs):
|
||||
return first, second, kwargs
|
||||
|
||||
def func(self):
|
||||
self.test(42)
|
||||
self.test(42, second=34)
|
||||
self.test(42, 42)
|
||||
self.test() # [no-value-for-parameter]
|
||||
self.test(42, 42, 42) # [too-many-function-args]
|
||||
|
||||
|
||||
class TypeCheckConstructor(object):
|
||||
def __init__(self, first, second):
|
||||
self.first = first
|
||||
self.second = second
|
||||
def test(self):
|
||||
type(self)(1, 2, 3) # [too-many-function-args]
|
||||
# +1: [no-value-for-parameter,no-value-for-parameter]
|
||||
type(self)()
|
||||
type(self)(1, lala=2) # [no-value-for-parameter,unexpected-keyword-arg]
|
||||
type(self)(1, 2)
|
||||
type(self)(first=1, second=2)
|
||||
|
||||
|
||||
class Test(object):
|
||||
""" lambda needs Test instance as first argument """
|
||||
lam = lambda self, icon: (self, icon)
|
||||
|
||||
def test(self):
|
||||
self.lam(42)
|
||||
self.lam() # [no-value-for-parameter]
|
||||
self.lam(1, 2, 3) # [too-many-function-args]
|
||||
|
||||
Test().lam() # [no-value-for-parameter]
|
||||
|
||||
# Don't emit a redundant-keyword-arg for this example,
|
||||
# it's perfectly valid
|
||||
|
||||
class Issue642(object):
|
||||
attr = 0
|
||||
def __str__(self):
|
||||
return "{self.attr}".format(self=self)
|
||||
|
||||
# These should not emit anything regarding the number of arguments,
|
||||
# since they have something invalid.
|
||||
from ala_bala_portocola import unknown
|
||||
|
||||
# pylint: disable=not-a-mapping,not-an-iterable
|
||||
|
||||
function_1_arg(*unknown)
|
||||
function_1_arg(1, *2)
|
||||
function_1_arg(1, 2, 3, **unknown)
|
||||
function_1_arg(4, 5, **1)
|
||||
function_1_arg(5, 6, **{unknown: 1})
|
||||
function_1_arg(**{object: 1})
|
||||
function_1_arg(**{1: 2})
|
||||
|
||||
def no_context_but_redefined(*args):
|
||||
args = [1]
|
||||
#+1: [no-value-for-parameter, no-value-for-parameter]
|
||||
expect_three(*list(args))
|
||||
|
||||
def no_context_one_elem(*args):
|
||||
expect_three(args) # [no-value-for-parameter, no-value-for-parameter]
|
||||
|
||||
# Don't emit no-value-for-parameter for this, since we
|
||||
# don't have the context at our disposal.
|
||||
def expect_three(one, two, three):
|
||||
return one + two + three
|
||||
|
||||
|
||||
def no_context(*args):
|
||||
expect_three(*args)
|
||||
|
||||
def no_context_two(*args):
|
||||
expect_three(*list(args))
|
||||
|
||||
def no_context_three(*args):
|
||||
expect_three(*set(args))
|
||||
|
||||
def compare_prices(arg):
|
||||
return set((arg, ))
|
||||
|
||||
def find_problems2(prob_dates):
|
||||
for fff in range(10):
|
||||
prob_dates |= compare_prices(fff)
|
||||
|
||||
|
||||
from collections import namedtuple
|
||||
|
||||
|
||||
def namedtuple_replace_issue_1036():
|
||||
cls = namedtuple('cls', 'a b c')
|
||||
new_instance = cls(1, 2, 3)._replace(
|
||||
a=24,
|
||||
b=24,
|
||||
c=42
|
||||
)
|
||||
# +1:[unexpected-keyword-arg,unexpected-keyword-arg]
|
||||
new_bad_instance = cls(1, 2, 3)._replace(d=24, e=32)
|
||||
return new_instance, new_bad_instance
|
||||
|
||||
|
||||
from functools import partial
|
||||
|
||||
def some_func(first, second, third):
|
||||
return first + second + third
|
||||
|
||||
|
||||
partial(some_func, 1, 2)(3)
|
||||
partial(some_func, third=1, second=2)(3)
|
||||
partial(some_func, 1, third=2)(second=3)
|
||||
partial(some_func, 1)(1) # [no-value-for-parameter]
|
||||
partial(some_func, 1)(third=1) # [no-value-for-parameter]
|
||||
partial(some_func, 1, 2)(third=1, fourth=4) # [unexpected-keyword-arg]
|
||||
@@ -0,0 +1,39 @@
|
||||
no-value-for-parameter:46::No value for argument 'first_argument' in function call
|
||||
too-many-function-args:47::Too many positional arguments for function call
|
||||
no-value-for-parameter:49::No value for argument 'third_argument' in function call
|
||||
no-value-for-parameter:51::No value for argument 'first_argument' in function call
|
||||
no-value-for-parameter:51::No value for argument 'second_argument' in function call
|
||||
no-value-for-parameter:51::No value for argument 'third_argument' in function call
|
||||
too-many-function-args:53::Too many positional arguments for function call
|
||||
no-value-for-parameter:58::No value for argument 'first_argument' in function call
|
||||
unexpected-keyword-arg:58::Unexpected keyword argument 'bob' in function call
|
||||
unexpected-keyword-arg:59::Unexpected keyword argument 'coin' in function call
|
||||
redundant-keyword-arg:61::Argument 'one' passed by position and keyword in function call
|
||||
no-value-for-parameter:66::No value for argument 'arg' in lambda call
|
||||
no-value-for-parameter:71:method_tests:No value for argument 'arg' in staticmethod call
|
||||
no-value-for-parameter:72:method_tests:No value for argument 'arg' in staticmethod call
|
||||
no-value-for-parameter:74:method_tests:No value for argument 'arg' in classmethod call
|
||||
no-value-for-parameter:75:method_tests:No value for argument 'arg' in classmethod call
|
||||
no-value-for-parameter:77:method_tests:No value for argument 'arg' in method call
|
||||
no-value-for-parameter:78:method_tests:No value for argument 'arg' in unbound method call
|
||||
no-value-for-parameter:80:method_tests:No value for argument 'arg' in method call
|
||||
no-value-for-parameter:81:method_tests:No value for argument 'arg' in unbound method call
|
||||
no-value-for-parameter:110:TestStaticMethod.func:No value for argument 'first' in staticmethod call
|
||||
too-many-function-args:111:TestStaticMethod.func:Too many positional arguments for staticmethod call
|
||||
too-many-function-args:119:TypeCheckConstructor.test:Too many positional arguments for constructor call
|
||||
no-value-for-parameter:121:TypeCheckConstructor.test:No value for argument 'first' in constructor call
|
||||
no-value-for-parameter:121:TypeCheckConstructor.test:No value for argument 'second' in constructor call
|
||||
no-value-for-parameter:122:TypeCheckConstructor.test:No value for argument 'second' in constructor call
|
||||
unexpected-keyword-arg:122:TypeCheckConstructor.test:Unexpected keyword argument 'lala' in constructor call
|
||||
no-value-for-parameter:133:Test.test:No value for argument 'icon' in method call
|
||||
too-many-function-args:134:Test.test:Too many positional arguments for method call
|
||||
no-value-for-parameter:136::No value for argument 'icon' in method call
|
||||
no-value-for-parameter:163:no_context_but_redefined:No value for argument 'three' in function call
|
||||
no-value-for-parameter:163:no_context_but_redefined:No value for argument 'two' in function call
|
||||
no-value-for-parameter:166:no_context_one_elem:No value for argument 'three' in function call
|
||||
no-value-for-parameter:166:no_context_one_elem:No value for argument 'two' in function call
|
||||
unexpected-keyword-arg:202:namedtuple_replace_issue_1036:Unexpected keyword argument 'd' in method call
|
||||
unexpected-keyword-arg:202:namedtuple_replace_issue_1036:Unexpected keyword argument 'e' in method call
|
||||
no-value-for-parameter:215::No value for argument 'third' in function call
|
||||
no-value-for-parameter:216::No value for argument 'second' in function call
|
||||
unexpected-keyword-arg:217::Unexpected keyword argument 'fourth' in function call
|
||||
@@ -0,0 +1,210 @@
|
||||
"""Test that we are emitting arguments-differ when the arguments are different."""
|
||||
# pylint: disable=missing-docstring, too-few-public-methods, unused-argument,useless-super-delegation, useless-object-inheritance
|
||||
|
||||
class Parent(object):
|
||||
|
||||
def test(self):
|
||||
pass
|
||||
|
||||
|
||||
class Child(Parent):
|
||||
|
||||
def test(self, arg): # [arguments-differ]
|
||||
pass
|
||||
|
||||
|
||||
class ParentDefaults(object):
|
||||
|
||||
def test(self, arg=None, barg=None):
|
||||
pass
|
||||
|
||||
class ChildDefaults(ParentDefaults):
|
||||
|
||||
def test(self, arg=None): # [arguments-differ]
|
||||
pass
|
||||
|
||||
|
||||
class Classmethod(object):
|
||||
|
||||
@classmethod
|
||||
def func(cls, data):
|
||||
return data
|
||||
|
||||
@classmethod
|
||||
def func1(cls):
|
||||
return cls
|
||||
|
||||
|
||||
class ClassmethodChild(Classmethod):
|
||||
|
||||
@staticmethod
|
||||
def func(): # [arguments-differ]
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def func1(cls):
|
||||
return cls()
|
||||
|
||||
|
||||
class Builtins(dict):
|
||||
"""Ignore for builtins, for which we don't know the number of required args."""
|
||||
|
||||
@classmethod
|
||||
def fromkeys(cls, arg, arg1):
|
||||
pass
|
||||
|
||||
|
||||
class Varargs(object):
|
||||
|
||||
def has_kwargs(self, arg, **kwargs):
|
||||
pass
|
||||
|
||||
def no_kwargs(self, args):
|
||||
pass
|
||||
|
||||
|
||||
class VarargsChild(Varargs):
|
||||
|
||||
def has_kwargs(self, arg): # [arguments-differ]
|
||||
"Not okay to lose capabilities."
|
||||
|
||||
def no_kwargs(self, arg, **kwargs): # [arguments-differ]
|
||||
"Not okay to add extra capabilities."
|
||||
|
||||
|
||||
class Super(object):
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def __private(self):
|
||||
pass
|
||||
|
||||
def __private2_(self):
|
||||
pass
|
||||
|
||||
def ___private3(self):
|
||||
pass
|
||||
|
||||
def method(self, param):
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class Sub(Super):
|
||||
|
||||
# pylint: disable=unused-argument
|
||||
def __init__(self, arg):
|
||||
super(Sub, self).__init__()
|
||||
|
||||
def __private(self, arg):
|
||||
pass
|
||||
|
||||
def __private2_(self, arg):
|
||||
pass
|
||||
|
||||
def ___private3(self, arg):
|
||||
pass
|
||||
|
||||
def method(self, param='abc'):
|
||||
pass
|
||||
|
||||
|
||||
class Staticmethod(object):
|
||||
|
||||
@staticmethod
|
||||
def func(data):
|
||||
return data
|
||||
|
||||
|
||||
class StaticmethodChild(Staticmethod):
|
||||
|
||||
@classmethod
|
||||
def func(cls, data):
|
||||
return data
|
||||
|
||||
|
||||
class Property(object):
|
||||
|
||||
@property
|
||||
def close(self):
|
||||
pass
|
||||
|
||||
class PropertySetter(Property):
|
||||
|
||||
@property
|
||||
def close(self):
|
||||
pass
|
||||
|
||||
@close.setter
|
||||
def close(self, attr):
|
||||
return attr
|
||||
|
||||
|
||||
class StaticmethodChild2(Staticmethod):
|
||||
|
||||
def func(self, data):
|
||||
super(StaticmethodChild2, self).func(data)
|
||||
|
||||
|
||||
class SuperClass(object):
|
||||
|
||||
@staticmethod
|
||||
def impl(arg1, arg2, **kwargs):
|
||||
return arg1 + arg2
|
||||
|
||||
|
||||
class MyClass(SuperClass):
|
||||
|
||||
def impl(self, *args, **kwargs): # [arguments-differ]
|
||||
|
||||
super(MyClass, self).impl(*args, **kwargs)
|
||||
|
||||
|
||||
class FirstHasArgs(object):
|
||||
|
||||
def test(self, *args):
|
||||
pass
|
||||
|
||||
|
||||
class SecondChangesArgs(FirstHasArgs):
|
||||
|
||||
def test(self, first, second, *args): # [arguments-differ]
|
||||
pass
|
||||
|
||||
class Positional(object):
|
||||
|
||||
def test(self, first, second):
|
||||
pass
|
||||
|
||||
|
||||
class PositionalChild(Positional):
|
||||
|
||||
def test(self, *args): # [arguments-differ]
|
||||
"""Accepts too many.
|
||||
|
||||
Why subclassing in the first case if the behavior is different?
|
||||
"""
|
||||
super(PositionalChild, self).test(args[0], args[1])
|
||||
|
||||
|
||||
class HasSpecialMethod(object):
|
||||
|
||||
def __getitem__(self, key):
|
||||
return key
|
||||
|
||||
|
||||
class OverridesSpecialMethod(HasSpecialMethod):
|
||||
|
||||
def __getitem__(self, cheie):
|
||||
return cheie + 1
|
||||
|
||||
|
||||
class ParentClass(object):
|
||||
|
||||
def meth(self, arg, arg1):
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class ChildClass(ParentClass):
|
||||
|
||||
def meth(self, _arg, dummy):
|
||||
pass
|
||||
@@ -0,0 +1,8 @@
|
||||
arguments-differ:12:Child.test:Parameters differ from overridden 'test' method
|
||||
arguments-differ:23:ChildDefaults.test:Parameters differ from overridden 'test' method
|
||||
arguments-differ:41:ClassmethodChild.func:Parameters differ from overridden 'func' method
|
||||
arguments-differ:68:VarargsChild.has_kwargs:Parameters differ from overridden 'has_kwargs' method
|
||||
arguments-differ:71:VarargsChild.no_kwargs:Parameters differ from overridden 'no_kwargs' method
|
||||
arguments-differ:157:MyClass.impl:Parameters differ from overridden 'impl' method
|
||||
arguments-differ:170:SecondChangesArgs.test:Parameters differ from overridden 'test' method
|
||||
arguments-differ:181:PositionalChild.test:Parameters differ from overridden 'test' method
|
||||
@@ -0,0 +1,36 @@
|
||||
# pylint: disable=missing-docstring,too-few-public-methods
|
||||
class AbstractFoo:
|
||||
|
||||
def kwonly_1(self, first, *, second, third):
|
||||
"Normal positional with two positional only params."
|
||||
|
||||
def kwonly_2(self, *, first, second):
|
||||
"Two positional only parameter."
|
||||
|
||||
def kwonly_3(self, *, first, second):
|
||||
"Two positional only params."
|
||||
|
||||
def kwonly_4(self, *, first, second=None):
|
||||
"One positional only and another with a default."
|
||||
|
||||
def kwonly_5(self, *, first, **kwargs):
|
||||
"Keyword only and keyword variadics."
|
||||
|
||||
|
||||
class Foo(AbstractFoo):
|
||||
|
||||
def kwonly_1(self, first, *, second): # [arguments-differ]
|
||||
"One positional and only one positional only param."
|
||||
|
||||
def kwonly_2(self, first): # [arguments-differ]
|
||||
"Only one positional parameter instead of two positional only parameters."
|
||||
|
||||
def kwonly_3(self, first, second): # [arguments-differ]
|
||||
"Two positional params."
|
||||
|
||||
def kwonly_4(self, first, second): # [arguments-differ]
|
||||
"Two positional params."
|
||||
|
||||
def kwonly_5(self, *, first): # [arguments-differ]
|
||||
"Keyword only, but no variadics."
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
[testoptions]
|
||||
min_pyver=3.0
|
||||
@@ -0,0 +1,5 @@
|
||||
arguments-differ:22:Foo.kwonly_1:Parameters differ from overridden 'kwonly_1' method
|
||||
arguments-differ:25:Foo.kwonly_2:Parameters differ from overridden 'kwonly_2' method
|
||||
arguments-differ:28:Foo.kwonly_3:Parameters differ from overridden 'kwonly_3' method
|
||||
arguments-differ:31:Foo.kwonly_4:Parameters differ from overridden 'kwonly_4' method
|
||||
arguments-differ:34:Foo.kwonly_5:Parameters differ from overridden 'kwonly_5' method
|
||||
@@ -0,0 +1,11 @@
|
||||
'''Assert check example'''
|
||||
|
||||
# pylint: disable=misplaced-comparison-constant, comparison-with-itself
|
||||
assert (1 == 1, 2 == 2), "no error"
|
||||
assert (1 == 1, 2 == 2) # [assert-on-tuple]
|
||||
assert 1 == 1, "no error"
|
||||
assert (1 == 1, ), "no error"
|
||||
assert (1 == 1, )
|
||||
assert (1 == 1, 2 == 2, 3 == 5), "no error"
|
||||
assert ()
|
||||
assert (True, 'error msg') # [assert-on-tuple]
|
||||
@@ -0,0 +1,2 @@
|
||||
assert-on-tuple:5::Assert called on a 2-uple. Did you mean 'assert x,y'?
|
||||
assert-on-tuple:11::Assert called on a 2-uple. Did you mean 'assert x,y'?
|
||||
@@ -0,0 +1,150 @@
|
||||
""" Checks assigning attributes not found in class slots
|
||||
will trigger assigning-non-slot warning.
|
||||
"""
|
||||
# pylint: disable=too-few-public-methods, no-init, missing-docstring, no-absolute-import, import-error, useless-object-inheritance
|
||||
from collections import deque
|
||||
|
||||
from missing import Unknown
|
||||
|
||||
class Empty(object):
|
||||
""" empty """
|
||||
|
||||
class Bad(object):
|
||||
""" missing not in slots. """
|
||||
|
||||
__slots__ = ['member']
|
||||
|
||||
def __init__(self):
|
||||
self.missing = 42 # [assigning-non-slot]
|
||||
|
||||
class Bad2(object):
|
||||
""" missing not in slots """
|
||||
__slots__ = [deque.__name__, 'member']
|
||||
|
||||
def __init__(self):
|
||||
self.deque = 42
|
||||
self.missing = 42 # [assigning-non-slot]
|
||||
|
||||
class Bad3(Bad):
|
||||
""" missing not found in slots """
|
||||
|
||||
__slots__ = ['component']
|
||||
|
||||
def __init__(self):
|
||||
self.component = 42
|
||||
self.member = 24
|
||||
self.missing = 42 # [assigning-non-slot]
|
||||
super(Bad3, self).__init__()
|
||||
|
||||
class Good(Empty):
|
||||
""" missing not in slots, but Empty doesn't
|
||||
specify __slots__.
|
||||
"""
|
||||
__slots__ = ['a']
|
||||
|
||||
def __init__(self):
|
||||
self.missing = 42
|
||||
|
||||
class Good2(object):
|
||||
""" Using __dict__ in slots will be safe. """
|
||||
|
||||
__slots__ = ['__dict__', 'comp']
|
||||
|
||||
def __init__(self):
|
||||
self.comp = 4
|
||||
self.missing = 5
|
||||
|
||||
class PropertyGood(object):
|
||||
""" Using properties is safe. """
|
||||
|
||||
__slots__ = ['tmp', '_value']
|
||||
|
||||
@property
|
||||
def test(self):
|
||||
return self._value
|
||||
|
||||
@test.setter
|
||||
def test(self, value):
|
||||
# pylint: disable=attribute-defined-outside-init
|
||||
self._value = value
|
||||
|
||||
def __init__(self):
|
||||
self.test = 42
|
||||
|
||||
class PropertyGood2(object):
|
||||
""" Using properties in the body of the class is safe. """
|
||||
__slots__ = ['_value']
|
||||
|
||||
def _getter(self):
|
||||
return self._value
|
||||
|
||||
def _setter(self, value):
|
||||
# pylint: disable=attribute-defined-outside-init
|
||||
self._value = value
|
||||
|
||||
test = property(_getter, _setter)
|
||||
|
||||
def __init__(self):
|
||||
self.test = 24
|
||||
|
||||
class UnicodeSlots(object):
|
||||
"""Using unicode objects in __slots__ is okay.
|
||||
|
||||
On Python 3.3 onward, u'' is equivalent to '',
|
||||
so this test should be safe for both versions.
|
||||
"""
|
||||
__slots__ = (u'first', u'second')
|
||||
|
||||
def __init__(self):
|
||||
self.first = 42
|
||||
self.second = 24
|
||||
|
||||
|
||||
class DataDescriptor(object):
|
||||
def __init__(self, name, default=''):
|
||||
self.__name = name
|
||||
self.__default = default
|
||||
|
||||
def __get__(self, inst, cls):
|
||||
return getattr(inst, self.__name, self.__default)
|
||||
|
||||
def __set__(self, inst, value):
|
||||
setattr(inst, self.__name, value)
|
||||
|
||||
|
||||
class NonDataDescriptor(object):
|
||||
def __get__(self, inst, cls):
|
||||
return 42
|
||||
|
||||
|
||||
class SlotsWithDescriptor(object):
|
||||
__slots__ = ['_err']
|
||||
data_descriptor = DataDescriptor('_err')
|
||||
non_data_descriptor = NonDataDescriptor()
|
||||
missing_descriptor = Unknown()
|
||||
|
||||
|
||||
def dont_emit_for_descriptors():
|
||||
inst = SlotsWithDescriptor()
|
||||
# This should not emit, because attr is
|
||||
# a data descriptor
|
||||
inst.data_descriptor = 'foo'
|
||||
inst.non_data_descriptor = 'lala' # [assigning-non-slot]
|
||||
|
||||
|
||||
class ClassWithSlots(object):
|
||||
__slots__ = ['foobar']
|
||||
|
||||
|
||||
class ClassReassigningDunderClass(object):
|
||||
__slots__ = ['foobar']
|
||||
|
||||
def release(self):
|
||||
self.__class__ = ClassWithSlots
|
||||
|
||||
|
||||
class ClassReassingingInvalidLayoutClass(object):
|
||||
__slots__ = []
|
||||
|
||||
def release(self):
|
||||
self.__class__ = ClassWithSlots # [assigning-non-slot]
|
||||
@@ -0,0 +1,5 @@
|
||||
assigning-non-slot:18:Bad.__init__:Assigning to attribute 'missing' not defined in class slots
|
||||
assigning-non-slot:26:Bad2.__init__:Assigning to attribute 'missing' not defined in class slots
|
||||
assigning-non-slot:36:Bad3.__init__:Assigning to attribute 'missing' not defined in class slots
|
||||
assigning-non-slot:132:dont_emit_for_descriptors:Assigning to attribute 'non_data_descriptor' not defined in class slots
|
||||
assigning-non-slot:150:ClassReassingingInvalidLayoutClass.release:Assigning to attribute '__class__' not defined in class slots
|
||||
@@ -0,0 +1,31 @@
|
||||
# pylint: disable=missing-docstring
|
||||
|
||||
|
||||
def some_func():
|
||||
pass
|
||||
|
||||
|
||||
def decorate(func):
|
||||
"""Decorate *fn* to return ``self`` to enable chained method calls."""
|
||||
def wrapper(self, *args, **kw):
|
||||
func(self, *args, **kw)
|
||||
return 42
|
||||
return wrapper
|
||||
|
||||
|
||||
class Class:
|
||||
|
||||
def some_method(self):
|
||||
pass
|
||||
|
||||
@decorate
|
||||
def some_other_decorated_method(self):
|
||||
pass
|
||||
|
||||
def some_other_method(self):
|
||||
value = self.some_method() # [assignment-from-no-return]
|
||||
other_value = self.some_other_decorated_method()
|
||||
return value + other_value
|
||||
|
||||
|
||||
VALUE = some_func() # [assignment-from-no-return]
|
||||
@@ -0,0 +1,2 @@
|
||||
assignment-from-no-return:26:Class.some_other_method:Assigning result of a function call, where the function has no return
|
||||
assignment-from-no-return:31::Assigning result of a function call, where the function has no return
|
||||
@@ -0,0 +1,28 @@
|
||||
# pylint: disable=missing-docstring
|
||||
|
||||
import asyncio
|
||||
|
||||
|
||||
async def bla1():
|
||||
await asyncio.sleep(1)
|
||||
|
||||
|
||||
async def bla2():
|
||||
await asyncio.sleep(2)
|
||||
|
||||
|
||||
async def combining_coroutine1():
|
||||
await bla1()
|
||||
await bla2()
|
||||
|
||||
|
||||
async def combining_coroutine2():
|
||||
future1 = bla1()
|
||||
future2 = bla2()
|
||||
await asyncio.gather(future1, future2)
|
||||
|
||||
|
||||
def do_stuff():
|
||||
loop = asyncio.get_event_loop()
|
||||
loop.run_until_complete(combining_coroutine1())
|
||||
loop.run_until_complete(combining_coroutine2())
|
||||
@@ -0,0 +1,2 @@
|
||||
[testoptions]
|
||||
min_pyver=3.6
|
||||
@@ -0,0 +1,63 @@
|
||||
"""Check that Python 3.5's async functions are properly analyzed by Pylint."""
|
||||
# pylint: disable=missing-docstring,invalid-name,too-few-public-methods
|
||||
# pylint: disable=using-constant-test, useless-object-inheritance
|
||||
|
||||
async def next(): # [redefined-builtin]
|
||||
pass
|
||||
|
||||
async def some_function(arg1, arg2): # [unused-argument]
|
||||
await arg1
|
||||
|
||||
|
||||
class OtherClass(object):
|
||||
|
||||
@staticmethod
|
||||
def test():
|
||||
return 42
|
||||
|
||||
|
||||
class Class(object):
|
||||
|
||||
async def some_method(self):
|
||||
super(OtherClass, self).test() # [bad-super-call]
|
||||
|
||||
|
||||
# +1: [too-many-arguments,too-many-return-statements, too-many-branches]
|
||||
async def complex_function(this, function, has, more, arguments, than,
|
||||
one, _, should, have):
|
||||
if 1:
|
||||
return this
|
||||
if 1:
|
||||
return function
|
||||
if 1:
|
||||
return has
|
||||
if 1:
|
||||
return more
|
||||
if 1:
|
||||
return arguments
|
||||
if 1:
|
||||
return than
|
||||
try:
|
||||
return one
|
||||
finally:
|
||||
pass
|
||||
if 2:
|
||||
return should
|
||||
while True:
|
||||
pass
|
||||
if 1:
|
||||
return have
|
||||
if 2:
|
||||
return function
|
||||
if 3:
|
||||
pass
|
||||
|
||||
|
||||
# +1: [duplicate-argument-name, duplicate-argument-name, dangerous-default-value]
|
||||
async def func(a, a, b=[]):
|
||||
return a, b
|
||||
|
||||
|
||||
# +1: [empty-docstring, blacklisted-name]
|
||||
async def foo():
|
||||
""
|
||||
@@ -0,0 +1,2 @@
|
||||
[testoptions]
|
||||
min_pyver=3.5
|
||||
@@ -0,0 +1,11 @@
|
||||
redefined-builtin:5:next:"Redefining built-in 'next'"
|
||||
unused-argument:8:some_function:"Unused argument 'arg2'"
|
||||
bad-super-call:22:Class.some_method:"Bad first argument 'OtherClass' given to super()"
|
||||
too-many-arguments:26:complex_function:Too many arguments (10/5)
|
||||
too-many-branches:26:complex_function:Too many branches (13/12)
|
||||
too-many-return-statements:26:complex_function:Too many return statements (10/6)
|
||||
dangerous-default-value:57:func:Dangerous default value [] as argument
|
||||
duplicate-argument-name:57:func:Duplicate argument name a in function definition
|
||||
duplicate-argument-name:57:func:Duplicate argument name a in function definition
|
||||
blacklisted-name:62:foo:Black listed name "foo"
|
||||
empty-docstring:62:foo:Empty function docstring
|
||||
@@ -0,0 +1,62 @@
|
||||
# pylint: disable=missing-docstring,too-few-public-methods,invalid-name, useless-object-inheritance
|
||||
|
||||
class A(object):
|
||||
|
||||
def __init__(self):
|
||||
self.x = 0
|
||||
self.setUp()
|
||||
|
||||
def set_y(self, y):
|
||||
self.y = y
|
||||
|
||||
def set_x(self, x):
|
||||
self.x = x
|
||||
|
||||
def set_z(self, z):
|
||||
self.z = z # [attribute-defined-outside-init]
|
||||
|
||||
def setUp(self):
|
||||
self.x = 0
|
||||
self.y = 0
|
||||
|
||||
|
||||
class B(A):
|
||||
|
||||
def test(self):
|
||||
self.z = 44 # [attribute-defined-outside-init]
|
||||
|
||||
|
||||
class C(object):
|
||||
|
||||
def __init__(self):
|
||||
self._init()
|
||||
|
||||
def _init(self):
|
||||
self.z = 44
|
||||
|
||||
|
||||
class D(object):
|
||||
|
||||
def setUp(self):
|
||||
self.set_z()
|
||||
|
||||
def set_z(self):
|
||||
self.z = 42
|
||||
|
||||
|
||||
class E(object):
|
||||
|
||||
def __init__(self):
|
||||
i = self._init
|
||||
i()
|
||||
|
||||
def _init(self):
|
||||
self.z = 44
|
||||
|
||||
|
||||
class Mixin(object):
|
||||
|
||||
def test_mixin(self):
|
||||
"""Don't emit attribute-defined-outside-init for mixin classes."""
|
||||
if self.defined_already: # pylint: disable=access-member-before-definition
|
||||
self.defined_already = None
|
||||
@@ -0,0 +1,2 @@
|
||||
attribute-defined-outside-init:16:A.set_z:Attribute 'z' defined outside __init__
|
||||
attribute-defined-outside-init:26:B.test:Attribute 'z' defined outside __init__
|
||||
@@ -0,0 +1,232 @@
|
||||
"""Regression test case for bad-continuation."""
|
||||
# pylint: disable=print-statement,implicit-str-concat-in-sequence,using-constant-test,missing-docstring,wrong-import-position
|
||||
# Various alignment for brackets
|
||||
from __future__ import print_function
|
||||
|
||||
LIST0 = [
|
||||
1, 2, 3
|
||||
]
|
||||
LIST1 = [
|
||||
1, 2, 3
|
||||
]
|
||||
LIST2 = [
|
||||
1, 2, 3
|
||||
] # [bad-continuation]
|
||||
|
||||
# Alignment inside literals
|
||||
W0 = [1, 2, 3,
|
||||
4, 5, 6,
|
||||
7, # [bad-continuation]
|
||||
8, 9, 10,
|
||||
11, 12, 13,
|
||||
# and a comment
|
||||
14, 15, 16]
|
||||
|
||||
W1 = {
|
||||
'a': 1,
|
||||
'b': 2, # [bad-continuation]
|
||||
'c': 3,
|
||||
}
|
||||
|
||||
W2 = {
|
||||
'a': 1,
|
||||
'b': 2, # [bad-continuation]
|
||||
'c': 3,
|
||||
}
|
||||
|
||||
W2 = ['some', 'contents' # with a continued comment that may be aligned
|
||||
# under the previous comment (optionally)
|
||||
'and',
|
||||
'more', # but this
|
||||
# [bad-continuation] is not accepted
|
||||
'contents', # [bad-continuation] nor this.
|
||||
]
|
||||
|
||||
# Values in dictionaries should be indented 4 spaces further if they are on a
|
||||
# different line than their key
|
||||
W4 = {
|
||||
'key1':
|
||||
'value1', # Grandfather in the old style
|
||||
'key2':
|
||||
'value2', # [bad-continuation]
|
||||
'key3':
|
||||
'value3', # Comma here
|
||||
}
|
||||
|
||||
# And should follow the same rules as continuations within parens
|
||||
W5 = {
|
||||
'key1': 'long value'
|
||||
'long continuation',
|
||||
'key2': 'breaking'
|
||||
'wrong', # [bad-continuation]
|
||||
'key3': 2*(
|
||||
2+2),
|
||||
'key4': ('parenthesis',
|
||||
'continuation') # No comma here
|
||||
}
|
||||
|
||||
# Allow values to line up with their keys when the key is next to the brace
|
||||
W6 = {'key1':
|
||||
'value1',
|
||||
'key2':
|
||||
'value2',
|
||||
}
|
||||
|
||||
# Or allow them to be indented
|
||||
W7 = {'key1':
|
||||
'value1',
|
||||
'key2':
|
||||
'value2'
|
||||
}
|
||||
|
||||
# Bug that caused a warning on the previous two cases permitted these odd
|
||||
# incorrect indentations
|
||||
W8 = {'key1':
|
||||
'value1', # [bad-continuation]
|
||||
}
|
||||
|
||||
W9 = {'key1':
|
||||
'value1', # [bad-continuation]
|
||||
}
|
||||
|
||||
# Alignment of arguments in function definitions
|
||||
def continue1(some_arg,
|
||||
some_other_arg):
|
||||
"""A function with well-aligned arguments."""
|
||||
print(some_arg, some_other_arg)
|
||||
|
||||
|
||||
def continue2(
|
||||
some_arg,
|
||||
some_other_arg):
|
||||
"""A function with well-aligned arguments."""
|
||||
print(some_arg, some_other_arg)
|
||||
|
||||
def continue3(
|
||||
some_arg, # [bad-continuation]
|
||||
some_other_arg): # [bad-continuation]
|
||||
"""A function with misaligned arguments"""
|
||||
print(some_arg, some_other_arg)
|
||||
|
||||
def continue4( # pylint:disable=missing-docstring
|
||||
arg1,
|
||||
arg2): print(arg1, arg2)
|
||||
|
||||
|
||||
def callee(*args):
|
||||
"""noop"""
|
||||
print(args)
|
||||
|
||||
|
||||
callee(
|
||||
"a",
|
||||
"b"
|
||||
)
|
||||
|
||||
callee("a",
|
||||
"b") # [bad-continuation]
|
||||
|
||||
callee(5, {'a': 'b',
|
||||
'c': 'd'})
|
||||
|
||||
if (
|
||||
1
|
||||
): pass
|
||||
|
||||
if (
|
||||
1
|
||||
): pass
|
||||
if (
|
||||
1
|
||||
): pass # [bad-continuation]
|
||||
|
||||
if (1 and
|
||||
2): # [bad-continuation]
|
||||
pass
|
||||
|
||||
while (1 and
|
||||
2):
|
||||
pass
|
||||
|
||||
while (1 and
|
||||
2 and # [bad-continuation]
|
||||
3):
|
||||
pass
|
||||
|
||||
if (
|
||||
2): pass # [bad-continuation]
|
||||
|
||||
if (1 or
|
||||
2 or
|
||||
3): pass
|
||||
|
||||
if (1 or
|
||||
2 or # [bad-continuation]
|
||||
3): print(1, 2)
|
||||
|
||||
if (1 and
|
||||
2): pass # [bad-continuation]
|
||||
|
||||
if (
|
||||
2): pass
|
||||
|
||||
if (
|
||||
2): # [bad-continuation]
|
||||
pass
|
||||
|
||||
L1 = (lambda a,
|
||||
b: a + b)
|
||||
|
||||
if not (1 and
|
||||
2):
|
||||
print(3)
|
||||
|
||||
if not (1 and
|
||||
2): # [bad-continuation]
|
||||
print(3)
|
||||
|
||||
continue2("foo",
|
||||
some_other_arg="this "
|
||||
"is "
|
||||
"fine")
|
||||
|
||||
from contextlib import contextmanager
|
||||
@contextmanager
|
||||
def mycontext(*args):
|
||||
yield args
|
||||
|
||||
with mycontext(
|
||||
"this is",
|
||||
"great stuff",
|
||||
"mane"):
|
||||
pass
|
||||
|
||||
# pylint: disable=using-constant-test
|
||||
# More indentation included to distinguish this from the rest.
|
||||
def long_function_name(
|
||||
var_one, var_two, var_three,
|
||||
var_four):
|
||||
print(var_one, var_two, var_three, var_four)
|
||||
|
||||
|
||||
def short_func_name(first, second, third):
|
||||
# Add some extra indentation on the conditional continuation line.
|
||||
if (first
|
||||
and second == first == 'some_big_long_statement_that_should_not_trigger'):
|
||||
third()
|
||||
|
||||
|
||||
# Some normal multi-line statements with double-indented continuation lines.
|
||||
LARGE_COLLECTION = [
|
||||
"spam",
|
||||
"eggs",
|
||||
"beans",
|
||||
]
|
||||
|
||||
long_function_name(
|
||||
"1", "2", "3", "4")
|
||||
|
||||
CONCATENATED_TEXT = (
|
||||
"spam"
|
||||
"eggs"
|
||||
"beans")
|
||||
@@ -0,0 +1,63 @@
|
||||
bad-continuation:14::"Wrong hanging indentation.
|
||||
] # [bad-continuation]
|
||||
| ^|"
|
||||
bad-continuation:19::"Wrong continued indentation (remove 3 spaces).
|
||||
7, # [bad-continuation]
|
||||
| ^"
|
||||
bad-continuation:27::"Wrong hanging indentation (add 1 space).
|
||||
'b': 2, # [bad-continuation]
|
||||
^|"
|
||||
bad-continuation:33::"Wrong hanging indentation (add 1 space).
|
||||
'b': 2, # [bad-continuation]
|
||||
^|"
|
||||
bad-continuation:41::"Wrong continued indentation.
|
||||
# [bad-continuation] is not accepted
|
||||
| | ^"
|
||||
bad-continuation:42::"Wrong continued indentation (remove 20 spaces).
|
||||
'contents', # [bad-continuation] nor this.
|
||||
| ^"
|
||||
bad-continuation:51::"Wrong hanging indentation in dict value.
|
||||
'value2', # [bad-continuation]
|
||||
| ^ |"
|
||||
bad-continuation:61::"Wrong continued indentation (add 4 spaces).
|
||||
'wrong', # [bad-continuation]
|
||||
^ |"
|
||||
bad-continuation:85::"Wrong hanging indentation in dict value.
|
||||
'value1', # [bad-continuation]
|
||||
^ | |"
|
||||
bad-continuation:89::"Wrong hanging indentation in dict value.
|
||||
'value1', # [bad-continuation]
|
||||
^ | |"
|
||||
bad-continuation:106::"Wrong hanging indentation before block (add 4 spaces).
|
||||
some_arg, # [bad-continuation]
|
||||
^ |"
|
||||
bad-continuation:107::"Wrong hanging indentation before block (add 4 spaces).
|
||||
some_other_arg): # [bad-continuation]
|
||||
^ |"
|
||||
bad-continuation:127::"Wrong continued indentation (add 3 spaces).
|
||||
""b"") # [bad-continuation]
|
||||
^ |"
|
||||
bad-continuation:141::"Wrong hanging indentation before block.
|
||||
): pass # [bad-continuation]
|
||||
| ^|"
|
||||
bad-continuation:144::"Wrong continued indentation before block (add 4 spaces).
|
||||
2): # [bad-continuation]
|
||||
^ |"
|
||||
bad-continuation:152::"Wrong continued indentation (remove 2 spaces).
|
||||
2 and # [bad-continuation]
|
||||
| ^"
|
||||
bad-continuation:157::"Wrong hanging indentation before block.
|
||||
2): pass # [bad-continuation]
|
||||
^ | |"
|
||||
bad-continuation:164::"Wrong continued indentation before block.
|
||||
2 or # [bad-continuation]
|
||||
|^ |"
|
||||
bad-continuation:168::"Wrong continued indentation before block.
|
||||
2): pass # [bad-continuation]
|
||||
^ | |"
|
||||
bad-continuation:174::"Wrong hanging indentation before block.
|
||||
2): # [bad-continuation]
|
||||
^ | |"
|
||||
bad-continuation:185::"Wrong continued indentation (add 4 spaces).
|
||||
2): # [bad-continuation]
|
||||
^ |"
|
||||
@@ -0,0 +1,8 @@
|
||||
# pylint: disable=missing-docstring, unused-argument
|
||||
|
||||
async def upload_post(
|
||||
content: bytes,
|
||||
source: str,
|
||||
tags: dict) -> dict:
|
||||
# regression test for https://github.com/PyCQA/pylint/issues/1415
|
||||
raise NotImplementedError('Not implemented')
|
||||
@@ -0,0 +1,2 @@
|
||||
[testoptions]
|
||||
min_pyver=3.6
|
||||
@@ -0,0 +1,52 @@
|
||||
"""Regression test case for bad-continuation with tabs"""
|
||||
# pylint: disable=too-few-public-methods,missing-docstring,invalid-name,unused-variable, useless-object-inheritance
|
||||
# Various alignment for brackets
|
||||
|
||||
# Issue 638
|
||||
TEST1 = ["foo",
|
||||
"bar",
|
||||
"baz"
|
||||
]
|
||||
|
||||
MY_LIST = [
|
||||
1, 2, 3,
|
||||
4, 5, 6
|
||||
]
|
||||
|
||||
# Issue 1148
|
||||
class Abc(object):
|
||||
def b(self, c):
|
||||
# bock indentation
|
||||
self.d(
|
||||
c) # (is: tabs only)
|
||||
|
||||
def d(self, e):
|
||||
# bad hanging indentation
|
||||
self.b(
|
||||
e) # [bad-continuation] (is: 2 tabs + 7 spaces)
|
||||
|
||||
def f(self):
|
||||
# block indentiation (is: all tabs only)
|
||||
return [
|
||||
self.b,
|
||||
self.d
|
||||
]
|
||||
|
||||
def g(self):
|
||||
# bad hanging indentation
|
||||
# the closing ] requires 7 - 8 more spcaes; see h(), i()
|
||||
return [self.b,
|
||||
self.d # (is: 2 tabs + 8 spaces)
|
||||
] # [bad-continuation] (is: tabs only)
|
||||
|
||||
def h(self):
|
||||
# hanging indentation: all lined up with first token 'self.b'
|
||||
return [self.b,
|
||||
self.d # (is: 2 tabs + 8 spaces)
|
||||
] # (is: 2 tabs + 8 spaces)
|
||||
|
||||
def i(self):
|
||||
# hangin identation: closing ] lined up with opening [
|
||||
return [self.b,
|
||||
self.d # (2 tabs + 8 spaces)
|
||||
] # (2 tabs + 7 spaces)
|
||||
@@ -0,0 +1,3 @@
|
||||
[FORMAT]
|
||||
indent-string='\t'
|
||||
indent-after-paren=1
|
||||
@@ -0,0 +1,6 @@
|
||||
bad-continuation:26::"Wrong hanging indentation (add 1 space).
|
||||
e) # [bad-continuation] (is: 2 tabs + 7 spaces)
|
||||
^|"
|
||||
bad-continuation:40::"Wrong continued indentation.
|
||||
] # [bad-continuation] (is: tabs only)
|
||||
^ ||"
|
||||
@@ -0,0 +1,45 @@
|
||||
# pylint: disable=missing-docstring, bare-except, broad-except
|
||||
|
||||
__revision__ = 1
|
||||
|
||||
try:
|
||||
__revision__ += 1
|
||||
except Exception:
|
||||
__revision__ = 0
|
||||
except TypeError: # [bad-except-order]
|
||||
__revision__ = 0
|
||||
|
||||
try:
|
||||
__revision__ += 1
|
||||
except LookupError:
|
||||
__revision__ = 0
|
||||
except IndexError: # [bad-except-order]
|
||||
__revision__ = 0
|
||||
|
||||
try:
|
||||
__revision__ += 1
|
||||
except (LookupError, NameError):
|
||||
__revision__ = 0
|
||||
except (IndexError, UnboundLocalError): # [bad-except-order, bad-except-order]
|
||||
__revision__ = 0
|
||||
|
||||
try: # [bad-except-order]
|
||||
__revision__ += 1
|
||||
except:
|
||||
pass
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
try:
|
||||
__revision__ += 1
|
||||
except TypeError:
|
||||
__revision__ = 0
|
||||
except:
|
||||
__revision__ = 0
|
||||
|
||||
try:
|
||||
__revision__ += 1
|
||||
except Exception:
|
||||
pass
|
||||
except:
|
||||
pass
|
||||
@@ -0,0 +1,5 @@
|
||||
bad-except-order:9::Bad except clauses order (Exception is an ancestor class of TypeError)
|
||||
bad-except-order:16::Bad except clauses order (LookupError is an ancestor class of IndexError)
|
||||
bad-except-order:23::Bad except clauses order (LookupError is an ancestor class of IndexError)
|
||||
bad-except-order:23::Bad except clauses order (NameError is an ancestor class of UnboundLocalError)
|
||||
bad-except-order:26::Bad except clauses order (empty except clause should always appear last)
|
||||
@@ -0,0 +1,24 @@
|
||||
"""Check that raise ... from .. uses a proper exception context """
|
||||
|
||||
# pylint: disable=unreachable, import-error, multiple-imports
|
||||
|
||||
import socket, unknown
|
||||
|
||||
__revision__ = 0
|
||||
|
||||
class ExceptionSubclass(Exception):
|
||||
""" subclass """
|
||||
|
||||
def test():
|
||||
""" docstring """
|
||||
raise IndexError from 1 # [bad-exception-context]
|
||||
raise IndexError from None
|
||||
raise IndexError from ZeroDivisionError
|
||||
raise IndexError from object() # [bad-exception-context]
|
||||
raise IndexError from ExceptionSubclass
|
||||
raise IndexError from socket.error
|
||||
raise IndexError() from None
|
||||
raise IndexError() from ZeroDivisionError
|
||||
raise IndexError() from ZeroDivisionError()
|
||||
raise IndexError() from object() # [bad-exception-context]
|
||||
raise IndexError() from unknown
|
||||
@@ -0,0 +1,2 @@
|
||||
[testoptions]
|
||||
min_pyver=3.0
|
||||
@@ -0,0 +1,3 @@
|
||||
bad-exception-context:14:test:Exception context set to something which is not an exception, nor None
|
||||
bad-exception-context:17:test:Exception context set to something which is not an exception, nor None
|
||||
bad-exception-context:23:test:Exception context set to something which is not an exception, nor None
|
||||
@@ -0,0 +1,19 @@
|
||||
# pylint: disable=missing-docstring, pointless-statement
|
||||
from __future__ import print_function
|
||||
|
||||
|
||||
def totoo():
|
||||
print('malindented') # [bad-indentation]
|
||||
|
||||
def tutuu():
|
||||
print('good indentation')
|
||||
|
||||
def titii():
|
||||
1 # and this. # [bad-indentation]
|
||||
|
||||
def tataa(kdict):
|
||||
for key in ['1', '2', '3']:
|
||||
key = key.lower()
|
||||
|
||||
if key in kdict:
|
||||
del kdict[key]
|
||||
@@ -0,0 +1,2 @@
|
||||
bad-indentation:6::Bad indentation. Found 1 spaces, expected 4
|
||||
bad-indentation:12::Bad indentation. Found 5 spaces, expected 4
|
||||
@@ -0,0 +1,5 @@
|
||||
"""errors-only is not usable as an inline option"""
|
||||
# +1: [bad-inline-option]
|
||||
# pylint: errors-only
|
||||
|
||||
CONST = "This is not a pylint: inline option."
|
||||
@@ -0,0 +1,2 @@
|
||||
[Messages Control]
|
||||
enable=I
|
||||
@@ -0,0 +1 @@
|
||||
bad-inline-option:3::Unable to consider inline option 'errors-only'
|
||||
@@ -0,0 +1,37 @@
|
||||
"""Warnings for using open() with an invalid mode string."""
|
||||
|
||||
open('foo.bar', 'w', 2)
|
||||
open('foo.bar', 'rw') # [bad-open-mode]
|
||||
open(name='foo.bar', buffering=10, mode='rw') # [bad-open-mode]
|
||||
open(mode='rw', name='foo.bar') # [bad-open-mode]
|
||||
open('foo.bar', 'U+')
|
||||
open('foo.bar', 'rb+')
|
||||
open('foo.bar', 'Uw') # [bad-open-mode]
|
||||
open('foo.bar', 2) # [bad-open-mode]
|
||||
open('foo.bar', buffering=2)
|
||||
WRITE_MODE = 'w'
|
||||
open('foo.bar', 'U' + WRITE_MODE + 'z') # [bad-open-mode]
|
||||
open('foo.bar', 'br') # [bad-open-mode]
|
||||
open('foo.bar', 'wU') # [bad-open-mode]
|
||||
open('foo.bar', 'r+b')
|
||||
open('foo.bar', 'r+')
|
||||
open('foo.bar', 'w+')
|
||||
open('foo.bar', 'xb') # [bad-open-mode]
|
||||
open('foo.bar', 'rx') # [bad-open-mode]
|
||||
open('foo.bar', 'Ur')
|
||||
open('foo.bar', 'rU')
|
||||
open('foo.bar', 'rUb')
|
||||
open('foo.bar', 'rUb+')
|
||||
open('foo.bar', 'rU+b')
|
||||
open('foo.bar', 'r+Ub')
|
||||
open('foo.bar', '+rUb') # [bad-open-mode]
|
||||
open('foo.bar', 'ab+')
|
||||
open('foo.bar', 'a+b')
|
||||
open('foo.bar', 'aU') # [bad-open-mode]
|
||||
open('foo.bar', 'U+b')
|
||||
open('foo.bar', '+Ub')
|
||||
open('foo.bar', 'b+U')
|
||||
open('foo.bar', 'Urb+')
|
||||
open('foo.bar', 'Ur+b')
|
||||
open('foo.bar', 'Ubr') # [bad-open-mode]
|
||||
open('foo.bar', 'Ut') # [bad-open-mode]
|
||||
@@ -0,0 +1,2 @@
|
||||
[testoptions]
|
||||
max_pyver=3.0
|
||||
@@ -0,0 +1,14 @@
|
||||
bad-open-mode:4::"""rw"" is not a valid mode for open."
|
||||
bad-open-mode:5::"""rw"" is not a valid mode for open."
|
||||
bad-open-mode:6::"""rw"" is not a valid mode for open."
|
||||
bad-open-mode:9::"""Uw"" is not a valid mode for open."
|
||||
bad-open-mode:10::"""2"" is not a valid mode for open."
|
||||
bad-open-mode:13::"""Uwz"" is not a valid mode for open."
|
||||
bad-open-mode:14::"""br"" is not a valid mode for open."
|
||||
bad-open-mode:15::"""wU"" is not a valid mode for open."
|
||||
bad-open-mode:19::"""xb"" is not a valid mode for open."
|
||||
bad-open-mode:20::"""rx"" is not a valid mode for open."
|
||||
bad-open-mode:27::"""+rUb"" is not a valid mode for open."
|
||||
bad-open-mode:30::"""aU"" is not a valid mode for open."
|
||||
bad-open-mode:36::"""Ubr"" is not a valid mode for open."
|
||||
bad-open-mode:37::"""Ut"" is not a valid mode for open."
|
||||
@@ -0,0 +1,23 @@
|
||||
"""Warnings for using open() with an invalid mode string."""
|
||||
|
||||
NAME = "foo.bar"
|
||||
open(NAME, "wb")
|
||||
open(NAME, "w")
|
||||
open(NAME, "rb")
|
||||
open(NAME, "x")
|
||||
open(NAME, "br")
|
||||
open(NAME, "+r")
|
||||
open(NAME, "xb")
|
||||
open(NAME, "rwx") # [bad-open-mode]
|
||||
open(NAME, "rr") # [bad-open-mode]
|
||||
open(NAME, "+") # [bad-open-mode]
|
||||
open(NAME, "xw") # [bad-open-mode]
|
||||
open(NAME, "ab+")
|
||||
open(NAME, "a+b")
|
||||
open(NAME, "+ab")
|
||||
open(NAME, "+rUb")
|
||||
open(NAME, "x+b")
|
||||
open(NAME, "Ua") # [bad-open-mode]
|
||||
open(NAME, "Ur++") # [bad-open-mode]
|
||||
open(NAME, "Ut")
|
||||
open(NAME, "Ubr")
|
||||
@@ -0,0 +1,3 @@
|
||||
[testoptions]
|
||||
min_pyver=3.0
|
||||
except_implementations=PyPy
|
||||
@@ -0,0 +1,6 @@
|
||||
bad-open-mode:11::"""rwx"" is not a valid mode for open."
|
||||
bad-open-mode:12::"""rr"" is not a valid mode for open."
|
||||
bad-open-mode:13::"""+"" is not a valid mode for open."
|
||||
bad-open-mode:14::"""xw"" is not a valid mode for open."
|
||||
bad-open-mode:20::"""Ua"" is not a valid mode for open."
|
||||
bad-open-mode:21::"""Ur++"" is not a valid mode for open."
|
||||
@@ -0,0 +1,84 @@
|
||||
""" Checks that reversed() receive proper argument """
|
||||
# pylint: disable=missing-docstring, useless-object-inheritance
|
||||
# pylint: disable=too-few-public-methods,no-self-use,no-absolute-import
|
||||
from collections import deque
|
||||
|
||||
__revision__ = 0
|
||||
|
||||
class GoodReversed(object):
|
||||
""" Implements __reversed__ """
|
||||
def __reversed__(self):
|
||||
return [1, 2, 3]
|
||||
|
||||
class SecondGoodReversed(object):
|
||||
""" Implements __len__ and __getitem__ """
|
||||
def __len__(self):
|
||||
return 3
|
||||
|
||||
def __getitem__(self, index):
|
||||
return index
|
||||
|
||||
class BadReversed(object):
|
||||
""" implements only len() """
|
||||
def __len__(self):
|
||||
return 3
|
||||
|
||||
class SecondBadReversed(object):
|
||||
""" implements only __getitem__ """
|
||||
def __getitem__(self, index):
|
||||
return index
|
||||
|
||||
class ThirdBadReversed(dict):
|
||||
""" dict subclass """
|
||||
|
||||
def uninferable(seq):
|
||||
""" This can't be infered at this moment,
|
||||
make sure we don't have a false positive.
|
||||
"""
|
||||
return reversed(seq)
|
||||
|
||||
def test(path):
|
||||
""" test function """
|
||||
seq = reversed() # No argument given
|
||||
seq = reversed(None) # [bad-reversed-sequence]
|
||||
seq = reversed([1, 2, 3])
|
||||
seq = reversed((1, 2, 3))
|
||||
seq = reversed(set()) # [bad-reversed-sequence]
|
||||
seq = reversed({'a': 1, 'b': 2}) # [bad-reversed-sequence]
|
||||
seq = reversed(iter([1, 2, 3])) # [bad-reversed-sequence]
|
||||
seq = reversed(GoodReversed())
|
||||
seq = reversed(SecondGoodReversed())
|
||||
seq = reversed(BadReversed()) # [bad-reversed-sequence]
|
||||
seq = reversed(SecondBadReversed()) # [bad-reversed-sequence]
|
||||
seq = reversed(range(100))
|
||||
seq = reversed(ThirdBadReversed()) # [bad-reversed-sequence]
|
||||
seq = reversed(lambda: None) # [bad-reversed-sequence]
|
||||
seq = reversed(deque([]))
|
||||
seq = reversed("123")
|
||||
seq = uninferable([1, 2, 3])
|
||||
seq = reversed(path.split("/"))
|
||||
return seq
|
||||
|
||||
def test_dict_ancestor_and_reversed():
|
||||
"""Don't emit for subclasses of dict, with __reversed__ implemented."""
|
||||
from collections import OrderedDict
|
||||
|
||||
class Child(dict):
|
||||
def __reversed__(self):
|
||||
return reversed(range(10))
|
||||
|
||||
seq = reversed(OrderedDict())
|
||||
return reversed(Child()), seq
|
||||
|
||||
|
||||
def test_dont_emit_for_reversing_enums():
|
||||
"""Don't emit when reversing enum classes"""
|
||||
from enum import IntEnum
|
||||
|
||||
class Color(IntEnum):
|
||||
RED = 1
|
||||
GREEN = 2
|
||||
BLUE = 3
|
||||
|
||||
for color in reversed(Color):
|
||||
yield color
|
||||
@@ -0,0 +1,8 @@
|
||||
bad-reversed-sequence:43:test:The first reversed() argument is not a sequence
|
||||
bad-reversed-sequence:46:test:The first reversed() argument is not a sequence
|
||||
bad-reversed-sequence:47:test:The first reversed() argument is not a sequence
|
||||
bad-reversed-sequence:48:test:The first reversed() argument is not a sequence
|
||||
bad-reversed-sequence:51:test:The first reversed() argument is not a sequence
|
||||
bad-reversed-sequence:52:test:The first reversed() argument is not a sequence
|
||||
bad-reversed-sequence:54:test:The first reversed() argument is not a sequence
|
||||
bad-reversed-sequence:55:test:The first reversed() argument is not a sequence
|
||||
@@ -0,0 +1,16 @@
|
||||
# pylint: disable=missing-docstring, no-staticmethod-decorator, useless-object-inheritance
|
||||
|
||||
class Abcd(object):
|
||||
|
||||
def method1(self): # [bad-staticmethod-argument]
|
||||
pass
|
||||
|
||||
method1 = staticmethod(method1)
|
||||
|
||||
def method2(cls): # [bad-staticmethod-argument]
|
||||
pass
|
||||
|
||||
method2 = staticmethod(method2)
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
@@ -0,0 +1,2 @@
|
||||
bad-staticmethod-argument:5:Abcd.method1:Static method with 'self' as first argument
|
||||
bad-staticmethod-argument:10:Abcd.method2:Static method with 'cls' as first argument
|
||||
@@ -0,0 +1,8 @@
|
||||
# pylint: disable=missing-docstring
|
||||
import threading
|
||||
|
||||
|
||||
threading.Thread(lambda: None).run() # [bad-thread-instantiation]
|
||||
threading.Thread(None, lambda: None)
|
||||
threading.Thread(group=None, target=lambda: None).run()
|
||||
threading.Thread() # [bad-thread-instantiation]
|
||||
@@ -0,0 +1,2 @@
|
||||
bad-thread-instantiation:5::threading.Thread needs the target function
|
||||
bad-thread-instantiation:8::threading.Thread needs the target function
|
||||
@@ -0,0 +1,7 @@
|
||||
# pylint: disable = invalid-name,missing-docstring,unused-variable,unused-argument
|
||||
def function(hello):
|
||||
x, y, z = (1,2,3,) # [bad-whitespace, bad-whitespace]
|
||||
|
||||
AAA =1 # [bad-whitespace]
|
||||
BBB = 2 # [bad-whitespace]
|
||||
CCC= 1 # [bad-whitespace]
|
||||
@@ -0,0 +1,15 @@
|
||||
bad-whitespace:3::"Exactly one space required after comma
|
||||
x, y, z = (1,2,3,) # [bad-whitespace, bad-whitespace]
|
||||
^"
|
||||
bad-whitespace:3::"Exactly one space required after comma
|
||||
x, y, z = (1,2,3,) # [bad-whitespace, bad-whitespace]
|
||||
^"
|
||||
bad-whitespace:5::"Exactly one space required after assignment
|
||||
AAA =1 # [bad-whitespace]
|
||||
^"
|
||||
bad-whitespace:6::"Exactly one space required after assignment
|
||||
BBB = 2 # [bad-whitespace]
|
||||
^"
|
||||
bad-whitespace:7::"Exactly one space required before assignment
|
||||
CCC= 1 # [bad-whitespace]
|
||||
^"
|
||||
@@ -0,0 +1,6 @@
|
||||
# pylint: disable=missing-docstring, import-error
|
||||
|
||||
try:
|
||||
1 + "2"
|
||||
except: # [bare-except]
|
||||
pass
|
||||
@@ -0,0 +1 @@
|
||||
bare-except:5::No exception type(s) specified
|
||||
@@ -0,0 +1,4 @@
|
||||
# pylint: disable=missing-docstring
|
||||
|
||||
def baz(): # [blacklisted-name]
|
||||
pass
|
||||
@@ -0,0 +1 @@
|
||||
blacklisted-name:3:baz:Black listed name "baz"
|
||||
@@ -0,0 +1,30 @@
|
||||
""" Checks for boolean uses of datetime.time. """
|
||||
# pylint: disable=superfluous-parens,print-statement,no-absolute-import,consider-using-ternary,simplifiable-if-expression
|
||||
import datetime
|
||||
|
||||
if datetime.time(0, 0, 0): # [boolean-datetime]
|
||||
print("datetime.time(0,0,0) is not a bug!")
|
||||
else:
|
||||
print("datetime.time(0,0,0) is a bug!")
|
||||
|
||||
if not datetime.time(0, 0, 1): # [boolean-datetime]
|
||||
print("datetime.time(0,0,1) is not a bug!")
|
||||
else:
|
||||
print("datetime.time(0,0,1) is a bug!")
|
||||
|
||||
DATA = not datetime.time(0, 0, 0) # [boolean-datetime]
|
||||
DATA1 = True if datetime.time(0, 0, 0) else False # [boolean-datetime]
|
||||
DATA2 = datetime.time(0, 0, 0) or True # [boolean-datetime]
|
||||
DATA3 = datetime.time(0, 0, 0) and True # [boolean-datetime]
|
||||
DATA4 = False or True or datetime.time(0, 0, 0) # [boolean-datetime]
|
||||
DATA5 = False and datetime.time(0, 0, 0) or True # [boolean-datetime]
|
||||
|
||||
|
||||
def cant_infer(data):
|
||||
""" Can't infer what data is """
|
||||
hophop = not data
|
||||
troptrop = True if data else False
|
||||
toptop = data or True
|
||||
return hophop, troptrop, toptop
|
||||
|
||||
cant_infer(datetime.time(0, 0, 0))
|
||||
@@ -0,0 +1,2 @@
|
||||
[testoptions]
|
||||
max_pyver=3.5
|
||||
@@ -0,0 +1,8 @@
|
||||
boolean-datetime:5::Using datetime.time in a boolean context.
|
||||
boolean-datetime:10::Using datetime.time in a boolean context.
|
||||
boolean-datetime:15::Using datetime.time in a boolean context.
|
||||
boolean-datetime:16::Using datetime.time in a boolean context.
|
||||
boolean-datetime:17::Using datetime.time in a boolean context.
|
||||
boolean-datetime:18::Using datetime.time in a boolean context.
|
||||
boolean-datetime:19::Using datetime.time in a boolean context.
|
||||
boolean-datetime:20::Using datetime.time in a boolean context.
|
||||
@@ -0,0 +1,14 @@
|
||||
# pylint: disable=missing-docstring
|
||||
from __future__ import print_function
|
||||
__revision__ = 0
|
||||
|
||||
try:
|
||||
__revision__ += 1
|
||||
except Exception: # [broad-except]
|
||||
print('error')
|
||||
|
||||
|
||||
try:
|
||||
__revision__ += 1
|
||||
except BaseException: # [broad-except]
|
||||
print('error')
|
||||
@@ -0,0 +1,2 @@
|
||||
broad-except:7::Catching too general exception Exception
|
||||
broad-except:13::Catching too general exception BaseException
|
||||
@@ -0,0 +1,56 @@
|
||||
# pylint: disable=missing-docstring,too-few-public-methods,import-error
|
||||
from UNINFERABLE import ImportedMetaclass
|
||||
|
||||
|
||||
class Meta(type):
|
||||
pass
|
||||
|
||||
|
||||
class Class(metaclass=Meta):
|
||||
pass
|
||||
|
||||
|
||||
def func_scope():
|
||||
class Meta2(type):
|
||||
pass
|
||||
|
||||
class Class2(metaclass=Meta2):
|
||||
pass
|
||||
|
||||
return Class2
|
||||
|
||||
|
||||
class ClassScope:
|
||||
class Meta3(type):
|
||||
pass
|
||||
|
||||
class Class3(metaclass=Meta3):
|
||||
pass
|
||||
|
||||
instance = Class3()
|
||||
|
||||
|
||||
def mixed_scopes():
|
||||
class ClassM(metaclass=Meta):
|
||||
pass
|
||||
|
||||
return ClassM
|
||||
|
||||
|
||||
def imported_and_nested_scope1():
|
||||
class ClassImp1(metaclass=ImportedMetaclass):
|
||||
pass
|
||||
|
||||
class ClassImp2(metaclass=ImportedMetaclass):
|
||||
pass
|
||||
|
||||
return ClassImp1, ClassImp2
|
||||
|
||||
|
||||
def imported_and_nested_scope2():
|
||||
from UNINFERABLE import ImportedMetaclass2
|
||||
|
||||
class ClassImp3(metaclass=ImportedMetaclass2):
|
||||
pass
|
||||
|
||||
return ClassImp3
|
||||
@@ -0,0 +1,2 @@
|
||||
[testoptions]
|
||||
min_pyver=3.0
|
||||
@@ -0,0 +1,120 @@
|
||||
# pylint: disable=print-statement
|
||||
"""Tests for loopvar-in-closure."""
|
||||
from __future__ import print_function
|
||||
|
||||
def good_case():
|
||||
"""No problems here."""
|
||||
lst = []
|
||||
for i in range(10):
|
||||
lst.append(i)
|
||||
|
||||
|
||||
def good_case2():
|
||||
"""No problems here."""
|
||||
return [i for i in range(10)]
|
||||
|
||||
|
||||
def good_case3():
|
||||
"""No problems here."""
|
||||
lst = []
|
||||
for i in range(10):
|
||||
lst.append(lambda i=i: i)
|
||||
|
||||
|
||||
def good_case4():
|
||||
"""No problems here."""
|
||||
lst = []
|
||||
for i in range(10):
|
||||
print(i)
|
||||
lst.append(lambda i: i)
|
||||
|
||||
|
||||
def good_case5():
|
||||
"""No problems here."""
|
||||
return (i for i in range(10))
|
||||
|
||||
|
||||
def good_case6():
|
||||
"""Accept use of the variable inside return."""
|
||||
for i in range(10):
|
||||
if i == 8:
|
||||
return lambda: i
|
||||
return lambda: -1
|
||||
|
||||
|
||||
def good_case7():
|
||||
"""Lambda defined and called in loop."""
|
||||
for i in range(10):
|
||||
print((lambda x: i + x)(1))
|
||||
|
||||
|
||||
def good_case8():
|
||||
"""Another eager binding of the cell variable."""
|
||||
funs = []
|
||||
for i in range(10):
|
||||
def func(bound_i=i):
|
||||
"""Ignore."""
|
||||
return bound_i
|
||||
funs.append(func)
|
||||
return funs
|
||||
|
||||
|
||||
def bad_case():
|
||||
"""Closing over a loop variable."""
|
||||
lst = []
|
||||
for i in range(10):
|
||||
print(i)
|
||||
lst.append(lambda: i) # [cell-var-from-loop]
|
||||
|
||||
|
||||
def bad_case2():
|
||||
"""Closing over a loop variable."""
|
||||
return [lambda: i for i in range(10)] # [cell-var-from-loop]
|
||||
|
||||
|
||||
def bad_case3():
|
||||
"""Closing over variable defined in loop."""
|
||||
lst = []
|
||||
for i in range(10):
|
||||
j = i * i
|
||||
lst.append(lambda: j) # [cell-var-from-loop]
|
||||
return lst
|
||||
|
||||
|
||||
def bad_case4():
|
||||
"""Closing over variable defined in loop."""
|
||||
lst = []
|
||||
for i in range(10):
|
||||
def nested():
|
||||
"""Nested function."""
|
||||
return i**2 # [cell-var-from-loop]
|
||||
lst.append(nested)
|
||||
return lst
|
||||
|
||||
|
||||
def bad_case5():
|
||||
"""Problematic case.
|
||||
|
||||
If this function is used as
|
||||
|
||||
>>> [x() for x in bad_case5()]
|
||||
|
||||
it behaves 'as expected', i.e. the result is range(10).
|
||||
|
||||
If it's used with
|
||||
|
||||
>>> lst = list(bad_case5())
|
||||
>>> [x() for x in lst]
|
||||
|
||||
the result is [9] * 10 again.
|
||||
"""
|
||||
return (lambda: i for i in range(10)) # [cell-var-from-loop]
|
||||
|
||||
|
||||
def bad_case6():
|
||||
"""Closing over variable defined in loop."""
|
||||
lst = []
|
||||
for i, j in zip(range(10), range(10, 20)):
|
||||
print(j)
|
||||
lst.append(lambda: i) # [cell-var-from-loop]
|
||||
return lst
|
||||
@@ -0,0 +1,6 @@
|
||||
cell-var-from-loop:67:bad_case.<lambda>:Cell variable i defined in loop
|
||||
cell-var-from-loop:72:bad_case2.<lambda>:Cell variable i defined in loop
|
||||
cell-var-from-loop:80:bad_case3.<lambda>:Cell variable j defined in loop
|
||||
cell-var-from-loop:90:bad_case4.nested:Cell variable i defined in loop
|
||||
cell-var-from-loop:111:bad_case5.<lambda>:Cell variable i defined in loop
|
||||
cell-var-from-loop:119:bad_case6.<lambda>:Cell variable i defined in loop
|
||||
@@ -0,0 +1,70 @@
|
||||
""" Various tests for class members access. """
|
||||
# pylint: disable=R0903,print-statement,no-absolute-import, metaclass-assignment,import-error,no-init,missing-docstring, wrong-import-order,wrong-import-position, useless-object-inheritance
|
||||
from missing import Missing
|
||||
class MyClass(object):
|
||||
"""class docstring"""
|
||||
|
||||
def __init__(self):
|
||||
"""init"""
|
||||
self.correct = 1
|
||||
|
||||
def test(self):
|
||||
"""test"""
|
||||
self.correct += 2
|
||||
self.incorrect += 2 # [no-member]
|
||||
del self.havenot # [no-member]
|
||||
self.nonexistent1.truc() # [no-member]
|
||||
self.nonexistent2[1] = 'hehe' # [no-member]
|
||||
|
||||
class XYZMixin(object):
|
||||
"""access to undefined members should be ignored in mixin classes by
|
||||
default
|
||||
"""
|
||||
def __init__(self):
|
||||
print self.nonexistent
|
||||
|
||||
|
||||
class NewClass(object):
|
||||
"""use object.__setattr__"""
|
||||
def __init__(self):
|
||||
self.__setattr__('toto', 'tutu')
|
||||
|
||||
from abc import ABCMeta
|
||||
|
||||
class TestMetaclass(object):
|
||||
""" Test attribute access for metaclasses. """
|
||||
__metaclass__ = ABCMeta
|
||||
|
||||
class Metaclass(type):
|
||||
""" metaclass """
|
||||
@classmethod
|
||||
def test(cls):
|
||||
""" classmethod """
|
||||
|
||||
class UsingMetaclass(object):
|
||||
""" empty """
|
||||
__metaclass__ = Metaclass
|
||||
|
||||
TestMetaclass.register(int)
|
||||
UsingMetaclass.test()
|
||||
TestMetaclass().register(int) # [no-member]
|
||||
UsingMetaclass().test() # [no-member]
|
||||
|
||||
|
||||
class NoKnownBases(Missing):
|
||||
"""Don't emit no-member if we don't know the bases of a class."""
|
||||
|
||||
NoKnownBases().lalala()
|
||||
|
||||
|
||||
class MetaClass(object):
|
||||
"""Look some methods in the implicit metaclass."""
|
||||
|
||||
@classmethod
|
||||
def whatever(cls):
|
||||
return cls.mro() + cls.missing() # [no-member]
|
||||
|
||||
from collections import namedtuple
|
||||
|
||||
Tuple = namedtuple("Tuple", "field other")
|
||||
Tuple.field.__doc__ = "A doc for the field."
|
||||
@@ -0,0 +1,3 @@
|
||||
[testoptions]
|
||||
min_pyver=2.7
|
||||
max_pyver=3.0
|
||||
@@ -0,0 +1,7 @@
|
||||
no-member:14:MyClass.test:Instance of 'MyClass' has no 'incorrect' member:INFERENCE
|
||||
no-member:15:MyClass.test:Instance of 'MyClass' has no 'havenot' member:INFERENCE
|
||||
no-member:16:MyClass.test:Instance of 'MyClass' has no 'nonexistent1' member:INFERENCE
|
||||
no-member:17:MyClass.test:Instance of 'MyClass' has no 'nonexistent2' member:INFERENCE
|
||||
no-member:50::Instance of 'TestMetaclass' has no 'register' member:INFERENCE
|
||||
no-member:51::Instance of 'UsingMetaclass' has no 'test' member:INFERENCE
|
||||
no-member:65:MetaClass.whatever:Class 'MetaClass' has no 'missing' member:INFERENCE
|
||||
@@ -0,0 +1,68 @@
|
||||
""" Various tests for class members access. """
|
||||
# pylint: disable=R0903,import-error,no-init,missing-docstring, wrong-import-position,wrong-import-order, useless-object-inheritance
|
||||
from missing import Missing
|
||||
class MyClass(object):
|
||||
"""class docstring"""
|
||||
|
||||
def __init__(self):
|
||||
"""init"""
|
||||
self.correct = 1
|
||||
|
||||
def test(self):
|
||||
"""test"""
|
||||
self.correct += 2
|
||||
self.incorrect += 2 # [no-member]
|
||||
del self.havenot # [no-member]
|
||||
self.nonexistent1.truc() # [no-member]
|
||||
self.nonexistent2[1] = 'hehe' # [no-member]
|
||||
|
||||
class XYZMixin(object):
|
||||
"""access to undefined members should be ignored in mixin classes by
|
||||
default
|
||||
"""
|
||||
def __init__(self):
|
||||
print(self.nonexistent)
|
||||
|
||||
|
||||
class NewClass(object):
|
||||
"""use object.__setattr__"""
|
||||
def __init__(self):
|
||||
self.__setattr__('toto', 'tutu')
|
||||
|
||||
from abc import ABCMeta
|
||||
|
||||
class TestMetaclass(object, metaclass=ABCMeta):
|
||||
""" Test attribute access for metaclasses. """
|
||||
|
||||
class Metaclass(type):
|
||||
""" metaclass """
|
||||
@classmethod
|
||||
def test(cls):
|
||||
""" classmethod """
|
||||
|
||||
class UsingMetaclass(object, metaclass=Metaclass):
|
||||
""" empty """
|
||||
|
||||
TestMetaclass.register(int)
|
||||
UsingMetaclass.test()
|
||||
TestMetaclass().register(int) # [no-member]
|
||||
UsingMetaclass().test() # [no-member]
|
||||
|
||||
|
||||
class NoKnownBases(Missing):
|
||||
"""Don't emit no-member if we don't know the bases of a class."""
|
||||
|
||||
NoKnownBases().lalala()
|
||||
|
||||
|
||||
class MetaClass(object):
|
||||
"""Look some methods in the implicit metaclass."""
|
||||
|
||||
@classmethod
|
||||
def whatever(cls):
|
||||
return cls.mro() + cls.missing() # [no-member]
|
||||
|
||||
from collections import namedtuple
|
||||
|
||||
Tuple = namedtuple("Tuple", "field other")
|
||||
Tuple.field.__doc__ = "A doc for the field."
|
||||
@@ -0,0 +1,2 @@
|
||||
[testoptions]
|
||||
min_pyver=3.0
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user