Mercurial > hg
annotate contrib/hgfixes/fix_leftover_imports.py @ 21895:5809d62e7106
context: extend efficient manifest filtering to when all paths are files
On a repository with over 250,000 files and 700,000 commits, this improves
cases like
hg status --rev <rev> -- <file> # rev is not .
from 2.1 seconds to 1.4 seconds.
There is further scope for improvement here: for a single file or a small set
of files, it is probably more efficient to use filelog linkrevs when possible.
However there will always be cases where that will fail (multiple commits
pointing to the same file revision, removed files...), so this is independently
useful.
author | Siddharth Agarwal <sid0@fb.com> |
---|---|
date | Wed, 16 Jul 2014 14:53:03 -0700 |
parents | 9de689d20230 |
children |
rev | line source |
---|---|
11949
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
1 "Fixer that translates some APIs ignored by the default 2to3 fixers." |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
2 |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
3 # FIXME: This fixer has some ugly hacks. Its main design is based on that of |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
4 # fix_imports, from lib2to3. Unfortunately, the fix_imports framework only |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
5 # changes module names "without dots", meaning it won't work for some changes |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
6 # in the email module/package. Thus this fixer was born. I believe that with a |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
7 # bit more thinking, a more generic fixer can be implemented, but I'll leave |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
8 # that as future work. |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
9 |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
10 from lib2to3.fixer_util import Name |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
11 from lib2to3.fixes import fix_imports |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
12 |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
13 # This maps the old names to the new names. Note that a drawback of the current |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
14 # design is that the dictionary keys MUST have EXACTLY one dot (.) in them, |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
15 # otherwise things will break. (If you don't need a module hierarchy, you're |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
16 # better of just inherit from fix_imports and overriding the MAPPING dict.) |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
17 |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
18 MAPPING = {'email.Utils': 'email.utils', |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
19 'email.Errors': 'email.errors', |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
20 'email.Header': 'email.header', |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
21 'email.Parser': 'email.parser', |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
22 'email.Encoders': 'email.encoders', |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
23 'email.MIMEText': 'email.mime.text', |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
24 'email.MIMEBase': 'email.mime.base', |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
25 'email.Generator': 'email.generator', |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
26 'email.MIMEMultipart': 'email.mime.multipart', |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
27 } |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
28 |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
29 def alternates(members): |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
30 return "(" + "|".join(map(repr, members)) + ")" |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
31 |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
32 def build_pattern(mapping=MAPPING): |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
33 packages = {} |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
34 for key in mapping: |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
35 # What we are doing here is the following: with dotted names, we'll |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
36 # have something like package_name <trailer '.' module>. Then, we are |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
37 # making a dictionary to copy this structure. For example, if |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
38 # mapping={'A.B': 'a.b', 'A.C': 'a.c'}, it will generate the dictionary |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
39 # {'A': ['b', 'c']} to, then, generate something like "A <trailer '.' |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
40 # ('b' | 'c')". |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
41 name = key.split('.') |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
42 prefix = name[0] |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
43 if prefix in packages: |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
44 packages[prefix].append(name[1:][0]) |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
45 else: |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
46 packages[prefix] = name[1:] |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
47 |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
48 mod_list = ' | '.join(["'%s' '.' ('%s')" % |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
49 (key, "' | '".join(packages[key])) for key in packages]) |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
50 mod_list = '(' + mod_list + ' )' |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
51 |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
52 yield """name_import=import_name< 'import' module_name=dotted_name< %s > > |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
53 """ % mod_list |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
54 |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
55 yield """name_import=import_name< 'import' |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
56 multiple_imports=dotted_as_names< any* |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
57 module_name=dotted_name< %s > |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
58 any* > |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
59 >""" % mod_list |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
60 |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
61 packs = ' | '.join(["'%s' trailer<'.' ('%s')>" % (key, |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
62 "' | '".join(packages[key])) for key in packages]) |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
63 |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
64 yield "power< package=(%s) trailer<'.' any > any* >" % packs |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
65 |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
66 class FixLeftoverImports(fix_imports.FixImports): |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
67 # We want to run this fixer after fix_import has run (this shouldn't matter |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
68 # for hg, though, as setup3k prefers to run the default fixers first) |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
69 mapping = MAPPING |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
70 |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
71 def build_pattern(self): |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
72 return "|".join(build_pattern(self.mapping)) |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
73 |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
74 def transform(self, node, results): |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
75 # Mostly copied from fix_imports.py |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
76 import_mod = results.get("module_name") |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
77 if import_mod: |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
78 try: |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
79 mod_name = import_mod.value |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
80 except AttributeError: |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
81 # XXX: A hack to remove whitespace prefixes and suffixes |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
82 mod_name = str(import_mod).strip() |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
83 new_name = self.mapping[mod_name] |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
84 import_mod.replace(Name(new_name, prefix=import_mod.prefix)) |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
85 if "name_import" in results: |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
86 # If it's not a "from x import x, y" or "import x as y" import, |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
87 # marked its usage to be replaced. |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
88 self.replace[mod_name] = new_name |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
89 if "multiple_imports" in results: |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
90 # This is a nasty hack to fix multiple imports on a line (e.g., |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
91 # "import StringIO, urlparse"). The problem is that I can't |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
92 # figure out an easy way to make a pattern recognize the keys of |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
93 # MAPPING randomly sprinkled in an import statement. |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
94 results = self.match(node) |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
95 if results: |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
96 self.transform(node, results) |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
97 else: |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
98 # Replace usage of the module. |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
99 # Now this is, mostly, a hack |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
100 bare_name = results["package"][0] |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
101 bare_name_text = ''.join(map(str, results['package'])).strip() |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
102 new_name = self.replace.get(bare_name_text) |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
103 prefix = results['package'][0].prefix |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
104 if new_name: |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
105 bare_name.replace(Name(new_name, prefix=prefix)) |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
106 results["package"][1].replace(Name('')) |
626fe5c99231
hgfixes: added a fixer to convert changes in the email package
Renato Cunha <renatoc@gmail.com>
parents:
diff
changeset
|
107 |