Skip to content

Remove all references to _infer #2168

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
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
214 changes: 152 additions & 62 deletions astroid/inference.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
AttributeInferenceError,
InferenceError,
NameInferenceError,
UseInferenceDefault,
_NonDeducibleTypeHierarchy,
)
from astroid.interpreter import dunder_lookup
Expand Down Expand Up @@ -85,15 +86,6 @@ def infer_end(
yield self


# We add ignores to all assignments to methods
# See https://github.com/python/mypy/issues/2427
nodes.Module._infer = infer_end
nodes.ClassDef._infer = infer_end
nodes.Lambda._infer = infer_end # type: ignore[assignment]
nodes.Const._infer = infer_end # type: ignore[assignment]
nodes.Slice._infer = infer_end # type: ignore[assignment]


def _infer_sequence_helper(
node: _BaseContainerT, context: InferenceContext | None = None
) -> list[SuccessfulInferenceResult]:
Expand Down Expand Up @@ -139,11 +131,6 @@ def infer_sequence(
yield self


nodes.List._infer = infer_sequence # type: ignore[assignment]
nodes.Tuple._infer = infer_sequence # type: ignore[assignment]
nodes.Set._infer = infer_sequence # type: ignore[assignment]


def infer_map(
self: nodes.Dict, context: InferenceContext | None = None
) -> Iterator[nodes.Dict]:
Expand Down Expand Up @@ -206,9 +193,6 @@ def _infer_map(
return values


nodes.Dict._infer = infer_map # type: ignore[assignment]


def _higher_function_scope(node: nodes.NodeNG) -> nodes.FunctionDef | None:
"""Search for the first function which encloses the given
scope. This can be used for looking up in that function's
Expand Down Expand Up @@ -254,12 +238,18 @@ def infer_name(
return bases._infer_stmts(stmts, context, frame)


# pylint: disable=no-value-for-parameter
# The order of the decorators here is important
# See https://github.com/pylint-dev/astroid/commit/0a8a75db30da060a24922e05048bc270230f5
nodes.Name._infer = decorators.raise_if_nothing_inferred(
decorators.path_wrapper(infer_name)
)
@decorators.raise_if_nothing_inferred
@decorators.path_wrapper
def _infer_name(
self: nodes.Name | nodes.AssignName,
context: InferenceContext | None = None,
**kwargs: Any,
) -> Generator[InferenceResult, None, None]:
return infer_name(self, context, **kwargs)


nodes.AssignName.infer_lhs = infer_name # won't work with a path wrapper


Expand Down Expand Up @@ -289,9 +279,6 @@ def infer_call(
return InferenceErrorInfo(node=self, context=context)


nodes.Call._infer = infer_call # type: ignore[assignment]


@decorators.raise_if_nothing_inferred
@decorators.path_wrapper
def infer_import(
Expand All @@ -315,9 +302,6 @@ def infer_import(
raise InferenceError(node=self, context=context) from exc


nodes.Import._infer = infer_import


@decorators.raise_if_nothing_inferred
@decorators.path_wrapper
def infer_import_from(
Expand Down Expand Up @@ -353,9 +337,6 @@ def infer_import_from(
) from error


nodes.ImportFrom._infer = infer_import_from # type: ignore[assignment]


def infer_attribute(
self: nodes.Attribute | nodes.AssignAttr,
context: InferenceContext | None = None,
Expand Down Expand Up @@ -390,9 +371,16 @@ def infer_attribute(

# The order of the decorators here is important
# See https://github.com/pylint-dev/astroid/commit/0a8a75db30da060a24922e05048bc270230f5
nodes.Attribute._infer = decorators.raise_if_nothing_inferred(
decorators.path_wrapper(infer_attribute)
)
@decorators.raise_if_nothing_inferred
@decorators.path_wrapper
def _infer_attribute(
self: nodes.Attribute | nodes.AssignAttr,
context: InferenceContext | None = None,
**kwargs: Any,
) -> Generator[InferenceResult, None, InferenceErrorInfo]:
return infer_attribute(self, context, **kwargs)


# won't work with a path wrapper
nodes.AssignAttr.infer_lhs = decorators.raise_if_nothing_inferred(infer_attribute)

Expand All @@ -412,9 +400,6 @@ def infer_global(
) from error


nodes.Global._infer = infer_global # type: ignore[assignment]


_SUBSCRIPT_SENTINEL = object()


Expand Down Expand Up @@ -479,9 +464,14 @@ def infer_subscript(

# The order of the decorators here is important
# See https://github.com/pylint-dev/astroid/commit/0a8a75db30da060a24922e05048bc270230f5
nodes.Subscript._infer = decorators.raise_if_nothing_inferred( # type: ignore[assignment]
decorators.path_wrapper(infer_subscript)
)
@decorators.raise_if_nothing_inferred
@decorators.path_wrapper
def _infer_subscript(
self: nodes.Subscript, context: InferenceContext | None = None, **kwargs: Any
) -> Generator[InferenceResult, None, InferenceErrorInfo | None]:
return infer_subscript(self, context=context, **kwargs)


nodes.Subscript.infer_lhs = decorators.raise_if_nothing_inferred(infer_subscript)


Expand Down Expand Up @@ -540,9 +530,6 @@ def _infer_boolop(
return InferenceErrorInfo(node=self, context=context)


nodes.BoolOp._infer = _infer_boolop


# UnaryOp, BinOp and AugAssign inferences


Expand Down Expand Up @@ -639,7 +626,6 @@ def infer_unaryop(


nodes.UnaryOp._infer_unaryop = _infer_unaryop
nodes.UnaryOp._infer = infer_unaryop


def _is_not_implemented(const) -> bool:
Expand Down Expand Up @@ -991,7 +977,6 @@ def infer_binop(


nodes.BinOp._infer_binop = _infer_binop
nodes.BinOp._infer = infer_binop

COMPARE_OPS: dict[str, Callable[[Any, Any], bool]] = {
"==": operator.eq,
Expand Down Expand Up @@ -1089,9 +1074,6 @@ def _infer_compare(
yield nodes.Const(retval)


nodes.Compare._infer = _infer_compare # type: ignore[assignment]


def _infer_augassign(
self: nodes.AugAssign, context: InferenceContext | None = None
) -> Generator[InferenceResult | util.BadBinaryOperationMessage, None, None]:
Expand Down Expand Up @@ -1131,7 +1113,6 @@ def infer_augassign(


nodes.AugAssign._infer_augassign = _infer_augassign
nodes.AugAssign._infer = infer_augassign

# End of binary operation inference.

Expand All @@ -1145,9 +1126,6 @@ def infer_arguments(
return protocols._arguments_infer_argname(self, context.lookupname, context)


nodes.Arguments._infer = infer_arguments # type: ignore[assignment]


@decorators.raise_if_nothing_inferred
@decorators.path_wrapper
def infer_assign(
Expand All @@ -1165,10 +1143,6 @@ def infer_assign(
return bases._infer_stmts(stmts, context)


nodes.AssignName._infer = infer_assign
nodes.AssignAttr._infer = infer_assign


@decorators.raise_if_nothing_inferred
@decorators.path_wrapper
def infer_empty_node(
Expand All @@ -1185,9 +1159,6 @@ def infer_empty_node(
yield util.Uninferable


nodes.EmptyNode._infer = infer_empty_node # type: ignore[assignment]


def _populate_context_lookup(call: nodes.Call, context: InferenceContext | None):
# Allows context to be saved for later
# for inference inside a function
Expand Down Expand Up @@ -1240,9 +1211,6 @@ def infer_ifexp(
yield from self.orelse.infer(context=rhs_context)


nodes.IfExp._infer = infer_ifexp # type: ignore[assignment]


def infer_functiondef(
self: _FunctionDefT, context: InferenceContext | None = None, **kwargs: Any
) -> Generator[Property | _FunctionDefT, None, InferenceErrorInfo]:
Expand Down Expand Up @@ -1277,4 +1245,126 @@ def infer_functiondef(
return InferenceErrorInfo(node=self, context=context)


nodes.FunctionDef._infer = infer_functiondef
# pylint: disable-next=too-many-return-statements
def _infer_node(
node: nodes.NodeNG, context: InferenceContext | None = None, **kwargs: Any
) -> Generator[InferenceResult, None, None]:
"""Find the infer method for the given node and call it."""
if isinstance(
node,
(
nodes.Module,
nodes.ClassDef,
nodes.Lambda,
nodes.Const,
nodes.Slice,
objects.Property,
objects.FrozenSet,
objects.Super,
),
):
return infer_end(node, context=context, **kwargs)
if isinstance(node, (nodes.List, nodes.Tuple, nodes.Set)):
return infer_sequence(node, context=context, **kwargs)
if isinstance(node, nodes.Dict):
return infer_map(node, context=context, **kwargs)
if isinstance(node, nodes.Name):
return _infer_name(node, context=context, **kwargs)
if isinstance(node, nodes.Call):
return infer_call(node, context=context, **kwargs)
if isinstance(node, nodes.Import):
return infer_import(node, context=context, **kwargs)
if isinstance(node, nodes.ImportFrom):
return infer_import_from(node, context=context, **kwargs)
if isinstance(node, nodes.Attribute):
return _infer_attribute(node, context=context, **kwargs)
if isinstance(node, nodes.Global):
return infer_global(node, context=context, **kwargs)
if isinstance(node, nodes.Subscript):
return _infer_subscript(node, context=context, **kwargs)
if isinstance(node, nodes.BoolOp):
return _infer_boolop(node, context=context, **kwargs)
if isinstance(node, nodes.UnaryOp):
return infer_unaryop(node, context=context, **kwargs)
if isinstance(node, nodes.BinOp):
return infer_binop(node, context=context, **kwargs)
if isinstance(node, nodes.Compare):
return _infer_compare(node, context=context, **kwargs)
if isinstance(node, nodes.AugAssign):
return infer_augassign(node, context=context, **kwargs)
if isinstance(node, nodes.Arguments):
return infer_arguments(node, context=context, **kwargs)
if isinstance(node, (nodes.AssignName, nodes.AssignAttr)):
return infer_assign(node, context=context, **kwargs)
if isinstance(node, nodes.EmptyNode):
return infer_empty_node(node, context=context, **kwargs)
if isinstance(node, nodes.IfExp):
return infer_ifexp(node, context=context, **kwargs)
if isinstance(node, nodes.FunctionDef):
return infer_functiondef(node, context=context, **kwargs)
if isinstance(node, nodes.Unknown):
return iter((util.Uninferable,))
if isinstance(node, nodes.EvaluatedObject):
return iter((node.value,))
raise InferenceError(
"No inference function for {node!r}.", node=node, context=context
)


def infer_object(
node: nodes.NodeNG, context: InferenceContext | None = None, **kwargs: Any
) -> Generator[InferenceResult, None, None]:
"""Get a generator of the inferred values.

This is the main entry point to the inference system.

.. seealso:: :ref:`inference`

If the instance has some explicit inference function set, it will be
called instead of the default interface.

:returns: The inferred values.
"""
if context is not None:
context = context.extra_context.get(node, context)
if node._explicit_inference is not None:
# explicit_inference is not bound, give it self explicitly
try:
if context is None:
yield from node._explicit_inference(node, context, **kwargs)
return
for result in node._explicit_inference(node, context, **kwargs):
context.nodes_inferred += 1
yield result
return
except UseInferenceDefault:
pass

if not context:
# nodes_inferred?
yield from _infer_node(node, context=context, **kwargs)
return

key = (node, context.lookupname, context.callcontext, context.boundnode)
if key in context.inferred:
yield from context.inferred[key]
return

results = []

# Limit inference amount to help with performance issues with
# exponentially exploding possible results.
limit = AstroidManager.max_inferable_values
for i, result in enumerate(_infer_node(node, context=context, **kwargs)):
if i >= limit or (context.nodes_inferred > context.max_inferred):
results.append(util.Uninferable)
yield util.Uninferable
break
results.append(result)
yield result
context.nodes_inferred += 1

# Cache generated results for subsequent inferences of the
# same node using the same context
context.inferred[key] = tuple(results)
return
9 changes: 0 additions & 9 deletions astroid/nodes/node_classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -3932,10 +3932,6 @@ def __init__(
def qname(self) -> Literal["Unknown"]:
return "Unknown"

def _infer(self, context: InferenceContext | None = None, **kwargs):
"""Inference on an Unknown node immediately terminates."""
yield util.Uninferable


class EvaluatedObject(NodeNG):
"""Contains an object that has already been inferred
Expand Down Expand Up @@ -3963,11 +3959,6 @@ def __init__(self, original: NodeNG, value: NodeNG | util.UninferableBase) -> No
end_col_offset=self.original.end_col_offset,
)

def _infer(
self, context: InferenceContext | None = None, **kwargs: Any
) -> Generator[NodeNG | util.UninferableBase, None, None]:
yield self.value


# Pattern matching #######################################################

Expand Down
Loading