From 2b19658564ace0dbac96c4232abdfe04d6d8f8b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl=20van=20Noord?= <13665637+DanielNoord@users.noreply.github.com> Date: Mon, 2 May 2022 13:20:23 +0200 Subject: [PATCH] Improve recognition of ``_io`` module during bootstrapping on ``PyPy`` (#1529) --- astroid/raw_building.py | 25 +++++++++---------------- tests/unittest_inference.py | 5 +---- 2 files changed, 10 insertions(+), 20 deletions(-) diff --git a/astroid/raw_building.py b/astroid/raw_building.py index 129a0612bd..bcc414baea 100644 --- a/astroid/raw_building.py +++ b/astroid/raw_building.py @@ -26,17 +26,6 @@ TYPE_ELLIPSIS = type(...) -def _io_discrepancy(member): - # _io module names itself `io`: http://bugs.python.org/issue18602 - member_self = getattr(member, "__self__", None) - return ( - member_self - and inspect.ismodule(member_self) - and member_self.__name__ == "_io" - and member.__module__ == "io" - ) - - def _attach_local_node(parent, node, name): node.name = name # needed by add_local_node parent.add_local_node(node) @@ -343,9 +332,7 @@ def object_build(self, node, obj): if inspect.isfunction(member): _build_from_function(node, name, member, self._module) elif inspect.isbuiltin(member): - if not _io_discrepancy(member) and self.imported_member( - node, member, name - ): + if self.imported_member(node, member, name): continue object_build_methoddescriptor(node, member, name) elif inspect.isclass(member): @@ -383,7 +370,7 @@ def object_build(self, node, obj): attach_dummy_node(node, name, member) return None - def imported_member(self, node, member, name): + def imported_member(self, node, member, name: str) -> bool: """verify this is not an imported class or handle it""" # /!\ some classes like ExtensionClass doesn't have a __module__ # attribute ! Also, this may trigger an exception on badly built module @@ -402,7 +389,13 @@ def imported_member(self, node, member, name): attach_dummy_node(node, name, member) return True - real_name = {"gtk": "gtk_gtk", "_io": "io"}.get(modname, modname) + # On PyPy during bootstrapping we infer _io while _module is + # builtins. In CPython _io names itself io, see http://bugs.python.org/issue18602 + # Therefore, this basically checks whether we are not in PyPy. + if modname == "_io" and not self._module.__name__ == "builtins": + return False + + real_name = {"gtk": "gtk_gtk"}.get(modname, modname) if real_name != self._module.__name__: # check if it sounds valid and then add an import node, else use a diff --git a/tests/unittest_inference.py b/tests/unittest_inference.py index b5fc7d99f4..dc117ee418 100644 --- a/tests/unittest_inference.py +++ b/tests/unittest_inference.py @@ -20,7 +20,7 @@ from astroid.arguments import CallSite from astroid.bases import BoundMethod, Instance, UnboundMethod from astroid.builder import AstroidBuilder, extract_node, parse -from astroid.const import IS_PYPY, PY38_PLUS, PY39_PLUS +from astroid.const import PY38_PLUS, PY39_PLUS from astroid.context import InferenceContext from astroid.exceptions import ( AstroidTypeError, @@ -817,9 +817,6 @@ def test_builtin_open(self) -> None: self.assertIsInstance(inferred[0], nodes.FunctionDef) self.assertEqual(inferred[0].name, "open") - if IS_PYPY: - test_builtin_open = unittest.expectedFailure(test_builtin_open) - def test_callfunc_context_func(self) -> None: code = """ def mirror(arg=None):