source: orange/orange/fixes/fix_changed_names_aggressive.py @ 8042:ffcb93bc9028

Revision 8042:ffcb93bc9028, 3.1 KB checked in by markotoplak, 3 years ago (diff)

Hierarchical clustering: also catch RuntimeError when importing matplotlib (or the documentation could not be built on server).

Line 
1from lib2to3 import pytree
2from lib2to3.fixer_util import Name, Dot, Node, attr_chain, touch_import, find_root
3from lib2to3 import fixer_base
4from lib2to3 import patcomp
5from collections import defaultdict
6
7from .fix_changed_names import FixChangedNames, MAPPING
8
9def find_matches(pattern, tree):
10    for node in tree.pre_order():
11        res = {}
12        match = pattern.match(node, res)
13        if match:
14            yield res
15   
16def build_pattern(mapping=MAPPING):
17    PATTERN = """
18    power< local=(%s)
19         tail=any*
20    >
21    """ 
22    return PATTERN % "|".join("'%s'" % key.split(".")[-1] for key in mapping.keys())
23
24
25## Pattern for finding from module import *
26from_import_pattern = """import_from<'from' module=(%s) 'import' star='*'>"""
27module_names = set(["'%s'" % key.split(".", 1)[0] for key in MAPPING.keys()])
28from_import_pattern = from_import_pattern % "|".join(module_names)
29
30from_import_expr = patcomp.compile_pattern(from_import_pattern)
31 
32class FixChangedNamesAggressive(FixChangedNames):
33    mapping = MAPPING
34    run_order = 2
35   
36    def compile_pattern(self):
37        # We override this, so MAPPING can be pragmatically altered and the
38        # changes will be reflected in PATTERN.
39        self.PATTERN = build_pattern(self.mapping)
40        name2mod = defaultdict(set)
41        for key in self.mapping.keys():
42            mod, name = key.split(".", 1)
43            name2mod[name].add(mod)
44        self._names_to_modules = name2mod
45       
46        fixer_base.BaseFix.compile_pattern(self)
47       
48    def start_tree(self, tree, filename):
49        super(FixChangedNamesAggressive, self).start_tree(tree, filename)
50        ## Find unqualified imports
51        self._import_matches = list(find_matches(from_import_expr, tree))
52       
53    def finish_tree(self, tree, filename):
54        del self._import_matches
55               
56    def transform(self, node, results):
57        local = results.get("local")
58        tail = results.get("tail")
59        if local:
60            local = local[0]
61            local_name = local.value
62            modules = self._names_to_modules[local_name]
63            if len(modules) > 1:
64                self.warnings(node, "Conflicting name '%s' is present in %s! Ignoring transformation!" % local_name, modules)
65                return
66           
67            module = list(modules)[0]
68           
69            if all("module" not in res for res in self._import_matches): 
70                self.warning(node, "Aggressive name matched '%s' but no corresponding import! Fix manually." % local_name)
71                return
72               
73            new_name = unicode(self.mapping[module + "." + local_name])
74           
75            syms = self.syms
76           
77            if tail:
78                tail = [t.clone() for t in tail]
79#            tail = tail.clone()
80            new = self.package_tree(new_name)
81            new = pytree.Node(syms.power, new + tail, prefix=local.prefix)
82           
83            # Make sure the proper package is imported
84            package = new_name.rsplit(".", 1)[0]
85            touch_import(None, package, node)
86            return new
87       
Note: See TracBrowser for help on using the repository browser.