Skip to content

Commit be480c6

Browse files
DanielNoordcdce8p
andauthored
Type _infer of binary operation nodes (#1659)
Co-authored-by: Marc Mueller <[email protected]>
1 parent 41fcd15 commit be480c6

File tree

2 files changed

+46
-20
lines changed

2 files changed

+46
-20
lines changed

astroid/inference.py

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -510,18 +510,28 @@ def _infer_boolop(
510510
# UnaryOp, BinOp and AugAssign inferences
511511

512512

513-
def _filter_operation_errors(self, infer_callable, context, error):
513+
def _filter_operation_errors(
514+
self: _T,
515+
infer_callable: Callable[
516+
[_T, InferenceContext | None],
517+
Generator[InferenceResult | util.BadOperationMessage, None, None],
518+
],
519+
context: InferenceContext | None,
520+
error: type[util.BadOperationMessage],
521+
) -> Generator[InferenceResult, None, None]:
514522
for result in infer_callable(self, context):
515523
if isinstance(result, error):
516524
# For the sake of .infer(), we don't care about operation
517525
# errors, which is the job of pylint. So return something
518526
# which shows that we can't infer the result.
519527
yield util.Uninferable
520528
else:
521-
yield result
529+
yield result # type: ignore[misc]
522530

523531

524-
def _infer_unaryop(self, context=None):
532+
def _infer_unaryop(
533+
self: nodes.UnaryOp, context: InferenceContext | None = None
534+
) -> Generator[InferenceResult | util.BadUnaryOperationMessage, None, None]:
525535
"""Infer what an UnaryOp should return when evaluated."""
526536
for operand in self.operand.infer(context):
527537
try:
@@ -579,16 +589,18 @@ def _infer_unaryop(self, context=None):
579589

580590
@decorators.raise_if_nothing_inferred
581591
@decorators.path_wrapper
582-
def infer_unaryop(self, context=None):
592+
def infer_unaryop(
593+
self: nodes.UnaryOp, context: InferenceContext | None = None, **kwargs: Any
594+
) -> Generator[InferenceResult, None, InferenceErrorInfo]:
583595
"""Infer what an UnaryOp should return when evaluated."""
584596
yield from _filter_operation_errors(
585597
self, _infer_unaryop, context, util.BadUnaryOperationMessage
586598
)
587-
return dict(node=self, context=context)
599+
return InferenceErrorInfo(node=self, context=context)
588600

589601

590602
nodes.UnaryOp._infer_unaryop = _infer_unaryop
591-
nodes.UnaryOp._infer = infer_unaryop
603+
nodes.UnaryOp._infer = infer_unaryop # type: ignore[assignment]
592604

593605

594606
def _is_not_implemented(const):
@@ -828,7 +840,9 @@ def _infer_binary_operation(left, right, binary_opnode, context, flow_factory):
828840
yield util.BadBinaryOperationMessage(left_type, binary_opnode.op, right_type)
829841

830842

831-
def _infer_binop(self, context):
843+
def _infer_binop(
844+
self: nodes.BinOp, context: InferenceContext | None = None
845+
) -> Generator[InferenceResult | util.BadBinaryOperationMessage, None, None]:
832846
"""Binary operation inference logic."""
833847
left = self.left
834848
right = self.right
@@ -855,14 +869,16 @@ def _infer_binop(self, context):
855869

856870
@decorators.yes_if_nothing_inferred
857871
@decorators.path_wrapper
858-
def infer_binop(self, context=None):
872+
def infer_binop(
873+
self: nodes.BinOp, context: InferenceContext | None = None, **kwargs: Any
874+
) -> Generator[InferenceResult, None, None]:
859875
return _filter_operation_errors(
860876
self, _infer_binop, context, util.BadBinaryOperationMessage
861877
)
862878

863879

864880
nodes.BinOp._infer_binop = _infer_binop
865-
nodes.BinOp._infer = infer_binop
881+
nodes.BinOp._infer = infer_binop # type: ignore[assignment]
866882

867883
COMPARE_OPS: dict[str, Callable[[Any, Any], bool]] = {
868884
"==": operator.eq,
@@ -932,8 +948,8 @@ def _do_compare(
932948

933949

934950
def _infer_compare(
935-
self: nodes.Compare, context: InferenceContext | None = None
936-
) -> Iterator[nodes.Const | type[util.Uninferable]]:
951+
self: nodes.Compare, context: InferenceContext | None = None, **kwargs: Any
952+
) -> Generator[nodes.Const | type[util.Uninferable], None, None]:
937953
"""Chained comparison inference logic."""
938954
retval: bool | type[util.Uninferable] = True
939955

@@ -961,7 +977,9 @@ def _infer_compare(
961977
nodes.Compare._infer = _infer_compare # type: ignore[assignment]
962978

963979

964-
def _infer_augassign(self, context=None):
980+
def _infer_augassign(
981+
self: nodes.AugAssign, context: InferenceContext | None = None
982+
) -> Generator[InferenceResult | util.BadBinaryOperationMessage, None, None]:
965983
"""Inference logic for augmented binary operations."""
966984
context = context or InferenceContext()
967985

@@ -989,14 +1007,16 @@ def _infer_augassign(self, context=None):
9891007

9901008
@decorators.raise_if_nothing_inferred
9911009
@decorators.path_wrapper
992-
def infer_augassign(self, context=None):
1010+
def infer_augassign(
1011+
self: nodes.AugAssign, context: InferenceContext | None = None, **kwargs: Any
1012+
) -> Generator[InferenceResult, None, None]:
9931013
return _filter_operation_errors(
9941014
self, _infer_augassign, context, util.BadBinaryOperationMessage
9951015
)
9961016

9971017

9981018
nodes.AugAssign._infer_augassign = _infer_augassign
999-
nodes.AugAssign._infer = infer_augassign
1019+
nodes.AugAssign._infer = infer_augassign # type: ignore[assignment]
10001020

10011021
# End of binary operation inference.
10021022

astroid/nodes/node_classes.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ def _is_const(value):
5656

5757

5858
_NodesT = TypeVar("_NodesT", bound=NodeNG)
59+
_BadOpMessageT = TypeVar("_BadOpMessageT", bound=util.BadOperationMessage)
5960

6061
AssignedStmtsPossibleNode = Union["List", "Tuple", "AssignName", "AssignAttr", None]
6162
AssignedStmtsCall = Callable[
@@ -71,6 +72,10 @@ def _is_const(value):
7172
[_NodesT, Optional[InferenceContext]],
7273
typing.Generator[InferenceResult, None, Optional[InferenceErrorInfo]],
7374
]
75+
InferBinaryOperation = Callable[
76+
[_NodesT, Optional[InferenceContext]],
77+
typing.Generator[Union[InferenceResult, _BadOpMessageT], None, None],
78+
]
7479

7580

7681
@decorators.raise_if_nothing_inferred
@@ -1349,8 +1354,9 @@ def postinit(
13491354
"""
13501355

13511356
# This is set by inference.py
1352-
def _infer_augassign(self, context=None):
1353-
raise NotImplementedError
1357+
_infer_augassign: ClassVar[
1358+
InferBinaryOperation[AugAssign, util.BadBinaryOperationMessage]
1359+
]
13541360

13551361
def type_errors(self, context=None):
13561362
"""Get a list of type errors which can occur during inference.
@@ -1449,8 +1455,7 @@ def postinit(self, left: NodeNG | None = None, right: NodeNG | None = None) -> N
14491455
self.right = right
14501456

14511457
# This is set by inference.py
1452-
def _infer_binop(self, context=None):
1453-
raise NotImplementedError
1458+
_infer_binop: ClassVar[InferBinaryOperation[BinOp, util.BadBinaryOperationMessage]]
14541459

14551460
def type_errors(self, context=None):
14561461
"""Get a list of type errors which can occur during inference.
@@ -4232,8 +4237,9 @@ def postinit(self, operand: NodeNG | None = None) -> None:
42324237
self.operand = operand
42334238

42344239
# This is set by inference.py
4235-
def _infer_unaryop(self, context=None):
4236-
raise NotImplementedError
4240+
_infer_unaryop: ClassVar[
4241+
InferBinaryOperation[UnaryOp, util.BadUnaryOperationMessage]
4242+
]
42374243

42384244
def type_errors(self, context=None):
42394245
"""Get a list of type errors which can occur during inference.

0 commit comments

Comments
 (0)