cubicweb/devtools/instrument.py
author Philippe Pepiot <ph@itsalwaysdns.eu>
Mon, 30 Mar 2020 15:19:23 +0200
changeset 12959 39ee325e6758
parent 12567 26744ad37953
permissions -rw-r--r--
[server] avoid a possible race condition on _CnxSetPool.close() The pool could become empty between time to check and time to use.
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"""
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    17
import os
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
try:
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    20
    import pygraphviz
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    21
except ImportError:
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    22
    pygraphviz = None
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    23
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    24
from cubicweb.cwvreg import CWRegistryStore
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    25
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
    26
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    27
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    28
ALL_COLORS = [
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    29
    "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
    30
    "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
    31
    "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
    32
    "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
    33
    "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
    34
    "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
    35
    "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
    36
    "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
    37
    ]
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    38
_COLORS = {}
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    39
def get_color(key):
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    40
    try:
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    41
        return _COLORS[key]
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    42
    except KeyError:
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    43
        _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
    44
        return _COLORS[key]
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    45
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    46
def warn(msg, *args):
10589
7c23b7de2b8d [py3k] print function
Samuel Trégouët <samuel.tregouet@logilab.fr>
parents: 9368
diff changeset
    47
    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
    48
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    49
def info(msg):
10589
7c23b7de2b8d [py3k] print function
Samuel Trégouët <samuel.tregouet@logilab.fr>
parents: 9368
diff changeset
    50
    print('INFO: ' + msg)
9368
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    51
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    52
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    53
class PropagationAnalyzer(object):
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    54
    """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
    55
    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
    56
    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
    57
    :class:`CubeTracerSet`).
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    58
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    59
    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
    60
    implements the `is_root` method.
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    61
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    62
    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
    63
    """
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    64
    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
    65
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    66
    def init(self, cube):
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    67
        """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
    68
        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
    69
        """
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    70
        config = DevConfiguration(cube)
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    71
        schema = config.load_schema()
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    72
        vreg = CWRegistryStore(config)
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    73
        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
    74
        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
    75
                       if self.should_include(eschema))
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    76
        return vreg, eschemas
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    77
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    78
    def is_root(self, eschema):
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    79
        """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
    80
        raise NotImplementedError()
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    81
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    82
    def should_include(self, eschema):
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    83
        """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
    84
        """
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    85
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    86
        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
    87
            return True
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    88
        return False
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    89
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    90
    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
    91
        """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
    92
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    93
        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
    94
        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
    95
        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
    96
        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
    97
        """
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    98
        schema = iter(eschemas).next().schema
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    99
        prop_edges = set()
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   100
        for rtype in s_rels:
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   101
            found = False
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   102
            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
   103
                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
   104
                    found = True
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   105
                    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
   106
            if not found:
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   107
                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
   108
        for rtype in o_rels:
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   109
            found = False
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   110
            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
   111
                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
   112
                    found = True
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   113
                    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
   114
            if not found:
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   115
                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
   116
        return prop_edges
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   117
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   118
    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
   119
        """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
   120
        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
   121
        """
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   122
        problematic = set()
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   123
        for eschema in eschemas:
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   124
            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
   125
                problematic.add(eschema)
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   126
        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
   127
        if not_problematic:
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   128
            info('nothing problematic in: %s' %
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   129
                 ', '.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
   130
        return problematic
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   131
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   132
    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
   133
        """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
   134
        considering base propagation rules.
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   135
        """
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   136
        root = self.is_root(eschema)
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   137
        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
   138
        # root but no propagation relation
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   139
        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
   140
            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
   141
            return True
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   142
        # 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
   143
        # with propagation relation
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   144
        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
   145
                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
   146
            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
   147
                 eschema, self.prop_rel)
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   148
            return True
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   149
        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
   150
            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
   151
            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
   152
            if not edges:
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   153
                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
   154
                     "propagation", eschema, self.prop_rel)
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   155
                return True
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   156
            # 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
   157
            # the same cube
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   158
            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
   159
                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
   160
                     ' 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
   161
                     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
   162
                return True
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   163
        return False
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   164
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   165
    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
   166
        """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
   167
        edges between them.
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   168
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   169
        Require pygraphviz installed.
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
        if pygraphviz is None:
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   172
            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
   173
        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
   174
        for eschema in eschemas:
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   175
            if eschema in problematic:
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   176
                params = {'color': '#ff0000', 'fontcolor': '#ff0000'}
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   177
            else:
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   178
                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
   179
            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
   180
        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
   181
            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
   182
                           color=get_color(package))
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   183
        return graph
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   184
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   185
    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
   186
        """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
   187
        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
   188
            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
   189
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   190
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   191
class CubeTracerSet(object):
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   192
    """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
   193
    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
   194
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   195
    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
   196
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   197
    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
   198
    """
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   199
    def __init__(self, vreg, wrapped):
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   200
        self.vreg = vreg
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   201
        self.wrapped = wrapped
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   202
        self.value_cube = {}
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   203
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   204
    def add(self, value):
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   205
        self.wrapped.add(value)
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   206
        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
   207
        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
   208
            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
   209
                 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
   210
        else:
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   211
            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
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   213
    def __iter__(self):
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   214
        return iter(self.wrapped)
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   215
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   216
    def __ior__(self, other):
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   217
        for value in other:
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   218
            self.add(value)
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   219
        return self
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   220
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   221
    def __ror__(self, other):
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   222
        other |= self.wrapped
10694dd136f3 [devtools] bases for instrumenting / debugging standard propagation hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   223
        return other