[Python-checkins] r61479 - in sandbox/trunk/2to3/lib2to3: fixes/fix_map.py tests/test_fixers.py

david.wolever python-checkins at python.org
Tue Mar 18 04:15:29 CET 2008


Author: david.wolever
Date: Tue Mar 18 04:15:28 2008
New Revision: 61479

Modified:
   sandbox/trunk/2to3/lib2to3/fixes/fix_map.py
   sandbox/trunk/2to3/lib2to3/tests/test_fixers.py
Log:
Fixed 2to3s handing of map when 'from future_builtins import map' is called.  See #2171.



Modified: sandbox/trunk/2to3/lib2to3/fixes/fix_map.py
==============================================================================
--- sandbox/trunk/2to3/lib2to3/fixes/fix_map.py	(original)
+++ sandbox/trunk/2to3/lib2to3/fixes/fix_map.py	Tue Mar 18 04:15:28 2008
@@ -1,7 +1,9 @@
 # Copyright 2007 Google, Inc. All Rights Reserved.
 # Licensed to PSF under a Contributor Agreement.
 
-"""Fixer that changes map(F, ...) into list(map(F, ...)).
+"""Fixer that changes map(F, ...) into list(map(F, ...)) unless there
+exists a 'from future_builtins import map' statement in the top-level
+namespace.
 
 As a special case, map(None, X) is changed into list(X).  (This is
 necessary because the semantics are changed in this case -- the new
@@ -22,7 +24,7 @@
 from .. import patcomp
 from ..pgen2 import token
 from . import basefix
-from .util import Name, Call, ListComp, attr_chain
+from .util import Name, Call, ListComp, attr_chain, find_binding
 from ..pygram import python_symbols as syms
 
 class FixMap(basefix.BaseFix):
@@ -54,7 +56,36 @@
     >
     """
 
+    def start_tree(self, *args):
+        super(FixMap, self).start_tree(*args)
+        self._future_map_found = None
+
+    def has_future_map(self, node):
+        if self._future_map_found is not None:
+            return self._future_map_found
+
+        # Scamper up to the top level namespace
+        top = node
+        while top.type != syms.file_input:
+            assert top.parent, "Tree is insane! root found before "\
+                               "file_input node was found."
+            top = top.parent
+        top=top.children[0]
+
+        self._future_map_found = False
+
+        binding = find_binding('map', top, 'future_builtins')
+
+        self._future_map_found = bool(binding)
+
+        return self._future_map_found
+
     def transform(self, node, results):
+        if self.has_future_map(node):
+            # If a future map has been imported for this file, we won't
+            # be making any modifications
+            return
+            
         if node.parent.type == syms.simple_stmt:
             self.warning(node, "You should use a for loop here")
             new = node.clone()

Modified: sandbox/trunk/2to3/lib2to3/tests/test_fixers.py
==============================================================================
--- sandbox/trunk/2to3/lib2to3/tests/test_fixers.py	(original)
+++ sandbox/trunk/2to3/lib2to3/tests/test_fixers.py	Tue Mar 18 04:15:28 2008
@@ -2374,6 +2374,10 @@
 class Test_map(FixerTestCase):
     fixer = "map"
 
+    def check(self, b, a):
+        self.unchanged("from future_builtins import map; " + b, a)
+        FixerTestCase.check(self, b, a)
+
     def test_prefix_preservation(self):
         b = """x =    map(   f,    'abc'   )"""
         a = """x =    list(map(   f,    'abc'   ))"""
@@ -2463,6 +2467,17 @@
         a = """(x for x in map(f, 'abc'))"""
         self.unchanged(a)
 
+    def test_future_builtins(self):
+        a = "from future_builtins import spam, map, eggs; map(f, 'ham')"
+        self.unchanged(a)
+
+        b = """from future_builtins import spam, eggs; x = map(f, 'abc')"""
+        a = """from future_builtins import spam, eggs; x = list(map(f, 'abc'))"""
+        self.check(b, a)
+
+        a = "from future_builtins import *; map(f, 'ham')"
+        self.unchanged(a)
+
 class Test_standarderror(FixerTestCase):
     fixer = "standarderror"
 


More information about the Python-checkins mailing list