|
8 | 8 | # For details: https://github.com/PyCQA/astroid/blob/main/LICENSE
|
9 | 9 | # Copyright (c) https://github.com/PyCQA/astroid/blob/main/CONTRIBUTORS.txt
|
10 | 10 |
|
| 11 | +from __future__ import annotations |
| 12 | + |
| 13 | +import logging |
| 14 | +import os |
| 15 | +import sys |
11 | 16 | import types
|
12 | 17 | import unittest
|
| 18 | +from typing import Any |
| 19 | +from unittest import mock |
13 | 20 |
|
14 | 21 | import _io
|
15 | 22 | import pytest
|
@@ -117,5 +124,45 @@ def test_module_object_with_broken_getattr(self) -> None:
|
117 | 124 | AstroidBuilder().inspect_build(fm_getattr, "test")
|
118 | 125 |
|
119 | 126 |
|
| 127 | +@pytest.mark.skipif( |
| 128 | + "posix" not in sys.builtin_module_names, reason="Platform doesn't support posix" |
| 129 | +) |
| 130 | +def test_build_module_getattr_catch_output( |
| 131 | + capsys: pytest.CaptureFixture[str], |
| 132 | + caplog: pytest.LogCaptureFixture, |
| 133 | +) -> None: |
| 134 | + """Catch stdout and stderr in module __getattr__ calls when building a module. |
| 135 | +
|
| 136 | + Usually raised by DeprecationWarning or FutureWarning. |
| 137 | + """ |
| 138 | + caplog.set_level(logging.INFO) |
| 139 | + original_sys = sys.modules |
| 140 | + original_module = sys.modules["posix"] |
| 141 | + expected_out = "INFO (TEST): Welcome to posix!" |
| 142 | + expected_err = "WARNING (TEST): Monkey-patched version of posix - module getattr" |
| 143 | + |
| 144 | + class CustomGetattr: |
| 145 | + def __getattr__(self, name: str) -> Any: |
| 146 | + print(f"{expected_out}") |
| 147 | + print(expected_err, file=sys.stderr) |
| 148 | + return getattr(original_module, name) |
| 149 | + |
| 150 | + def mocked_sys_modules_getitem(name: str) -> types.ModuleType | CustomGetattr: |
| 151 | + if name != "posix": |
| 152 | + return original_sys[name] |
| 153 | + return CustomGetattr() |
| 154 | + |
| 155 | + with mock.patch("astroid.raw_building.sys.modules") as sys_mock: |
| 156 | + sys_mock.__getitem__.side_effect = mocked_sys_modules_getitem |
| 157 | + builder = AstroidBuilder() |
| 158 | + builder.inspect_build(os) |
| 159 | + |
| 160 | + out, err = capsys.readouterr() |
| 161 | + assert expected_out in caplog.text |
| 162 | + assert expected_err in caplog.text |
| 163 | + assert not out |
| 164 | + assert not err |
| 165 | + |
| 166 | + |
120 | 167 | if __name__ == "__main__":
|
121 | 168 | unittest.main()
|
0 commit comments