1. Victor Stinner
  2. astoptimizer

Commits

Victor Stinner  committed 36698fb

don't use a shadowed builtin

  • Participants
  • Parent commits 559493f
  • Branches default

Comments (0)

Files changed (3)

File TODO

View file
 bugs:
 
  - "i=0; while i < 10: print(i); i = i + 1": don't replace print(i) with print('0')
- - "from math import pow as xrange; list(range(n))"
-    => "from math import pow as xrange; list(xrange(n))" is wrong
 
 major optimizations:
 

File astoptimizer/optimizer.py

View file
         else:
             return UNSET
 
+    def is_builtin_shadowed(self, name):
+        if name in self.qualnames:
+            return True
+        if not self._aliases_enabled:
+            return True
+        return False
+
     def get_qualname(self, name):
         qualname = self._get_qualname(name)
         if qualname is UNSET:
         qualname = self.namespace.get_qualname(node.func.id)
         if qualname != 'range':
             return
+        if self.namespace.is_builtin_shadowed('xrange'):
+            return
 
         # range(int, [int[, int]]) => xrange(...)
         node.func.id = 'xrange'
         else:
             return iter_expr
 
+    def can_use_builtin(self, name):
+        if 'builtin_funcs' not in self.config.features:
+            return False
+        return not self.namespace.is_builtin_shadowed(name)
+
     def visit_GeneratorExp(self, node):
         # use iter() builtin function
         iter_expr = self.optimize_comprehension(node)
         if iter_expr is None:
             return
 
-        if 'builtin_funcs' in self.config.features:
+        if self.can_use_builtin('iter'):
             if iter_expr is DROP_NODE:
                 # (x*2 for x in "abc" if False) => iter(())
                 iter_expr = new_constant(node, ())
         if iter_expr is None:
             return
         if iter_expr is not DROP_NODE:
-            if 'builtin_funcs' not in self.config.features:
+            if not self.can_use_builtin('list'):
                 return
             return new_call(node, 'list', iter_expr)
         else:

File astoptimizer/tests.py

View file
             self.check('[x for x in range(1000)]',
                        self.text_ast('list(xrange(1000))'),
                        config)
+            self.check_not_optimized(
+                'from re import *; [x for x in range(1000)]',
+                config)
+            self.check_not_optimized(
+                'from math import pow as xrange; [x for x in range(1000)]',
+                config)
             self.check('[x*2 for x in range(1, 1000)]',
                        self.text_ast('[x*2 for x in xrange(1, 1000)]'),
                        config)