summaryrefslogtreecommitdiff
path: root/astroid/helpers.py
diff options
context:
space:
mode:
authorClaudiu Popa <pcmanticore@gmail.com>2018-03-05 11:17:35 +0100
committerClaudiu Popa <pcmanticore@gmail.com>2018-03-10 10:02:48 +0100
commitda26488c8f88e04b6157149a163384de8dd3f9cd (patch)
treefc0779d29fcde3f975043ca22aa88a92731b1afd /astroid/helpers.py
parent518e4a9dbff1ca041fa46a19c891a1d8a143f985 (diff)
downloadastroid-git-da26488c8f88e04b6157149a163384de8dd3f9cd.tar.gz
Add brain inference support for the `issubclass` builtin
This is in a similar vein with the `isinstance` builtin, with minor changes.
Diffstat (limited to 'astroid/helpers.py')
-rw-r--r--astroid/helpers.py35
1 files changed, 35 insertions, 0 deletions
diff --git a/astroid/helpers.py b/astroid/helpers.py
index d3522442..bce1a59f 100644
--- a/astroid/helpers.py
+++ b/astroid/helpers.py
@@ -116,6 +116,41 @@ def object_isinstance(node, class_or_seq, context=None):
return False
+def object_issubclass(node, class_or_seq, context=None):
+ """Check if a type is a subclass of any node in class_or_seq
+
+ :param node: A given node
+ :param class_or_seq: Union[Nodes.NodeNG], Sequence[nodes.NodeNG]]
+ :rtype: bool
+
+ :raises AstroidTypeError: if the given ``classes_or_seq`` are not types
+ :raises AstroidError: if the type of the given node cannot be inferred
+ or its type's mro doesn't work
+ """
+ if not isinstance(class_or_seq, (tuple, list)):
+ class_seq = (class_or_seq,)
+ else:
+ class_seq = class_or_seq
+
+ if not isinstance(node, nodes.ClassDef):
+ raise TypeError("{node} needs to be a ClassDef node".format(node=node))
+
+ # Instances are not types
+ class_seq = [item if not isinstance(item, bases.Instance)
+ else util.Uninferable for item in class_seq]
+ # strict compatibility with issubclass
+ # issubclass(int, (int, 1)) evaluates to true
+ # issubclass(int, (1, int)) raises TypeError
+ for klass in class_seq:
+ if klass is util.Uninferable:
+ raise exceptions.AstroidTypeError(
+ "issubclass() arg 2 must be a type or tuple of types")
+ for obj_subclass in node.mro():
+ if obj_subclass == klass:
+ return True
+ return False
+
+
def safe_infer(node, context=None):
"""Return the inferred value for the given node.