Repository: pylint-dev/astroid

Issue:
Cython module with import triggers deep introspection for pandas, raises unhandled FutureWarning
This is a somewhat complicated situation to reproduce, but basically `pandas` throws `FutureWarning`s for certain attributes, and when you import it into a Cython module (triggering astroid's deep module inspection), these future warnings are not handled by astroid and bubble up as `AstroidError`s through to pylint. Here is a full repro:


### Cython module `pyx.pyx`

```python
# distutils: language = c++
import pandas as pd

cdef class Test:
    def __cinit__(self):
        ...
```


### Python module `test.py`

```python
import pyx

pyx.Test()
```



### Commands
```
cythonize -a -i pyx.pyx
pylint --extension-pkg-allow-list=pyx,pandas test.py
```


### Exception
```
Exception on node <Import l.1 at 0x106b23ca0> in file '/Users/timkpaine/Programs/projects/other/astroid/test.py'
Traceback (most recent call last):
  File "/opt/homebrew/lib/python3.9/site-packages/pylint/checkers/imports.py", line 765, in _get_imported_module
    return importnode.do_import_module(modname)
  File "/opt/homebrew/lib/python3.9/site-packages/astroid/mixins.py", line 102, in do_import_module
    return mymodule.import_module(
  File "/opt/homebrew/lib/python3.9/site-packages/astroid/nodes/scoped_nodes/scoped_nodes.py", line 527, in import_module
    return AstroidManager().ast_from_module_name(absmodname)
  File "/opt/homebrew/lib/python3.9/site-packages/astroid/manager.py", line 168, in ast_from_module_name
    return self.ast_from_module(module, modname)
  File "/opt/homebrew/lib/python3.9/site-packages/astroid/manager.py", line 265, in ast_from_module
    return AstroidBuilder(self).module_build(module, modname)
  File "/opt/homebrew/lib/python3.9/site-packages/astroid/builder.py", line 91, in module_build
    node = self.inspect_build(module, modname=modname, path=path)
  File "/opt/homebrew/lib/python3.9/site-packages/astroid/raw_building.py", line 311, in inspect_build
    self.object_build(node, module)
  File "/opt/homebrew/lib/python3.9/site-packages/astroid/raw_building.py", line 367, in object_build
    self.object_build(module, member)
  File "/opt/homebrew/lib/python3.9/site-packages/astroid/raw_building.py", line 325, in object_build
    member = getattr(obj, name)
  File "/opt/homebrew/lib/python3.9/site-packages/pandas/__init__.py", line 198, in __getattr__
    warnings.warn(
FutureWarning: pandas.Float64Index is deprecated and will be removed from pandas in a future version. Use pandas.Index with the appropriate dtype instead.

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/opt/homebrew/lib/python3.9/site-packages/pylint/utils/ast_walker.py", line 90, in walk
    callback(astroid)
  File "/opt/homebrew/lib/python3.9/site-packages/pylint/checkers/imports.py", line 472, in visit_import
    imported_module = self._get_imported_module(node, name)
  File "/opt/homebrew/lib/python3.9/site-packages/pylint/checkers/imports.py", line 788, in _get_imported_module
    raise astroid.AstroidError from e
astroid.exceptions.AstroidError
************* Module test
test.py:1:0: F0002: test.py: Fatal error while checking 'test.py'. Please open an issue in our bug tracker so we address this. There is a pre-filled template that you can use in '/Users/timkpaine/Library/Caches/pylint/pylint-crash-2022-07-19-17.txt'. (astroid-error)
```




### Standalone (Non Cython) repro for convenience

```python
import types
import pandas as pd
from astroid.builder import AstroidBuilder


m = types.ModuleType("test")
m.pd = pd

AstroidBuilder().module_build(m, "test")
```


xref: https://github.com/PyCQA/pylint/issues/7205
xref: https://github.com/PyCQA/astroid/pull/1719


Discussion:

Patch:
diff --git a/astroid/raw_building.py b/astroid/raw_building.py
--- a/astroid/raw_building.py
+++ b/astroid/raw_building.py
@@ -388,9 +388,9 @@ def object_build(
             pypy__class_getitem__ = IS_PYPY and name == "__class_getitem__"
             try:
                 with warnings.catch_warnings():
-                    warnings.simplefilter("error")
+                    warnings.simplefilter("ignore")
                     member = getattr(obj, name)
-            except (AttributeError, DeprecationWarning):
+            except (AttributeError):
                 # damned ExtensionClass.Base, I know you're there !
                 attach_dummy_node(node, name)
                 continue


Test patch:
diff --git a/tests/testdata/python3/data/fake_module_with_warnings.py b/tests/testdata/python3/data/fake_module_with_warnings.py
new file mode 100644
--- /dev/null
+++ b/tests/testdata/python3/data/fake_module_with_warnings.py
@@ -0,0 +1,22 @@
+'''
+This is a mock of a module like Pandas, which can throw warnings for deprecated attributes
+'''
+import warnings
+
+
+def __dir__():
+    # GH43028
+    # Int64Index etc. are deprecated, but we still want them to be available in the dir.
+    # Remove in Pandas 2.0, when we remove Int64Index etc. from the code base.
+    return list(globals().keys()) + ["Float64Index"]
+
+
+def __getattr__(name):
+    if name == "Float64Index":
+        warnings.warn("This is what pandas would do", FutureWarning, stacklevel=2)
+        return 5
+    raise AttributeError(f"module 'pandas' has no attribute '{name}'")
+
+
+__all__ = ["Float64Index"]  # pylint: disable=E0603
+__doc__ = ""
diff --git a/tests/unittest_raw_building.py b/tests/unittest_raw_building.py
--- a/tests/unittest_raw_building.py
+++ b/tests/unittest_raw_building.py
@@ -2,11 +2,14 @@
 # For details: https://github.com/PyCQA/astroid/blob/main/LICENSE
 # Copyright (c) https://github.com/PyCQA/astroid/blob/main/CONTRIBUTORS.txt
 
+import types
 import unittest
 
 import _io
 import pytest
 
+# A fake module to simulate pandas in unittest below
+import tests.testdata.python3.data.fake_module_with_warnings as fm
 from astroid.builder import AstroidBuilder
 from astroid.const import IS_PYPY
 from astroid.raw_building import (
@@ -86,6 +89,19 @@ def test_io_is__io(self):
         buffered_reader = module.getattr("BufferedReader")[0]
         self.assertEqual(buffered_reader.root().name, "io")
 
+    def test_build_function_deepinspect_deprecation(self) -> None:
+        # Tests https://github.com/PyCQA/astroid/issues/1717
+        # When astroid deep inspection of modules raises
+        # attribute errors when getting all attributes
+        # Create a mock module to simulate a Cython module
+        m = types.ModuleType("test")
+
+        # Attach a mock of pandas with the same behavior
+        m.pd = fm
+
+        # This should not raise an exception
+        AstroidBuilder().module_build(m, "test")
+
 
 if __name__ == "__main__":
     unittest.main()