1
"""Fix changes imports of urllib which are now incompatible.
2
This is rather similar to fix_imports, but because of the more
3
complex nature of the fixing for urllib, it has its own fixer.
8
from .fix_imports import alternates, FixImports
9
from .. import fixer_base
10
from ..fixer_util import Name, Comma, FromImport, Newline, attr_chain
12
MAPPING = {'urllib': [
14
['URLOpener', 'FancyURLOpener', 'urlretrieve',
15
'_urlopener', 'urlcleanup']),
17
['quote', 'quote_plus', 'unquote', 'unquote_plus',
18
'urlencode', 'pahtname2url', 'url2pathname']),
20
['ContentTooShortError'])],
23
['urlopen', 'install_opener', 'build_opener',
24
'Request', 'OpenerDirector', 'BaseHandler',
25
'HTTPDefaultErrorHandler', 'HTTPRedirectHandler',
26
'HTTPCookieProcessor', 'ProxyHandler',
28
'HTTPPasswordMgrWithDefaultRealm',
29
'AbstractBasicAuthHandler',
30
'HTTPBasicAuthHandler', 'ProxyBasicAuthHandler',
31
'AbstractDigestAuthHandler',
32
'HTTPDigestAuthHander', 'ProxyDigestAuthHandler',
33
'HTTPHandler', 'HTTPSHandler', 'FileHandler',
34
'FTPHandler', 'CacheFTPHandler',
37
['URLError', 'HTTPError'])],
41
# def alternates(members):
42
# return "(" + "|".join(map(repr, members)) + ")"
47
for old_module, changes in MAPPING.items():
48
for change in changes:
49
new_module, members = change
50
members = alternates(members)
51
yield """import_name< 'import' (module=%r
52
| dotted_as_names< any* module=%r any* >) >
53
""" % (old_module, old_module)
54
yield """import_from< 'from' mod_member=%r 'import'
55
( member=%s | import_as_name< member=%s 'as' any > |
56
import_as_names< members=any* >) >
57
""" % (old_module, members, members)
58
yield """import_from< 'from' module_star=%r 'import' star='*' >
60
yield """import_name< 'import'
61
dotted_as_name< module_as=%r 'as' any > >
63
yield """power< module_dot=%r trailer< '.' member=%s > any* >
64
""" % (old_module, members)
67
class FixUrllib(FixImports):
69
def build_pattern(self):
70
return "|".join(build_pattern())
72
def transform_import(self, node, results):
73
"""Transform for the basic import case. Replaces the old
74
import name with a comma separated list of its
77
import_mod = results.get('module')
78
pref = import_mod.get_prefix()
82
# create a Node list of the replacement modules
83
for name in MAPPING[import_mod.value][:-1]:
84
names.extend([Name(name[0], prefix=pref), Comma()])
85
names.append(Name(MAPPING[import_mod.value][-1][0], prefix=pref))
86
import_mod.replace(names)
88
def transform_member(self, node, results):
89
"""Transform for imports of specific module elements. Replaces
90
the module to be imported from with the appropriate new
93
mod_member = results.get('mod_member')
94
pref = mod_member.get_prefix()
95
member = results.get('member')
97
# Simple case with only a single member being imported
99
# this may be a list of length one, or just a node
100
if isinstance(member, list):
103
for change in MAPPING[mod_member.value]:
104
if member.value in change[1]:
108
mod_member.replace(Name(new_name, prefix=pref))
110
self.cannot_convert(node,
111
'This is an invalid module element')
113
# Multiple members being imported
115
# a dictionary for replacements, order matters
118
members = results.get('members')
119
for member in members:
120
member = member.value
121
# we only care about the actual members
123
for change in MAPPING[mod_member.value]:
124
if member in change[1]:
125
if change[0] in mod_dict:
126
mod_dict[change[0]].append(member)
128
mod_dict[change[0]] = [member]
129
modules.append(change[0])
132
for module in modules:
133
elts = mod_dict[module]
135
for elt in elts[:-1]:
136
names.extend([Name(elt, prefix=pref), Comma()])
137
names.append(Name(elts[-1], prefix=pref))
138
new_nodes.append(FromImport(module, names))
141
for new_node in new_nodes[:-1]:
142
nodes.extend([new_node, Newline()])
143
nodes.append(new_nodes[-1])
146
self.cannot_convert(node, 'All module elements are invalid')
148
def transform_dot(self, node, results):
149
"""Transform for calls to module members in code."""
150
module_dot = results.get('module_dot')
151
member = results.get('member')
152
# this may be a list of length one, or just a node
153
if isinstance(member, list):
156
for change in MAPPING[module_dot.value]:
157
if member.value in change[1]:
161
module_dot.replace(Name(new_name,
162
prefix=module_dot.get_prefix()))
164
self.cannot_convert(node, 'This is an invalid module element')
166
def transform(self, node, results):
167
if results.get('module'):
168
self.transform_import(node, results)
169
elif results.get('mod_member'):
170
self.transform_member(node, results)
171
elif results.get('module_dot'):
172
self.transform_dot(node, results)
173
# Renaming and star imports are not supported for these modules.
174
elif results.get('module_star'):
175
self.cannot_convert(node, 'Cannot handle star imports.')
176
elif results.get('module_as'):
177
self.cannot_convert(node, 'This module is now multiple modules')