diff options
author | Benjamin Peterson <benjamin@python.org> | 2010-08-08 19:01:25 (GMT) |
---|---|---|
committer | Benjamin Peterson <benjamin@python.org> | 2010-08-08 19:01:25 (GMT) |
commit | 4eb5fa56e4b84a3a76ddc9487f19764dfab52a7f (patch) | |
tree | 3a21cf2596a14b14f1cb9bbdcd39b80b2f5c1b49 /Lib/lib2to3/fixes | |
parent | bf4cc5d469d9361ea1ea3db257fa7117c658f752 (diff) | |
download | cpython-4eb5fa56e4b84a3a76ddc9487f19764dfab52a7f.zip cpython-4eb5fa56e4b84a3a76ddc9487f19764dfab52a7f.tar.gz cpython-4eb5fa56e4b84a3a76ddc9487f19764dfab52a7f.tar.bz2 |
Merged revisions 82779,82855,83740,83789-83791,83797-83801,83803,83811,83827,83844 via svnmerge from
svn+ssh://pythondev@svn.python.org/sandbox/trunk/2to3/lib2to3
........
r82779 | benjamin.peterson | 2010-07-10 14:45:08 -0500 (Sat, 10 Jul 2010) | 1 line
typo in attribute name #9217
........
r82855 | benjamin.peterson | 2010-07-13 16:27:38 -0500 (Tue, 13 Jul 2010) | 1 line
remove more extraneous commas #9245
........
r83740 | alexandre.vassalotti | 2010-08-05 01:58:36 -0500 (Thu, 05 Aug 2010) | 4 lines
Issue 5077: Update fixer for the other functions gone from the operator module.
Patch by Meador Inge.
........
r83789 | benjamin.peterson | 2010-08-07 17:45:14 -0500 (Sat, 07 Aug 2010) | 1 line
cleanup and use unicode consistently
........
r83790 | benjamin.peterson | 2010-08-07 17:52:06 -0500 (Sat, 07 Aug 2010) | 1 line
unicode literal
........
r83791 | benjamin.peterson | 2010-08-07 17:52:55 -0500 (Sat, 07 Aug 2010) | 1 line
.get() is pointless here
........
r83797 | benjamin.peterson | 2010-08-07 18:54:51 -0500 (Sat, 07 Aug 2010) | 1 line
add a function to find how a node is indented
........
r83798 | benjamin.peterson | 2010-08-07 18:55:28 -0500 (Sat, 07 Aug 2010) | 1 line
when splitting import statements, use correct indentation #9386
........
r83799 | benjamin.peterson | 2010-08-07 18:57:43 -0500 (Sat, 07 Aug 2010) | 1 line
double quotes
........
r83800 | benjamin.peterson | 2010-08-07 18:58:52 -0500 (Sat, 07 Aug 2010) | 1 line
add another test
........
r83801 | benjamin.peterson | 2010-08-07 19:02:10 -0500 (Sat, 07 Aug 2010) | 1 line
cleanup; style-nits
........
r83803 | benjamin.peterson | 2010-08-07 19:05:08 -0500 (Sat, 07 Aug 2010) | 1 line
slightly more explicit
........
r83811 | benjamin.peterson | 2010-08-07 22:56:44 -0500 (Sat, 07 Aug 2010) | 4 lines
Fix node.pre_order() to call the right method on its children.
This was a rather tragic copy-paste error.
........
r83827 | benjamin.peterson | 2010-08-08 08:12:48 -0500 (Sun, 08 Aug 2010) | 1 line
cause test to actually run and fix it
........
r83844 | benjamin.peterson | 2010-08-08 13:46:37 -0500 (Sun, 08 Aug 2010) | 1 line
fix whitespace
........
Diffstat (limited to 'Lib/lib2to3/fixes')
-rw-r--r-- | Lib/lib2to3/fixes/fix_itertools_imports.py | 4 | ||||
-rw-r--r-- | Lib/lib2to3/fixes/fix_operator.py | 97 | ||||
-rw-r--r-- | Lib/lib2to3/fixes/fix_urllib.py | 110 |
3 files changed, 133 insertions, 78 deletions
diff --git a/Lib/lib2to3/fixes/fix_itertools_imports.py b/Lib/lib2to3/fixes/fix_itertools_imports.py index f4b4ead..a1702ba 100644 --- a/Lib/lib2to3/fixes/fix_itertools_imports.py +++ b/Lib/lib2to3/fixes/fix_itertools_imports.py @@ -43,8 +43,8 @@ class FixItertoolsImports(fixer_base.BaseFix): else: remove_comma ^= True - if children[-1].type == token.COMMA: - children[-1].remove() + while children and children[-1].type == token.COMMA: + children.pop().remove() # If there are no imports left, just get rid of the entire statement if (not (imports.children or getattr(imports, 'value', None)) or diff --git a/Lib/lib2to3/fixes/fix_operator.py b/Lib/lib2to3/fixes/fix_operator.py index ded9eee..c393f1e 100644 --- a/Lib/lib2to3/fixes/fix_operator.py +++ b/Lib/lib2to3/fixes/fix_operator.py @@ -1,40 +1,89 @@ -"""Fixer for operator.{isCallable,sequenceIncludes} +"""Fixer for operator functions. -operator.isCallable(obj) -> hasattr(obj, '__call__') +operator.isCallable(obj) -> hasattr(obj, '__call__') operator.sequenceIncludes(obj) -> operator.contains(obj) +operator.isSequenceType(obj) -> isinstance(obj, collections.Sequence) +operator.isMappingType(obj) -> isinstance(obj, collections.Mapping) +operator.isNumberType(obj) -> isinstance(obj, numbers.Number) +operator.repeat(obj, n) -> operator.mul(obj, n) +operator.irepeat(obj, n) -> operator.imul(obj, n) """ +import collections + # Local imports -from .. import fixer_base -from ..fixer_util import Call, Name, String +from lib2to3 import fixer_base +from lib2to3.fixer_util import Call, Name, String, touch_import + class FixOperator(fixer_base.BaseFix): - methods = "method=('isCallable'|'sequenceIncludes')" - func = "'(' func=any ')'" + methods = """ + method=('isCallable'|'sequenceIncludes' + |'isSequenceType'|'isMappingType'|'isNumberType' + |'repeat'|'irepeat') + """ + obj = "'(' obj=any ')'" PATTERN = """ power< module='operator' - trailer< '.' %(methods)s > trailer< %(func)s > > + trailer< '.' %(methods)s > trailer< %(obj)s > > | - power< %(methods)s trailer< %(func)s > > - """ % dict(methods=methods, func=func) + power< %(methods)s trailer< %(obj)s > > + """ % dict(methods=methods, obj=obj) def transform(self, node, results): + method = self._check_method(node, results) + if method is not None: + return method(node, results) + + def _sequenceIncludes(self, node, results): + """operator.contains(%s)""" + return self._handle_rename(node, results, "contains") + + def _isCallable(self, node, results): + """hasattr(%s, '__call__')""" + obj = results["obj"] + args = [obj.clone(), String(", "), String("'__call__'")] + return Call(Name("hasattr"), args, prefix=node.prefix) + + def _repeat(self, node, results): + """operator.mul(%s)""" + return self._handle_rename(node, results, "mul") + + def _irepeat(self, node, results): + """operator.imul(%s)""" + return self._handle_rename(node, results, "imul") + + def _isSequenceType(self, node, results): + """isinstance(%s, collections.Sequence)""" + return self._handle_type2abc(node, results, "collections", "Sequence") + + def _isMappingType(self, node, results): + """isinstance(%s, collections.Mapping)""" + return self._handle_type2abc(node, results, "collections", "Mapping") + + def _isNumberType(self, node, results): + """isinstance(%s, numbers.Number)""" + return self._handle_type2abc(node, results, "numbers", "Number") + + def _handle_rename(self, node, results, name): method = results["method"][0] + method.value = name + method.changed() - if method.value == "sequenceIncludes": - if "module" not in results: - # operator may not be in scope, so we can't make a change. - self.warning(node, "You should use operator.contains here.") - else: - method.value = "contains" - method.changed() - elif method.value == "isCallable": - if "module" not in results: - self.warning(node, - "You should use hasattr(%s, '__call__') here." % - results["func"].value) + def _handle_type2abc(self, node, results, module, abc): + touch_import(None, module, node) + obj = results["obj"] + args = [obj.clone(), String(", " + ".".join([module, abc]))] + return Call(Name("isinstance"), args, prefix=node.prefix) + + def _check_method(self, node, results): + method = getattr(self, "_" + results["method"][0].value) + if isinstance(method, collections.Callable): + if "module" in results: + return method else: - func = results["func"] - args = [func.clone(), String(", "), String("'__call__'")] - return Call(Name("hasattr"), args, prefix=node.prefix) + sub = (str(results["obj"]),) + invocation_str = str(method.__doc__) % sub + self.warning(node, "You should use '%s' here." % invocation_str) + return None diff --git a/Lib/lib2to3/fixes/fix_urllib.py b/Lib/lib2to3/fixes/fix_urllib.py index db18ca8..87ccec0 100644 --- a/Lib/lib2to3/fixes/fix_urllib.py +++ b/Lib/lib2to3/fixes/fix_urllib.py @@ -5,39 +5,40 @@ # 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', - 'pathname2url', 'url2pathname']), - ('urllib.parse', - ['quote', 'quote_plus', 'unquote', 'unquote_plus', - 'urlencode', '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']), +from lib2to3.fixes.fix_imports import alternates, FixImports +from lib2to3 import fixer_base +from lib2to3.fixer_util import (Name, Comma, FromImport, Newline, + find_indentation) + +MAPPING = {"urllib": [ + ("urllib.request", + ["URLOpener", "FancyURLOpener", "urlretrieve", + "_urlopener", "urlopen", "urlcleanup", + "pathname2url", "url2pathname"]), + ("urllib.parse", + ["quote", "quote_plus", "unquote", "unquote_plus", + "urlencode", "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"]), ] } @@ -78,7 +79,7 @@ class FixUrllib(FixImports): import name with a comma separated list of its replacements. """ - import_mod = results.get('module') + import_mod = results.get("module") pref = import_mod.prefix names = [] @@ -94,9 +95,9 @@ class FixUrllib(FixImports): the module to be imported from with the appropriate new module. """ - mod_member = results.get('mod_member') + mod_member = results.get("mod_member") pref = mod_member.prefix - member = results.get('member') + member = results.get("member") # Simple case with only a single member being imported if member: @@ -111,19 +112,18 @@ class FixUrllib(FixImports): if new_name: mod_member.replace(Name(new_name, prefix=pref)) else: - self.cannot_convert(node, - 'This is an invalid module element') + 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') + members = results["members"] for member in members: member = member.value # we only care about the actual members - if member != ',': + if member != ",": for change in MAPPING[mod_member.value]: if member in change[1]: if change[0] in mod_dict: @@ -133,13 +133,19 @@ class FixUrllib(FixImports): modules.append(change[0]) new_nodes = [] + indentation = find_indentation(node) + first = True 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)) + new = FromImport(module, names) + if not first or node.parent.prefix.endswith(indentation): + new.prefix = indentation + new_nodes.append(new) + first = False if new_nodes: nodes = [] for new_node in new_nodes[:-1]: @@ -147,12 +153,12 @@ class FixUrllib(FixImports): nodes.append(new_nodes[-1]) node.replace(nodes) else: - self.cannot_convert(node, 'All module elements are invalid') + 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('bare_with_attr') - member = results.get('member') + module_dot = results.get("bare_with_attr") + member = results.get("member") new_name = None if isinstance(member, list): member = member[0] @@ -164,17 +170,17 @@ class FixUrllib(FixImports): module_dot.replace(Name(new_name, prefix=module_dot.prefix)) else: - self.cannot_convert(node, 'This is an invalid module element') + self.cannot_convert(node, "This is an invalid module element") def transform(self, node, results): - if results.get('module'): + if results.get("module"): self.transform_import(node, results) - elif results.get('mod_member'): + elif results.get("mod_member"): self.transform_member(node, results) - elif results.get('bare_with_attr'): + elif results.get("bare_with_attr"): 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') + 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") |