cubicweb/devtools/instrument.py
author Denis Laxalde <denis.laxalde@logilab.fr>
Wed, 26 Oct 2016 08:34:34 +0200
changeset 11751 b57b76091481
parent 11057 0b59724cb3f2
child 12567 26744ad37953
permissions -rw-r--r--
[devtools] Make dependency on backports.tempfile (Python2) optional The package may not be available in all systems (e.g. no Debian package exist at the moment), and we should not crash with ImportError when importing testlib from client code. Follow up on a6dc650bc230 where the dependency was introduced.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
9368
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
     1
# copyright 2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
     2
# contact http://www.logilab.fr -- mailto:contact@logilab.fr
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
     3
#
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
     4
# This program is free software: you can redistribute it and/or modify it under
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
     5
# the terms of the GNU Lesser General Public License as published by the Free
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
     6
# Software Foundation, either version 2.1 of the License, or (at your option)
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
     7
# any later version.
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
     8
#
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
     9
# This program is distributed in the hope that it will be useful, but WITHOUT
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    10
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    11
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    12
# details.
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    13
#
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    14
# You should have received a copy of the GNU Lesser General Public License along
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    15
# with this program. If not, see <http://www.gnu.org/licenses/>.
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    16
"""Instrumentation utilities"""
10589
7c23b7de2b8d [py3k] print function
Samuel Trégouët <samuel.tregouet@logilab.fr>
parents: 9368
diff changeset
    17
from __future__ import print_function
9368
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    18
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    19
import os
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    20
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    21
try:
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    22
    import pygraphviz
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    23
except ImportError:
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    24
    pygraphviz = None
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    25
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    26
from cubicweb.cwvreg import CWRegistryStore
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    27
from cubicweb.devtools.devctl import DevConfiguration
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    28
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    29
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    30
ALL_COLORS = [
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    31
    "00FF00", "0000FF", "FFFF00", "FF00FF", "00FFFF", "000000",
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    32
    "800000", "008000", "000080", "808000", "800080", "008080", "808080",
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    33
    "C00000", "00C000", "0000C0", "C0C000", "C000C0", "00C0C0", "C0C0C0",
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    34
    "400000", "004000", "000040", "404000", "400040", "004040", "404040",
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    35
    "200000", "002000", "000020", "202000", "200020", "002020", "202020",
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    36
    "600000", "006000", "000060", "606000", "600060", "006060", "606060",
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    37
    "A00000", "00A000", "0000A0", "A0A000", "A000A0", "00A0A0", "A0A0A0",
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    38
    "E00000", "00E000", "0000E0", "E0E000", "E000E0", "00E0E0", "E0E0E0",
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    39
    ]
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    40
_COLORS = {}
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    41
def get_color(key):
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    42
    try:
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    43
        return _COLORS[key]
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    44
    except KeyError:
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    45
        _COLORS[key] = '#'+ALL_COLORS[len(_COLORS) % len(ALL_COLORS)]
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    46
        return _COLORS[key]
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    47
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    48
def warn(msg, *args):
10589
7c23b7de2b8d [py3k] print function
Samuel Trégouët <samuel.tregouet@logilab.fr>
parents: 9368
diff changeset
    49
    print('WARNING: %s' % (msg % args))
9368
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    50
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    51
def info(msg):
10589
7c23b7de2b8d [py3k] print function
Samuel Trégouët <samuel.tregouet@logilab.fr>
parents: 9368
diff changeset
    52
    print('INFO: ' + msg)
