diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/checkers/unittest_format.py | 4 | ||||
-rw-r--r-- | tests/functional/c/consider/consider_using_with.py | 138 | ||||
-rw-r--r-- | tests/functional/c/consider/consider_using_with.txt | 22 | ||||
-rw-r--r-- | tests/functional/c/consider/consider_using_with_open.py | 15 | ||||
-rw-r--r-- | tests/functional/c/consider/consider_using_with_open.rc | 2 | ||||
-rw-r--r-- | tests/functional/c/consider/consider_using_with_open.txt | 1 | ||||
-rw-r--r-- | tests/functional/d/disabled_msgid_in_pylintrc.rc | 2 | ||||
-rw-r--r-- | tests/functional/n/non/non_iterator_returned.py | 19 | ||||
-rw-r--r-- | tests/functional/n/non/non_iterator_returned.txt | 8 |
9 files changed, 200 insertions, 11 deletions
diff --git a/tests/checkers/unittest_format.py b/tests/checkers/unittest_format.py index 80d654f98..a2aa4687f 100644 --- a/tests/checkers/unittest_format.py +++ b/tests/checkers/unittest_format.py @@ -252,7 +252,9 @@ def test_disable_global_option_end_of_line(): Test for issue with disabling tokenizer messages that extend beyond the scope of the ast tokens """ - file_ = tempfile.NamedTemporaryFile("w", delete=False) + file_ = tempfile.NamedTemporaryFile( # pylint: disable=consider-using-with + "w", delete=False + ) with file_: file_.write( """ diff --git a/tests/functional/c/consider/consider_using_with.py b/tests/functional/c/consider/consider_using_with.py new file mode 100644 index 000000000..234c6093d --- /dev/null +++ b/tests/functional/c/consider/consider_using_with.py @@ -0,0 +1,138 @@ +# pylint: disable=missing-function-docstring, missing-module-docstring, invalid-name, import-outside-toplevel +import codecs +import multiprocessing +import subprocess +import tarfile +import tempfile +import threading +import urllib +import zipfile +from concurrent import futures + + +def test_codecs_open(): + fh = codecs.open("test.txt", "utf8") # [consider-using-with] + fh.close() + + +def test_urlopen(): + _ = urllib.request.urlopen("http://www.python.org") # [consider-using-with] + + +def test_temporary_file(): + _ = tempfile.TemporaryFile("r") # [consider-using-with] + + +def test_named_temporary_file(): + _ = tempfile.NamedTemporaryFile("r") # [consider-using-with] + + +def test_spooled_temporary_file(): + _ = tempfile.SpooledTemporaryFile("r") # [consider-using-with] + + +def test_temporary_directory(): + _ = tempfile.TemporaryDirectory() # [consider-using-with] + + +def test_zipfile(): + myzip = zipfile.ZipFile("spam.zip", "w") # [consider-using-with] + _ = myzip.open("eggs.txt") # [consider-using-with] + + +def test_pyzipfile(): + myzip = zipfile.PyZipFile("spam.zip", "w") # [consider-using-with] + + with zipfile.PyZipFile("spam.zip", "w"): # must not trigger + pass + + _ = myzip.open("eggs.txt") # [consider-using-with] + + with myzip.open("eggs.txt"): # must not trigger + pass + + +def test_tarfile(): + tf = tarfile.open("/tmp/test.tar", "w") # [consider-using-with] + tf.close() + + with tarfile.open("/tmp/test.tar", "w"): # must not trigger + pass + + tf = tarfile.TarFile("/tmp/test2.tar", "w") # [consider-using-with] + tf.close() + + with tarfile.TarFile("/tmp/test2.tar", "w"): # must not trigger + pass + + +def test_lock_acquisition(): + lock = threading.Lock() + lock.acquire() # [consider-using-with] + lock.release() + + with lock: # must not trigger + pass + + rlock = threading.RLock() + rlock.acquire() # [consider-using-with] + rlock.release() + + with rlock: # must not trigger + pass + + # Not working currently + # condition = threading.Condition() + # condition.acquire() + # condition.release() + + # with condition: # must not trigger + # pass + + sema = threading.Semaphore() + sema.acquire() # [consider-using-with] + sema.release() + + with sema: # must not trigger + pass + + bounded_sema = threading.BoundedSemaphore() + bounded_sema.acquire() # [consider-using-with] + bounded_sema.release() + + with bounded_sema: # must not trigger + pass + + +def test_multiprocessing(): + # the different Locks provided by multiprocessing would be candidates + # for consider-using-with as well, but they lead to InferenceErrors. + _ = multiprocessing.Pool() # [consider-using-with] + with multiprocessing.Pool(): + pass + + manager = multiprocessing.managers.BaseManager() + manager.start() # [consider-using-with] + with multiprocessing.managers.BaseManager(): + pass + + manager = multiprocessing.managers.SyncManager() + manager.start() # [consider-using-with] + with multiprocessing.managers.SyncManager(): + pass + + +def test_futures(): + _ = futures.ThreadPoolExecutor() # [consider-using-with] + with futures.ThreadPoolExecutor(): + pass + + _ = futures.ProcessPoolExecutor() # [consider-using-with] + with futures.ProcessPoolExecutor(): + pass + + +def test_popen(): + _ = subprocess.Popen("sh") # [consider-using-with] + with subprocess.Popen("sh"): + pass diff --git a/tests/functional/c/consider/consider_using_with.txt b/tests/functional/c/consider/consider_using_with.txt new file mode 100644 index 000000000..43ea7f752 --- /dev/null +++ b/tests/functional/c/consider/consider_using_with.txt @@ -0,0 +1,22 @@ +consider-using-with:14:4:test_codecs_open:Consider using 'with' for resource-allocating operations +consider-using-with:19:4:test_urlopen:Consider using 'with' for resource-allocating operations +consider-using-with:23:4:test_temporary_file:Consider using 'with' for resource-allocating operations +consider-using-with:27:4:test_named_temporary_file:Consider using 'with' for resource-allocating operations +consider-using-with:31:4:test_spooled_temporary_file:Consider using 'with' for resource-allocating operations +consider-using-with:35:4:test_temporary_directory:Consider using 'with' for resource-allocating operations +consider-using-with:39:4:test_zipfile:Consider using 'with' for resource-allocating operations +consider-using-with:40:4:test_zipfile:Consider using 'with' for resource-allocating operations +consider-using-with:44:4:test_pyzipfile:Consider using 'with' for resource-allocating operations +consider-using-with:49:4:test_pyzipfile:Consider using 'with' for resource-allocating operations +consider-using-with:56:4:test_tarfile:Consider using 'with' for resource-allocating operations +consider-using-with:62:4:test_tarfile:Consider using 'with' for resource-allocating operations +consider-using-with:71:4:test_lock_acquisition:Consider using 'with' for resource-allocating operations +consider-using-with:78:4:test_lock_acquisition:Consider using 'with' for resource-allocating operations +consider-using-with:93:4:test_lock_acquisition:Consider using 'with' for resource-allocating operations +consider-using-with:100:4:test_lock_acquisition:Consider using 'with' for resource-allocating operations +consider-using-with:110:4:test_multiprocessing:Consider using 'with' for resource-allocating operations +consider-using-with:115:4:test_multiprocessing:Consider using 'with' for resource-allocating operations +consider-using-with:120:4:test_multiprocessing:Consider using 'with' for resource-allocating operations +consider-using-with:126:4:test_futures:Consider using 'with' for resource-allocating operations +consider-using-with:130:4:test_futures:Consider using 'with' for resource-allocating operations +consider-using-with:136:4:test_popen:Consider using 'with' for resource-allocating operations diff --git a/tests/functional/c/consider/consider_using_with_open.py b/tests/functional/c/consider/consider_using_with_open.py new file mode 100644 index 000000000..6e7cb04bd --- /dev/null +++ b/tests/functional/c/consider/consider_using_with_open.py @@ -0,0 +1,15 @@ +# pylint: disable=missing-function-docstring, missing-module-docstring, invalid-name, import-outside-toplevel +""" +The functional test for the standard ``open()`` function has to be moved in a separate file, +because PyPy has to be excluded for the tests as the ``open()`` function is uninferable in PyPy. +However, all remaining checks for consider-using-with work in PyPy, so we do not want to exclude +PyPy from ALL functional tests. +""" + + +def test_open(): + fh = open("test.txt") # [consider-using-with] + fh.close() + + with open("test.txt") as fh: # must not trigger + fh.read() diff --git a/tests/functional/c/consider/consider_using_with_open.rc b/tests/functional/c/consider/consider_using_with_open.rc new file mode 100644 index 000000000..b47a74525 --- /dev/null +++ b/tests/functional/c/consider/consider_using_with_open.rc @@ -0,0 +1,2 @@ +[testoptions] +except_implementations=PyPy diff --git a/tests/functional/c/consider/consider_using_with_open.txt b/tests/functional/c/consider/consider_using_with_open.txt new file mode 100644 index 000000000..8e7c03e39 --- /dev/null +++ b/tests/functional/c/consider/consider_using_with_open.txt @@ -0,0 +1 @@ +consider-using-with:11:4:test_open:Consider using 'with' for resource-allocating operations diff --git a/tests/functional/d/disabled_msgid_in_pylintrc.rc b/tests/functional/d/disabled_msgid_in_pylintrc.rc index 2964930df..6a584cb99 100644 --- a/tests/functional/d/disabled_msgid_in_pylintrc.rc +++ b/tests/functional/d/disabled_msgid_in_pylintrc.rc @@ -1,4 +1,4 @@ [MESSAGES CONTROL] disable= - C0111,C0326,W0703 + C0111,C0326,W0703,R1732 diff --git a/tests/functional/n/non/non_iterator_returned.py b/tests/functional/n/non/non_iterator_returned.py index 89bcdb7d9..94c3601f5 100644 --- a/tests/functional/n/non/non_iterator_returned.py +++ b/tests/functional/n/non/non_iterator_returned.py @@ -1,6 +1,7 @@ """Check non-iterators returned by __iter__ """ -# pylint: disable=too-few-public-methods, missing-docstring, no-self-use, useless-object-inheritance +# pylint: disable=too-few-public-methods, missing-docstring, no-self-use, useless-object-inheritance, consider-using-with + class FirstGoodIterator(object): """ yields in iterator. """ @@ -9,6 +10,7 @@ class FirstGoodIterator(object): for index in range(10): yield index + class SecondGoodIterator(object): """ __iter__ and next """ @@ -23,12 +25,14 @@ class SecondGoodIterator(object): """Same as __next__, but for Python 2.""" return 1 + class ThirdGoodIterator(object): """ Returns other iterator, not the current instance """ def __iter__(self): return SecondGoodIterator() + class FourthGoodIterator(object): """ __iter__ returns iter(...) """ @@ -50,9 +54,11 @@ class IteratorClass(object, metaclass=IteratorMetaclass): class FifthGoodIterator(object): """__iter__ returns a class which uses an iterator-metaclass.""" + def __iter__(self): return IteratorClass + class FileBasedIterator(object): def __init__(self, path): self.path = path @@ -70,23 +76,26 @@ class FileBasedIterator(object): class FirstBadIterator(object): """ __iter__ returns a list """ - def __iter__(self): # [non-iterator-returned] + def __iter__(self): # [non-iterator-returned] return [] + class SecondBadIterator(object): """ __iter__ without next """ - def __iter__(self): # [non-iterator-returned] + def __iter__(self): # [non-iterator-returned] return self + class ThirdBadIterator(object): """ __iter__ returns an instance of another non-iterator """ - def __iter__(self): # [non-iterator-returned] + def __iter__(self): # [non-iterator-returned] return SecondBadIterator() + class FourthBadIterator(object): """__iter__ returns a class.""" - def __iter__(self): # [non-iterator-returned] + def __iter__(self): # [non-iterator-returned] return ThirdBadIterator diff --git a/tests/functional/n/non/non_iterator_returned.txt b/tests/functional/n/non/non_iterator_returned.txt index ab9d69e7e..a78948236 100644 --- a/tests/functional/n/non/non_iterator_returned.txt +++ b/tests/functional/n/non/non_iterator_returned.txt @@ -1,4 +1,4 @@ -non-iterator-returned:73:4:FirstBadIterator.__iter__:__iter__ returns non-iterator -non-iterator-returned:79:4:SecondBadIterator.__iter__:__iter__ returns non-iterator -non-iterator-returned:85:4:ThirdBadIterator.__iter__:__iter__ returns non-iterator -non-iterator-returned:91:4:FourthBadIterator.__iter__:__iter__ returns non-iterator +non-iterator-returned:79:4:FirstBadIterator.__iter__:__iter__ returns non-iterator +non-iterator-returned:86:4:SecondBadIterator.__iter__:__iter__ returns non-iterator +non-iterator-returned:93:4:ThirdBadIterator.__iter__:__iter__ returns non-iterator +non-iterator-returned:100:4:FourthBadIterator.__iter__:__iter__ returns non-iterator |