fix implements selector to avoid returning false positive due to entity class inheritance tls-sprint
authorsylvain.thenault@logilab.fr
Fri, 24 Apr 2009 15:37:51 +0200
branchtls-sprint
changeset 1472 96e06e623494
parent 1471 c889c3bcf5ec
child 1473 717dea3362c0
fix implements selector to avoid returning false positive due to entity class inheritance
selectors.py
--- a/selectors.py	Fri Apr 24 15:37:05 2009 +0200
+++ b/selectors.py	Fri Apr 24 15:37:51 2009 +0200
@@ -112,6 +112,28 @@
         return traceback is None
 
 
+def score_interface(cls_or_inst, cls, iface):
+    """Return true if the give object (maybe an instance or class) implements
+    the interface.
+    """
+    if getattr(iface, '__registry__', None) == 'etypes':
+        # adjust score if the interface is an entity class
+        parents = cls_or_inst.parent_classes()
+        if iface is cls:
+            return len(parents) + 4
+        if iface is parents[-1]: # Any
+            return 1
+        for index, etype in enumerate(reversed(parents[:-1])):
+            basecls = vreg.etype_class(etype)
+            if iface is basecls:
+                return index + 3
+        return 0
+    if implements_iface(cls_or_inst, iface):
+        # implenting an interface takes precedence other special Any interface
+        return 2
+    return 0
+
+
 # abstract selectors ##########################################################
 
 class PartialSelectorMixIn(object):
@@ -146,24 +168,7 @@
                     iface = vreg.etype_class(iface)
                 except KeyError:
                     continue # entity type not in the schema
-            if implements_iface(cls_or_inst, iface):
-                if getattr(iface, '__registry__', None) == 'etypes':
-                    # adjust score if the interface is an entity class
-                    if iface is cls:
-                        score += len(eschema.ancestors()) + 4
-                    else: 
-                        parents = [e.type for e in eschema.ancestors()]
-                        for index, etype in enumerate(reversed(parents)):
-                            basecls = vreg.etype_class(etype)
-                            if iface is basecls:
-                                score += index + 3
-                                break
-                        else: # Any
-                            score += 1
-                else:
-                    # implenting an interface takes precedence other special Any
-                    # interface
-                    score += 2
+            score += score_interface(cls_or_inst, cls, iface)
         return score