source: trunk/misc/python3/tahoe-depgraph.py

Last change on this file was 28f219ad, checked in by Itamar Turner-Trauring <itamar@…>, at 2020-07-08T20:46:54Z

Update to version that supports _python3.py variant of port list.

  • Property mode set to 100644
File size: 4.5 KB
Line 
1# Copyright 2004, 2009 Toby Dickenson
2# Copyright 2014-2015 Aaron Gallagher
3#
4# Permission is hereby granted, free of charge, to any person obtaining
5# a copy of this software and associated documentation files (the
6# "Software"), to deal in the Software without restriction, including
7# without limitation the rights to use, copy, modify, merge, publish,
8# distribute, sublicense, and/or sell copies of the Software, and to
9# permit persons to whom the Software is furnished to do so, subject
10# to the following conditions:
11#
12# The above copyright notice and this permission notice shall be included
13# in all copies or substantial portions of the Software.
14#
15# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
23import collections
24import functools
25import json
26import os
27import modulefinder
28import sys
29import tempfile
30
31from twisted.python import reflect
32
33
34class mymf(modulefinder.ModuleFinder):
35    def __init__(self, *args, **kwargs):
36        self._depgraph = collections.defaultdict(set)
37        self._types = {}
38        self._last_caller = None
39        modulefinder.ModuleFinder.__init__(self, *args, **kwargs)
40
41    def import_hook(self, name, caller=None, fromlist=None, level=None):
42        old_last_caller = self._last_caller
43        try:
44            self._last_caller = caller
45            return modulefinder.ModuleFinder.import_hook(
46                self, name, caller, fromlist)
47        finally:
48            self._last_caller = old_last_caller
49
50    def import_module(self, partnam, fqname, parent):
51        if partnam.endswith('_py3'):
52            return None
53        r = modulefinder.ModuleFinder.import_module(
54            self, partnam, fqname, parent)
55        last_caller = self._last_caller
56        if r is not None and 'allmydata' in r.__name__:
57            if last_caller is None or last_caller.__name__ == '__main__':
58                self._depgraph[fqname]
59            else:
60                self._depgraph[last_caller.__name__].add(fqname)
61        return r
62
63    def load_module(self, fqname, fp, pathname, additional_info):
64        (suffix, mode, type) = additional_info
65        r = modulefinder.ModuleFinder.load_module(
66            self, fqname, fp, pathname, (suffix, mode, type))
67        if r is not None:
68            self._types[r.__name__] = type
69        return r
70
71    def as_json(self):
72        return {
73            'depgraph': {
74                name: dict.fromkeys(deps, 1)
75                for name, deps in self._depgraph.items()},
76            'types': self._types,
77        }
78
79
80json_dump = functools.partial(
81    json.dump, indent=4, separators=(',', ': '), sort_keys=True)
82
83
84def main(target):
85    mf = mymf(sys.path[:], 0, [])
86
87    moduleNames = []
88    for path, dirnames, filenames in os.walk(os.path.join(target, 'src', 'allmydata')):
89        if 'test' in dirnames:
90            dirnames.remove('test')
91        for filename in filenames:
92            if not filename.endswith('.py'):
93                continue
94            if filename in ('setup.py',):
95                continue
96            if '-' in filename:
97                # a script like update-documentation.py
98                continue
99            if filename != '__init__.py':
100                filepath = os.path.join(path, filename)
101            else:
102                filepath = path
103            moduleNames.append(reflect.filenameToModuleName(filepath))
104
105    with tempfile.NamedTemporaryFile("w") as tmpfile:
106        for moduleName in moduleNames:
107            tmpfile.write('import %s\n' % moduleName)
108        tmpfile.flush()
109        mf.run_script(tmpfile.name)
110
111    with open('tahoe-deps.json', 'w') as outfile:
112        json_dump(mf.as_json(), outfile)
113        outfile.write('\n')
114
115    ported_modules_path = os.path.join(target, "src", "allmydata", "util", "_python3.py")
116    with open(ported_modules_path) as f:
117        ported_modules = {}
118        exec(f.read(), ported_modules, ported_modules)
119        port_status = dict.fromkeys(
120            ported_modules["PORTED_MODULES"] + ported_modules["PORTED_TEST_MODULES"],
121            "ported"
122        )
123    with open('tahoe-ported.json', 'w') as outfile:
124        json_dump(port_status, outfile)
125        outfile.write('\n')
126
127
128if __name__ == '__main__':
129    main(*sys.argv[1:])
Note: See TracBrowser for help on using the repository browser.