#11749: Remove unneeded imports
---------------------------+------------------------------------------------
Reporter: robertwb | Owner: tbd
Type: enhancement | Status: needs_review
Priority: major | Milestone: sage-4.7.2
Component: performance | Keywords:
Work_issues: | Upstream: N/A
Reviewer: Keshav Kini | Author: Robert Bradshaw
Merged: | Dependencies:
---------------------------+------------------------------------------------
Comment(by robertwb):
I generated the patch with this code, plus a handful (less than a dozen)
manual touch-ups where, e.g., symbols were used in eval() strings but not
directly.
{{{
import symtable
import ast
import re
class GlobalImports(ast.NodeVisitor):
func_depth = 0
def __init__(self):
self.modules = {}
self.names = {}
self.used = {}
def visit_FunctionDef(self, node):
self.func_depth += 1
self.generic_visit(node)
self.func_depth -= 1
def visit_Import(self, node):
if self.func_depth == 0:
for alias in node.names:
self.modules[alias.asname or alias.name] = alias.name
def visit_ImportFrom(self, node):
if self.func_depth == 0:
for alias in node.names:
if alias.name != '*':
self.names[alias.asname or alias.name] = (node.module,
alias.name)
def visit_Name(self, node):
self.used[node.id] = True
def list_unused(file, source=None):
source = source or open(file).read()
tree = ast.parse(source)
visitor = GlobalImports()
visitor.visit(tree)
# print visitor.modules
# print visitor.names
# print visitor.used
all = dict(visitor.modules)
all.update(visitor.names)
for name in all:
if name not in visitor.used:
if '.' in name:
if source.count(name) == 1:
print "Unused", name
else:
print "Unused", name
# symtab = symtable. symtable(source, file, 'exec')
# return symtab
def extract_used(source):
visitor = GlobalImports()
tree = ast.parse(source)
visitor.visit(tree)
return visitor.used
def prune_unused_one(file, source=None):
if source is None:
source = open(file).read()
used = extract_used(source)
import_matcher = re.compile(r'(from (\S+) import (.*))|(import
(.*))').match
bad_name = re.compile('[()#]').search
lines = source.split('\n')
for lineno, line in enumerate(lines):
m = import_matcher(line)
if m:
g = m.groups()
if g[0]:
if g[1] == '__future__':
continue
names = g[2].split(',')
else:
names = g[4].split(',')
#print names
for ix, name in enumerate(names):
name = name.strip()
if bad_name(name) or name in ('', '*', '\\'):
continue
if ' as ' in name:
name, alias = name.split(" as ")
name = name.strip()
alias = alias.strip()
else:
alias = name
if alias not in used:
if "." in alias:
unused = source.count(alias) == 1
else:
unused = True
if unused:
print "Unused %s%s" % (g[1] + "." if g[1] else "",
name)
names[ix] = None
if None in names:
new_names = ", ".join(name.strip() for name in names if
name is not None)
#print names, "->", new_names
if new_names:
if g[0]:
lines[lineno] = "from %s import %s" % (g[1],
new_names)
else:
lines[lineno] = "import %s" % new_names
else:
lines[lineno] = None
return "\n".join(line for line in lines if line is not None)
def prune_unused_all(sage_root):
for root, dirs, files in os.walk('%s/devel/sage/sage/' % sage_root):
for file in files:
file = os.path.join(root, file)
if file.endswith('.py'):
if os.path.basename(file) in ('__init__.py', 'all.py',
'interpreter.py'):
continue
source = open(file).read()
try:
new_source = prune_unused_one(file, source)
if new_source != source:
ast.parse(new_source)
print file
open(file, 'w').write(new_source)
r = os.system("%s/sage -b > /dev/null 2>
/dev/null" % sage_root)
if r == 0:
r = os.system("%s/sage -python -c 'import
sage.all'" % sage_root)
if r != 0:
print "Failed!"
open(file, 'w').write(source)
else:
print "Good!"
except Exception, exn:
print file, exn
}}}
Then
{{{
prune_unused_all('/Users/robertwb/sage/sage-4.7.1')
}}}
--
Ticket URL: <http://trac.sagemath.org/sage_trac/ticket/11749#comment:7>
Sage <http://www.sagemath.org>
Sage: Creating a Viable Open Source Alternative to Magma, Maple, Mathematica,
and MATLAB
--
You received this message because you are subscribed to the Google Groups
"sage-trac" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/sage-trac?hl=en.