+++ /dev/null
-"""Fix changes imports of urllib which are now incompatible.\r
- This is rather similar to fix_imports, but because of the more\r
- complex nature of the fixing for urllib, it has its own fixer.\r
-"""\r
-# Author: Nick Edds\r
-\r
-# Local imports\r
-from lib2to3.fixes.fix_imports import alternates, FixImports\r
-from lib2to3 import fixer_base\r
-from lib2to3.fixer_util import (Name, Comma, FromImport, Newline,\r
- find_indentation, Node, syms)\r
-\r
-MAPPING = {"urllib": [\r
- ("urllib.request",\r
- ["URLopener", "FancyURLopener", "urlretrieve",\r
- "_urlopener", "urlopen", "urlcleanup",\r
- "pathname2url", "url2pathname"]),\r
- ("urllib.parse",\r
- ["quote", "quote_plus", "unquote", "unquote_plus",\r
- "urlencode", "splitattr", "splithost", "splitnport",\r
- "splitpasswd", "splitport", "splitquery", "splittag",\r
- "splittype", "splituser", "splitvalue", ]),\r
- ("urllib.error",\r
- ["ContentTooShortError"])],\r
- "urllib2" : [\r
- ("urllib.request",\r
- ["urlopen", "install_opener", "build_opener",\r
- "Request", "OpenerDirector", "BaseHandler",\r
- "HTTPDefaultErrorHandler", "HTTPRedirectHandler",\r
- "HTTPCookieProcessor", "ProxyHandler",\r
- "HTTPPasswordMgr",\r
- "HTTPPasswordMgrWithDefaultRealm",\r
- "AbstractBasicAuthHandler",\r
- "HTTPBasicAuthHandler", "ProxyBasicAuthHandler",\r
- "AbstractDigestAuthHandler",\r
- "HTTPDigestAuthHandler", "ProxyDigestAuthHandler",\r
- "HTTPHandler", "HTTPSHandler", "FileHandler",\r
- "FTPHandler", "CacheFTPHandler",\r
- "UnknownHandler"]),\r
- ("urllib.error",\r
- ["URLError", "HTTPError"]),\r
- ]\r
-}\r
-\r
-# Duplicate the url parsing functions for urllib2.\r
-MAPPING["urllib2"].append(MAPPING["urllib"][1])\r
-\r
-\r
-def build_pattern():\r
- bare = set()\r
- for old_module, changes in MAPPING.items():\r
- for change in changes:\r
- new_module, members = change\r
- members = alternates(members)\r
- yield """import_name< 'import' (module=%r\r
- | dotted_as_names< any* module=%r any* >) >\r
- """ % (old_module, old_module)\r
- yield """import_from< 'from' mod_member=%r 'import'\r
- ( member=%s | import_as_name< member=%s 'as' any > |\r
- import_as_names< members=any* >) >\r
- """ % (old_module, members, members)\r
- yield """import_from< 'from' module_star=%r 'import' star='*' >\r
- """ % old_module\r
- yield """import_name< 'import'\r
- dotted_as_name< module_as=%r 'as' any > >\r
- """ % old_module\r
- # bare_with_attr has a special significance for FixImports.match().\r
- yield """power< bare_with_attr=%r trailer< '.' member=%s > any* >\r
- """ % (old_module, members)\r
-\r
-\r
-class FixUrllib(FixImports):\r
-\r
- def build_pattern(self):\r
- return "|".join(build_pattern())\r
-\r
- def transform_import(self, node, results):\r
- """Transform for the basic import case. Replaces the old\r
- import name with a comma separated list of its\r
- replacements.\r
- """\r
- import_mod = results.get("module")\r
- pref = import_mod.prefix\r
-\r
- names = []\r
-\r
- # create a Node list of the replacement modules\r
- for name in MAPPING[import_mod.value][:-1]:\r
- names.extend([Name(name[0], prefix=pref), Comma()])\r
- names.append(Name(MAPPING[import_mod.value][-1][0], prefix=pref))\r
- import_mod.replace(names)\r
-\r
- def transform_member(self, node, results):\r
- """Transform for imports of specific module elements. Replaces\r
- the module to be imported from with the appropriate new\r
- module.\r
- """\r
- mod_member = results.get("mod_member")\r
- pref = mod_member.prefix\r
- member = results.get("member")\r
-\r
- # Simple case with only a single member being imported\r
- if member:\r
- # this may be a list of length one, or just a node\r
- if isinstance(member, list):\r
- member = member[0]\r
- new_name = None\r
- for change in MAPPING[mod_member.value]:\r
- if member.value in change[1]:\r
- new_name = change[0]\r
- break\r
- if new_name:\r
- mod_member.replace(Name(new_name, prefix=pref))\r
- else:\r
- self.cannot_convert(node, "This is an invalid module element")\r
-\r
- # Multiple members being imported\r
- else:\r
- # a dictionary for replacements, order matters\r
- modules = []\r
- mod_dict = {}\r
- members = results["members"]\r
- for member in members:\r
- # we only care about the actual members\r
- if member.type == syms.import_as_name:\r
- as_name = member.children[2].value\r
- member_name = member.children[0].value\r
- else:\r
- member_name = member.value\r
- as_name = None\r
- if member_name != u",":\r
- for change in MAPPING[mod_member.value]:\r
- if member_name in change[1]:\r
- if change[0] not in mod_dict:\r
- modules.append(change[0])\r
- mod_dict.setdefault(change[0], []).append(member)\r
-\r
- new_nodes = []\r
- indentation = find_indentation(node)\r
- first = True\r
- def handle_name(name, prefix):\r
- if name.type == syms.import_as_name:\r
- kids = [Name(name.children[0].value, prefix=prefix),\r
- name.children[1].clone(),\r
- name.children[2].clone()]\r
- return [Node(syms.import_as_name, kids)]\r
- return [Name(name.value, prefix=prefix)]\r
- for module in modules:\r
- elts = mod_dict[module]\r
- names = []\r
- for elt in elts[:-1]:\r
- names.extend(handle_name(elt, pref))\r
- names.append(Comma())\r
- names.extend(handle_name(elts[-1], pref))\r
- new = FromImport(module, names)\r
- if not first or node.parent.prefix.endswith(indentation):\r
- new.prefix = indentation\r
- new_nodes.append(new)\r
- first = False\r
- if new_nodes:\r
- nodes = []\r
- for new_node in new_nodes[:-1]:\r
- nodes.extend([new_node, Newline()])\r
- nodes.append(new_nodes[-1])\r
- node.replace(nodes)\r
- else:\r
- self.cannot_convert(node, "All module elements are invalid")\r
-\r
- def transform_dot(self, node, results):\r
- """Transform for calls to module members in code."""\r
- module_dot = results.get("bare_with_attr")\r
- member = results.get("member")\r
- new_name = None\r
- if isinstance(member, list):\r
- member = member[0]\r
- for change in MAPPING[module_dot.value]:\r
- if member.value in change[1]:\r
- new_name = change[0]\r
- break\r
- if new_name:\r
- module_dot.replace(Name(new_name,\r
- prefix=module_dot.prefix))\r
- else:\r
- self.cannot_convert(node, "This is an invalid module element")\r
-\r
- def transform(self, node, results):\r
- if results.get("module"):\r
- self.transform_import(node, results)\r
- elif results.get("mod_member"):\r
- self.transform_member(node, results)\r
- elif results.get("bare_with_attr"):\r
- self.transform_dot(node, results)\r
- # Renaming and star imports are not supported for these modules.\r
- elif results.get("module_star"):\r
- self.cannot_convert(node, "Cannot handle star imports.")\r
- elif results.get("module_as"):\r
- self.cannot_convert(node, "This module is now multiple modules")\r