diff options
-rw-r--r-- | ChangeLog | 3 | ||||
-rw-r--r-- | astroid/brain/brain_unittest.py | 27 | ||||
-rw-r--r-- | astroid/interpreter/_import/spec.py | 1 | ||||
-rw-r--r-- | astroid/manager.py | 1 | ||||
-rw-r--r-- | tests/unittest_brain_unittest.py | 30 |
5 files changed, 60 insertions, 2 deletions
@@ -15,6 +15,9 @@ Release date: TBA Closes PyCQA/pylint#2224 Closes PyCQA/pylint#2626 +* Adds a brain that deals with dynamic import of `IsolatedAsyncioTestCase` class of the `unittest` module. + + Closes PyCQA/pylint#4060 What's New in astroid 2.6.7? ============================ diff --git a/astroid/brain/brain_unittest.py b/astroid/brain/brain_unittest.py new file mode 100644 index 00000000..d371d38b --- /dev/null +++ b/astroid/brain/brain_unittest.py @@ -0,0 +1,27 @@ +"""Astroid hooks for unittest module""" +from astroid.brain.helpers import register_module_extender +from astroid.builder import parse +from astroid.const import PY38_PLUS +from astroid.manager import AstroidManager + + +def IsolatedAsyncioTestCaseImport(): + """ + In the unittest package, the IsolatedAsyncioTestCase class is imported lazily, i.e only + when the __getattr__ method of the unittest module is called with 'IsolatedAsyncioTestCase' as + argument. Thus the IsolatedAsyncioTestCase is not imported statically (during import time). + This function mocks a classical static import of the IsolatedAsyncioTestCase. + + (see https://github.com/PyCQA/pylint/issues/4060) + """ + return parse( + """ + from .async_case import IsolatedAsyncioTestCase + """ + ) + + +if PY38_PLUS: + register_module_extender( + AstroidManager(), "unittest", IsolatedAsyncioTestCaseImport + ) diff --git a/astroid/interpreter/_import/spec.py b/astroid/interpreter/_import/spec.py index 6fa9074b..403aada4 100644 --- a/astroid/interpreter/_import/spec.py +++ b/astroid/interpreter/_import/spec.py @@ -291,7 +291,6 @@ def _precache_zipimporters(path=None): req_paths = tuple(path or sys.path) cached_paths = tuple(pic) new_paths = _cached_set_diff(req_paths, cached_paths) - # pylint: disable=no-member for entry_path in new_paths: try: pic[entry_path] = zipimport.zipimporter(entry_path) diff --git a/astroid/manager.py b/astroid/manager.py index 5c436a83..306189db 100644 --- a/astroid/manager.py +++ b/astroid/manager.py @@ -229,7 +229,6 @@ class AstroidManager: except ValueError: continue try: - # pylint: disable=no-member importer = zipimport.zipimporter(eggpath + ext) # pylint: enable=no-member zmodname = resource.replace(os.path.sep, ".") diff --git a/tests/unittest_brain_unittest.py b/tests/unittest_brain_unittest.py new file mode 100644 index 00000000..644614d8 --- /dev/null +++ b/tests/unittest_brain_unittest.py @@ -0,0 +1,30 @@ +import unittest + +from astroid import builder +from astroid.test_utils import require_version + + +class UnittestTest(unittest.TestCase): + """ + A class that tests the brain_unittest module + """ + + @require_version(minver="3.8.0") + def test_isolatedasynciotestcase(self): + """ + Tests that the IsolatedAsyncioTestCase class is statically imported + thanks to the brain_unittest module. + """ + node = builder.extract_node( + """ + from unittest import IsolatedAsyncioTestCase + + class TestClass(IsolatedAsyncioTestCase): + pass + """ + ) + assert [n.qname() for n in node.ancestors()] == [ + "unittest.async_case.IsolatedAsyncioTestCase", + "unittest.case.TestCase", + "builtins.object", + ] |