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

Merge branch '_METH_FASTCALL_py37'

parents 863b50c3 baac4846
......@@ -196,17 +196,22 @@
#define Py_TPFLAGS_HAVE_FINALIZE 0
#endif
#ifndef METH_FASTCALL
// new in CPython 3.6
#define METH_FASTCALL 0x80
typedef PyObject *(*__Pyx_PyCFunctionFast) (PyObject *self, PyObject **args,
Py_ssize_t nargs, PyObject *kwnames);
#if PY_VERSION_HEX < 0x030700A0 || !defined(METH_FASTCALL)
// new in CPython 3.6, but changed in 3.7
#ifndef METH_FASTCALL
#define METH_FASTCALL 0x80
#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);
#else
#define __Pyx_PyCFunctionFast _PyCFunctionFast
#define __Pyx_PyCFunctionFastWithKeywords _PyCFunctionFastWithKeywords
#endif
#if CYTHON_FAST_PYCCALL
#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
#define __Pyx_PyFastCFunction_Check(func) 0
#endif
......
......@@ -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_VARARGS | METH_KEYWORDS)) ? ((*(PyCFunctionWithKeywords)(cfunc)->func)(self, $empty_tuple, NULL)) : \
((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) : \
__Pyx__CallUnboundCMethod0(cfunc, self))))) : \
(PY_VERSION_HEX >= 0x030600B1 && (cfunc)->flag == METH_FASTCALL ? \
(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))
#else
#define __Pyx_CallUnboundCMethod0(cfunc, self) __Pyx__CallUnboundCMethod0(cfunc, self)
......@@ -1642,9 +1647,10 @@ static CYTHON_INLINE PyObject * __Pyx_PyCFunction_FastCall(PyObject *func_obj, P
PyCFunctionObject *func = (PyCFunctionObject*)func_obj;
PyCFunction meth = PyCFunction_GET_FUNCTION(func);
PyObject *self = PyCFunction_GET_SELF(func);
int flags = PyCFunction_GET_FLAGS(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 || args != NULL);
......@@ -1653,7 +1659,11 @@ static CYTHON_INLINE PyObject * __Pyx_PyCFunction_FastCall(PyObject *func_obj, P
caller loses its exception */
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 */
......
......@@ -349,6 +349,7 @@ VER_DEP_MODULES = {
(3,4): (operator.lt, lambda x: x in ['run.py34_signature',
]),
(3,5): (operator.lt, lambda x: x in ['run.py35_pep492_interop',
'run.fastcall', # uses new deque features
]),
}
......
cimport cython
def generator():
yield 2
yield 1
yield 3
def returns_set():
return {"foo", "bar", "baz"}
def returns_tuple():
return (1, 2, 3, 0)
@cython.test_fail_if_path_exists("//SimpleCallNode")
def sorted_arg(x):
"""
......@@ -31,6 +35,26 @@ def sorted_arg(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",
"//NoneCheckNode")
@cython.test_assert_path_exists("//InlinedGeneratorExpressionNode")
......@@ -41,6 +65,7 @@ def sorted_genexp():
"""
return sorted(i*i for i in range(10,0,-1))
@cython.test_fail_if_path_exists("//SimpleCallNode//SimpleCallNode")
@cython.test_assert_path_exists("//SimpleCallNode/NameNode[@name = 'range']")
def sorted_list_of_range():
......@@ -50,6 +75,7 @@ def sorted_list_of_range():
"""
return sorted(list(range(10,0,-1)))
@cython.test_fail_if_path_exists("//SimpleCallNode")
def sorted_list_literal():
"""
......@@ -58,6 +84,7 @@ def sorted_list_literal():
"""
return sorted([3, 1, 2] * 2)
@cython.test_fail_if_path_exists("//SimpleCallNode")
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