ยปCore Development>Code coverage>Lib/lib2to3/fixes/fix_urllib.py

Python code coverage for Lib/lib2to3/fixes/fix_urllib.py

#countcontent
1n/a"""Fix changes imports of urllib which are now incompatible.
2n/a This is rather similar to fix_imports, but because of the more
3n/a complex nature of the fixing for urllib, it has its own fixer.
4n/a"""
5n/a# Author: Nick Edds
6n/a
7n/a# Local imports
8n/afrom lib2to3.fixes.fix_imports import alternates, FixImports
9n/afrom lib2to3.fixer_util import (Name, Comma, FromImport, Newline,
10n/a find_indentation, Node, syms)
11n/a
12n/aMAPPING = {"urllib": [
13n/a ("urllib.request",
14n/a ["URLopener", "FancyURLopener", "urlretrieve",
15n/a "_urlopener", "urlopen", "urlcleanup",
16n/a "pathname2url", "url2pathname"]),
17n/a ("urllib.parse",
18n/a ["quote", "quote_plus", "unquote", "unquote_plus",
19n/a "urlencode", "splitattr", "splithost", "splitnport",
20n/a "splitpasswd", "splitport", "splitquery", "splittag",
21n/a "splittype", "splituser", "splitvalue", ]),
22n/a ("urllib.error",
23n/a ["ContentTooShortError"])],
24n/a "urllib2" : [
25n/a ("urllib.request",
26n/a ["urlopen", "install_opener", "build_opener",
27n/a "Request", "OpenerDirector", "BaseHandler",
28n/a "HTTPDefaultErrorHandler", "HTTPRedirectHandler",
29n/a "HTTPCookieProcessor", "ProxyHandler",
30n/a "HTTPPasswordMgr",
31n/a "HTTPPasswordMgrWithDefaultRealm",
32n/a "AbstractBasicAuthHandler",
33n/a "HTTPBasicAuthHandler", "ProxyBasicAuthHandler",
34n/a "AbstractDigestAuthHandler",
35n/a "HTTPDigestAuthHandler", "ProxyDigestAuthHandler",
36n/a "HTTPHandler", "HTTPSHandler", "FileHandler",
37n/a "FTPHandler", "CacheFTPHandler",
38n/a "UnknownHandler"]),
39n/a ("urllib.error",
40n/a ["URLError", "HTTPError"]),
41n/a ]
42n/a}
43n/a
44n/a# Duplicate the url parsing functions for urllib2.
45n/aMAPPING["urllib2"].append(MAPPING["urllib"][1])
46n/a
47n/a
48n/adef build_pattern():
49n/a bare = set()
50n/a for old_module, changes in MAPPING.items():
51n/a for change in changes:
52n/a new_module, members = change
53n/a members = alternates(members)
54n/a yield """import_name< 'import' (module=%r
55n/a | dotted_as_names< any* module=%r any* >) >
56n/a """ % (old_module, old_module)
57n/a yield """import_from< 'from' mod_member=%r 'import'
58n/a ( member=%s | import_as_name< member=%s 'as' any > |
59n/a import_as_names< members=any* >) >
60n/a """ % (old_module, members, members)
61n/a yield """import_from< 'from' module_star=%r 'import' star='*' >
62n/a """ % old_module
63n/a yield """import_name< 'import'
64n/a dotted_as_name< module_as=%r 'as' any > >
65n/a """ % old_module
66n/a # bare_with_attr has a special significance for FixImports.match().
67n/a yield """power< bare_with_attr=%r trailer< '.' member=%s > any* >
68n/a """ % (old_module, members)
69n/a
70n/a
71n/aclass FixUrllib(FixImports):
72n/a
73n/a def build_pattern(self):
74n/a return "|".join(build_pattern())
75n/a
76n/a def transform_import(self, node, results):
77n/a """Transform for the basic import case. Replaces the old
78n/a import name with a comma separated list of its
79n/a replacements.
80n/a """
81n/a import_mod = results.get("module")
82n/a pref = import_mod.prefix
83n/a
84n/a names = []
85n/a
86n/a # create a Node list of the replacement modules
87n/a for name in MAPPING[import_mod.value][:-1]:
88n/a names.extend([Name(name[0], prefix=pref), Comma()])
89n/a names.append(Name(MAPPING[import_mod.value][-1][0], prefix=pref))
90n/a import_mod.replace(names)
91n/a
92n/a def transform_member(self, node, results):
93n/a """Transform for imports of specific module elements. Replaces
94n/a the module to be imported from with the appropriate new
95n/a module.
96n/a """
97n/a mod_member = results.get("mod_member")
98n/a pref = mod_member.prefix
99n/a member = results.get("member")
100n/a
101n/a # Simple case with only a single member being imported
102n/a if member:
103n/a # this may be a list of length one, or just a node
104n/a if isinstance(member, list):
105n/a member = member[0]
106n/a new_name = None
107n/a for change in MAPPING[mod_member.value]:
108n/a if member.value in change[1]:
109n/a new_name = change[0]
110n/a break
111n/a if new_name:
112n/a mod_member.replace(Name(new_name, prefix=pref))
113n/a else:
114n/a self.cannot_convert(node, "This is an invalid module element")
115n/a
116n/a # Multiple members being imported
117n/a else:
118n/a # a dictionary for replacements, order matters
119n/a modules = []
120n/a mod_dict = {}
121n/a members = results["members"]
122n/a for member in members:
123n/a # we only care about the actual members
124n/a if member.type == syms.import_as_name:
125n/a as_name = member.children[2].value
126n/a member_name = member.children[0].value
127n/a else:
128n/a member_name = member.value
129n/a as_name = None
130n/a if member_name != ",":
131n/a for change in MAPPING[mod_member.value]:
132n/a if member_name in change[1]:
133n/a if change[0] not in mod_dict:
134n/a modules.append(change[0])
135n/a mod_dict.setdefault(change[0], []).append(member)
136n/a
137n/a new_nodes = []
138n/a indentation = find_indentation(node)
139n/a first = True
140n/a def handle_name(name, prefix):
141n/a if name.type == syms.import_as_name:
142n/a kids = [Name(name.children[0].value, prefix=prefix),
143n/a name.children[1].clone(),
144n/a name.children[2].clone()]
145n/a return [Node(syms.import_as_name, kids)]
146n/a return [Name(name.value, prefix=prefix)]
147n/a for module in modules:
148n/a elts = mod_dict[module]
149n/a names = []
150n/a for elt in elts[:-1]:
151n/a names.extend(handle_name(elt, pref))
152n/a names.append(Comma())
153n/a names.extend(handle_name(elts[-1], pref))
154n/a new = FromImport(module, names)
155n/a if not first or node.parent.prefix.endswith(indentation):
156n/a new.prefix = indentation
157n/a new_nodes.append(new)
158n/a first = False
159n/a if new_nodes:
160n/a nodes = []
161n/a for new_node in new_nodes[:-1]:
162n/a nodes.extend([new_node, Newline()])
163n/a nodes.append(new_nodes[-1])
164n/a node.replace(nodes)
165n/a else:
166n/a self.cannot_convert(node, "All module elements are invalid")
167n/a
168n/a def transform_dot(self, node, results):
169n/a """Transform for calls to module members in code."""
170n/a module_dot = results.get("bare_with_attr")
171n/a member = results.get("member")
172n/a new_name = None
173n/a if isinstance(member, list):
174n/a member = member[0]
175n/a for change in MAPPING[module_dot.value]:
176n/a if member.value in change[1]:
177n/a new_name = change[0]
178n/a break
179n/a if new_name:
180n/a module_dot.replace(Name(new_name,
181n/a prefix=module_dot.prefix))
182n/a else:
183n/a self.cannot_convert(node, "This is an invalid module element")
184n/a
185n/a def transform(self, node, results):
186n/a if results.get("module"):
187n/a self.transform_import(node, results)
188n/a elif results.get("mod_member"):
189n/a self.transform_member(node, results)
190n/a elif results.get("bare_with_attr"):
191n/a self.transform_dot(node, results)
192n/a # Renaming and star imports are not supported for these modules.
193n/a elif results.get("module_star"):
194n/a self.cannot_convert(node, "Cannot handle star imports.")
195n/a elif results.get("module_as"):
196n/a self.cannot_convert(node, "This module is now multiple modules")