summaryrefslogtreecommitdiff
path: root/astroid/helpers.py
diff options
context:
space:
mode:
authorClaudiu Popa <pcmanticore@gmail.com>2018-03-05 11:47:22 +0100
committerClaudiu Popa <pcmanticore@gmail.com>2018-03-10 10:02:48 +0100
commit6ed8cb3a612f28da94664642aeed47d6a67202a4 (patch)
treebab8a952013d1cc2240e50827de5f133fb114caf /astroid/helpers.py
parentda26488c8f88e04b6157149a163384de8dd3f9cd (diff)
downloadastroid-git-6ed8cb3a612f28da94664642aeed47d6a67202a4.tar.gz
Rewrite the object_isinstance and object_issubclass helpers to rely on common code
Diffstat (limited to 'astroid/helpers.py')
-rw-r--r--astroid/helpers.py58
1 files changed, 23 insertions, 35 deletions
diff --git a/astroid/helpers.py b/astroid/helpers.py
index bce1a59f..21f7445f 100644
--- a/astroid/helpers.py
+++ b/astroid/helpers.py
@@ -83,39 +83,46 @@ def object_type(node, context=None):
return list(types)[0]
-def object_isinstance(node, class_or_seq, context=None):
- """Check if a node 'isinstance' 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
- """
+def _object_type_is_subclass(obj_type, class_or_seq, context=None):
if not isinstance(class_or_seq, (tuple, list)):
class_seq = (class_or_seq,)
else:
class_seq = class_or_seq
- obj_type = object_type(node, context)
+
if obj_type is util.Uninferable:
return util.Uninferable
# Instances are not types
class_seq = [item if not isinstance(item, bases.Instance)
else util.Uninferable for item in class_seq]
- # strict compatibility with isinstance
- # isinstance(1, (int, 1)) evaluates to true
- # isinstance(1, (1, int)) raises TypeError
+ # strict compatibility with issubclass
+ # issubclass(1, (int, 1)) evaluates to true
+ # issubclass(1, (1, int)) raises TypeError
for klass in class_seq:
if klass is util.Uninferable:
- raise exceptions.AstroidTypeError(
- "isinstance() arg 2 must be a type or tuple of types")
+ raise exceptions.AstroidTypeError("arg 2 must be a type or tuple of types")
+
for obj_subclass in obj_type.mro():
if obj_subclass == klass:
return True
return False
+def object_isinstance(node, class_or_seq, context=None):
+ """Check if a node 'isinstance' 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
+ """
+ obj_type = object_type(node, context)
+ if obj_type is util.Uninferable:
+ return util.Uninferable
+ return _object_type_is_subclass(obj_type, class_or_seq, context=context)
+
+
def object_issubclass(node, class_or_seq, context=None):
"""Check if a type is a subclass of any node in class_or_seq
@@ -127,28 +134,9 @@ def object_issubclass(node, class_or_seq, context=None):
: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
+ return _object_type_is_subclass(node, class_or_seq, context=context)
def safe_infer(node, context=None):