Skip to content

Commit 5dcb5fa

Browse files
committed
Add tests
1 parent ef43a90 commit 5dcb5fa

File tree

1 file changed

+134
-0
lines changed

1 file changed

+134
-0
lines changed

tests/test_constraint.py

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import pytest
99

1010
from astroid import builder, nodes
11+
from astroid.bases import Instance
1112
from astroid.util import Uninferable
1213

1314

@@ -19,6 +20,8 @@ def common_params(node: str) -> pytest.MarkDecorator:
1920
(f"{node} is not None", 3, None),
2021
(f"{node}", 3, None),
2122
(f"not {node}", None, 3),
23+
(f"isinstance({node}, int)", 3, None),
24+
(f"isinstance({node}, (int, str))", 3, None),
2225
),
2326
)
2427

@@ -773,3 +776,134 @@ def method(self, x = {fail_val}):
773776
assert isinstance(inferred[0], nodes.Const)
774777
assert inferred[0].value == fail_val
775778
assert inferred[1].value is Uninferable
779+
780+
781+
def test_isinstance_equal_types() -> None:
782+
"""Test constraint for an object whose type is equal to the checked type."""
783+
node = builder.extract_node(
784+
f"""
785+
class A:
786+
pass
787+
788+
x = A()
789+
790+
if isinstance(x, A):
791+
x #@
792+
"""
793+
)
794+
795+
inferred = node.inferred()
796+
assert len(inferred) == 1
797+
assert isinstance(inferred[0], Instance)
798+
assert isinstance(inferred[0]._proxied, nodes.ClassDef)
799+
assert inferred[0].name == "A"
800+
801+
802+
def test_isinstance_subtype() -> None:
803+
"""Test constraint for an object whose type is a strict subtype of the checked type."""
804+
node = builder.extract_node(
805+
f"""
806+
class A:
807+
pass
808+
809+
class B(A):
810+
pass
811+
812+
x = B()
813+
814+
if isinstance(x, A):
815+
x #@
816+
"""
817+
)
818+
819+
inferred = node.inferred()
820+
assert len(inferred) == 1
821+
assert isinstance(inferred[0], Instance)
822+
assert isinstance(inferred[0]._proxied, nodes.ClassDef)
823+
assert inferred[0].name == "B"
824+
825+
826+
def test_isinstance_unrelated_types():
827+
"""Test constraint for an object whose type is not related to the checked type."""
828+
node = builder.extract_node(
829+
f"""
830+
class A:
831+
pass
832+
833+
class B:
834+
pass
835+
836+
x = A()
837+
838+
if isinstance(x, B):
839+
x #@
840+
"""
841+
)
842+
843+
inferred = node.inferred()
844+
assert len(inferred) == 1
845+
assert inferred[0] is Uninferable
846+
847+
848+
def test_isinstance_supertype():
849+
"""Test constraint for an object whose type is a strict supertype of the checked type."""
850+
node = builder.extract_node(
851+
f"""
852+
class A:
853+
pass
854+
855+
class B(A):
856+
pass
857+
858+
x = A()
859+
860+
if isinstance(x, B):
861+
x #@
862+
"""
863+
)
864+
865+
inferred = node.inferred()
866+
assert len(inferred) == 1
867+
assert inferred[0] is Uninferable
868+
869+
870+
def test_isinstance_keyword_arguments():
871+
"""Test that constraint does not apply when `isinstance` is called
872+
with keyword arguments.
873+
"""
874+
n1, n2 = builder.extract_node(
875+
f"""
876+
x = 3
877+
878+
if isinstance(object=x, classinfo=str):
879+
x #@
880+
881+
if isinstance(x, str, object=x, classinfo=str):
882+
x #@
883+
"""
884+
)
885+
886+
for node in (n1, n2):
887+
inferred = node.inferred()
888+
assert len(inferred) == 1
889+
assert isinstance(inferred[0], nodes.Const)
890+
assert inferred[0].value == 3
891+
892+
893+
def test_isinstance_extra_argument():
894+
"""Test that constraint does not apply when `isinstance` is called
895+
with more than two positional arguments.
896+
"""
897+
node = builder.extract_node(
898+
f"""
899+
x = 3
900+
901+
if isinstance(x, str, bool):
902+
x #@
903+
"""
904+
)
905+
906+
inferred = node.inferred()
907+
assert len(inferred) == 1
908+
assert isinstance(inferred[0], nodes.Const)
909+
assert inferred[0].value == 3

0 commit comments

Comments
 (0)