Commits

Victor Stinner committed 7c756e9

Drop support of Python 2.5

  • Participants
  • Parent commits 0e67ebd

Comments (0)

Files changed (10)

 Version 0.3
 -----------
 
+ * Drop support of Python 2.5, it is unable to compile an AST tree to bytecode.
+   AST objects of Python 2.5 don't accept arguments in constructors.
  * It is now posible to define a callback for warnings of the optimizer
  * Add an option to disable removal of dead code. Required for coverage tests
    for example.
 TODO
 ====
 
-before 0.3:
-
- - drop support of Python 2.5
-
 bugs:
 
  - "len=str; print(len(1))". Need to support variables.

File astoptimizer/__init__.py

 import sys
+if sys.version_info < (2, 6):
+    raise Exception("astoptimizer requires Python 2.6 or later")
 
 UNSET = object()
 

File astoptimizer/config_builtin_funcs.py

 """
-Enable optimizations on the builtins functions, ex: len().
+Enable optimizations on the builtins functions, example: len().
 """
 from astoptimizer.compatibility import (
     is_bytes_ascii, is_unicode_ascii,
     config.add_func('sum', Function(sum, (1, 2), (tuple, frozenset), COMPLEX_TYPES, check_args=check_sum_args))
     config.add_func('tuple', Function(tuple, (0, 1), IMMUTABLE_ITERABLE_TYPES, check_args=check_tuple_args))
 
-    if sys.version_info >= (2,6):
-        config.add_func('bin', Function(bin, 1, INT_TYPES))
+    config.add_func('bin', Function(bin, 1, INT_TYPES))
     if PYTHON2:
         config.add_func('long', Function(long, 1, FLOAT_TYPES))
         config.add_func('unichr', Function(unichr, 1, INT_TYPES, check_args=check_unichr))

File astoptimizer/config_builtin_types.py

         # FIXME: str.translate
 
     # tuple
-    if sys.version_info >= (2, 6):
-        config.add_method(Method(tuple, 'count', 1, ANY_TYPE))
-        config.add_method(Method(tuple, 'index', 1, ANY_TYPE, check_args=check_index_args))
+    config.add_method(Method(tuple, 'count', 1, ANY_TYPE))
+    config.add_method(Method(tuple, 'index', 1, ANY_TYPE, check_args=check_index_args))
 
     # frozenset
-    METHODS = [
+    for method in (
         'copy', 'difference', 'intersection', 'union', 'symmetric_difference',
-        'issubset', 'issuperset',
-    ]
-    if sys.version_info >= (2, 6):
-        METHODS.append('isdisjoint')
-    for method in METHODS:
+        'isdisjoint', 'issubset', 'issuperset',
+    ]:
         config.add_method(Method(frozenset, method, 1, IMMUTABLE_ITERABLE_TYPES))
 
     # int
         config.add_method(Method(int_type, 'bit_length', 0))
 
     # float
-    if sys.version_info >= (2,6):
-        config.add_method(Method(float, 'is_integer', 0))
-        config.add_method(Method(float, 'as_integer_ratio', 0))
-        config.add_method(Method(float, 'hex', 0))
-        config.add_func('float.fromhex', Function(float.fromhex, 1, NATIVE_STR))
+    config.add_method(Method(float, 'is_integer', 0))
+    config.add_method(Method(float, 'as_integer_ratio', 0))
+    config.add_method(Method(float, 'hex', 0))
+    config.add_func('float.fromhex', Function(float.fromhex, 1, NATIVE_STR))
 

File astoptimizer/config_math.py

     config.add_func('math.frexp', Function(math.frexp, 1, FLOAT_TYPES))
     config.add_func('math.ldexp', Function(math.ldexp, 2, FLOAT_TYPES, FLOAT_TYPES))
     config.add_func('math.modf', Function(math.modf, 1, FLOAT_TYPES))
-    if sys.version_info >= (2, 6):
-        config.add_func('math.copysign', Function(math.copysign, 2, FLOAT_TYPES, FLOAT_TYPES))
-        config.add_func('math.factorial', Function(math.factorial, 1, INT_TYPES))
-        config.add_func('math.fsum', Function(math.fsum, 1, (tuple, frozenset), check_args=check_sum_args))
-        config.add_func('math.log1p', Function(math.log1p, 1, FLOAT_TYPES))
-        config.add_func('math.trunc', Function(math.trunc, 1, FLOAT_TYPES))
+    config.add_func('math.copysign', Function(math.copysign, 2, FLOAT_TYPES, FLOAT_TYPES))
+    config.add_func('math.factorial', Function(math.factorial, 1, INT_TYPES))
+    config.add_func('math.fsum', Function(math.fsum, 1, (tuple, frozenset), check_args=check_sum_args))
+    config.add_func('math.log1p', Function(math.log1p, 1, FLOAT_TYPES))
+    config.add_func('math.trunc', Function(math.trunc, 1, FLOAT_TYPES))
     if sys.version_info >= (3, 2):
         config.add_func('math.expm1', Function(math.expm1, 1, FLOAT_TYPES))
         config.add_func('math.isfinite', Function(math.isfinite, 1, FLOAT_TYPES))

File astoptimizer/config_platform.py

     config.add_constant('sys.platform', sys.platform)
     if PYTHON2:
         config.add_constant('sys.maxint', sys.maxint)
-    if sys.version_info >= (2, 6):
-        config.add_constant('sys.maxsize', sys.maxsize)
+    config.add_constant('sys.maxsize', sys.maxsize)
 
     config.add_func('platform.machine', Function(platform.machine, 0))
     config.add_func('platform.release', Function(platform.release, 0))

File astoptimizer/config_pythonbin.py

 
     config.add_func('platform.python_version',
                     Function(platform.python_version, 0))
-    if sys.version_info >= (2, 6):
-        # On Python 2.5, platform.python_version_tuple is a list
-        config.add_func('platform.python_version_tuple',
-                        Function(platform.python_version_tuple, 0))
+    config.add_func('platform.python_version_tuple',
+                    Function(platform.python_version_tuple, 0))
 
     # Build options
     config.add_constant('sys.maxunicode', sys.maxunicode)

File astoptimizer/config_pythonenv.py

     # -Q command line option
 
     config.add_constant('__debug__', __debug__)
-    if sys.version_info >= (2, 6):
-        for attr in dir(sys.flags):
-            if attr.startswith(("_", "n_")):
-                continue
-            if attr in ("count", "index"):
-                continue
-            value = getattr(sys.flags, attr)
-            config.add_constant('sys.flags.%s' % attr, value)
+    for attr in dir(sys.flags):
+        if attr.startswith(("_", "n_")):
+            continue
+        if attr in ("count", "index"):
+            continue
+        value = getattr(sys.flags, attr)
+        config.add_constant('sys.flags.%s' % attr, value)
 
-    if sys.version_info >= (2, 6):
-        config.add_constant('sys.dont_write_bytecode', sys.dont_write_bytecode)
+    config.add_constant('sys.dont_write_bytecode', sys.dont_write_bytecode)
 

File astoptimizer/optimizer.py

     IMMUTABLE_ITERABLE_TYPES)
 import sys
 
