home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / lib / python2.6 / lib2to3 / fixes / fix_imports.py < prev    next >
Encoding:
Python Source  |  2009-04-18  |  5.5 KB  |  144 lines

  1. """Fix incompatible imports and module references."""
  2. # Authors: Collin Winter, Nick Edds
  3.  
  4. # Local imports
  5. from .. import fixer_base
  6. from ..fixer_util import Name, attr_chain
  7.  
  8. MAPPING = {'StringIO':  'io',
  9.            'cStringIO': 'io',
  10.            'cPickle': 'pickle',
  11.            '__builtin__' : 'builtins',
  12.            'copy_reg': 'copyreg',
  13.            'Queue': 'queue',
  14.            'SocketServer': 'socketserver',
  15.            'ConfigParser': 'configparser',
  16.            'repr': 'reprlib',
  17.            'FileDialog': 'tkinter.filedialog',
  18.            'tkFileDialog': 'tkinter.filedialog',
  19.            'SimpleDialog': 'tkinter.simpledialog',
  20.            'tkSimpleDialog': 'tkinter.simpledialog',
  21.            'tkColorChooser': 'tkinter.colorchooser',
  22.            'tkCommonDialog': 'tkinter.commondialog',
  23.            'Dialog': 'tkinter.dialog',
  24.            'Tkdnd': 'tkinter.dnd',
  25.            'tkFont': 'tkinter.font',
  26.            'tkMessageBox': 'tkinter.messagebox',
  27.            'ScrolledText': 'tkinter.scrolledtext',
  28.            'Tkconstants': 'tkinter.constants',
  29.            'Tix': 'tkinter.tix',
  30.            'Tkinter': 'tkinter',
  31.            'markupbase': '_markupbase',
  32.            '_winreg': 'winreg',
  33.            'thread': '_thread',
  34.            'dummy_thread': '_dummy_thread',
  35.            # anydbm and whichdb are handled by fix_imports2
  36.            'dbhash': 'dbm.bsd',
  37.            'dumbdbm': 'dbm.dumb',
  38.            'dbm': 'dbm.ndbm',
  39.            'gdbm': 'dbm.gnu',
  40.            'xmlrpclib': 'xmlrpc.client',
  41.            'DocXMLRPCServer': 'xmlrpc.server',
  42.            'SimpleXMLRPCServer': 'xmlrpc.server',
  43.            'httplib': 'http.client',
  44.            'htmlentitydefs' : 'html.entities',
  45.            'HTMLParser' : 'html.parser',
  46.            'Cookie': 'http.cookies',
  47.            'cookielib': 'http.cookiejar',
  48.            'BaseHTTPServer': 'http.server',
  49.            'SimpleHTTPServer': 'http.server',
  50.            'CGIHTTPServer': 'http.server',
  51.            #'test.test_support': 'test.support',
  52.            'commands': 'subprocess',
  53.            'UserString' : 'collections',
  54.            'UserList' : 'collections',
  55.            'urlparse' : 'urllib.parse',
  56.            'robotparser' : 'urllib.robotparser',
  57. }
  58.  
  59.  
  60. def alternates(members):
  61.     return "(" + "|".join(map(repr, members)) + ")"
  62.  
  63.  
  64. def build_pattern(mapping=MAPPING):
  65.     mod_list = ' | '.join(["module_name='%s'" % key for key in mapping])
  66.     bare_names = alternates(mapping.keys())
  67.  
  68.     yield """name_import=import_name< 'import' ((%s) |
  69.                multiple_imports=dotted_as_names< any* (%s) any* >) >
  70.           """ % (mod_list, mod_list)
  71.     yield """import_from< 'from' (%s) 'import' ['(']
  72.               ( any | import_as_name< any 'as' any > |
  73.                 import_as_names< any* >)  [')'] >
  74.           """ % mod_list
  75.     yield """import_name< 'import' (dotted_as_name< (%s) 'as' any > |
  76.                multiple_imports=dotted_as_names<
  77.                  any* dotted_as_name< (%s) 'as' any > any* >) >
  78.           """ % (mod_list, mod_list)
  79.  
  80.     # Find usages of module members in code e.g. thread.foo(bar)
  81.     yield "power< bare_with_attr=(%s) trailer<'.' any > any* >" % bare_names
  82.  
  83.  
  84. class FixImports(fixer_base.BaseFix):
  85.  
  86.     order = "pre" # Pre-order tree traversal
  87.  
  88.     # This is overridden in fix_imports2.
  89.     mapping = MAPPING
  90.  
  91.     # We want to run this fixer late, so fix_import doesn't try to make stdlib
  92.     # renames into relative imports.
  93.     run_order = 6
  94.  
  95.     def build_pattern(self):
  96.         return "|".join(build_pattern(self.mapping))
  97.  
  98.     def compile_pattern(self):
  99.         # We override this, so MAPPING can be pragmatically altered and the
  100.         # changes will be reflected in PATTERN.
  101.         self.PATTERN = self.build_pattern()
  102.         super(FixImports, self).compile_pattern()
  103.  
  104.     # Don't match the node if it's within another match.
  105.     def match(self, node):
  106.         match = super(FixImports, self).match
  107.         results = match(node)
  108.         if results:
  109.             # Module usage could be in the trailer of an attribute lookup, so we
  110.             # might have nested matches when "bare_with_attr" is present.
  111.             if "bare_with_attr" not in results and \
  112.                     any([match(obj) for obj in attr_chain(node, "parent")]):
  113.                 return False
  114.             return results
  115.         return False
  116.  
  117.     def start_tree(self, tree, filename):
  118.         super(FixImports, self).start_tree(tree, filename)
  119.         self.replace = {}
  120.  
  121.     def transform(self, node, results):
  122.         import_mod = results.get("module_name")
  123.         if import_mod:
  124.             new_name = self.mapping[import_mod.value]
  125.             import_mod.replace(Name(new_name, prefix=import_mod.get_prefix()))
  126.             if "name_import" in results:
  127.                 # If it's not a "from x import x, y" or "import x as y" import,
  128.                 # marked its usage to be replaced.
  129.                 self.replace[import_mod.value] = new_name
  130.             if "multiple_imports" in results:
  131.                 # This is a nasty hack to fix multiple imports on a
  132.                 # line (e.g., "import StringIO, urlparse"). The problem is that I
  133.                 # can't figure out an easy way to make a pattern recognize the
  134.                 # keys of MAPPING randomly sprinkled in an import statement.
  135.                 results = self.match(node)
  136.                 if results:
  137.                     self.transform(node, results)
  138.         else:
  139.             # Replace usage of the module.
  140.             bare_name = results["bare_with_attr"][0]
  141.             new_name = self.replace.get(bare_name.value)
  142.             if new_name:
  143.                 bare_name.replace(Name(new_name, prefix=bare_name.get_prefix()))
  144.