Commits

Victor Stinner committed dbc0434

for x in [1, 2, 3]: ...

Comments (0)

Files changed (5)

  * math.log(32) / math.log(2) => 5.0
  * pass; pass => pass
  * for x in range(n): ... => for x in xrange(n): ... (only on Python 2)
+ * for x in [1, 2, 3]: ... => for x in (1, 2, 3): ...
  * from math import *; pow(2, 4) => 16.0 (call math.pow, not builtin pow)
 
 You can specified your own constants and your own pure functions for more
  - 1 < 2 < 3
  - x in [1, 2, 3] => x in (1, 2, 3)
  - x in {1, 2, 3} => x in frozenset((1, 2, 3))
- - for x in [1, 2, 3]: ... => for x in (1, 2, 3): ...
  - str.format() (str%args already implemented), don't optimize {!n} (locale dependant)
  - logging machinery: "from unknown import *" => WARNING
  - write tests for patch_compile(), ex: ast.literal_ast("1+(2+3j)")

astoptimizer/config.py

         self.max_string_length = 4096
 
         # Maximum number of items of a tuple or a frozenset
-        self.max_tuple_length = 9
+        self.max_tuple_length = 20
 
         # The maximum size is at least 2^31-1 according to Python 2.7
         # documentation

astoptimizer/optimizer.py

             pass
 
     def visit_For(self, node):
-        if (isinstance(node.target, ast.Name)
-        and isinstance(node.iter, ast.Call)
+        if (isinstance(node.iter, ast.Call)
         and isinstance(node.iter.func, ast.Name)):
             func_name = node.iter.func
             # for x in range(...) => for x in xrange(...)
             if (PYTHON2
             and func_name.id == 'range'):
                 func_name.id = 'xrange'
+        elif isinstance(node.iter, ast.List):
+            iter_list = node.iter
+            if len(iter_list.elts) > self.config.max_tuple_length:
+                return
+            node.iter = ast.Tuple(elts=iter_list.elts, ctx=iter_list.ctx)
+            copy_lineno(iter_list, node.iter)
+
 
 class FunctionOptimizer(BaseOptimizer):
     def __init__(self, config):

astoptimizer/tests.py

         if PYTHON2:
             self.check('for x in range(n): pass',
                        self.text_ast('for x in xrange(n): pass'))
+        self.check('for x in [1, 2, 3]: pass',
+                   self.text_ast('for x in (1, 2, 3): pass'))
+
+        config = Config()
+        config.max_tuple_length = 2
+        self.check('for x in [1, 2]: pass',
+                   self.text_ast('for x in (1, 2): pass'), config)
+        self.check_not_optimized('for x in [1, 2, 3]: pass', config)
 
     def test_max_tuple_length(self):
         config = Config()