=== added file 'lib2to3/fixes/fix_urllib.py' --- lib2to3/fixes/fix_urllib.py 1970-01-01 00:00:00 +0000 +++ lib2to3/fixes/fix_urllib.py 2008-07-07 21:10:50 +0000 @@ -0,0 +1,178 @@ +"""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 .. 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'])], + 'urlparse' : [ + ('urllib.parse', + ['urlparse', 'urlunparse', 'urlsplit', + 'urlunsplit', 'urljoin', 'urldefraq', + 'ParseResult', 'SplitResult'])], + 'robotparser' : [ + ('urllib.robotparser', + ['RobotFileParser'])] +} + + +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(fixer_base.BaseFix): + PATTERN = "|".join(build_pattern()) + + order = "pre" # Pre-order tree traversal + + # Don't match the node if it's within another match + def match(self, node): + match = super(FixUrllib, self).match + results = match(node) + if results: + if any([match(obj) for obj in attr_chain(node, "parent")]): + return False + return results + return False + + def start_tree(self, tree, filename): + super(FixUrllib, self).start_tree(tree, filename) + self.replace = {} + + def transform_import(self, node, results): + """Transform for the basic import case.""" + import_mod = results.get('module') + pref = import_mod.get_prefix() + names = [Name(MAPPING[import_mod.value][0][0], prefix=pref)] + for change in MAPPING[import_mod.value][1:]: + names.extend([Comma(), Name(change[0], prefix=pref)]) + import_mod.replace(names) + + def transform_member(self, node, results): + """Transform for imports of specific module elements.""" + mod_member = results.get('mod_member') + pref = mod_member.get_prefix() + member = results.get('member') + if member: + new_name = None + for change in MAPPING[mod_member.value]: + if member[0].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') + else: + mod_dict = {} + members = results.get('members') + for member in members: + member = member.value + 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] + + new_nodes = [] + for module, elts in mod_dict.items(): + names = [Name(elts[0], prefix=pref)] + if len(elts) > 1: + for elt in elts[1:]: + names.extend([Comma(), Name(elt, prefix=pref)]) + new_nodes.append(FromImport(module, names)) + new_nodes.append(Newline()) + if new_nodes: + node.replace(new_nodes) + else: + self.cannot_convert(node, 'All module elements are invalid') + + def transform_as(self, node, results): + """Transform for imports with renaming.""" + module_as = results.get('module_as') + if len(MAPPING[module_as.value]) == 1: + module_as.replace(Name(MAPPING[module_as.value][0][0], + prefix=module_as.get_prefix())) + else: + self.cannot_convert(node, 'This module is now multiple modules') + + def transform_dot(self, node, results): + """Transform for calls to module members in code.""" + module_dot = results.get('module_dot') + member = results.get('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_star'): + self.cannot_convert(node, 'Cannot handle star imports.') + elif results.get('module_as'): + self.transform_as(node, results) + elif results.get('module_dot'): + self.transform_dot(node, results) === added file 'temp.py' --- temp.py 1970-01-01 00:00:00 +0000 +++ temp.py 2008-07-07 19:56:19 +0000 @@ -0,0 +1,11 @@ +import urllib +import sandwich +from urllib2 import urlopen +from urllib2 import install_opener, build_opener, URLError +from urllib2 import Request, bacon +from urlparse import * +import robotparser as bacon +import urllib2 as sandwich + +urllib.urlcleanup +urllib2.install_opener === modified file 'lib2to3/fixer_util.py' --- lib2to3/fixer_util.py 2008-06-10 04:12:51 +0000 +++ lib2to3/fixer_util.py 2008-07-07 20:21:25 +0000 @@ -112,9 +112,9 @@ """ Return an import statement in the form: from package import name_leafs""" # XXX: May not handle dotted imports properly (eg, package_name='foo.bar') - assert package_name == '.' or '.' not in package.name, "FromImport has "\ - "not been tested with dotted package names -- use at your own "\ - "peril!" + #assert package_name == '.' or '.' not in package_name, "FromImport has "\ + # "not been tested with dotted package names -- use at your own "\ + # "peril!" for leaf in name_leafs: # Pull the leaves out of their old tree