cubicweb/devtools/instrument.py
author Denis Laxalde <denis.laxalde@logilab.fr>
Fri, 05 Apr 2019 17:58:19 +0200
changeset 12567 26744ad37953
parent 11057 0b59724cb3f2
permissions -rw-r--r--
Drop python2 support This mostly consists in removing the dependency on "six" and updating the code to use only Python3 idioms. Notice that we previously used TemporaryDirectory from cubicweb.devtools.testlib for compatibility with Python2. We now directly import it from tempfile.
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