From 8120a25c0822598c9ed974562f068a94b0097ace Mon Sep 17 00:00:00 2001 From: Berker Peksag Date: Sun, 29 Dec 2013 12:57:48 +0200 Subject: [PATCH 1/6] Add py_compile.{MAGIC, wr_long} to hy._compat. Closes #344. --- hy/_compat.py | 14 ++++++++++++++ hy/importer.py | 8 +++----- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/hy/_compat.py b/hy/_compat.py index e30d0dc..65aa29b 100644 --- a/hy/_compat.py +++ b/hy/_compat.py @@ -1,5 +1,6 @@ # Copyright (c) 2013 Paul Tagliamonte # Copyright (c) 2013 Julien Danjou +# Copyright (c) 2013 Berker Peksag # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the "Software"), @@ -23,9 +24,22 @@ try: import __builtin__ as builtins except ImportError: import builtins # NOQA +try: + from py_compile import MAGIC, wr_long +except ImportError: + # py_compile.MAGIC removed and imp.get_magic() deprecated in Python 3.4 + from importlib.util import MAGIC_NUMBER as MAGIC # NOQA + + def wr_long(f, x): + """Internal; write a 32-bit int to a file in little-endian order.""" + f.write(bytes([x & 0xff, + (x >> 8) & 0xff, + (x >> 16) & 0xff, + (x >> 24) & 0xff])) import sys PY3 = sys.version_info[0] >= 3 +PY33 = sys.version_info[0] >= 3 and sys.version_info[1] >= 3 if PY3: str_type = str diff --git a/hy/importer.py b/hy/importer.py index b32b71a..63cc55a 100644 --- a/hy/importer.py +++ b/hy/importer.py @@ -18,12 +18,10 @@ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # DEALINGS IN THE SOFTWARE. -from py_compile import wr_long, MAGIC from hy.compiler import hy_compile from hy.models import HyObject from hy.lex import tokenize - from io import open import marshal import imp @@ -32,7 +30,7 @@ import ast import os import __future__ -from hy._compat import builtins, long_type +from hy._compat import PY3, PY33, MAGIC, builtins, long_type, wr_long def ast_compile(ast, filename, mode): @@ -128,12 +126,12 @@ def write_hy_as_pyc(fname): open_ = builtins.open with open_(cfile, 'wb') as fc: - if sys.version_info[0] >= 3: + if PY3: fc.write(b'\0\0\0\0') else: fc.write('\0\0\0\0') wr_long(fc, timestamp) - if (sys.version_info[0] >= 3 and sys.version_info[1] >= 3): + if PY33: wr_long(fc, st.st_size) marshal.dump(code, fc) fc.flush() From 26e2fb3606d4c56585d329773cd7d5a6f0ff6915 Mon Sep 17 00:00:00 2001 From: Paul Tagliamonte Date: Wed, 1 Jan 2014 18:56:09 -0500 Subject: [PATCH 2/6] Give a whack at Python 3.4 support This adds ast.arg for Python 3.4+, for FunctionDef args and other args (starargs, kwargs) --- hy/compiler.py | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/hy/compiler.py b/hy/compiler.py index c418dba..fd45eb1 100644 --- a/hy/compiler.py +++ b/hy/compiler.py @@ -1699,12 +1699,32 @@ class HyASTCompiler(object): arglist = expression.pop(0) ret, args, defaults, stararg, kwargs = self._parse_lambda_list(arglist) + if sys.version_info[0] >= 3 and sys.version_info[1] >= 4: + # Python 3.4+ requres that args are an ast.arg object, rather + # than an ast.Name or bare string. + args = [ast.arg(arg=ast_str(x), + annotation=None, ### Fix me! + lineno=x.start_line, + col_offset=x.start_column) for x in args] + + # XXX: Beware. Beware. This wasn't put into the parse lambda + # list because it's really just an internal parsing thing. + + if kwargs: + kwargs = ast.arg(arg=kwargs, annotation=None) + + if stararg: + stararg = ast.arg(arg=stararg, annotation=None) + + # Let's find a better home for these guys. + else: + args = [ast.Name(arg=ast_str(x), id=ast_str(x), + ctx=ast.Param(), + lineno=x.start_line, + col_offset=x.start_column) for x in args] + args = ast.arguments( - args=[ast.Name(arg=ast_str(x), id=ast_str(x), - ctx=ast.Param(), - lineno=x.start_line, - col_offset=x.start_column) - for x in args], + args=args, vararg=stararg, kwarg=kwargs, kwonlyargs=[], From 1d58e5258452e6dd5f60799cf6f1ed017bbd7dab Mon Sep 17 00:00:00 2001 From: Paul Tagliamonte Date: Wed, 1 Jan 2014 19:12:17 -0500 Subject: [PATCH 3/6] Flake8 style fix. --- hy/compiler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hy/compiler.py b/hy/compiler.py index fd45eb1..0a7071c 100644 --- a/hy/compiler.py +++ b/hy/compiler.py @@ -1703,7 +1703,7 @@ class HyASTCompiler(object): # Python 3.4+ requres that args are an ast.arg object, rather # than an ast.Name or bare string. args = [ast.arg(arg=ast_str(x), - annotation=None, ### Fix me! + annotation=None, # Fix me! lineno=x.start_line, col_offset=x.start_column) for x in args] From f452558f5e7b795887130891ea0c9fe6fa7022cb Mon Sep 17 00:00:00 2001 From: Nicolas Dandrimont Date: Thu, 2 Jan 2014 04:10:31 +0100 Subject: [PATCH 4/6] Force output encoding of hy2py as utf-8 Fixes hy2py in py34 --- bin/hy2py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bin/hy2py b/bin/hy2py index 125fd26..85186b7 100755 --- a/bin/hy2py +++ b/bin/hy2py @@ -11,15 +11,15 @@ import ast module_name = "" hst = import_file_to_hst(sys.argv[1]) -print(hst) +print(str(hst).encode("utf-8")) print("") print("") _ast = import_file_to_ast(sys.argv[1], module_name) print("") print("") -print(ast.dump(_ast)) +print(ast.dump(_ast).encode("utf-8")) print("") print("") -print(astor.codegen.to_source(_ast)) +print(astor.codegen.to_source(_ast).encode("utf-8")) import_file_to_module(module_name, sys.argv[1]) From 590d3bf1df4bf5ef8d8297dc7a189b4a9f08e747 Mon Sep 17 00:00:00 2001 From: Paul Tagliamonte Date: Wed, 1 Jan 2014 22:30:09 -0500 Subject: [PATCH 5/6] Clean up compare to use the tuple. Thanks @olasd --- hy/_compat.py | 2 +- hy/compiler.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/hy/_compat.py b/hy/_compat.py index 65aa29b..e25f9cd 100644 --- a/hy/_compat.py +++ b/hy/_compat.py @@ -39,7 +39,7 @@ except ImportError: import sys PY3 = sys.version_info[0] >= 3 -PY33 = sys.version_info[0] >= 3 and sys.version_info[1] >= 3 +PY33 = sys.version_info >= (3, 3) if PY3: str_type = str diff --git a/hy/compiler.py b/hy/compiler.py index 0a7071c..dbb3ee5 100644 --- a/hy/compiler.py +++ b/hy/compiler.py @@ -754,7 +754,7 @@ class HyASTCompiler(object): ret = handler_results - if sys.version_info[0] >= 3 and sys.version_info[1] >= 3: + if sys.version_info >= (3, 3): # Python 3.3 features a merge of TryExcept+TryFinally into Try. return ret + ast.Try( lineno=expr.start_line, @@ -1199,7 +1199,7 @@ class HyASTCompiler(object): optional_vars=thing, body=body.stmts) - if sys.version_info[0] >= 3 and sys.version_info[1] >= 3: + if sys.version_info >= (3, 3): the_with.items = [ast.withitem(context_expr=ctx.force_expr, optional_vars=thing)] @@ -1699,7 +1699,7 @@ class HyASTCompiler(object): arglist = expression.pop(0) ret, args, defaults, stararg, kwargs = self._parse_lambda_list(arglist) - if sys.version_info[0] >= 3 and sys.version_info[1] >= 4: + if sys.version_info >= (3, 4): # Python 3.4+ requres that args are an ast.arg object, rather # than an ast.Name or bare string. args = [ast.arg(arg=ast_str(x), From de31aea5d2d7ffd22ce82ffc609c8cbdccbd4d01 Mon Sep 17 00:00:00 2001 From: Paul Tagliamonte Date: Fri, 3 Jan 2014 20:02:36 -0500 Subject: [PATCH 6/6] Cleanup use of PY3* in the compiler. --- hy/_compat.py | 1 + hy/compiler.py | 12 ++++++------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/hy/_compat.py b/hy/_compat.py index e25f9cd..37bb023 100644 --- a/hy/_compat.py +++ b/hy/_compat.py @@ -40,6 +40,7 @@ import sys PY3 = sys.version_info[0] >= 3 PY33 = sys.version_info >= (3, 3) +PY34 = sys.version_info >= (3, 4) if PY3: str_type = str diff --git a/hy/compiler.py b/hy/compiler.py index dbb3ee5..d788c8a 100644 --- a/hy/compiler.py +++ b/hy/compiler.py @@ -39,7 +39,7 @@ from hy.errors import HyCompileError, HyTypeError import hy.macros from hy.macros import require, macroexpand -from hy._compat import str_type, long_type +from hy._compat import str_type, long_type, PY33, PY3, PY34 import hy.importer import traceback @@ -77,7 +77,7 @@ _compile_table = {} def ast_str(foobar): - if sys.version_info[0] >= 3: + if PY3: return str(foobar) try: @@ -754,7 +754,7 @@ class HyASTCompiler(object): ret = handler_results - if sys.version_info >= (3, 3): + if PY33: # Python 3.3 features a merge of TryExcept+TryFinally into Try. return ret + ast.Try( lineno=expr.start_line, @@ -831,7 +831,7 @@ class HyASTCompiler(object): exceptions, "Exception storage target name must be a symbol.") - if sys.version_info[0] >= 3: + if PY3: # Python3 features a change where the Exception handler # moved the name from a Name() to a pure Python String type. # @@ -1199,7 +1199,7 @@ class HyASTCompiler(object): optional_vars=thing, body=body.stmts) - if sys.version_info >= (3, 3): + if PY33: the_with.items = [ast.withitem(context_expr=ctx.force_expr, optional_vars=thing)] @@ -1699,7 +1699,7 @@ class HyASTCompiler(object): arglist = expression.pop(0) ret, args, defaults, stararg, kwargs = self._parse_lambda_list(arglist) - if sys.version_info >= (3, 4): + if PY34: # Python 3.4+ requres that args are an ast.arg object, rather # than an ast.Name or bare string. args = [ast.arg(arg=ast_str(x),