fix_imports.py 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. u"""
  2. Fixer for standard library imports renamed in Python 3
  3. """
  4. from lib2to3 import fixer_base
  5. from lib2to3.fixer_util import Name, is_probably_builtin, Newline, does_tree_import
  6. from lib2to3.pygram import python_symbols as syms
  7. from lib2to3.pgen2 import token
  8. from lib2to3.pytree import Node, Leaf
  9. from libfuturize.fixer_util import touch_import_top
  10. # from ..fixer_util import NameImport
  11. # used in simple_mapping_to_pattern()
  12. MAPPING = {u"reprlib": u"repr",
  13. u"winreg": u"_winreg",
  14. u"configparser": u"ConfigParser",
  15. u"copyreg": u"copy_reg",
  16. u"queue": u"Queue",
  17. u"socketserver": u"SocketServer",
  18. u"_markupbase": u"markupbase",
  19. u"test.support": u"test.test_support",
  20. u"dbm.bsd": u"dbhash",
  21. u"dbm.ndbm": u"dbm",
  22. u"dbm.dumb": u"dumbdbm",
  23. u"dbm.gnu": u"gdbm",
  24. u"html.parser": u"HTMLParser",
  25. u"html.entities": u"htmlentitydefs",
  26. u"http.client": u"httplib",
  27. u"http.cookies": u"Cookie",
  28. u"http.cookiejar": u"cookielib",
  29. # "tkinter": "Tkinter",
  30. u"tkinter.dialog": u"Dialog",
  31. u"tkinter._fix": u"FixTk",
  32. u"tkinter.scrolledtext": u"ScrolledText",
  33. u"tkinter.tix": u"Tix",
  34. u"tkinter.constants": u"Tkconstants",
  35. u"tkinter.dnd": u"Tkdnd",
  36. u"tkinter.__init__": u"Tkinter",
  37. u"tkinter.colorchooser": u"tkColorChooser",
  38. u"tkinter.commondialog": u"tkCommonDialog",
  39. u"tkinter.font": u"tkFont",
  40. u"tkinter.ttk": u"ttk",
  41. u"tkinter.messagebox": u"tkMessageBox",
  42. u"tkinter.turtle": u"turtle",
  43. u"urllib.robotparser": u"robotparser",
  44. u"xmlrpc.client": u"xmlrpclib",
  45. u"builtins": u"__builtin__",
  46. }
  47. # generic strings to help build patterns
  48. # these variables mean (with http.client.HTTPConnection as an example):
  49. # name = http
  50. # attr = client
  51. # used = HTTPConnection
  52. # fmt_name is a formatted subpattern (simple_name_match or dotted_name_match)
  53. # helps match 'queue', as in 'from queue import ...'
  54. simple_name_match = u"name='%s'"
  55. # helps match 'client', to be used if client has been imported from http
  56. subname_match = u"attr='%s'"
  57. # helps match 'http.client', as in 'import urllib.request'
  58. dotted_name_match = u"dotted_name=dotted_name< %s '.' %s >"
  59. # helps match 'queue', as in 'queue.Queue(...)'
  60. power_onename_match = u"%s"
  61. # helps match 'http.client', as in 'http.client.HTTPConnection(...)'
  62. power_twoname_match = u"power< %s trailer< '.' %s > any* >"
  63. # helps match 'client.HTTPConnection', if 'client' has been imported from http
  64. power_subname_match = u"power< %s any* >"
  65. # helps match 'from http.client import HTTPConnection'
  66. from_import_match = u"from_import=import_from< 'from' %s 'import' imported=any >"
  67. # helps match 'from http import client'
  68. from_import_submod_match = u"from_import_submod=import_from< 'from' %s 'import' (%s | import_as_name< %s 'as' renamed=any > | import_as_names< any* (%s | import_as_name< %s 'as' renamed=any >) any* > ) >"
  69. # helps match 'import urllib.request'
  70. name_import_match = u"name_import=import_name< 'import' %s > | name_import=import_name< 'import' dotted_as_name< %s 'as' renamed=any > >"
  71. # helps match 'import http.client, winreg'
  72. multiple_name_import_match = u"name_import=import_name< 'import' dotted_as_names< names=any* > >"
  73. def all_patterns(name):
  74. u"""
  75. Accepts a string and returns a pattern of possible patterns involving that name
  76. Called by simple_mapping_to_pattern for each name in the mapping it receives.
  77. """
  78. # i_ denotes an import-like node
  79. # u_ denotes a node that appears to be a usage of the name
  80. if u'.' in name:
  81. name, attr = name.split(u'.', 1)
  82. simple_name = simple_name_match % (name)
  83. simple_attr = subname_match % (attr)
  84. dotted_name = dotted_name_match % (simple_name, simple_attr)
  85. i_from = from_import_match % (dotted_name)
  86. i_from_submod = from_import_submod_match % (simple_name, simple_attr, simple_attr, simple_attr, simple_attr)
  87. i_name = name_import_match % (dotted_name, dotted_name)
  88. u_name = power_twoname_match % (simple_name, simple_attr)
  89. u_subname = power_subname_match % (simple_attr)
  90. return u' | \n'.join((i_name, i_from, i_from_submod, u_name, u_subname))
  91. else:
  92. simple_name = simple_name_match % (name)
  93. i_name = name_import_match % (simple_name, simple_name)
  94. i_from = from_import_match % (simple_name)
  95. u_name = power_onename_match % (simple_name)
  96. return u' | \n'.join((i_name, i_from, u_name))
  97. class FixImports(fixer_base.BaseFix):
  98. PATTERN = u' | \n'.join([all_patterns(name) for name in MAPPING])
  99. PATTERN = u' | \n'.join((PATTERN, multiple_name_import_match))
  100. def transform(self, node, results):
  101. touch_import_top(u'future', u'standard_library', node)