-PYTHON26 = (sys.version_info >= (2, 6))
-
 def operator_not_in(data, item):
     return item not in data
 
     ast.copy_location(new_node, node)
     return new_node
 
-if PYTHON26:
-    def new_constant(node, value):
-        if isinstance(value, bool):
-            name = "True" if value else "False"
-            new_node = ast.Name(id=name, ctx=ast.Load())
-        elif isinstance(value, COMPLEX_TYPES):
-            new_node = ast.Num(n=value)
-        elif isinstance(value, UNICODE_TYPE):
-            if PYTHON3:
-                new_node = ast.Str(s=value)
-            else:
-                new_node = ast.Str(s=value)
-        elif isinstance(value, BYTES_TYPE):
-            if PYTHON3:
-                new_node = ast.Bytes(s=value)
-            else:
-                new_node = ast.Str(s=value)
-        elif value is None:
-            new_node = ast.Name(id="None", ctx=ast.Load())
-        elif isinstance(value, tuple):
+def new_constant(node, value):
+    if isinstance(value, bool):
+        name = "True" if value else "False"
+        new_node = ast.Name(id=name, ctx=ast.Load())
+    elif isinstance(value, COMPLEX_TYPES):
+        new_node = ast.Num(n=value)
+    elif isinstance(value, UNICODE_TYPE):
+        if PYTHON3:
+            new_node = ast.Str(s=value)
+        else:
+            new_node = ast.Str(s=value)
+    elif isinstance(value, BYTES_TYPE):
+        if PYTHON3:
+            new_node = ast.Bytes(s=value)
+        else:
+            new_node = ast.Str(s=value)
+    elif value is None:
+        new_node = ast.Name(id="None", ctx=ast.Load())
+    elif isinstance(value, tuple):
+        elts = [new_constant(node, elt) for elt in value]
+        new_node = ast.Tuple(elts=elts, ctx=ast.Load())
+    elif isinstance(value, frozenset):
+        if all(isinstance(elt, UNICODE_TYPE) for elt in value):
+            arg = new_constant(node, UNICODE_TYPE().join(sorted(value)))
+        elif all(isinstance(elt, BYTES_TYPE) for elt in value):
+            arg = new_constant(node, BYTES_TYPE().join(sorted(value)))
+        else:
             elts = [new_constant(node, elt) for elt in value]
