summaryrefslogtreecommitdiffstats
path: root/Lib/lib2to3/fixes/fix_urllib.py
diff options
context:
space:
mode:
authorBenjamin Peterson <benjamin@python.org>2008-07-16 17:01:46 (GMT)
committerBenjamin Peterson <benjamin@python.org>2008-07-16 17:01:46 (GMT)
commit699b09010f4158910d855b4d02ae3d25a0c0ef06 (patch)
treeb9f3dbffd2cdfe002f6317a6324ed28a2a041966 /Lib/lib2to3/fixes/fix_urllib.py
parent13e9d582fd55c3f680cbe9d3d4c219722a484d92 (diff)
downloadcpython-699b09010f4158910d855b4d02ae3d25a0c0ef06.zip
cpython-699b09010f4158910d855b4d02ae3d25a0c0ef06.tar.gz
cpython-699b09010f4158910d855b4d02ae3d25a0c0ef06.tar.bz2
Merged revisions 64863,64868,64870,64942,65001-65002,65017-65018 via svnmerge from
svn+ssh://pythondev@svn.python.org/sandbox/trunk/2to3/lib2to3 ........ r64863 | brett.cannon | 2008-07-10 19:42:32 -0500 (Thu, 10 Jul 2008) | 1 line Add urlparse -> urllib.parse to fix_imports. ........ r64868 | brett.cannon | 2008-07-10 20:00:10 -0500 (Thu, 10 Jul 2008) | 1 line Add robotparser -> urllib.robotparser to fix_imports. ........ r64870 | brett.cannon | 2008-07-11 00:56:27 -0500 (Fri, 11 Jul 2008) | 6 lines Fix the fixers for the new dbm package. Had to create a new fixer (fix_imports2) which did fixes in post-order. This because ``import anydbm`` was being translated into ``import dbm`` which was then subsequently changed into ``import dbm.ndbm``; one transform too many. ........ r64942 | collin.winter | 2008-07-13 20:19:05 -0500 (Sun, 13 Jul 2008) | 1 line Add a comment explaining part of fix_imports.py ........ r65001 | brett.cannon | 2008-07-16 00:11:12 -0500 (Wed, 16 Jul 2008) | 2 lines Remove some extraneous whitespace. ........ r65002 | brett.cannon | 2008-07-16 00:12:04 -0500 (Wed, 16 Jul 2008) | 4 lines Implement a fixer for urllib(2). Thanks Nick Edds for the patch. ........ r65017 | benjamin.peterson | 2008-07-16 11:04:19 -0500 (Wed, 16 Jul 2008) | 1 line fix 2to3 in Python 2.6 ........ r65018 | benjamin.peterson | 2008-07-16 11:55:21 -0500 (Wed, 16 Jul 2008) | 1 line normalize whitespace ........
Diffstat (limited to 'Lib/lib2to3/fixes/fix_urllib.py')
-rw-r--r--Lib/lib2to3/fixes/fix_urllib.py175
1 files changed, 175 insertions, 0 deletions
diff --git a/Lib/lib2to3/fixes/fix_urllib.py b/Lib/lib2to3/fixes/fix_urllib.py
new file mode 100644
index 0000000..1255085
--- /dev/null
+++ b/Lib/lib2to3/fixes/fix_urllib.py
@@ -0,0 +1,175 @@
+"""Fix changes imports of urllib which are now incompatible.
+ This is rather similar to fix_imports, but because of the more
+ complex nature of the fixing for urllib, it has its own fixer.
+"""
+# Author: Nick Edds
+
+# Local imports
+from .fix_imports import alternates, FixImports
+from .. import fixer_base
+from ..fixer_util import Name, Comma, FromImport, Newline, attr_chain, any, set
+
+MAPPING = {'urllib': [
+ ('urllib.request',
+ ['URLOpener', 'FancyURLOpener', 'urlretrieve',
+ '_urlopener', 'urlcleanup']),
+ ('urllib.parse',
+ ['quote', 'quote_plus', 'unquote', 'unquote_plus',
+ 'urlencode', 'pahtname2url', 'url2pathname']),
+ ('urllib.error',
+ ['ContentTooShortError'])],
+ 'urllib2' : [
+ ('urllib.request',
+ ['urlopen', 'install_opener', 'build_opener',
+ 'Request', 'OpenerDirector', 'BaseHandler',
+ 'HTTPDefaultErrorHandler', 'HTTPRedirectHandler',
+ 'HTTPCookieProcessor', 'ProxyHandler',
+ 'HTTPPasswordMgr',
+ 'HTTPPasswordMgrWithDefaultRealm',
+ 'AbstractBasicAuthHandler',
+ 'HTTPBasicAuthHandler', 'ProxyBasicAuthHandler',
+ 'AbstractDigestAuthHandler',
+ 'HTTPDigestAuthHander', 'ProxyDigestAuthHandler',
+ 'HTTPHandler', 'HTTPSHandler', 'FileHandler',
+ 'FTPHandler', 'CacheFTPHandler',
+ 'UnknownHandler']),
+ ('urllib.error',
+ ['URLError', 'HTTPError'])],
+}
+
+
+# def alternates(members):
+# return "(" + "|".join(map(repr, members)) + ")"
+
+
+def build_pattern():
+ bare = set()
+ for old_module, changes in MAPPING.items():
+ for change in changes:
+ new_module, members = change
+ members = alternates(members)
+ yield """import_name< 'import' (module=%r
+ | dotted_as_names< any* module=%r any* >) >
+ """ % (old_module, old_module)
+ yield """import_from< 'from' mod_member=%r 'import'
+ ( member=%s | import_as_name< member=%s 'as' any > |
+ import_as_names< members=any* >) >
+ """ % (old_module, members, members)
+ yield """import_from< 'from' module_star=%r 'import' star='*' >
+ """ % old_module
+ yield """import_name< 'import'
+ dotted_as_name< module_as=%r 'as' any > >
+ """ % old_module
+ yield """power< module_dot=%r trailer< '.' member=%s > any* >
+ """ % (old_module, members)
+
+
+class FixUrllib(FixImports):
+ PATTERN = "|".join(build_pattern())
+
+ def transform_import(self, node, results):
+ """Transform for the basic import case. Replaces the old
+ import name with a comma separated list of its
+ replacements.
+ """
+ import_mod = results.get('module')
+ pref = import_mod.get_prefix()
+
+ names = []
+
+ # create a Node list of the replacement modules
+ for name in MAPPING[import_mod.value][:-1]:
+ names.extend([Name(name[0], prefix=pref), Comma()])
+ names.append(Name(MAPPING[import_mod.value][-1][0], prefix=pref))
+ import_mod.replace(names)
+
+ def transform_member(self, node, results):
+ """Transform for imports of specific module elements. Replaces
+ the module to be imported from with the appropriate new
+ module.
+ """
+ mod_member = results.get('mod_member')
+ pref = mod_member.get_prefix()
+ member = results.get('member')
+
+ # Simple case with only a single member being imported
+ if member:
+ # this may be a list of length one, or just a node
+ if isinstance(member, list):
+ member = member[0]
+ new_name = None
+ for change in MAPPING[mod_member.value]:
+ if member.value in change[1]:
+ new_name = change[0]
+ break
+ if new_name:
+ mod_member.replace(Name(new_name, prefix=pref))
+ else:
+ self.cannot_convert(node,
+ 'This is an invalid module element')
+
+ # Multiple members being imported
+ else:
+ # a dictionary for replacements, order matters
+ modules = []
+ mod_dict = {}
+ members = results.get('members')
+ for member in members:
+ member = member.value
+ # we only care about the actual members
+ if member != ',':
+ for change in MAPPING[mod_member.value]:
+ if member in change[1]:
+ if mod_dict.has_key(change[0]):
+ mod_dict[change[0]].append(member)
+ else:
+ mod_dict[change[0]] = [member]
+ modules.append(change[0])
+
+ new_nodes = []
+ for module in modules:
+ elts = mod_dict[module]
+ names = []
+ for elt in elts[:-1]:
+ names.extend([Name(elt, prefix=pref), Comma()])
+ names.append(Name(elts[-1], prefix=pref))
+ new_nodes.append(FromImport(module, names))
+ if new_nodes:
+ nodes = []
+ for new_node in new_nodes[:-1]:
+ nodes.extend([new_node, Newline()])
+ nodes.append(new_nodes[-1])
+ node.replace(nodes)
+ else:
+ self.cannot_convert(node, 'All module elements are invalid')
+
+ def transform_dot(self, node, results):
+ """Transform for calls to module members in code."""
+ module_dot = results.get('module_dot')
+ member = results.get('member')
+ # this may be a list of length one, or just a node
+ if isinstance(member, list):
+ member = member[0]
+ new_name = None
+ for change in MAPPING[module_dot.value]:
+ if member.value in change[1]:
+ new_name = change[0]
+ break
+ if new_name:
+ module_dot.replace(Name(new_name,
+ prefix=module_dot.get_prefix()))
+ else:
+ self.cannot_convert(node, 'This is an invalid module element')
+
+ def transform(self, node, results):
+ if results.get('module'):
+ self.transform_import(node, results)
+ elif results.get('mod_member'):
+ self.transform_member(node, results)
+ elif results.get('module_dot'):
+ self.transform_dot(node, results)
+ # Renaming and star imports are not supported for these modules.
+ elif results.get('module_star'):
+ self.cannot_convert(node, 'Cannot handle star imports.')
+ elif results.get('module_as'):
+ self.cannot_convert(node, 'This module is now multiple modules')