Merge pull request #1759 from Kodiologist/no-py34
Drop support for Python 3.4
This commit is contained in:
commit
808f81f7e8
@ -2,7 +2,6 @@ sudo: false
|
||||
language: python
|
||||
python:
|
||||
- "2.7"
|
||||
- "3.4"
|
||||
- "3.5"
|
||||
- "3.6"
|
||||
- pypy
|
||||
|
4
NEWS.rst
4
NEWS.rst
@ -3,6 +3,10 @@
|
||||
Unreleased
|
||||
==============================
|
||||
|
||||
Removals
|
||||
------------------------------
|
||||
* Python 3.4 is no longer supported.
|
||||
|
||||
New Features
|
||||
------------------------------
|
||||
* Format strings with embedded Hy code (e.g., `f"The sum is {(+ x y)}"`)
|
||||
|
@ -4,7 +4,7 @@ import importlib
|
||||
import py
|
||||
import pytest
|
||||
import hy
|
||||
from hy._compat import PY3, PY35, PY36
|
||||
from hy._compat import PY3, PY36
|
||||
|
||||
NATIVE_TESTS = os.path.join("", "tests", "native_tests", "")
|
||||
|
||||
@ -13,7 +13,6 @@ _fspath_pyimport = py.path.local.pyimport
|
||||
|
||||
def pytest_ignore_collect(path, config):
|
||||
return (("py3_only" in path.basename and not PY3) or
|
||||
("py35_only" in path.basename and not PY35) or
|
||||
("py36_only" in path.basename and not PY36) or None)
|
||||
|
||||
|
||||
|
@ -1678,20 +1678,14 @@ object (respectively) to provide positional or keywords arguments
|
||||
=> (f #* [1 2] #** {"c" 3 "d" 4})
|
||||
[1, 2, 3, 4]
|
||||
|
||||
With Python 3, you can unpack in an assignment list (:pep:`3132`).
|
||||
With Python 3, unpacking is allowed in more contexts, and you can unpack
|
||||
more than once in one expression (:pep:`3132`, :pep:`448`).
|
||||
|
||||
.. code-block:: clj
|
||||
|
||||
=> (setv [a #* b c] [1 2 3 4 5])
|
||||
=> [a b c]
|
||||
[1, [2, 3, 4], 5]
|
||||
|
||||
With Python 3.5 or greater, unpacking is allowed in more contexts than just
|
||||
function calls, and you can unpack more than once in the same expression
|
||||
(:pep:`448`).
|
||||
|
||||
.. code-block:: clj
|
||||
|
||||
=> [#* [1 2] #* [3 4]]
|
||||
[1, 2, 3, 4]
|
||||
=> {#** {1 2} #** {3 4}}
|
||||
|
@ -9,7 +9,6 @@ except ImportError:
|
||||
import sys, keyword, textwrap
|
||||
|
||||
PY3 = sys.version_info[0] >= 3
|
||||
PY35 = sys.version_info >= (3, 5)
|
||||
PY36 = sys.version_info >= (3, 6)
|
||||
PY37 = sys.version_info >= (3, 7)
|
||||
|
||||
|
@ -15,7 +15,7 @@ from hy.errors import (HyCompileError, HyTypeError, HyLanguageError,
|
||||
from hy.lex import mangle, unmangle, hy_parse, parse_one_thing, LexException
|
||||
|
||||
from hy._compat import (string_types, str_type, bytes_type, long_type, PY3,
|
||||
PY35, PY36, reraise)
|
||||
PY36, reraise)
|
||||
from hy.macros import require, load_macros, macroexpand, tag_macroexpand
|
||||
|
||||
import hy.core
|
||||
@ -106,7 +106,7 @@ def ast_str(x, piecewise=False):
|
||||
_special_form_compilers = {}
|
||||
_model_compilers = {}
|
||||
_decoratables = (ast.FunctionDef, ast.ClassDef)
|
||||
if PY35:
|
||||
if PY3:
|
||||
_decoratables += (ast.AsyncFunctionDef,)
|
||||
# _bad_roots are fake special operators, which are used internally
|
||||
# by other special forms (e.g., `except` in `try`) but can't be
|
||||
@ -279,7 +279,7 @@ class Result(object):
|
||||
var.arg = new_name
|
||||
elif isinstance(var, ast.FunctionDef):
|
||||
var.name = new_name
|
||||
elif PY35 and isinstance(var, ast.AsyncFunctionDef):
|
||||
elif PY3 and isinstance(var, ast.AsyncFunctionDef):
|
||||
var.name = new_name
|
||||
else:
|
||||
raise TypeError("Don't know how to rename a %s!" % (
|
||||
@ -475,7 +475,7 @@ class HyASTCompiler(object):
|
||||
exprs_iter = iter(exprs)
|
||||
for expr in exprs_iter:
|
||||
|
||||
if not PY35 and oldpy_unpack and is_unpack("iterable", expr):
|
||||
if not PY3 and oldpy_unpack and is_unpack("iterable", expr):
|
||||
if oldpy_starargs:
|
||||
raise self._syntax_error(expr,
|
||||
"Pythons < 3.5 allow only one `unpack-iterable` per call")
|
||||
@ -485,7 +485,7 @@ class HyASTCompiler(object):
|
||||
|
||||
elif is_unpack("mapping", expr):
|
||||
ret += self.compile(expr[1])
|
||||
if PY35:
|
||||
if PY3:
|
||||
if dict_display:
|
||||
compiled_exprs.append(None)
|
||||
compiled_exprs.append(ret.force_expr)
|
||||
@ -912,7 +912,7 @@ class HyASTCompiler(object):
|
||||
ret += self.compile(arg)
|
||||
return ret + asty.Yield(expr, value=ret.force_expr)
|
||||
|
||||
@special([(PY3, "yield-from"), (PY35, "await")], [FORM])
|
||||
@special([(PY3, "yield-from"), (PY3, "await")], [FORM])
|
||||
def compile_yield_from_or_await_expression(self, expr, root, arg):
|
||||
ret = Result() + self.compile(arg)
|
||||
node = asty.YieldFrom if root == "yield-from" else asty.Await
|
||||
@ -991,7 +991,7 @@ class HyASTCompiler(object):
|
||||
fn.stmts[-1].decorator_list = decs + fn.stmts[-1].decorator_list
|
||||
return ret + fn
|
||||
|
||||
@special(["with*", (PY35, "with/a*")],
|
||||
@special(["with*", (PY3, "with/a*")],
|
||||
[brackets(FORM, maybe(FORM)), many(FORM)])
|
||||
def compile_with_expression(self, expr, root, args, body):
|
||||
thing, ctx = (None, args[0]) if args[1] is None else args
|
||||
@ -1348,11 +1348,11 @@ class HyASTCompiler(object):
|
||||
"|": ast.BitOr,
|
||||
"^": ast.BitXor,
|
||||
"&": ast.BitAnd}
|
||||
if PY35:
|
||||
if PY3:
|
||||
m_ops["@"] = ast.MatMult
|
||||
|
||||
@special(["+", "*", "|"], [many(FORM)])
|
||||
@special(["-", "/", "&", (PY35, "@")], [oneplus(FORM)])
|
||||
@special(["-", "/", "&", (PY3, "@")], [oneplus(FORM)])
|
||||
@special(["**", "//", "<<", ">>"], [times(2, Inf, FORM)])
|
||||
@special(["%", "^"], [times(2, 2, FORM)])
|
||||
def compile_maths_expression(self, expr, root, args):
|
||||
@ -1478,7 +1478,7 @@ class HyASTCompiler(object):
|
||||
|
||||
NASYM = some(lambda x: isinstance(x, HySymbol) and x not in (
|
||||
"&optional", "&rest", "&kwonly", "&kwargs"))
|
||||
@special(["fn", "fn*", (PY35, "fn/a")], [
|
||||
@special(["fn", "fn*", (PY3, "fn/a")], [
|
||||
# The starred version is for internal use (particularly, in the
|
||||
# definition of `defn`). It ensures that a FunctionDef is
|
||||
# produced rather than a Lambda.
|
||||
|
@ -5,7 +5,7 @@
|
||||
;;;; Hy shadow functions
|
||||
|
||||
(import operator)
|
||||
(import [hy._compat [PY3 PY35]])
|
||||
(import [hy._compat [PY3]])
|
||||
|
||||
(require [hy.core.bootstrap [*]])
|
||||
|
||||
@ -60,7 +60,7 @@
|
||||
"Shadowed `%` operator takes `x` modulo `y`."
|
||||
(% x y))
|
||||
|
||||
(if PY35
|
||||
(if PY3
|
||||
(defn @ [a1 &rest a-rest]
|
||||
"Shadowed `@` operator matrix multiples `a1` by each `a-rest`."
|
||||
(reduce operator.matmul a-rest a1)))
|
||||
@ -173,5 +173,5 @@
|
||||
'and 'or 'not
|
||||
'is 'is-not 'in 'not-in
|
||||
'get])
|
||||
(if (not PY35)
|
||||
(if (not PY3)
|
||||
(.remove EXPORTS '@))
|
||||
|
1
setup.py
1
setup.py
@ -79,7 +79,6 @@ setup(
|
||||
"Programming Language :: Python :: 2",
|
||||
"Programming Language :: Python :: 2.7",
|
||||
"Programming Language :: Python :: 3",
|
||||
"Programming Language :: Python :: 3.4",
|
||||
"Programming Language :: Python :: 3.5",
|
||||
"Programming Language :: Python :: 3.6",
|
||||
"Programming Language :: Python :: 3.7",
|
||||
|
@ -11,7 +11,7 @@
|
||||
pytest)
|
||||
(import sys)
|
||||
|
||||
(import [hy._compat [PY3 PY35 PY37]])
|
||||
(import [hy._compat [PY3 PY37]])
|
||||
|
||||
(defn test-sys-argv []
|
||||
"NATIVE: test sys.argv"
|
||||
@ -1550,7 +1550,7 @@ cee\"} dee" "ey bee\ncee dee"))
|
||||
(defn test-disassemble []
|
||||
"NATIVE: Test the disassemble function"
|
||||
(assert (= (disassemble '(do (leaky) (leaky) (macros))) (cond
|
||||
[PY35 "Module(
|
||||
[PY3 "Module(
|
||||
body=[Expr(value=Call(func=Name(id='leaky'), args=[], keywords=[])),
|
||||
Expr(value=Call(func=Name(id='leaky'), args=[], keywords=[])),
|
||||
Expr(value=Call(func=Name(id='macros'), args=[], keywords=[]))])"]
|
||||
|
@ -2,7 +2,7 @@
|
||||
;; This file is part of Hy, which is free software licensed under the Expat
|
||||
;; license. See the LICENSE.
|
||||
|
||||
(import [hy._compat [PY35]])
|
||||
(import [hy._compat [PY3]])
|
||||
|
||||
(setv square (fn [x]
|
||||
(* x x)))
|
||||
@ -191,7 +191,7 @@
|
||||
|
||||
(defn test-matmul []
|
||||
"NATIVE: test matrix multiplication"
|
||||
(if PY35
|
||||
(if PY3
|
||||
(assert (= (@ first-test-matrix second-test-matrix)
|
||||
product-of-test-matrices))
|
||||
;; Python <= 3.4
|
||||
@ -205,6 +205,6 @@
|
||||
(setv matrix first-test-matrix
|
||||
matmul-attempt (try (@= matrix second-test-matrix)
|
||||
(except [e [Exception]] e)))
|
||||
(if PY35
|
||||
(if PY3
|
||||
(assert (= product-of-test-matrices matrix))
|
||||
(assert (isinstance matmul-attempt NameError))))
|
||||
|
@ -2,7 +2,7 @@
|
||||
;; This file is part of Hy, which is free software licensed under the Expat
|
||||
;; license. See the LICENSE.
|
||||
|
||||
(import pytest [hy._compat [PY35]])
|
||||
(import pytest [hy._compat [PY3]])
|
||||
|
||||
(defmacro op-and-shadow-test [op &rest body]
|
||||
; Creates two tests with the given `body`, one where all occurrences
|
||||
@ -102,7 +102,7 @@
|
||||
(forbid (f 1 2 3)))
|
||||
|
||||
|
||||
(when PY35 (op-and-shadow-test @
|
||||
(when PY3 (op-and-shadow-test @
|
||||
(defclass C [object] [
|
||||
__init__ (fn [self content] (setv self.content content))
|
||||
__matmul__ (fn [self other] (C (+ self.content other.content)))])
|
||||
|
@ -1,103 +0,0 @@
|
||||
;; Copyright 2019 the authors.
|
||||
;; This file is part of Hy, which is free software licensed under the Expat
|
||||
;; license. See the LICENSE.
|
||||
|
||||
;; Tests where the emitted code relies on Python ≥3.5.
|
||||
;; conftest.py skips this file when running on Python <3.5.
|
||||
|
||||
(import [asyncio [get-event-loop sleep]])
|
||||
|
||||
|
||||
(defn test-unpacking-pep448-1star []
|
||||
(setv l [1 2 3])
|
||||
(setv p [4 5])
|
||||
(assert (= ["a" #*l "b" #*p #*l] ["a" 1 2 3 "b" 4 5 1 2 3]))
|
||||
(assert (= (, "a" #*l "b" #*p #*l) (, "a" 1 2 3 "b" 4 5 1 2 3)))
|
||||
(assert (= #{"a" #*l "b" #*p #*l} #{"a" "b" 1 2 3 4 5}))
|
||||
(defn f [&rest args] args)
|
||||
(assert (= (f "a" #*l "b" #*p #*l) (, "a" 1 2 3 "b" 4 5 1 2 3)))
|
||||
(assert (= (+ #*l #*p) 15))
|
||||
(assert (= (and #*l) 3)))
|
||||
|
||||
|
||||
(defn test-unpacking-pep448-2star []
|
||||
(setv d1 {"a" 1 "b" 2})
|
||||
(setv d2 {"c" 3 "d" 4})
|
||||
(assert (= {1 "x" #**d1 #**d2 2 "y"} {"a" 1 "b" 2 "c" 3 "d" 4 1 "x" 2 "y"}))
|
||||
(defn fun [&optional a b c d e f] [a b c d e f])
|
||||
(assert (= (fun #**d1 :e "eee" #**d2) [1 2 3 4 "eee" None])))
|
||||
|
||||
|
||||
(defn run-coroutine [coro]
|
||||
"Run a coroutine until its done in the default event loop."""
|
||||
(.run_until_complete (get-event-loop) (coro)))
|
||||
|
||||
|
||||
(defn test-fn/a []
|
||||
(assert (= (run-coroutine (fn/a [] (await (sleep 0)) [1 2 3]))
|
||||
[1 2 3])))
|
||||
|
||||
|
||||
(defn test-defn/a []
|
||||
(defn/a coro-test []
|
||||
(await (sleep 0))
|
||||
[1 2 3])
|
||||
(assert (= (run-coroutine coro-test) [1 2 3])))
|
||||
|
||||
|
||||
(defn test-decorated-defn/a []
|
||||
(defn decorator [func] (fn/a [] (/ (await (func)) 2)))
|
||||
|
||||
#@(decorator
|
||||
(defn/a coro-test []
|
||||
(await (sleep 0))
|
||||
42))
|
||||
(assert (= (run-coroutine coro-test) 21)))
|
||||
|
||||
|
||||
(defclass AsyncWithTest []
|
||||
(defn --init-- [self val]
|
||||
(setv self.val val)
|
||||
None)
|
||||
|
||||
(defn/a --aenter-- [self]
|
||||
self.val)
|
||||
|
||||
(defn/a --aexit-- [self tyle value traceback]
|
||||
(setv self.val None)))
|
||||
|
||||
|
||||
(defn test-single-with/a []
|
||||
(run-coroutine
|
||||
(fn/a []
|
||||
(with/a [t (AsyncWithTest 1)]
|
||||
(assert (= t 1))))))
|
||||
|
||||
(defn test-two-with/a []
|
||||
(run-coroutine
|
||||
(fn/a []
|
||||
(with/a [t1 (AsyncWithTest 1)
|
||||
t2 (AsyncWithTest 2)]
|
||||
(assert (= t1 1))
|
||||
(assert (= t2 2))))))
|
||||
|
||||
(defn test-thrice-with/a []
|
||||
(run-coroutine
|
||||
(fn/a []
|
||||
(with/a [t1 (AsyncWithTest 1)
|
||||
t2 (AsyncWithTest 2)
|
||||
t3 (AsyncWithTest 3)]
|
||||
(assert (= t1 1))
|
||||
(assert (= t2 2))
|
||||
(assert (= t3 3))))))
|
||||
|
||||
(defn test-quince-with/a []
|
||||
(run-coroutine
|
||||
(fn/a []
|
||||
(with/a [t1 (AsyncWithTest 1)
|
||||
t2 (AsyncWithTest 2)
|
||||
t3 (AsyncWithTest 3)
|
||||
_ (AsyncWithTest 4)]
|
||||
(assert (= t1 1))
|
||||
(assert (= t2 2))
|
||||
(assert (= t3 3))))))
|
@ -107,3 +107,101 @@
|
||||
|
||||
(assert (= (. (MyClass) member-names)
|
||||
["__module__" "__qualname__" "method1" "method2"])))
|
||||
|
||||
|
||||
(import [asyncio [get-event-loop sleep]])
|
||||
|
||||
|
||||
(defn test-unpacking-pep448-1star []
|
||||
(setv l [1 2 3])
|
||||
(setv p [4 5])
|
||||
(assert (= ["a" #*l "b" #*p #*l] ["a" 1 2 3 "b" 4 5 1 2 3]))
|
||||
(assert (= (, "a" #*l "b" #*p #*l) (, "a" 1 2 3 "b" 4 5 1 2 3)))
|
||||
(assert (= #{"a" #*l "b" #*p #*l} #{"a" "b" 1 2 3 4 5}))
|
||||
(defn f [&rest args] args)
|
||||
(assert (= (f "a" #*l "b" #*p #*l) (, "a" 1 2 3 "b" 4 5 1 2 3)))
|
||||
(assert (= (+ #*l #*p) 15))
|
||||
(assert (= (and #*l) 3)))
|
||||
|
||||
|
||||
(defn test-unpacking-pep448-2star []
|
||||
(setv d1 {"a" 1 "b" 2})
|
||||
(setv d2 {"c" 3 "d" 4})
|
||||
(assert (= {1 "x" #**d1 #**d2 2 "y"} {"a" 1 "b" 2 "c" 3 "d" 4 1 "x" 2 "y"}))
|
||||
(defn fun [&optional a b c d e f] [a b c d e f])
|
||||
(assert (= (fun #**d1 :e "eee" #**d2) [1 2 3 4 "eee" None])))
|
||||
|
||||
|
||||
(defn run-coroutine [coro]
|
||||
"Run a coroutine until its done in the default event loop."""
|
||||
(.run_until_complete (get-event-loop) (coro)))
|
||||
|
||||
|
||||
(defn test-fn/a []
|
||||
(assert (= (run-coroutine (fn/a [] (await (sleep 0)) [1 2 3]))
|
||||
[1 2 3])))
|
||||
|
||||
|
||||
(defn test-defn/a []
|
||||
(defn/a coro-test []
|
||||
(await (sleep 0))
|
||||
[1 2 3])
|
||||
(assert (= (run-coroutine coro-test) [1 2 3])))
|
||||
|
||||
|
||||
(defn test-decorated-defn/a []
|
||||
(defn decorator [func] (fn/a [] (/ (await (func)) 2)))
|
||||
|
||||
#@(decorator
|
||||
(defn/a coro-test []
|
||||
(await (sleep 0))
|
||||
42))
|
||||
(assert (= (run-coroutine coro-test) 21)))
|
||||
|
||||
|
||||
(defclass AsyncWithTest []
|
||||
(defn --init-- [self val]
|
||||
(setv self.val val)
|
||||
None)
|
||||
|
||||
(defn/a --aenter-- [self]
|
||||
self.val)
|
||||
|
||||
(defn/a --aexit-- [self tyle value traceback]
|
||||
(setv self.val None)))
|
||||
|
||||
|
||||
(defn test-single-with/a []
|
||||
(run-coroutine
|
||||
(fn/a []
|
||||
(with/a [t (AsyncWithTest 1)]
|
||||
(assert (= t 1))))))
|
||||
|
||||
(defn test-two-with/a []
|
||||
(run-coroutine
|
||||
(fn/a []
|
||||
(with/a [t1 (AsyncWithTest 1)
|
||||
t2 (AsyncWithTest 2)]
|
||||
(assert (= t1 1))
|
||||
(assert (= t2 2))))))
|
||||
|
||||
(defn test-thrice-with/a []
|
||||
(run-coroutine
|
||||
(fn/a []
|
||||
(with/a [t1 (AsyncWithTest 1)
|
||||
t2 (AsyncWithTest 2)
|
||||
t3 (AsyncWithTest 3)]
|
||||
(assert (= t1 1))
|
||||
(assert (= t2 2))
|
||||
(assert (= t3 3))))))
|
||||
|
||||
(defn test-quince-with/a []
|
||||
(run-coroutine
|
||||
(fn/a []
|
||||
(with/a [t1 (AsyncWithTest 1)
|
||||
t2 (AsyncWithTest 2)
|
||||
t3 (AsyncWithTest 3)
|
||||
_ (AsyncWithTest 4)]
|
||||
(assert (= t1 1))
|
||||
(assert (= t2 2))
|
||||
(assert (= t3 3))))))
|
||||
|
Loading…
Reference in New Issue
Block a user