Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 18 additions & 6 deletions astroid/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,9 @@ def file_build(self, path, modname=None):
module, builder = self._data_build(data, modname, path)
return self._post_build(module, builder, encoding)

def string_build(self, data, modname="", path=None):
def string_build(self, data, modname="", path=None, *, tree_rev: int | None = None):
"""Build astroid from source code string."""
module, builder = self._data_build(data, modname, path)
module, builder = self._data_build(data, modname, path, tree_rev)
module.file_bytes = data.encode("utf-8")
return self._post_build(module, builder, "utf-8")

Expand All @@ -162,7 +162,7 @@ def _post_build(
return module

def _data_build(
self, data: str, modname, path
self, data: str, modname, path, tree_rev: int | None = None
) -> tuple[nodes.Module, rebuilder.TreeRebuilder]:
"""Build tree node from data and add some informations"""
try:
Expand All @@ -188,7 +188,12 @@ def _data_build(
path is not None
and os.path.splitext(os.path.basename(path))[0] == "__init__"
)
builder = rebuilder.TreeRebuilder(self._manager, parser_module, data)
builder = rebuilder.TreeRebuilder(
self._manager,
parser_module,
data,
tree_rev=tree_rev or AstroidManager.tree_rev,
)
module = builder.visit_module(node, modname, node_file, package)
return module, builder

Expand Down Expand Up @@ -265,7 +270,14 @@ def build_namespace_package_module(name: str, path: list[str]) -> nodes.Module:
return nodes.Module(name, path=path, package=True)


def parse(code, module_name="", path=None, apply_transforms=True):
def parse(
code,
module_name="",
path=None,
apply_transforms=True,
*,
tree_rev: int | None = None,
):
"""Parses a source string in order to obtain an astroid AST from it

:param str code: The code for the module.
Expand All @@ -279,7 +291,7 @@ def parse(code, module_name="", path=None, apply_transforms=True):
builder = AstroidBuilder(
manager=AstroidManager(), apply_transforms=apply_transforms
)
return builder.string_build(code, modname=module_name, path=path)
return builder.string_build(code, modname=module_name, path=path, tree_rev=tree_rev)


def _extract_expressions(node):
Expand Down
8 changes: 8 additions & 0 deletions astroid/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@
import sys
from pathlib import Path

if sys.version_info >= (3, 8):
from typing import Final
else:
from typing_extensions import Final

PY38 = sys.version_info[:2] == (3, 8)
PY38_PLUS = sys.version_info >= (3, 8)
PY39_PLUS = sys.version_info >= (3, 9)
Expand Down Expand Up @@ -33,3 +38,6 @@ class Context(enum.Enum):

ASTROID_INSTALL_DIRECTORY = Path(__file__).parent
BRAIN_MODULES_DIRECTORY = ASTROID_INSTALL_DIRECTORY / "brain"

TREE_REV: Final = 1
"""Default AST tree revision. Any update here is a breaking change!"""
3 changes: 2 additions & 1 deletion astroid/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from importlib.util import find_spec, module_from_spec
from typing import TYPE_CHECKING, ClassVar

from astroid.const import BRAIN_MODULES_DIRECTORY
from astroid.const import BRAIN_MODULES_DIRECTORY, TREE_REV
from astroid.exceptions import AstroidBuildingError, AstroidImportError
from astroid.interpreter._import import spec
from astroid.modutils import (
Expand Down Expand Up @@ -62,6 +62,7 @@ class AstroidManager:
"_transform": TransformVisitor(),
}
max_inferable_values: ClassVar[int] = 100
tree_rev: ClassVar[int] = TREE_REV

def __init__(self):
# NOTE: cache entries are added by the [re]builder
Expand Down
5 changes: 4 additions & 1 deletion astroid/rebuilder.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

from astroid import nodes
from astroid._ast import ParserModule, get_parser_module, parse_function_type_comment
from astroid.const import IS_PYPY, PY38, PY38_PLUS, PY39_PLUS, Context
from astroid.const import IS_PYPY, PY38, PY38_PLUS, PY39_PLUS, TREE_REV, Context
from astroid.manager import AstroidManager
from astroid.nodes import NodeNG
from astroid.nodes.utils import Position
Expand Down Expand Up @@ -61,9 +61,12 @@ def __init__(
manager: AstroidManager,
parser_module: ParserModule | None = None,
data: str | None = None,
*,
tree_rev: int = TREE_REV,
) -> None:
self._manager = manager
self._data = data.split("\n") if data else None
self._tree_rev = tree_rev
self._global_names: list[dict[str, list[nodes.Global]]] = []
self._import_from_nodes: list[nodes.ImportFrom] = []
self._delayed_assattr: list[nodes.AssignAttr] = []
Expand Down