-            new_node = ast.Tuple(elts=elts, ctx=ast.Load())
-        elif isinstance(value, frozenset):
-            if all(isinstance(elt, UNICODE_TYPE) for elt in value):
-                arg = new_constant(node, UNICODE_TYPE().join(sorted(value)))
-            elif all(isinstance(elt, BYTES_TYPE) for elt in value):
-                arg = new_constant(node, BYTES_TYPE().join(sorted(value)))
-            else:
-                elts = [new_constant(node, elt) for elt in value]
-                arg = ast.Tuple(elts=elts, ctx=ast.Load())
-                copy_lineno(node, arg)
-            func = ast.Name(id='frozenset', ctx=ast.Load())
-            new_node = ast.Call(func, [arg], [], None, None)
-        else:
-            raise NotImplementedError("unable to create an AST object for constant: %r" % (value,))
-        return copy_lineno(node, new_node)
-else:
-    # Implementation for Python 2.5
-    def new_constant(node, value):
-        if isinstance(value, bool):
-            name = "True" if value else "False"
-            new_node = ast.Name()
-            new_node.id = name
-            new_node.ctx = ast.Load()
-        elif isinstance(value, COMPLEX_TYPES):
-            new_node = ast.Num()
-            new_node.n = value
-        elif isinstance(value, (UNICODE_TYPE, BYTES_TYPE)):
-            new_node = ast.Str()
-            new_node.s = value
-        elif value is None:
-            new_node = ast.Name()
-            new_node.id = "None"
-            new_node.ctx = ast.Load()
-        elif isinstance(value, tuple):
-            elts = [new_constant(node, elt) for elt in value]
-            new_node = ast.Tuple()
-            new_node.elts = elts
-            new_node.ctx = ast.Load()
-        elif isinstance(value, frozenset):
-            if all(isinstance(elt, unicode) for elt in value):
-                arg = new_constant(node, unicode().join(sorted(value)))
-            elif all(isinstance(elt, str) for elt in value):
-                arg = new_constant(node, str().join(sorted(value)))
-            else:
-                elts = [new_constant(node, elt) for elt in value]
-                arg = ast.Tuple()
-                arg.elts = elts
-                arg.ctx = ast.Load()
-                copy_lineno(node, arg)
-
-            func = ast.Name()
-            func.id = 'frozenset'
-            func.ctx = ast.Load()
-
-            new_node = ast.Call()
-            new_node.func = func
-            new_node.args = [arg]
-            new_node.keywords = []
-            new_node.starargs = None
-            new_node.kwargs  = None
-        else:
-            raise NotImplementedError("unable to create an AST object for constant: %r" % (value,))
-        return copy_lineno(node, new_node)
+            arg = ast.Tuple(elts=elts, ctx=ast.Load())
+            copy_lineno(node, arg)
+        func = ast.Name(id='frozenset', ctx=ast.Load())
+        new_node = ast.Call(func, [arg], [], None, None)
+    else:
+        raise NotImplementedError("unable to create an AST object for constant: %r" % (value,))
+    return copy_lineno(node, new_node)
 
 def remove_duplicate_pass(node_list):
     # Remove duplicate pass instructions
             else:
                 return new_constant(node, constant)
         if len(result) > 1:
-            if PYTHON26:
-                new_node = ast.BoolOp(node.op, result)
-            else:
-                new_node = ast.BoolOp()
-                new_node.op = node.op
-                new_node.values = result
+            new_node = ast.BoolOp(node.op, result)
             return copy_lineno(node, new_node)
         else:
             return result[0]
             else:
                 text = ' '.join(str(constant) for constant in constants)
             text = new_constant(node, text)
-            if PYTHON26:
-                new_node = ast.Print(node.dest, [text], node.nl)
-            else:
-                new_node = ast.Print()
-                new_node.dest = node.dest
-                new_node.values = [text]
-                new_node.nl = node.nl
+            new_node = ast.Print(node.dest, [text], node.nl)
             return copy_lineno(node, new_node)
 
     def import_all(self, module_name):
             iter_list = node.iter
             if len(iter_list.elts) > self.config.max_tuple_length:
                 return
-            if PYTHON26:
-                node.iter = ast.Tuple(elts=iter_list.elts, ctx=iter_list.ctx)
-            else:
-                node.iter = ast.Tuple()
-                node.iter.elts = iter_list.elts
-                node.iter.ctx = iter_list.ctx
+            node.iter = ast.Tuple(elts=iter_list.elts, ctx=iter_list.ctx)
             copy_lineno(iter_list, node.iter)
 
     def fullvisit_arguments(self, node):