Skip to content

Commit 3c6516e

Browse files
Make manager required in AstroidBuilder/InspectBuilder (#2313)
Co-authored-by: Pierre Sassoulas <[email protected]>
1 parent d2fa037 commit 3c6516e

16 files changed

+331
-253
lines changed

ChangeLog

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ Release date: TBA
1010
* Removed internal functions ``infer_numpy_member``, ``name_looks_like_numpy_member``, and
1111
``attribute_looks_like_numpy_member`` from ``astroid.brain.brain_numpy_utils``.
1212

13+
* To alleviate circular imports, the ``manager`` argument to ``AstroidBuilder()`` is now required.
14+
1315
* Constants now have a parent of ``nodes.SYNTHETIC_ROOT``.
1416

1517
* Fix crashes with large positive and negative list multipliers.

astroid/brain/brain_nose.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ def _pep8(name, caps=CAPITALS):
2323

2424
def _nose_tools_functions():
2525
"""Get an iterator of names and bound methods."""
26-
module = AstroidBuilder().string_build(
26+
module = AstroidBuilder(AstroidManager()).string_build(
2727
textwrap.dedent(
2828
"""
2929
import unittest
@@ -54,7 +54,7 @@ def _nose_tools_transform(node):
5454

5555
def _nose_tools_trivial_transform():
5656
"""Custom transform for the nose.tools module."""
57-
stub = AstroidBuilder().string_build("""__all__ = []""")
57+
stub = AstroidBuilder(AstroidManager()).string_build("""__all__ = []""")
5858
all_entries = ["ok_", "eq_"]
5959

6060
for pep8_name, method in _nose_tools_functions():

astroid/builder.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,15 @@
1919
from collections.abc import Iterator, Sequence
2020
from io import TextIOWrapper
2121
from tokenize import detect_encoding
22+
from typing import TYPE_CHECKING
2223

2324
from astroid import bases, modutils, nodes, raw_building, rebuilder, util
2425
from astroid._ast import ParserModule, get_parser_module
2526
from astroid.const import PY312_PLUS
2627
from astroid.exceptions import AstroidBuildingError, AstroidSyntaxError, InferenceError
27-
from astroid.manager import AstroidManager
28+
29+
if TYPE_CHECKING:
30+
from astroid.manager import AstroidManager
2831

2932
# The name of the transient function that is used to
3033
# wrap expressions to be extracted when calling
@@ -62,20 +65,17 @@ def _can_assign_attr(node: nodes.ClassDef, attrname: str | None) -> bool:
6265
class AstroidBuilder(raw_building.InspectBuilder):
6366
"""Class for building an astroid tree from source code or from a live module.
6467
65-
The param *manager* specifies the manager class which should be used.
66-
If no manager is given, then the default one will be used. The
68+
The param *manager* specifies the manager class which should be used. The
6769
param *apply_transforms* determines if the transforms should be
6870
applied after the tree was built from source or from a live object,
6971
by default being True.
7072
"""
7173

72-
def __init__(
73-
self, manager: AstroidManager | None = None, apply_transforms: bool = True
74-
) -> None:
74+
def __init__(self, manager: AstroidManager, apply_transforms: bool = True) -> None:
7575
super().__init__(manager)
7676
self._apply_transforms = apply_transforms
7777
if not raw_building.InspectBuilder.bootstrapped:
78-
raw_building._astroid_bootstrapping()
78+
manager.bootstrap()
7979

8080
def module_build(
8181
self, module: types.ModuleType, modname: str | None = None
@@ -292,10 +292,11 @@ def parse(
292292
Apply the transforms for the give code. Use it if you
293293
don't want the default transforms to be applied.
294294
"""
295+
# pylint: disable-next=import-outside-toplevel
296+
from astroid.manager import AstroidManager
297+
295298
code = textwrap.dedent(code)
296-
builder = AstroidBuilder(
297-
manager=AstroidManager(), apply_transforms=apply_transforms
298-
)
299+
builder = AstroidBuilder(AstroidManager(), apply_transforms=apply_transforms)
299300
return builder.string_build(code, modname=module_name, path=path)
300301

301302

astroid/interpreter/_import/spec.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
from typing import Literal, NamedTuple, Protocol
2222

2323
from astroid.const import PY310_PLUS
24-
from astroid.modutils import EXT_LIB_DIRS, cached_os_path_isfile
2524

2625
from . import util
2726

@@ -134,6 +133,9 @@ def find_module(
134133
processed: tuple[str, ...],
135134
submodule_path: tuple[str, ...] | None,
136135
) -> ModuleSpec | None:
136+
# pylint: disable-next=import-outside-toplevel
137+
from astroid.modutils import cached_os_path_isfile
138+
137139
# Although we should be able to use `find_spec` this doesn't work on PyPy for builtins.
138140
# Therefore, we use the `builtin_module_nams` heuristic for these.
139141
if submodule_path is None and modname in sys.builtin_module_names:
@@ -225,6 +227,8 @@ def contribute_to_path(
225227
if spec.location is None:
226228
# Builtin.
227229
return None
230+
# pylint: disable-next=import-outside-toplevel
231+
from astroid.modutils import EXT_LIB_DIRS
228232

229233
if _is_setuptools_namespace(Path(spec.location)):
230234
# extend_path is called, search sys.path for module/packages

astroid/manager.py

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
from typing import Any, ClassVar
1818

1919
from astroid import nodes
20+
from astroid.builder import AstroidBuilder, build_namespace_package_module
2021
from astroid.context import InferenceContext, _invalidate_cache
2122
from astroid.exceptions import AstroidBuildingError, AstroidImportError
2223
from astroid.interpreter._import import spec, util
@@ -161,9 +162,6 @@ def ast_from_file(
161162
):
162163
return self.astroid_cache[modname]
163164
if source:
164-
# pylint: disable=import-outside-toplevel; circular import
165-
from astroid.builder import AstroidBuilder
166-
167165
return AstroidBuilder(self).file_build(filepath, modname)
168166
if fallback and modname:
169167
return self.ast_from_module_name(modname)
@@ -175,23 +173,14 @@ def ast_from_string(
175173
"""Given some source code as a string, return its corresponding astroid
176174
object.
177175
"""
178-
# pylint: disable=import-outside-toplevel; circular import
179-
from astroid.builder import AstroidBuilder
180-
181176
return AstroidBuilder(self).string_build(data, modname, filepath)
182177

183178
def _build_stub_module(self, modname: str) -> nodes.Module:
184-
# pylint: disable=import-outside-toplevel; circular import
185-
from astroid.builder import AstroidBuilder
186-
187179
return AstroidBuilder(self).string_build("", modname)
188180

189181
def _build_namespace_module(
190182
self, modname: str, path: Sequence[str]
191183
) -> nodes.Module:
192-
# pylint: disable=import-outside-toplevel; circular import
193-
from astroid.builder import build_namespace_package_module
194-
195184
return build_namespace_package_module(modname, path)
196185

197186
def _can_load_extension(self, modname: str) -> bool:
@@ -290,9 +279,6 @@ def zip_import_data(self, filepath: str) -> nodes.Module | None:
290279
if zipimport is None:
291280
return None
292281

293-
# pylint: disable=import-outside-toplevel; circular import
294-
from astroid.builder import AstroidBuilder
295-
296282
builder = AstroidBuilder(self)
297283
for ext in ZIP_IMPORT_EXTS:
298284
try:
@@ -351,9 +337,6 @@ def ast_from_module(
351337
except AttributeError:
352338
pass
353339

354-
# pylint: disable=import-outside-toplevel; circular import
355-
from astroid.builder import AstroidBuilder
356-
357340
return AstroidBuilder(self).module_build(module, modname)
358341

359342
def ast_from_class(self, klass: type, modname: str | None = None) -> nodes.ClassDef:

astroid/raw_building.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,15 @@
1818
import warnings
1919
from collections.abc import Iterable
2020
from contextlib import redirect_stderr, redirect_stdout
21-
from typing import Any, Union
21+
from typing import TYPE_CHECKING, Any, Union
2222

2323
from astroid import bases, nodes
2424
from astroid.const import _EMPTY_OBJECT_MARKER, IS_PYPY
25-
from astroid.manager import AstroidManager
2625
from astroid.nodes import node_classes
2726

27+
if TYPE_CHECKING:
28+
from astroid.manager import AstroidManager
29+
2830
logger = logging.getLogger(__name__)
2931

3032

@@ -37,8 +39,6 @@
3739
types.ClassMethodDescriptorType,
3840
]
3941

40-
# the keys of CONST_CLS eg python builtin types
41-
_CONSTANTS = tuple(node_classes.CONST_CLS)
4242
TYPE_NONE = type(None)
4343
TYPE_NOTIMPLEMENTED = type(NotImplemented)
4444
TYPE_ELLIPSIS = type(...)
@@ -424,8 +424,8 @@ class InspectBuilder:
424424

425425
bootstrapped: bool = False
426426

427-
def __init__(self, manager_instance: AstroidManager | None = None) -> None:
428-
self._manager = manager_instance or AstroidManager()
427+
def __init__(self, manager_instance: AstroidManager) -> None:
428+
self._manager = manager_instance
429429
self._done: dict[types.ModuleType | type, nodes.Module | nodes.ClassDef] = {}
430430
self._module: types.ModuleType
431431

@@ -502,7 +502,7 @@ def object_build(
502502
child: nodes.NodeNG = object_build_methoddescriptor(node, member)
503503
elif inspect.isdatadescriptor(member):
504504
child = object_build_datadescriptor(node, member)
505-
elif isinstance(member, _CONSTANTS):
505+
elif isinstance(member, tuple(node_classes.CONST_CLS)):
506506
if alias in node.special_attributes:
507507
continue
508508
child = nodes.const_factory(member)
@@ -595,7 +595,10 @@ def _astroid_bootstrapping() -> None:
595595
"""astroid bootstrapping the builtins module"""
596596
# this boot strapping is necessary since we need the Const nodes to
597597
# inspect_build builtins, and then we can proxy Const
598-
builder = InspectBuilder()
598+
# pylint: disable-next=import-outside-toplevel
599+
from astroid.manager import AstroidManager
600+
601+
builder = InspectBuilder(AstroidManager())
599602
astroid_builtin = builder.inspect_build(builtins)
600603

601604
for cls, node_cls in node_classes.CONST_CLS.items():

0 commit comments

Comments
 (0)