Skip to content

Use UninferableBase instead of Uninferable #8384

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

Merged
merged 1 commit into from
Mar 7, 2023
Merged
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
4 changes: 2 additions & 2 deletions pylint/checkers/async.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from typing import TYPE_CHECKING

import astroid
from astroid import nodes
from astroid import nodes, util

from pylint import checkers
from pylint.checkers import utils as checker_utils
Expand Down Expand Up @@ -55,7 +55,7 @@ def visit_asyncfunctiondef(self, node: nodes.AsyncFunctionDef) -> None:
def visit_asyncwith(self, node: nodes.AsyncWith) -> None:
for ctx_mgr, _ in node.items:
inferred = checker_utils.safe_infer(ctx_mgr)
if inferred is None or inferred is astroid.Uninferable:
if inferred is None or isinstance(inferred, util.UninferableBase):
continue

if isinstance(inferred, nodes.AsyncFunctionDef):
Expand Down
10 changes: 6 additions & 4 deletions pylint/checkers/base/basic_checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from typing import TYPE_CHECKING, cast

import astroid
from astroid import nodes, objects
from astroid import nodes, objects, util

from pylint import utils as lint_utils
from pylint.checkers import BaseChecker, utils
Expand Down Expand Up @@ -333,7 +333,9 @@ def _check_using_constant_test(
maybe_generator_call = None
if not isinstance(test, except_nodes):
inferred = utils.safe_infer(test)
if inferred is astroid.Uninferable and isinstance(test, nodes.Name):
if isinstance(inferred, util.UninferableBase) and isinstance(
test, nodes.Name
):
emit, maybe_generator_call = BasicChecker._name_holds_generator(test)

# Emit if calling a function that only returns GeneratorExp (always tests True)
Expand Down Expand Up @@ -677,7 +679,7 @@ def _check_misplaced_format_function(self, call_node: nodes.Call) -> None:
return

expr = utils.safe_infer(call_node.func.expr)
if expr is astroid.Uninferable:
if isinstance(expr, util.UninferableBase):
return
if not expr:
# we are doubtful on inferred type of node, so here just check if format
Expand Down Expand Up @@ -822,7 +824,7 @@ def _check_reversed(self, node: nodes.Call) -> None:
except utils.NoSuchArgumentError:
pass
else:
if argument is astroid.Uninferable:
if isinstance(argument, util.UninferableBase):
return
if argument is None:
# Nothing was inferred.
Expand Down
15 changes: 7 additions & 8 deletions pylint/checkers/classes/class_checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from typing import TYPE_CHECKING, Any, Union

import astroid
from astroid import bases, nodes
from astroid import bases, nodes, util
from astroid.nodes import LocalsDictNodeNG
from astroid.typing import SuccessfulInferenceResult

Expand Down Expand Up @@ -459,7 +459,7 @@ def _is_attribute_property(name: str, klass: nodes.ClassDef) -> bool:
return False
property_name = "builtins.property"
for attr in attributes:
if attr is astroid.Uninferable:
if isinstance(attr, util.UninferableBase):
continue
try:
inferred = next(attr.infer())
Expand Down Expand Up @@ -1453,7 +1453,7 @@ def _check_slots(self, node: nodes.ClassDef) -> None:

for slots in node.ilookup("__slots__"):
# check if __slots__ is a valid type
if slots is astroid.Uninferable:
if isinstance(slots, util.UninferableBase):
continue
if not is_iterable(slots) and not is_comprehension(slots):
self.add_message("invalid-slots", node=node)
Expand All @@ -1471,7 +1471,7 @@ def _check_slots(self, node: nodes.ClassDef) -> None:
values = [item[0] for item in slots.items]
else:
values = slots.itered()
if values is astroid.Uninferable:
if isinstance(values, util.UninferableBase):
continue
for elt in values:
try:
Expand Down Expand Up @@ -1518,7 +1518,7 @@ def _check_slots_elt(
self, elt: SuccessfulInferenceResult, node: nodes.ClassDef
) -> None:
for inferred in elt.infer():
if inferred is astroid.Uninferable:
if isinstance(inferred, util.UninferableBase):
continue
if not isinstance(inferred, nodes.Const) or not isinstance(
inferred.value, str
Expand Down Expand Up @@ -1623,8 +1623,7 @@ def _check_invalid_class_object(self, node: nodes.AssignAttr) -> None:
else:
inferred = safe_infer(node.parent.value)
if (
isinstance(inferred, nodes.ClassDef)
or inferred is astroid.Uninferable
isinstance(inferred, (nodes.ClassDef, util.UninferableBase))
or inferred is None
):
# If is uninferable, we allow it to prevent false positives
Expand Down Expand Up @@ -2133,7 +2132,7 @@ def _check_init(self, node: nodes.FunctionDef, klass_node: nodes.ClassDef) -> No
# pylint: disable = too-many-try-statements
try:
for klass in expr.expr.infer():
if klass is astroid.Uninferable:
if isinstance(klass, util.UninferableBase):
continue
# The inferred klass can be super(), which was
# assigned to a variable and the `__init__`
Expand Down
4 changes: 2 additions & 2 deletions pylint/checkers/classes/special_methods_checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from collections.abc import Callable

import astroid
from astroid import bases, nodes
from astroid import bases, nodes, util
from astroid.context import InferenceContext
from astroid.typing import InferenceResult

Expand Down Expand Up @@ -394,7 +394,7 @@ def _check_getnewargs_ex(
if isinstance(arg, nodes.Call):
arg = safe_infer(arg)

if arg and arg is not astroid.Uninferable:
if arg and not isinstance(arg, util.UninferableBase):
if not check(arg):
found_error = True
break
Expand Down
7 changes: 5 additions & 2 deletions pylint/checkers/dunder_methods.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@

from typing import TYPE_CHECKING

from astroid import Instance, Uninferable, nodes
from astroid import Instance, nodes
from astroid.util import UninferableBase

from pylint.checkers import BaseChecker
from pylint.checkers.utils import safe_infer
Expand Down Expand Up @@ -77,7 +78,9 @@ def visit_call(self, node: nodes.Call) -> None:
)
):
inf_expr = safe_infer(node.func.expr)
if not (inf_expr in {None, Uninferable} or isinstance(inf_expr, Instance)):
if not (
inf_expr is None or isinstance(inf_expr, (Instance, UninferableBase))
):
# Skip dunder calls to non instantiated classes.
return

Expand Down
12 changes: 6 additions & 6 deletions pylint/checkers/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from typing import TYPE_CHECKING, Any

import astroid
from astroid import nodes, objects
from astroid import nodes, objects, util
from astroid.context import InferenceContext
from astroid.typing import InferenceResult, SuccessfulInferenceResult

Expand Down Expand Up @@ -46,11 +46,11 @@ def _annotated_unpack_infer(
if isinstance(stmt, (nodes.List, nodes.Tuple)):
for elt in stmt.elts:
inferred = utils.safe_infer(elt)
if inferred and inferred is not astroid.Uninferable:
if inferred and not isinstance(inferred, util.UninferableBase):
yield elt, inferred
return
for inferred in stmt.infer(context):
if inferred is astroid.Uninferable:
if isinstance(inferred, util.UninferableBase):
continue
yield stmt, inferred

Expand Down Expand Up @@ -344,7 +344,7 @@ def visit_raise(self, node: nodes.Raise) -> None:
ExceptionRaiseRefVisitor(self, node).visit(expr)

inferred = utils.safe_infer(expr)
if inferred is None or inferred is astroid.Uninferable:
if inferred is None or isinstance(inferred, util.UninferableBase):
return
ExceptionRaiseLeafVisitor(self, node).visit(inferred)

Expand Down Expand Up @@ -375,7 +375,7 @@ def _check_bad_exception_cause(self, node: nodes.Raise) -> None:
An exception cause can be only `None` or an exception.
"""
cause = utils.safe_infer(node.cause)
if cause in (astroid.Uninferable, None):
if cause is None or isinstance(cause, util.UninferableBase):
return

if isinstance(cause, nodes.Const):
Expand Down Expand Up @@ -441,7 +441,7 @@ def _check_catching_non_exception(
if isinstance(exc, nodes.Tuple):
# Check if it is a tuple of exceptions.
inferred = [utils.safe_infer(elt) for elt in exc.elts]
if any(node is astroid.Uninferable for node in inferred):
if any(isinstance(node, util.UninferableBase) for node in inferred):
# Don't emit if we don't know every component.
return
if all(
Expand Down
6 changes: 4 additions & 2 deletions pylint/checkers/refactoring/implicit_booleaness_checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from __future__ import annotations

import astroid
from astroid import bases, nodes
from astroid import bases, nodes, util

from pylint import checkers
from pylint.checkers import utils
Expand Down Expand Up @@ -224,7 +224,9 @@ def _implicit_booleaness_message_args(
return original_comparison, suggestion, description

@staticmethod
def base_names_of_instance(node: bases.Uninferable | bases.Instance) -> list[str]:
def base_names_of_instance(
node: util.UninferableBase | bases.Instance,
) -> list[str]:
"""Return all names inherited by a class instance or those returned by a
function.

Expand Down
14 changes: 10 additions & 4 deletions pylint/checkers/refactoring/refactoring_checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

import astroid
from astroid import bases, nodes
from astroid.util import Uninferable
from astroid.util import UninferableBase

from pylint import checkers
from pylint.checkers import utils
Expand Down Expand Up @@ -1542,7 +1542,9 @@ def visit_return(self, node: nodes.Return | nodes.Assign) -> None:
return

inferred_truth_value = utils.safe_infer(truth_value, compare_constants=True)
if inferred_truth_value is None or inferred_truth_value == astroid.Uninferable:
if inferred_truth_value is None or isinstance(
inferred_truth_value, UninferableBase
):
return
truth_boolean_value = inferred_truth_value.bool_value()

Expand All @@ -1569,7 +1571,7 @@ def _append_context_managers_to_stack(self, node: nodes.Assign) -> None:
else:
assignees = [node.targets[0]]
values = [node.value]
if Uninferable in (assignees, values):
if any(isinstance(n, UninferableBase) for n in (assignees, values)):
Comment on lines -1572 to +1574
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unrelated to this PR, but this looks fishy. Why would Uninferable be in a tuple of lists? 🤔

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah.. I guess elts is Uninferable sometimes? Or this is just 100% broken..

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you mind opening a follow up issue to investigate?

return
for assignee, value in zip(assignees, values):
if not isinstance(value, nodes.Call):
Expand Down Expand Up @@ -1921,7 +1923,11 @@ def _is_raise_node_return_ended(self, node: nodes.Raise) -> bool:
# to infer it.
return True
exc = utils.safe_infer(node.exc)
if exc is None or exc is astroid.Uninferable or not hasattr(exc, "pytype"):
if (
exc is None
or isinstance(exc, UninferableBase)
or not hasattr(exc, "pytype")
):
return False
exc_name = exc.pytype().split(".")[-1]
handlers = utils.get_exception_handlers(node, exc_name)
Expand Down
8 changes: 4 additions & 4 deletions pylint/checkers/stdlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from typing import TYPE_CHECKING, Any, Dict, Set, Tuple

import astroid
from astroid import nodes
from astroid import nodes, util
from astroid.typing import InferenceResult

from pylint import interfaces
Expand Down Expand Up @@ -540,7 +540,7 @@ def visit_call(self, node: nodes.Call) -> None:
"""Visit a Call node."""
self.check_deprecated_class_in_call(node)
for inferred in utils.infer_all(node.func):
if inferred is astroid.Uninferable:
if isinstance(inferred, util.UninferableBase):
continue
if inferred.root().name in OPEN_MODULE:
open_func_name: str | None = None
Expand Down Expand Up @@ -805,7 +805,7 @@ def _check_invalid_envvar_value(
call_arg: InferenceResult | None,
allow_none: bool,
) -> None:
if call_arg in (astroid.Uninferable, None):
if call_arg is None or isinstance(call_arg, util.UninferableBase):
return

name = infer.qname()
Expand All @@ -818,7 +818,7 @@ def _check_invalid_envvar_value(
if emit:
self.add_message(message, node=node, args=(name, call_arg.pytype()))
else:
self.add_message(message, node=node, args=(name, call_arg.pytype())) # type: ignore[union-attr]
self.add_message(message, node=node, args=(name, call_arg.pytype()))

def deprecated_methods(self) -> set[str]:
return self._deprecated_methods
Expand Down
12 changes: 6 additions & 6 deletions pylint/checkers/strings.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from typing import TYPE_CHECKING

import astroid
from astroid import bases, nodes
from astroid import bases, nodes, util
from astroid.typing import SuccessfulInferenceResult

from pylint.checkers import BaseChecker, BaseRawFileChecker, BaseTokenChecker, utils
Expand Down Expand Up @@ -337,7 +337,7 @@ def visit_binop(self, node: nodes.BinOp) -> None:
if (
format_type is not None
and arg_type
and arg_type != astroid.Uninferable
and not isinstance(arg_type, util.UninferableBase)
and not arg_matches_format_type(arg_type, format_type)
):
self.add_message(
Expand Down Expand Up @@ -395,7 +395,7 @@ def visit_binop(self, node: nodes.BinOp) -> None:
arg_type = utils.safe_infer(arg)
if (
arg_type
and arg_type != astroid.Uninferable
and not isinstance(arg_type, util.UninferableBase)
and not arg_matches_format_type(arg_type, format_type)
):
self.add_message(
Expand Down Expand Up @@ -561,7 +561,7 @@ def _check_new_format_specifiers(
if key not in named:
continue
argname = named[key]
if argname in (astroid.Uninferable, None):
if argname is None or isinstance(argname, util.UninferableBase):
continue
try:
argument = utils.safe_infer(argname)
Expand All @@ -578,7 +578,7 @@ def _check_new_format_specifiers(
previous = argument
parsed: list[tuple[bool, str]] = []
for is_attribute, specifier in specifiers:
if previous is astroid.Uninferable:
if isinstance(previous, util.UninferableBase):
break
parsed.append((is_attribute, specifier))
if is_attribute:
Expand Down Expand Up @@ -611,7 +611,7 @@ def _check_new_format_specifiers(
warn_error = True
except astroid.InferenceError:
break
if previous is astroid.Uninferable:
if isinstance(previous, util.UninferableBase):
break
else:
try:
Expand Down
Loading