9368
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    53
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    54
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    55
class PropagationAnalyzer(object):
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    56
    """Abstract propagation analyzer, providing utility function to extract
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    57
    entities involved in propagation from a schema, as well as propagation
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    58
    rules from hooks (provided they use intrumentalized sets, see
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    59
    :class:`CubeTracerSet`).
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    60
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    61
    Concrete classes should at least define `prop_rel` class attribute and
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    62
    implements the `is_root` method.
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    63
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    64
    See `localperms` or `nosylist` cubes for example usage (`ccplugin` module).
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    65
    """
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    66
    prop_rel = None # name of the propagation relation
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    67
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    68
    def init(self, cube):
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    69
        """Initialize analyze for the given cube, returning the (already loaded)
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    70
        vregistry and a set of entities which we're interested in.
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    71
        """
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    72
        config = DevConfiguration(cube)
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    73
        schema = config.load_schema()
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    74
        vreg = CWRegistryStore(config)
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    75
        vreg.set_schema(schema) # set_schema triggers objects registrations
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    76
        eschemas = set(eschema for eschema in schema.entities()
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    77
                       if self.should_include(eschema))
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    78
        return vreg, eschemas
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    79
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    80
    def is_root(self, eschema):
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    81
        """Return `True` if given entity schema is a root of the graph"""
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    82
        raise NotImplementedError()
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    83
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    84
    def should_include(self, eschema):
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    85
        """Return `True` if given entity schema should be included by the graph.
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    86
        """
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    87
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    88
        if self.prop_rel in eschema.subjrels or self.is_root(eschema):
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    89
            return True
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    90
        return False
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    91
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    92
    def prop_edges(self, s_rels, o_rels, eschemas):
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    93
        """Return a set of edges where propagation has been detected.
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    94
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    95
        Each edge is defined by a 4-uple (from node, to node, rtype, package)
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    96
        where `rtype` is the relation type bringing from <from node> to <to
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    97
        node> and `package` is the cube adding the rule to the propagation
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    98
        control set (see see :class:`CubeTracerSet`).
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    99
        """
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   100
        schema = iter(eschemas).next().schema
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   101
        prop_edges = set()
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   102
        for rtype in s_rels:
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   103
            found = False
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   104
            for subj, obj in schema.rschema(rtype).rdefs:
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   105
                if subj in eschemas and obj in eschemas:
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   106
                    found = True
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   107
                    prop_edges.add( (subj, obj, rtype, s_rels.value_cube[rtype]) )
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   108
            if not found:
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   109
                warn('no rdef match for %s', rtype)
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   110
        for rtype in o_rels:
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   111
            found = False
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   112
            for subj, obj in schema.rschema(rtype).rdefs:
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   113
                if subj in eschemas and obj in eschemas:
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   114
                    found = True
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   115
                    prop_edges.add( (obj, subj, rtype, o_rels.value_cube[rtype]) )
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   116
            if not found:
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   117
                warn('no rdef match for %s', rtype)
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   118
        return prop_edges
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   119
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   120
    def detect_problems(self, eschemas, edges):
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   121
        """Given the set of analyzed entity schemas and edges between them,
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   122
        return a set of entity schemas where a problem has been detected.
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   123
        """
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   124
        problematic = set()
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   125
        for eschema in eschemas:
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   126
            if self.has_problem(eschema, edges):
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   127
                problematic.add(eschema)
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   128
        not_problematic = set(eschemas).difference(problematic)
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   129
        if not_problematic:
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   130
            info('nothing problematic in: %s' %
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   131
                 ', '.join(e.type for e in not_problematic))
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   132
        return problematic
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   133
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   134
    def has_problem(self, eschema, edges):
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   135
        """Return `True` if the given schema is considered problematic,
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   136
        considering base propagation rules.
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   137
        """
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   138
        root = self.is_root(eschema)
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   139
        has_prop_rel = self.prop_rel in eschema.subjrels
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   140
        # root but no propagation relation
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   141
        if root and not has_prop_rel:
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   142
            warn('%s is root but miss %s', eschema, self.prop_rel)
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   143
            return True
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   144
        # propagated but without propagation relation / not propagated but
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   145
        # with propagation relation
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   146
        if not has_prop_rel and \
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   147
                any(edge for edge in edges if edge[1] == eschema):
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   148
            warn("%s miss %s but is reached by propagation",
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   149
                 eschema, self.prop_rel)
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   150
            return True
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   151
        elif has_prop_rel and not root:
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   152
            rdef = eschema.rdef(self.prop_rel, takefirst=True)
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   153
            edges = [edge for edge in edges if edge[1] == eschema]
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   154
            if not edges:
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   155
                warn("%s has %s but isn't reached by "
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   156
                     "propagation", eschema, self.prop_rel)
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   157
                return True
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   158
            # require_permission relation / propagation rule not added by
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   159
            # the same cube
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   160
            elif not any(edge for edge in edges if edge[-1] == rdef.package):
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   161
                warn('%s has %s relation / propagation rule'
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   162
                     ' not added by the same cube (%s / %s)', eschema,
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   163
                     self.prop_rel, rdef.package, edges[0][-1])
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   164
                return True
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   165
        return False
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   166
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   167
    def init_graph(self, eschemas, edges, problematic):
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   168
        """Initialize and return graph, adding given nodes (entity schemas) and
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   169
        edges between them.
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   170
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   171
        Require pygraphviz installed.
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   172
        """
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   173
        if pygraphviz is None:
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   174
            raise RuntimeError('pygraphviz is not installed')
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   175
        graph = pygraphviz.AGraph(strict=False, directed=True)
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   176
        for eschema in eschemas:
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   177
            if eschema in problematic:
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   178
                params = {'color': '#ff0000', 'fontcolor': '#ff0000'}
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   179
            else:
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   180
                params = {}#'color': get_color(eschema.package)}
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   181
            graph.add_node(eschema.type, **params)
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   182
        for subj, obj, rtype, package in edges:
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   183
            graph.add_edge(str(subj), str(obj), label=rtype,
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   184
                           color=get_color(package))
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   185
        return graph
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   186
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   187
    def add_colors_legend(self, graph):
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   188
        """Add a legend of used colors to the graph."""
10662
10942ed172de [py3k] dict.iteritems → dict.items
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10589
diff changeset
   189
        for package, color in sorted(_COLORS.items()):
9368
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   190
            graph.add_node(package, color=color, fontcolor=color, shape='record')
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   191
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   192
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   193
class CubeTracerSet(object):
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   194
    """Dumb set implementation whose purpose is to keep track of which cube is
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   195
    being loaded when something is added to the set.
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   196
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   197
    Results will be found in the `value_cube` attribute dictionary.
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   198
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   199
    See `localperms` or `nosylist` cubes for example usage (`hooks` module).
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   200
    """
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   201
    def __init__(self, vreg, wrapped):
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   202
        self.vreg = vreg
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   203
        self.wrapped = wrapped
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   204
        self.value_cube = {}
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   205
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   206
    def add(self, value):
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   207
        self.wrapped.add(value)
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   208
        cube = self.vreg.currently_loading_cube
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   209
        if value in self.value_cube:
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   210
            warn('%s is propagated by cube %s and cube %s',
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   211
                 value, self.value_cube[value], cube)
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   212
        else:
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   213
            self.value_cube[value] = cube
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   214
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   215
    def __iter__(self):
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   216
        return iter(self.wrapped)
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   217
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   218
    def __ior__(self, other):
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   219
        for value in other:
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   220
            self.add(value)
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   221
        return self
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   222
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   223
    def __ror__(self, other):
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   224
        other |= self.wrapped
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   225
        return other