Commit 918729c3 authored by Stefan Behnel's avatar Stefan Behnel

Merge branch '_METH_FASTCALL_py37'

parents 863b50c3 baac4846
...@@ -196,17 +196,22 @@ ...@@ -196,17 +196,22 @@
#define Py_TPFLAGS_HAVE_FINALIZE 0 #define Py_TPFLAGS_HAVE_FINALIZE 0
#endif #endif
#ifndef METH_FASTCALL #if PY_VERSION_HEX < 0x030700A0 || !defined(METH_FASTCALL)
// new in CPython 3.6 // new in CPython 3.6, but changed in 3.7
#ifndef METH_FASTCALL
#define METH_FASTCALL 0x80 #define METH_FASTCALL 0x80
typedef PyObject *(*__Pyx_PyCFunctionFast) (PyObject *self, PyObject **args, #endif
typedef PyObject *(*__Pyx_PyCFunctionFast) (PyObject *self, PyObject **args, Py_ssize_t nargs);
// new in CPython 3.7, used to be old signature of _PyCFunctionFast() in 3.6
typedef PyObject *(*__Pyx_PyCFunctionFastWithKeywords) (PyObject *self, PyObject **args,
Py_ssize_t nargs, PyObject *kwnames); Py_ssize_t nargs, PyObject *kwnames);
#else #else
#define __Pyx_PyCFunctionFast _PyCFunctionFast #define __Pyx_PyCFunctionFast _PyCFunctionFast
#define __Pyx_PyCFunctionFastWithKeywords _PyCFunctionFastWithKeywords
#endif #endif
#if CYTHON_FAST_PYCCALL #if CYTHON_FAST_PYCCALL
#define __Pyx_PyFastCFunction_Check(func) \ #define __Pyx_PyFastCFunction_Check(func) \
((PyCFunction_Check(func) && (METH_FASTCALL == (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST))))) ((PyCFunction_Check(func) && (METH_FASTCALL == (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_KEYWORDS)))))
#else #else
#define __Pyx_PyFastCFunction_Check(func) 0 #define __Pyx_PyFastCFunction_Check(func) 0
#endif #endif
......
...@@ -1146,8 +1146,13 @@ static PyObject* __Pyx__CallUnboundCMethod0(__Pyx_CachedCFunction* cfunc, PyObje ...@@ -1146,8 +1146,13 @@ static PyObject* __Pyx__CallUnboundCMethod0(__Pyx_CachedCFunction* cfunc, PyObje
(likely((cfunc)->flag == METH_NOARGS) ? (*((cfunc)->func))(self, NULL) : \ (likely((cfunc)->flag == METH_NOARGS) ? (*((cfunc)->func))(self, NULL) : \
(likely((cfunc)->flag == (METH_VARARGS | METH_KEYWORDS)) ? ((*(PyCFunctionWithKeywords)(cfunc)->func)(self, $empty_tuple, NULL)) : \ (likely((cfunc)->flag == (METH_VARARGS | METH_KEYWORDS)) ? ((*(PyCFunctionWithKeywords)(cfunc)->func)(self, $empty_tuple, NULL)) : \
((cfunc)->flag == METH_VARARGS ? (*((cfunc)->func))(self, $empty_tuple) : \ ((cfunc)->flag == METH_VARARGS ? (*((cfunc)->func))(self, $empty_tuple) : \
(PY_VERSION_HEX >= 0x030600B1 && (cfunc)->flag == METH_FASTCALL ? (*(__Pyx_PyCFunctionFast)(cfunc)->func)(self, &PyTuple_GET_ITEM($empty_tuple, 0), 0, NULL) : \ (PY_VERSION_HEX >= 0x030600B1 && (cfunc)->flag == METH_FASTCALL ? \
__Pyx__CallUnboundCMethod0(cfunc, self))))) : \ (PY_VERSION_HEX >= 0x030700A0 ? \
(*(__Pyx_PyCFunctionFast)(cfunc)->func)(self, &PyTuple_GET_ITEM($empty_tuple, 0), 0) : \
(*(__Pyx_PyCFunctionFastWithKeywords)(cfunc)->func)(self, &PyTuple_GET_ITEM($empty_tuple, 0), 0, NULL)) : \
(PY_VERSION_HEX >= 0x030700A0 && (cfunc)->flag == (METH_FASTCALL | METH_KEYWORDS) ? \
(*(__Pyx_PyCFunctionFastWithKeywords)(cfunc)->func)(self, &PyTuple_GET_ITEM($empty_tuple, 0), 0, NULL) : \
__Pyx__CallUnboundCMethod0(cfunc, self)))))) : \
__Pyx__CallUnboundCMethod0(cfunc, self)) __Pyx__CallUnboundCMethod0(cfunc, self))
#else #else
#define __Pyx_CallUnboundCMethod0(cfunc, self) __Pyx__CallUnboundCMethod0(cfunc, self) #define __Pyx_CallUnboundCMethod0(cfunc, self) __Pyx__CallUnboundCMethod0(cfunc, self)
...@@ -1642,9 +1647,10 @@ static CYTHON_INLINE PyObject * __Pyx_PyCFunction_FastCall(PyObject *func_obj, P ...@@ -1642,9 +1647,10 @@ static CYTHON_INLINE PyObject * __Pyx_PyCFunction_FastCall(PyObject *func_obj, P
PyCFunctionObject *func = (PyCFunctionObject*)func_obj; PyCFunctionObject *func = (PyCFunctionObject*)func_obj;
PyCFunction meth = PyCFunction_GET_FUNCTION(func); PyCFunction meth = PyCFunction_GET_FUNCTION(func);
PyObject *self = PyCFunction_GET_SELF(func); PyObject *self = PyCFunction_GET_SELF(func);
int flags = PyCFunction_GET_FLAGS(func);
assert(PyCFunction_Check(func)); assert(PyCFunction_Check(func));
assert(METH_FASTCALL == (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST))); assert(METH_FASTCALL == (flags & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_KEYWORDS)));
assert(nargs >= 0); assert(nargs >= 0);
assert(nargs == 0 || args != NULL); assert(nargs == 0 || args != NULL);
...@@ -1653,7 +1659,11 @@ static CYTHON_INLINE PyObject * __Pyx_PyCFunction_FastCall(PyObject *func_obj, P ...@@ -1653,7 +1659,11 @@ static CYTHON_INLINE PyObject * __Pyx_PyCFunction_FastCall(PyObject *func_obj, P
caller loses its exception */ caller loses its exception */
assert(!PyErr_Occurred()); assert(!PyErr_Occurred());
return (*((__Pyx_PyCFunctionFast)meth)) (self, args, nargs, NULL); if ((PY_VERSION_HEX < 0x030700A0) || unlikely(flags & METH_KEYWORDS)) {
return (*((__Pyx_PyCFunctionFastWithKeywords)meth)) (self, args, nargs, NULL);
} else {
return (*((__Pyx_PyCFunctionFast)meth)) (self, args, nargs);
}
} }
#endif /* CYTHON_FAST_PYCCALL */ #endif /* CYTHON_FAST_PYCCALL */
......
...@@ -349,6 +349,7 @@ VER_DEP_MODULES = { ...@@ -349,6 +349,7 @@ VER_DEP_MODULES = {
(3,4): (operator.lt, lambda x: x in ['run.py34_signature', (3,4): (operator.lt, lambda x: x in ['run.py34_signature',
]), ]),
(3,5): (operator.lt, lambda x: x in ['run.py35_pep492_interop', (3,5): (operator.lt, lambda x: x in ['run.py35_pep492_interop',
'run.fastcall', # uses new deque features
]), ]),
} }
......
cimport cython cimport cython
def generator(): def generator():
yield 2 yield 2
yield 1 yield 1
yield 3 yield 3
def returns_set(): def returns_set():
return {"foo", "bar", "baz"} return {"foo", "bar", "baz"}
def returns_tuple(): def returns_tuple():
return (1, 2, 3, 0) return (1, 2, 3, 0)
@cython.test_fail_if_path_exists("//SimpleCallNode") @cython.test_fail_if_path_exists("//SimpleCallNode")
def sorted_arg(x): def sorted_arg(x):
""" """
...@@ -31,6 +35,26 @@ def sorted_arg(x): ...@@ -31,6 +35,26 @@ def sorted_arg(x):
""" """
return sorted(x) return sorted(x)
@cython.test_assert_path_exists("//GeneralCallNode")
def sorted_arg_with_key(x):
"""
>>> a = [3, 2, 1]
>>> sorted_arg_with_key(a)
[3, 2, 1]
>>> a
[3, 2, 1]
>>> sorted_arg_with_key(generator())
[3, 2, 1]
>>> sorted_arg_with_key(returns_tuple())
[3, 2, 1, 0]
>>> sorted_arg_with_key(object())
Traceback (most recent call last):
TypeError: 'object' object is not iterable
"""
return sorted(x, key=lambda x: -x)
@cython.test_fail_if_path_exists("//YieldExprNode", @cython.test_fail_if_path_exists("//YieldExprNode",
"//NoneCheckNode") "//NoneCheckNode")
@cython.test_assert_path_exists("//InlinedGeneratorExpressionNode") @cython.test_assert_path_exists("//InlinedGeneratorExpressionNode")
...@@ -41,6 +65,7 @@ def sorted_genexp(): ...@@ -41,6 +65,7 @@ def sorted_genexp():
""" """
return sorted(i*i for i in range(10,0,-1)) return sorted(i*i for i in range(10,0,-1))
@cython.test_fail_if_path_exists("//SimpleCallNode//SimpleCallNode") @cython.test_fail_if_path_exists("//SimpleCallNode//SimpleCallNode")
@cython.test_assert_path_exists("//SimpleCallNode/NameNode[@name = 'range']") @cython.test_assert_path_exists("//SimpleCallNode/NameNode[@name = 'range']")
def sorted_list_of_range(): def sorted_list_of_range():
...@@ -50,6 +75,7 @@ def sorted_list_of_range(): ...@@ -50,6 +75,7 @@ def sorted_list_of_range():
""" """
return sorted(list(range(10,0,-1))) return sorted(list(range(10,0,-1)))
@cython.test_fail_if_path_exists("//SimpleCallNode") @cython.test_fail_if_path_exists("//SimpleCallNode")
def sorted_list_literal(): def sorted_list_literal():
""" """
...@@ -58,6 +84,7 @@ def sorted_list_literal(): ...@@ -58,6 +84,7 @@ def sorted_list_literal():
""" """
return sorted([3, 1, 2] * 2) return sorted([3, 1, 2] * 2)
@cython.test_fail_if_path_exists("//SimpleCallNode") @cython.test_fail_if_path_exists("//SimpleCallNode")
def sorted_tuple_literal(): def sorted_tuple_literal():
""" """
......
# mode: run
# tag: METH_FASTCALL
from collections import deque
def deque_methods(v):
"""
>>> deque_methods(2)
[1, 2, 3, 4]
"""
d = deque([1, 3, 4])
assert list(d) == [1,3,4]
d.insert(1, v)
assert list(d) == [1,2,3,4]
d.rotate(len(d) // 2)
assert list(d) == [3,4,1,2]
d.rotate(len(d) // 2)
assert list(d) == [1,2,3,4]
return list(d)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment