mirror of
https://github.com/python/cpython.git
synced 2025-07-23 19:25:40 +00:00

svn+ssh://pythondev@svn.python.org/python/trunk ................ r72368 | benjamin.peterson | 2009-05-05 18:13:58 -0500 (Tue, 05 May 2009) | 53 lines Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from svn+ssh://pythondev@svn.python.org/sandbox/trunk/2to3/lib2to3 ........ r68503 | benjamin.peterson | 2009-01-10 14:14:49 -0600 (Sat, 10 Jan 2009) | 1 line use variable ........ r68507 | benjamin.peterson | 2009-01-10 15:13:16 -0600 (Sat, 10 Jan 2009) | 1 line rewrap ........ r68694 | benjamin.peterson | 2009-01-17 17:55:59 -0600 (Sat, 17 Jan 2009) | 1 line test for specific node type ........ r69054 | guilherme.polo | 2009-01-28 10:01:54 -0600 (Wed, 28 Jan 2009) | 2 lines Added mapping for the ttk module. ........ r69673 | benjamin.peterson | 2009-02-16 09:38:22 -0600 (Mon, 16 Feb 2009) | 1 line fix handling of as imports #5279 ........ r69679 | benjamin.peterson | 2009-02-16 11:36:06 -0600 (Mon, 16 Feb 2009) | 1 line make Base.get_next_sibling() and Base.get_prev_sibling() properties ........ r69680 | benjamin.peterson | 2009-02-16 11:41:48 -0600 (Mon, 16 Feb 2009) | 1 line normalize docstrings in pytree according to PEP 11 ........ r69681 | benjamin.peterson | 2009-02-16 11:43:09 -0600 (Mon, 16 Feb 2009) | 1 line use a set ........ r70991 | benjamin.peterson | 2009-04-01 15:54:50 -0500 (Wed, 01 Apr 2009) | 1 line map urllib.urlopen to urllib.request.open #5637 ........ r70999 | benjamin.peterson | 2009-04-01 17:36:47 -0500 (Wed, 01 Apr 2009) | 1 line add very alpha support to 2to3 for running concurrently with multiprocessing ........ r71003 | benjamin.peterson | 2009-04-01 18:10:43 -0500 (Wed, 01 Apr 2009) | 1 line fix when multiprocessing is not available or used ........ r71695 | benjamin.peterson | 2009-04-17 22:21:29 -0500 (Fri, 17 Apr 2009) | 1 line refactor multiprocessing support, so it's less hacky to employ and only loads mp when needed ........ ................
180 lines
7.3 KiB
Python
180 lines
7.3 KiB
Python
"""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
|
|
|
|
MAPPING = {'urllib': [
|
|
('urllib.request',
|
|
['URLOpener', 'FancyURLOpener', 'urlretrieve',
|
|
'_urlopener', 'urlopen', 'urlcleanup']),
|
|
('urllib.parse',
|
|
['quote', 'quote_plus', 'unquote', 'unquote_plus',
|
|
'urlencode', 'pathname2url', 'url2pathname', 'splitattr',
|
|
'splithost', 'splitnport', 'splitpasswd', 'splitport',
|
|
'splitquery', 'splittag', 'splittype', 'splituser',
|
|
'splitvalue', ]),
|
|
('urllib.error',
|
|
['ContentTooShortError'])],
|
|
'urllib2' : [
|
|
('urllib.request',
|
|
['urlopen', 'install_opener', 'build_opener',
|
|
'Request', 'OpenerDirector', 'BaseHandler',
|
|
'HTTPDefaultErrorHandler', 'HTTPRedirectHandler',
|
|
'HTTPCookieProcessor', 'ProxyHandler',
|
|
'HTTPPasswordMgr',
|
|
'HTTPPasswordMgrWithDefaultRealm',
|
|
'AbstractBasicAuthHandler',
|
|
'HTTPBasicAuthHandler', 'ProxyBasicAuthHandler',
|
|
'AbstractDigestAuthHandler',
|
|
'HTTPDigestAuthHandler', 'ProxyDigestAuthHandler',
|
|
'HTTPHandler', 'HTTPSHandler', 'FileHandler',
|
|
'FTPHandler', 'CacheFTPHandler',
|
|
'UnknownHandler']),
|
|
('urllib.error',
|
|
['URLError', 'HTTPError']),
|
|
]
|
|
}
|
|
|
|
# Duplicate the url parsing functions for urllib2.
|
|
MAPPING["urllib2"].append(MAPPING["urllib"][1])
|
|
|
|
|
|
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):
|
|
|
|
def build_pattern(self):
|
|
return "|".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 change[0] in mod_dict:
|
|
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')
|