mirror of
https://github.com/python/cpython.git
synced 2025-08-03 00:23:06 +00:00

svn+ssh://pythondev@svn.python.org/python/trunk ................ r67428 | benjamin.peterson | 2008-11-28 16:12:14 -0600 (Fri, 28 Nov 2008) | 57 lines Merged revisions 67384,67386-67387,67389-67390,67392,67399-67400,67403-67405,67426 via svnmerge from svn+ssh://pythondev@svn.python.org/sandbox/trunk/2to3/lib2to3 ........ r67384 | benjamin.peterson | 2008-11-25 16:13:31 -0600 (Tue, 25 Nov 2008) | 4 lines don't duplicate calls to start_tree() RefactoringTool.pre_order values now holds a list of the fixers while pre_order_mapping holds the dict. ........ r67386 | benjamin.peterson | 2008-11-25 16:44:52 -0600 (Tue, 25 Nov 2008) | 1 line #4423 fix_imports was still replacing usage of a module if attributes were being used ........ r67387 | benjamin.peterson | 2008-11-25 16:47:54 -0600 (Tue, 25 Nov 2008) | 1 line fix broken test ........ r67389 | benjamin.peterson | 2008-11-25 17:13:17 -0600 (Tue, 25 Nov 2008) | 1 line remove compatibility code; we only cater to 2.5+ ........ r67390 | benjamin.peterson | 2008-11-25 22:03:36 -0600 (Tue, 25 Nov 2008) | 1 line fix #3994; the usage of changed imports was fixed in nested cases ........ r67392 | benjamin.peterson | 2008-11-26 11:11:40 -0600 (Wed, 26 Nov 2008) | 1 line simpilfy and comment fix_imports ........ r67399 | benjamin.peterson | 2008-11-26 11:47:03 -0600 (Wed, 26 Nov 2008) | 1 line remove more compatibility code ........ r67400 | benjamin.peterson | 2008-11-26 12:07:41 -0600 (Wed, 26 Nov 2008) | 1 line set svn:ignore ........ r67403 | benjamin.peterson | 2008-11-26 13:11:11 -0600 (Wed, 26 Nov 2008) | 1 line wrap import ........ r67404 | benjamin.peterson | 2008-11-26 13:29:49 -0600 (Wed, 26 Nov 2008) | 1 line build the fix_imports pattern in compile_pattern, so MAPPING can be changed and reflected in the pattern ........ r67405 | benjamin.peterson | 2008-11-26 14:01:24 -0600 (Wed, 26 Nov 2008) | 1 line stop ugly messages about runtime errors being from printed ........ r67426 | benjamin.peterson | 2008-11-28 16:01:40 -0600 (Fri, 28 Nov 2008) | 5 lines don't replace a module name if it is in the middle of a attribute lookup This fix also stops module names from being replaced if they are not in an attribute lookup. ........ ................
129 lines
4.8 KiB
Python
129 lines
4.8 KiB
Python
"""Fix incompatible imports and module references."""
|
|
# Authors: Collin Winter, Nick Edds
|
|
|
|
# Local imports
|
|
from .. import fixer_base
|
|
from ..fixer_util import Name, attr_chain
|
|
|
|
MAPPING = {'StringIO': 'io',
|
|
'cStringIO': 'io',
|
|
'cPickle': 'pickle',
|
|
'__builtin__' : 'builtins',
|
|
'copy_reg': 'copyreg',
|
|
'Queue': 'queue',
|
|
'SocketServer': 'socketserver',
|
|
'ConfigParser': 'configparser',
|
|
'repr': 'reprlib',
|
|
'FileDialog': 'tkinter.filedialog',
|
|
'tkFileDialog': 'tkinter.filedialog',
|
|
'SimpleDialog': 'tkinter.simpledialog',
|
|
'tkSimpleDialog': 'tkinter.simpledialog',
|
|
'tkColorChooser': 'tkinter.colorchooser',
|
|
'tkCommonDialog': 'tkinter.commondialog',
|
|
'Dialog': 'tkinter.dialog',
|
|
'Tkdnd': 'tkinter.dnd',
|
|
'tkFont': 'tkinter.font',
|
|
'tkMessageBox': 'tkinter.messagebox',
|
|
'ScrolledText': 'tkinter.scrolledtext',
|
|
'turtle': 'tkinter.turtle',
|
|
'Tkconstants': 'tkinter.constants',
|
|
'Tix': 'tkinter.tix',
|
|
'Tkinter': 'tkinter',
|
|
'markupbase': '_markupbase',
|
|
'_winreg': 'winreg',
|
|
'thread': '_thread',
|
|
'dummy_thread': '_dummy_thread',
|
|
# anydbm and whichdb are handled by fix_imports2
|
|
'dbhash': 'dbm.bsd',
|
|
'dumbdbm': 'dbm.dumb',
|
|
'dbm': 'dbm.ndbm',
|
|
'gdbm': 'dbm.gnu',
|
|
'xmlrpclib': 'xmlrpc.client',
|
|
'DocXMLRPCServer': 'xmlrpc.server',
|
|
'SimpleXMLRPCServer': 'xmlrpc.server',
|
|
'httplib': 'http.client',
|
|
'Cookie': 'http.cookies',
|
|
'cookielib': 'http.cookiejar',
|
|
'BaseHTTPServer': 'http.server',
|
|
'SimpleHTTPServer': 'http.server',
|
|
'CGIHTTPServer': 'http.server',
|
|
#'test.test_support': 'test.support',
|
|
'commands': 'subprocess',
|
|
'UserString' : 'collections',
|
|
'UserList' : 'collections',
|
|
'urlparse' : 'urllib.parse',
|
|
'robotparser' : 'urllib.robotparser',
|
|
}
|
|
|
|
|
|
def alternates(members):
|
|
return "(" + "|".join(map(repr, members)) + ")"
|
|
|
|
|
|
def build_pattern(mapping=MAPPING):
|
|
mod_list = ' | '.join(["module_name='%s'" % key for key in mapping])
|
|
bare_names = alternates(mapping.keys())
|
|
|
|
yield """name_import=import_name< 'import' ((%s)
|
|
| dotted_as_names< any* (%s) any* >) >
|
|
""" % (mod_list, mod_list)
|
|
yield """import_from< 'from' (%s) 'import' ['(']
|
|
( any | import_as_name< any 'as' any > |
|
|
import_as_names< any* >) [')'] >
|
|
""" % mod_list
|
|
yield """import_name< 'import'
|
|
dotted_as_name< (%s) 'as' any > >
|
|
""" % mod_list
|
|
|
|
# Find usages of module members in code e.g. thread.foo(bar)
|
|
yield "power< bare_with_attr=(%s) trailer<'.' any > any* >" % bare_names
|
|
|
|
|
|
class FixImports(fixer_base.BaseFix):
|
|
|
|
order = "pre" # Pre-order tree traversal
|
|
|
|
# This is overridden in fix_imports2.
|
|
mapping = MAPPING
|
|
|
|
def build_pattern(self):
|
|
return "|".join(build_pattern(self.mapping))
|
|
|
|
def compile_pattern(self):
|
|
# We override this, so MAPPING can be pragmatically altered and the
|
|
# changes will be reflected in PATTERN.
|
|
self.PATTERN = self.build_pattern()
|
|
super(FixImports, self).compile_pattern()
|
|
|
|
# Don't match the node if it's within another match.
|
|
def match(self, node):
|
|
match = super(FixImports, self).match
|
|
results = match(node)
|
|
if results:
|
|
# Module usage could be in the trailier of an attribute lookup, so
|
|
# we might have nested matches when "bare_with_attr" is present.
|
|
if "bare_with_attr" not in results and \
|
|
any([match(obj) for obj in attr_chain(node, "parent")]):
|
|
return False
|
|
return results
|
|
return False
|
|
|
|
def start_tree(self, tree, filename):
|
|
super(FixImports, self).start_tree(tree, filename)
|
|
self.replace = {}
|
|
|
|
def transform(self, node, results):
|
|
import_mod = results.get("module_name")
|
|
if import_mod:
|
|
new_name = self.mapping[(import_mod or mod_name).value]
|
|
if "name_import" in results:
|
|
# If it's not a "from x import x, y" or "import x as y" import,
|
|
# marked its usage to be replaced.
|
|
self.replace[import_mod.value] = new_name
|
|
import_mod.replace(Name(new_name, prefix=import_mod.get_prefix()))
|
|
else:
|
|
# Replace usage of the module.
|
|
bare_name = results["bare_with_attr"][0]
|
|
new_name = self.replace.get(bare_name.value)
|
|
if new_name:
|
|
bare_name.replace(Name(new_name, prefix=bare_name.get_prefix()))
|