Commit 87e3baf2 authored by scoder's avatar scoder

Merge pull request #110 from scoder/pypy

Better support for PyPy's cpyext C-API
parents da7f51b1 72ef3640
......@@ -1839,7 +1839,7 @@ class NameNode(AtomicExprNode):
namespace = self.entry.scope.namespace_cname
interned_cname = code.intern_identifier(self.entry.name)
code.put_error_if_neg(self.pos,
'PyMapping_DelItem(%s, %s)' % (
'PyObject_DelItem(%s, %s)' % (
namespace,
interned_cname))
elif self.entry.is_pyglobal:
......@@ -4914,17 +4914,17 @@ class SequenceNode(ExprNode):
code.putln("}")
rhs.generate_disposal_code(code)
code.putln("} else")
if rhs.type is tuple_type:
code.putln("if (1) {")
code.globalstate.use_utility_code(tuple_unpacking_error_code)
code.putln("__Pyx_UnpackTupleError(%s, %s); %s" % (
rhs.py_result(), len(self.args), code.error_goto(self.pos)))
code.putln("} else")
code.putln("#endif")
code.putln("{")
if special_unpack and rhs.type is tuple_type:
code.globalstate.use_utility_code(tuple_unpacking_error_code)
code.putln("__Pyx_UnpackTupleError(%s, %s);" % (
rhs.py_result(), len(self.args)))
code.putln(code.error_goto(self.pos))
else:
self.generate_generic_parallel_unpacking_code(
code, rhs, self.unpacked_items, use_loop=long_enough_for_a_loop)
self.generate_generic_parallel_unpacking_code(
code, rhs, self.unpacked_items, use_loop=long_enough_for_a_loop)
code.putln("}")
for value_node in self.coerced_unpacked_items:
......@@ -5102,7 +5102,7 @@ class SequenceNode(ExprNode):
code.putln('#if !CYTHON_COMPILING_IN_CPYTHON')
sublist_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
code.putln('%s = PyList_GetSlice(%s, 0, %s-%d); %s' % (
code.putln('%s = PySequence_GetSlice(%s, 0, %s-%d); %s' % (
sublist_temp, target_list, length_temp, len(unpacked_fixed_items_right),
code.error_goto_if_null(sublist_temp, self.pos)))
code.put_gotref(sublist_temp)
......
......@@ -1910,6 +1910,9 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
# if entry.type.is_pyobject and entry.used:
# code.putln("Py_DECREF(%s); %s = 0;" % (
# code.entry_as_pyobject(entry), entry.cname))
code.putln('#if CYTHON_COMPILING_IN_PYPY')
code.putln('Py_CLEAR(%s);' % Naming.builtins_cname)
code.putln('#endif')
code.putln("Py_INCREF(Py_None); return Py_None;")
def generate_main_method(self, env, code):
......@@ -1968,7 +1971,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln(
"if (!%s) %s;" % (
env.module_cname,
code.error_goto(self.pos)));
code.error_goto(self.pos)))
code.putln("#if PY_MAJOR_VERSION < 3")
code.putln(
"Py_INCREF(%s);" %
......@@ -1980,7 +1983,10 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln(
"if (!%s) %s;" % (
Naming.builtins_cname,
code.error_goto(self.pos)));
code.error_goto(self.pos)))
code.putln('#if CYTHON_COMPILING_IN_PYPY')
code.putln('Py_INCREF(%s);' % Naming.builtins_cname)
code.putln('#endif')
code.putln(
'if (__Pyx_SetAttrString(%s, "__builtins__", %s) < 0) %s;' % (
env.module_cname,
......@@ -1994,7 +2000,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln(
"if (!%s) %s;" % (
Naming.preimport_cname,
code.error_goto(self.pos)));
code.error_goto(self.pos)))
def generate_global_init_code(self, env, code):
# Generate code to initialise global PyObject *
......@@ -2208,6 +2214,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
# a significant performance hit. (See trac #561.)
for func in entry.type.scope.pyfunc_entries:
if func.is_special and Options.docstrings and func.wrapperbase_cname:
code.putln('#if CYTHON_COMPILING_IN_CPYTHON')
code.putln("{")
code.putln(
'PyObject *wrapper = __Pyx_GetAttrString((PyObject *)&%s, "%s"); %s' % (
......@@ -2226,6 +2233,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
func.wrapperbase_cname))
code.putln("}")
code.putln("}")
code.putln('#endif')
if type.vtable_cname:
code.putln(
"if (__Pyx_SetVtable(%s.tp_dict, %s) < 0) %s" % (
......
......@@ -3428,8 +3428,10 @@ class DefNodeWrapper(FuncDefNode):
split_string_literal(escape_byte_string(docstr))))
if entry.is_special:
code.putln('#if CYTHON_COMPILING_IN_CPYTHON')
code.putln(
"struct wrapperbase %s;" % entry.wrapperbase_cname)
code.putln('#endif')
if with_pymethdef or self.target.fused_py_func:
code.put(
......@@ -8376,19 +8378,19 @@ else:
printing_utility_code = UtilityCode(
proto = """
static int __Pyx_Print(PyObject*, PyObject *, int); /*proto*/
#if PY_MAJOR_VERSION >= 3
#if CYTHON_COMPILING_IN_PYPY || PY_MAJOR_VERSION >= 3
static PyObject* %s = 0;
static PyObject* %s = 0;
#endif
""" % (Naming.print_function, Naming.print_function_kwargs),
cleanup = """
#if PY_MAJOR_VERSION >= 3
#if CYTHON_COMPILING_IN_PYPY || PY_MAJOR_VERSION >= 3
Py_CLEAR(%s);
Py_CLEAR(%s);
#endif
""" % (Naming.print_function, Naming.print_function_kwargs),
impl = r"""
#if PY_MAJOR_VERSION < 3
#if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION < 3
static PyObject *__Pyx_GetStdout(void) {
PyObject *f = PySys_GetObject((char *)"stdout");
if (!f) {
......@@ -8498,7 +8500,7 @@ proto = """
static int __Pyx_PrintOne(PyObject* stream, PyObject *o); /*proto*/
""",
impl = r"""
#if PY_MAJOR_VERSION < 3
#if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION < 3
static int __Pyx_PrintOne(PyObject* f, PyObject *o) {
if (!f) {
......
......@@ -367,7 +367,7 @@ class Scope(object):
# name is not None. Reports a warning if already
# declared.
if type.is_buffer and not isinstance(self, LocalScope):
error(pos, ERR_BUF_LOCALONLY)
error(pos, 'Buffer types only allowed as function local variables')
if not self.in_cinclude and cname and re.match("^_[_A-Z]+$", cname):
# See http://www.gnu.org/software/libc/manual/html_node/Reserved-Names.html#Reserved-Names
warning(pos, "'%s' is a reserved name in C." % cname, -1)
......@@ -1635,7 +1635,7 @@ class ClassScope(Scope):
# right thing in this scope (as the class memebers aren't still functions).
# Don't want to add a cfunction to this scope 'cause that would mess with
# the type definition, so we just return the right entry.
self.use_utility_code(classmethod_utility_code)
self.use_utility_code(Code.UtilityCode.load_cached("ClassMethod", "CythonFunction.c"))
entry = Entry(
"classmethod",
"__Pyx_Method_ClassMethod",
......@@ -2093,53 +2093,3 @@ class PropertyScope(Scope):
error(pos, "Only __get__, __set__ and __del__ methods allowed "
"in a property declaration")
return None
# Should this go elsewhere (and then get imported)?
#------------------------------------------------------------------------------------
classmethod_utility_code = Code.UtilityCode(
proto = """
#include "descrobject.h"
static PyObject* __Pyx_Method_ClassMethod(PyObject *method); /*proto*/
""",
impl = """
static PyObject* __Pyx_Method_ClassMethod(PyObject *method) {
/* It appears that PyMethodDescr_Type is not anywhere exposed in the Python/C API */
static PyTypeObject *methoddescr_type = NULL;
if (methoddescr_type == NULL) {
PyObject *meth = __Pyx_GetAttrString((PyObject*)&PyList_Type, "append");
if (!meth) return NULL;
methoddescr_type = Py_TYPE(meth);
Py_DECREF(meth);
}
if (PyObject_TypeCheck(method, methoddescr_type)) { /* cdef classes */
PyMethodDescrObject *descr = (PyMethodDescrObject *)method;
#if PY_VERSION_HEX < 0x03020000
PyTypeObject *d_type = descr->d_type;
#else
PyTypeObject *d_type = descr->d_common.d_type;
#endif
return PyDescr_NewClassMethod(d_type, descr->d_method);
}
else if (PyMethod_Check(method)) { /* python classes */
return PyClassMethod_New(PyMethod_GET_FUNCTION(method));
}
else if (PyCFunction_Check(method)) {
return PyClassMethod_New(method);
}
#ifdef __Pyx_CyFunction_USED
else if (PyObject_TypeCheck(method, __pyx_CyFunctionType)) {
return PyClassMethod_New(method);
}
#endif
PyErr_Format(PyExc_TypeError,
"Class-level classmethod() can only be called on "
"a method_descriptor or instance method.");
return NULL;
}
""")
#------------------------------------------------------------------------------------
ERR_BUF_LOCALONLY = 'Buffer types only allowed as function local variables'
......@@ -392,6 +392,59 @@ __Pyx_CyFunction_repr(__pyx_CyFunctionObject *op)
#endif
}
#if CYTHON_COMPILING_IN_PYPY
/* originally copied from PyCFunction_Call() in CPython's Objects/methodobject.c */
/* PyPy does not have this function */
static PyObject * __Pyx_CyFunction_Call(PyObject *func, PyObject *arg, PyObject *kw) {
PyCFunctionObject* f = (PyCFunctionObject*)func;
PyCFunction meth = PyCFunction_GET_FUNCTION(func);
PyObject *self = PyCFunction_GET_SELF(func);
Py_ssize_t size;
switch (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST)) {
case METH_VARARGS:
if (likely(kw == NULL) || PyDict_Size(kw) == 0)
return (*meth)(self, arg);
break;
case METH_VARARGS | METH_KEYWORDS:
return (*(PyCFunctionWithKeywords)meth)(self, arg, kw);
case METH_NOARGS:
if (likely(kw == NULL) || PyDict_Size(kw) == 0) {
size = PyTuple_GET_SIZE(arg);
if (size == 0)
return (*meth)(self, NULL);
PyErr_Format(PyExc_TypeError,
"%.200s() takes no arguments (%zd given)",
f->m_ml->ml_name, size);
return NULL;
}
break;
case METH_O:
if (likely(kw == NULL) || PyDict_Size(kw) == 0) {
size = PyTuple_GET_SIZE(arg);
if (size == 1)
return (*meth)(self, PyTuple_GET_ITEM(arg, 0));
PyErr_Format(PyExc_TypeError,
"%.200s() takes exactly one argument (%zd given)",
f->m_ml->ml_name, size);
return NULL;
}
break;
default:
PyErr_SetString(PyExc_SystemError, "Bad call flags in "
"__Pyx_CyFunction_Call. METH_OLDARGS is no "
"longer supported!");
return NULL;
}
PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments",
f->m_ml->ml_name);
return NULL;
}
#else
#define __Pyx_CyFunction_Call PyCFunction_Call
#endif
static PyTypeObject __pyx_CyFunctionType_type = {
PyVarObject_HEAD_INIT(0, 0)
__Pyx_NAMESTR("cython_function_or_method"), /*tp_name*/
......@@ -411,7 +464,7 @@ static PyTypeObject __pyx_CyFunctionType_type = {
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash*/
__Pyx_PyCFunction_Call, /*tp_call*/
__Pyx_CyFunction_Call, /*tp_call*/
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
......@@ -480,6 +533,8 @@ static CYTHON_INLINE void __Pyx_CyFunction_InitClassCell(PyObject *cyfunctions,
PyObject *classobj);
//////////////////// CyFunctionClassCell ////////////////////
//@requires: CythonFunction
void __Pyx_CyFunction_InitClassCell(PyObject *cyfunctions,
PyObject *classobj)
{
......@@ -514,6 +569,8 @@ static int __pyx_FusedFunction_init(void);
#define __Pyx_FusedFunction_USED
//////////////////// FusedFunction ////////////////////
//@requires: CythonFunction
static PyObject *
__pyx_FusedFunction_New(PyTypeObject *type, PyMethodDef *ml, int flags, PyObject *self,
PyObject *module, PyObject *code)
......@@ -712,12 +769,12 @@ __pyx_FusedFunction_callfunction(PyObject *func, PyObject *args, PyObject *kw)
m_self = cyfunc->func.m_self;
cyfunc->func.m_self = self;
result = __Pyx_PyCFunction_Call(func, new_args, kw);
result = __Pyx_CyFunction_Call(func, new_args, kw);
cyfunc->func.m_self = m_self;
Py_DECREF(new_args);
} else {
result = __Pyx_PyCFunction_Call(func, args, kw);
result = __Pyx_CyFunction_Call(func, args, kw);
}
return result;
......@@ -783,14 +840,14 @@ __pyx_FusedFunction_call(PyObject *func, PyObject *args, PyObject *kw)
if (!tup)
goto __pyx_err;
new_func = (__pyx_FusedFunctionObject *) __pyx_FusedFunction_callfunction(func, tup, NULL);;
new_func = (__pyx_FusedFunctionObject *) __pyx_FusedFunction_callfunction(func, tup, NULL);
Py_DECREF(tup);
if (!new_func)
goto __pyx_err;
Py_CLEAR(new_func->func.func_classobj);
Py_XINCREF(binding_func->func.func_classobj);
Py_CLEAR(new_func->func.func_classobj);
new_func->func.func_classobj = binding_func->func.func_classobj;
func = (PyObject *) new_func;
......@@ -881,3 +938,51 @@ static int __pyx_FusedFunction_init(void) {
__pyx_FusedFunctionType = &__pyx_FusedFunctionType_type;
return 0;
}
//////////////////// ClassMethod.proto ////////////////////
#include "descrobject.h"
static PyObject* __Pyx_Method_ClassMethod(PyObject *method); /*proto*/
//////////////////// ClassMethod ////////////////////
static PyObject* __Pyx_Method_ClassMethod(PyObject *method) {
#if CYTHON_COMPILING_IN_PYPY
if (PyObject_TypeCheck(method, &PyWrapperDescr_Type)) { /* cdef classes */
return PyClassMethod_New(method);
}
#else
/* It appears that PyMethodDescr_Type is not anywhere exposed in the Python/C API */
static PyTypeObject *methoddescr_type = NULL;
if (methoddescr_type == NULL) {
PyObject *meth = __Pyx_GetAttrString((PyObject*)&PyList_Type, "append");
if (!meth) return NULL;
methoddescr_type = Py_TYPE(meth);
Py_DECREF(meth);
}
if (PyObject_TypeCheck(method, methoddescr_type)) { /* cdef classes */
PyMethodDescrObject *descr = (PyMethodDescrObject *)method;
#if PY_VERSION_HEX < 0x03020000
PyTypeObject *d_type = descr->d_type;
#else
PyTypeObject *d_type = descr->d_common.d_type;
#endif
return PyDescr_NewClassMethod(d_type, descr->d_method);
}
#endif
else if (PyMethod_Check(method)) { /* python classes */
return PyClassMethod_New(PyMethod_GET_FUNCTION(method));
}
else if (PyCFunction_Check(method)) {
return PyClassMethod_New(method);
}
#ifdef __Pyx_CyFunction_USED
else if (PyObject_TypeCheck(method, __pyx_CyFunctionType)) {
return PyClassMethod_New(method);
}
#endif
PyErr_Format(PyExc_TypeError,
"Class-level classmethod() can only be called on "
"a method_descriptor or instance method.");
return NULL;
}
......@@ -200,6 +200,7 @@ static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb);
static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
PyObject *local_type, *local_value, *local_tb;
#if CYTHON_COMPILING_IN_CPYTHON
PyObject *tmp_type, *tmp_value, *tmp_tb;
PyThreadState *tstate = PyThreadState_GET();
local_type = tstate->curexc_type;
......@@ -208,19 +209,27 @@ static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb)
tstate->curexc_type = 0;
tstate->curexc_value = 0;
tstate->curexc_traceback = 0;
#else
PyErr_Fetch(&local_type, &local_value, &local_tb);
#endif
PyErr_NormalizeException(&local_type, &local_value, &local_tb);
#if CYTHON_COMPILING_IN_CPYTHON
if (unlikely(tstate->curexc_type))
#else
if (unlikely(PyErr_Occurred()))
#endif
goto bad;
#if PY_MAJOR_VERSION >= 3
if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0))
goto bad;
#endif
*type = local_type;
*value = local_value;
*tb = local_tb;
Py_INCREF(local_type);
Py_INCREF(local_value);
Py_INCREF(local_tb);
*type = local_type;
*value = local_value;
*tb = local_tb;
#if CYTHON_COMPILING_IN_CPYTHON
tmp_type = tstate->exc_type;
tmp_value = tstate->exc_value;
tmp_tb = tstate->exc_traceback;
......@@ -228,10 +237,13 @@ static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb)
tstate->exc_value = local_value;
tstate->exc_traceback = local_tb;
/* Make sure tstate is in a consistent state when we XDECREF
these objects (XDECREF may run arbitrary code). */
these objects (DECREF may run arbitrary code). */
Py_XDECREF(tmp_type);
Py_XDECREF(tmp_value);
Py_XDECREF(tmp_tb);
#else
PyErr_SetExcInfo(local_type, local_value, local_tb);
#endif
return 0;
bad:
*type = 0;
......@@ -251,6 +263,7 @@ static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb);
/////////////// SaveResetException ///////////////
static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
#if CYTHON_COMPILING_IN_CPYTHON
PyThreadState *tstate = PyThreadState_GET();
*type = tstate->exc_type;
*value = tstate->exc_value;
......@@ -258,9 +271,13 @@ static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value,
Py_XINCREF(*type);
Py_XINCREF(*value);
Py_XINCREF(*tb);
#else
PyErr_GetExcInfo(type, value, tb);
#endif
}
static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
#if CYTHON_COMPILING_IN_CPYTHON
PyObject *tmp_type, *tmp_value, *tmp_tb;
PyThreadState *tstate = PyThreadState_GET();
tmp_type = tstate->exc_type;
......@@ -272,6 +289,9 @@ static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb)
Py_XDECREF(tmp_type);
Py_XDECREF(tmp_value);
Py_XDECREF(tmp_tb);
#else
PyErr_SetExcInfo(type, value, tb);
#endif
}
/////////////// SwapException.proto ///////////////
......@@ -282,6 +302,7 @@ static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value,
static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb) {
PyObject *tmp_type, *tmp_value, *tmp_tb;
#if CYTHON_COMPILING_IN_CPYTHON
PyThreadState *tstate = PyThreadState_GET();
tmp_type = tstate->exc_type;
......@@ -291,6 +312,10 @@ static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value,
tstate->exc_type = *type;
tstate->exc_value = *value;
tstate->exc_traceback = *tb;
#else
PyErr_GetExcInfo(&tmp_type, &tmp_value, &tmp_tb);
PyErr_SetExcInfo(*type, *value, *tb);
#endif
*type = tmp_type;
*value = tmp_value;
......
......@@ -121,6 +121,12 @@ static CYTHON_INLINE int __Pyx_CheckKeywordStrings(
{
PyObject* key = 0;
Py_ssize_t pos = 0;
#if CPYTHON_COMPILING_IN_PYPY
/* PyPy appears to check keywords at call time, not at unpacking time => not much to do here */
if (!kw_allowed && PyDict_Next(kwdict, &pos, &key, 0))
goto invalid_keyword;
return 1;
#else
while (PyDict_Next(kwdict, &pos, &key, 0)) {
#if PY_MAJOR_VERSION < 3
if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
......@@ -136,6 +142,7 @@ invalid_keyword_type:
PyErr_Format(PyExc_TypeError,
"%s() keywords must be strings", function_name);
return 0;
#endif
invalid_keyword:
PyErr_Format(PyExc_TypeError,
#if PY_MAJOR_VERSION < 3
......
......@@ -188,6 +188,9 @@ PyObject *__Pyx_Generator_SendEx(__pyx_GeneratorObject *self, PyObject *value) {
if (value) {
#if CYTHON_COMPILING_IN_PYPY
// FIXME: what to do in PyPy?
#else
/* Generators always return to their most recent caller, not
* necessarily their creator. */
if (self->exc_traceback) {
......@@ -199,7 +202,7 @@ PyObject *__Pyx_Generator_SendEx(__pyx_GeneratorObject *self, PyObject *value) {
assert(f->f_back == NULL);
f->f_back = tstate->frame;
}
#endif
__Pyx_ExceptionSwap(&self->exc_type, &self->exc_value,
&self->exc_traceback);
} else {
......@@ -213,6 +216,9 @@ PyObject *__Pyx_Generator_SendEx(__pyx_GeneratorObject *self, PyObject *value) {
if (retval) {
__Pyx_ExceptionSwap(&self->exc_type, &self->exc_value,
&self->exc_traceback);
#if CYTHON_COMPILING_IN_PYPY
// FIXME: what to do in PyPy?
#else
/* Don't keep the reference to f_back any longer than necessary. It
* may keep a chain of frames alive or it could create a reference
* cycle. */
......@@ -221,6 +227,7 @@ PyObject *__Pyx_Generator_SendEx(__pyx_GeneratorObject *self, PyObject *value) {
PyFrameObject *f = tb->tb_frame;
Py_CLEAR(f->f_back);
}
#endif
} else {
__Pyx_Generator_ExceptionClear(self);
}
......@@ -506,12 +513,14 @@ static void __Pyx_Generator_del(PyObject *self) {
_Py_NewReference(self);
self->ob_refcnt = refcnt;
}
#if CYTHON_COMPILING_FOR_CPYTHON
assert(PyType_IS_GC(self->ob_type) &&
_Py_AS_GC(self)->gc.gc_refs != _PyGC_REFS_UNTRACKED);
/* If Py_REF_DEBUG, _Py_NewReference bumped _Py_RefTotal, so
* we need to undo that. */
_Py_DEC_REFTOTAL;
#endif
/* If Py_TRACE_REFS, _Py_NewReference re-added self to the object
* chain, so no more to do there.
* If COUNT_ALLOCS, the original decref bumped tp_frees, and
......
......@@ -40,12 +40,6 @@
#define CYTHON_COMPILING_IN_CPYTHON 1
#endif
#if CYTHON_COMPILING_IN_PYPY
#define __Pyx_PyCFunction_Call PyObject_Call
#else
#define __Pyx_PyCFunction_Call PyCFunction_Call
#endif
#if PY_VERSION_HEX < 0x02050000
typedef int Py_ssize_t;
#define PY_SSIZE_T_MAX INT_MAX
......
......@@ -119,10 +119,17 @@ static CYTHON_INLINE int __Pyx_unpack_tuple2(PyObject* tuple, PyObject** pvalue1
__Pyx_UnpackTupleError(tuple, 2);
goto bad;
}
#if CYTHON_COMPILING_IN_PYPY
value1 = PySequence_GetItem(tuple, 0);
if (unlikely(!value1)) goto bad;
value2 = PySequence_GetItem(tuple, 1);
if (unlikely(!value2)) goto bad;
#else
value1 = PyTuple_GET_ITEM(tuple, 0);
value2 = PyTuple_GET_ITEM(tuple, 1);
Py_INCREF(value1);
Py_INCREF(value2);
#endif
if (decref_tuple) { Py_DECREF(tuple); }
}
*pvalue1 = value1;
......
__doc__ = u"""
>>> iter(C())
>>> iter(C()) # doctest: +ELLIPSIS
Traceback (most recent call last):
TypeError: iter() returned non-iterator of type 'NoneType'
TypeError: iter() returned non-iterator...
"""
cdef class C:
......
......@@ -166,17 +166,17 @@ def test_noargs(f):
def test_int_kwargs(f):
"""
>>> test_int_kwargs(e)
>>> test_int_kwargs(e) # doctest: +ELLIPSIS
Traceback (most recent call last):
TypeError: e() keywords must be strings
>>> test_int_kwargs(f)
TypeError: ...keywords must be strings
>>> test_int_kwargs(f) # doctest: +ELLIPSIS
Traceback (most recent call last):
TypeError: f() keywords must be strings
>>> test_int_kwargs(g)
TypeError: ...keywords must be strings
>>> test_int_kwargs(g) # doctest: +ELLIPSIS
Traceback (most recent call last):
TypeError: g() keywords must be strings
>>> test_int_kwargs(h)
TypeError: ...keywords must be strings
>>> test_int_kwargs(h) # doctest: +ELLIPSIS
Traceback (most recent call last):
TypeError: h() keywords must be strings
TypeError: ...keywords must be strings
"""
f(a=1,b=2,c=3, **{10:20,30:40})
......@@ -59,25 +59,20 @@ True
TYPE_FIXES_REQUIRED:
>>> b.b1 = 1 #doctest: +ELLIPSIS
Traceback (most recent call last):
TypeError: ...
>>> try: b.b1 = 1
... except (TypeError, AttributeError): pass
>>> b.c1 = 1 #doctest: +ELLIPSIS
Traceback (most recent call last):
TypeError: ...
>>> try: b.c1 = 1
... except (TypeError, AttributeError): pass
>>> b.a2 = None #doctest: +ELLIPSIS
Traceback (most recent call last):
AttributeError: ...
>>> try: b.a2 = None
... except (TypeError, AttributeError): pass
>>> b.b2 = [] #doctest: +ELLIPSIS
Traceback (most recent call last):
AttributeError: ...
>>> try: b.b2 = []
... except (TypeError, AttributeError): pass
>>> b.c2 = A() #doctest: +ELLIPSIS
Traceback (most recent call last):
AttributeError: ...
>>> try: b.c2 = A()
... except (TypeError, AttributeError): pass
"""
import sys
......
......@@ -26,8 +26,7 @@ def test_list(list L, object i, object a):
[0, 1, 2, 3, 4, 5, 6, 7, 8, None, 10]
>>> test_list(list(range(11)), "invalid index", None) #doctest: +ELLIPSIS
Traceback (most recent call last):
...
TypeError: list indices must be integers...
TypeError: list ... must be ...integer...
"""
L[i] = a
return L
......@@ -2,9 +2,9 @@
__doc__ = u"""
>>> d = Defined()
>>> n = NotDefined()
>>> n = NotDefined() # doctest: +ELLIPSIS
Traceback (most recent call last):
NameError: name 'NotDefined' is not defined
NameError: ...name 'NotDefined' is not defined
"""
if True:
......
......@@ -133,18 +133,14 @@ def multiplied_lists_nonconst(x):
>>> multiplied_lists_nonconst(0) == [1,2,3] * 0
True
>>> [1,2,3] * 'abc' # doctest: +ELLIPSIS
Traceback (most recent call last):
TypeError: can't multiply sequence by non-int...
>>> multiplied_nonconst_tuple_arg('abc') # doctest: +ELLIPSIS
Traceback (most recent call last):
TypeError: can't multiply sequence by non-int...
>>> [1,2,3] * 1.0 # doctest: +ELLIPSIS
Traceback (most recent call last):
TypeError: can't multiply sequence by non-int...
>>> multiplied_nonconst_tuple_arg(1.0) # doctest: +ELLIPSIS
Traceback (most recent call last):
TypeError: can't multiply sequence by non-int...
>>> try: [1,2,3] * 'abc'
... except TypeError: pass
>>> try: multiplied_nonconst_tuple_arg('abc')
... except TypeError: pass
>>> try: [1,2,3] * 1.0
... except TypeError: pass
>>> try: multiplied_nonconst_tuple_arg(1.0)
... except TypeError: pass
"""
return [1,2,3] * x
......@@ -209,18 +205,14 @@ def multiplied_nonconst_tuple_arg(x):
>>> multiplied_nonconst_tuple_arg(0) == (1,2) * 0
True
>>> (1,2) * 'abc' # doctest: +ELLIPSIS
Traceback (most recent call last):
TypeError: can't multiply sequence by non-int...
>>> multiplied_nonconst_tuple_arg('abc') # doctest: +ELLIPSIS
Traceback (most recent call last):
TypeError: can't multiply sequence by non-int...
>>> (1,2) * 1.0 # doctest: +ELLIPSIS
Traceback (most recent call last):
TypeError: can't multiply sequence by non-int...
>>> multiplied_nonconst_tuple_arg(1.0) # doctest: +ELLIPSIS
Traceback (most recent call last):
TypeError: can't multiply sequence by non-int...
>>> try: (1,2) * 'abc'
... except TypeError: pass
>>> try: multiplied_nonconst_tuple_arg('abc')
... except TypeError: pass
>>> try: (1,2) * 1.0
... except TypeError: pass
>>> try: multiplied_nonconst_tuple_arg(1.0)
... except TypeError: pass
"""
return (1,2) * x
......
......@@ -106,9 +106,9 @@ def list_comp_module_level():
"""
>>> module_level_lc
[0, 2, 4, 6]
>>> module_level_loopvar
>>> module_level_loopvar # doctest: +ELLIPSIS
Traceback (most recent call last):
NameError: name 'module_level_loopvar' is not defined
NameError: ...name 'module_level_loopvar' is not defined
"""
module_level_list_genexp = list(module_level_genexp_loopvar*2 for module_level_genexp_loopvar in range(4))
......@@ -116,9 +116,9 @@ def genexpr_module_level():
"""
>>> module_level_list_genexp
[0, 2, 4, 6]
>>> module_level_genexp_loopvar
>>> module_level_genexp_loopvar # doctest: +ELLIPSIS
Traceback (most recent call last):
NameError: name 'module_level_genexp_loopvar' is not defined
NameError: ...name 'module_level_genexp_loopvar' is not defined
"""
def list_comp_unknown_type(l):
......
......@@ -87,4 +87,4 @@ def get_in_condition(dict d, key, expected_result):
>>> get_in_condition(d, 'a', 1)
True
"""
return d.get(key) is expected_result
return d.get(key) is expected_result or d.get(key) == expected_result
......@@ -36,4 +36,4 @@ def getitem_in_condition(dict d, key, expected_result):
>>> getitem_in_condition(d, 'a', 1)
True
"""
return d[key] is expected_result
return d[key] is expected_result or d[key] == expected_result
......@@ -14,13 +14,12 @@ def test_call(kwargs):
[('a', 1), ('b', 2)]
>>> kwargs = {'a' : 2}
>>> f(a=1, **kwargs)
>>> f(a=1, **kwargs) # doctest: +ELLIPSIS
Traceback (most recent call last):
TypeError: f() got multiple values for keyword argument 'a'
TypeError: ...got multiple values for keyword argument 'a'
FIXME: remove ellipsis, fix function name
>>> test_call(kwargs) # doctest: +ELLIPSIS
Traceback (most recent call last):
TypeError: ...() got multiple values for keyword argument 'a'
TypeError: ...got multiple values for keyword argument 'a'
"""
return f(a=1, **kwargs)
__doc__ = u"""
>>> class SampleException(Exception): pass
>>> import sys
>>> def assert_refcount(rc1, rc2, func):
... # test ref-counts, but allow a bit of freedom
......@@ -8,17 +7,17 @@ __doc__ = u"""
... func.__name__, rc1, rc2)
>>> def run_test(repeat, test_func):
... initial_refcount = sys.getrefcount(SampleException)
... initial_refcount = get_refcount(SampleException)
... for i in range(repeat):
... try: raise SampleException
... except:
... refcount1 = sys.getrefcount(SampleException)
... refcount1 = get_refcount(SampleException)
... test_func()
... refcount2 = sys.getrefcount(SampleException)
... refcount2 = get_refcount(SampleException)
...
... assert_refcount(refcount1, refcount2, test_func)
... assert_refcount(initial_refcount, refcount2, test_func)
... refcount3 = sys.getrefcount(SampleException)
... refcount3 = get_refcount(SampleException)
... assert_refcount(refcount1, refcount3, test_func)
... assert_refcount(initial_refcount, refcount3, test_func)
......@@ -28,6 +27,11 @@ __doc__ = u"""
>>> run_test(50, test_finally)
"""
from cpython.ref cimport PyObject
def get_refcount(obj):
return (<PyObject*>obj).ob_refcnt
def test_no_exception():
try:
a = 1+1
......
......@@ -63,9 +63,9 @@ __doc__ = u"""
>>> # errors
>>> d1, d2 = {}, {}
>>> test_dict_scope_ref(d1, d2)
>>> test_dict_scope_ref(d1, d2) # doctest: +ELLIPSIS
Traceback (most recent call last):
NameError: name 'a' is not defined
NameError: ...name 'a' is not defined
"""
#def test_module_scope():
......
......@@ -24,9 +24,9 @@ cdef class Spam:
def f(Spam spam):
"""
>>> s = Spam(12)
>>> f(s)
>>> f(s) # doctest: +ELLIPSIS
Traceback (most recent call last):
AttributeError: 'exttype.Spam' object has no attribute 'foo'
AttributeError: '...Spam' object has no attribute 'foo'
>>> s.eat()
12 42
>>> class Spam2(Spam):
......
......@@ -3,8 +3,8 @@
def test_import_error():
"""
>>> test_import_error()
>>> test_import_error() # doctest: +ELLIPSIS
Traceback (most recent call last):
ImportError: cannot import name xxx
ImportError: cannot import name ...xxx...
"""
from sys import xxx
......@@ -20,9 +20,9 @@ def test():
>>> p = PublicType
>>> i = InternalType
>>> i = InternalType # doctest: +ELLIPSIS
Traceback (most recent call last):
NameError: name 'InternalType' is not defined
NameError: ...name 'InternalType' is not defined
"""
p = PublicType
i = InternalType
......
......@@ -2,9 +2,9 @@
def test(**kw):
"""
>>> d = {1 : 2}
>>> test(**d)
>>> test(**d) # doctest: +ELLIPSIS
Traceback (most recent call last):
TypeError: test() keywords must be strings
TypeError: ...keywords must be strings
>>> d
{1: 2}
>>> d = {}
......@@ -12,7 +12,7 @@ def test(**kw):
{'arg': 3}
>>> d
{}
>>> d = {'arg' : 2} # this should be u'arg', but Py2 can't handle it...
>>> d = {'arg' : 2}
>>> test(**d)
{'arg': 3}
>>> d
......
......@@ -154,7 +154,7 @@ def crazy_pop(L):
"""
>>> crazy_pop(list(range(10))) # doctest: +ELLIPSIS
Traceback (most recent call last):
TypeError: pop... at most 1 argument...3...
TypeError: pop... at most ... argument...
>>> crazy_pop(A())
(1, 2, 3)
"""
......
__doc__ = """
>>> test_chars(b'yo')
(b'a', b'bc', b'yo')
>>> test_chars(None) # doctest: +ELLIPSIS
Traceback (most recent call last):
TypeError: expected ...
>>> try: test_chars(None)
... except TypeError: pass
"""
import sys
......
......@@ -5,9 +5,9 @@ True
True
>>> X == 4*5 + 1
True
>>> NONPUBLIC
>>> NONPUBLIC # doctest: +ELLIPSIS
Traceback (most recent call last):
NameError: name 'NONPUBLIC' is not defined
NameError: ...name 'NONPUBLIC' is not defined
>>> NOWPUBLIC == 23 + 42
True
"""
......
......@@ -43,10 +43,8 @@ def test_cast(x):
"""
>>> test_cast(1.5)
1
>>> test_cast(None)
Traceback (most recent call last):
...
TypeError: a float is required
>>> try: test_cast(None)
... except TypeError: pass
"""
n = cython.cast(cython.int, x)
return n
......
__doc__ = u"""
__doc__ = """
>>> try:
... s = Spam()
... except KeyError, e:
... print("Exception: %s" % e)
... else:
... print("Did not raise the expected exception")
Exception: u'This is not a spanish inquisition'
Exception: 'This is not a spanish inquisition'
"""
import sys
if sys.version_info[0] >= 3:
__doc__ = __doc__.replace(u"Error, e", u"Error as e")
__doc__ = __doc__.replace(u" u'", u" '")
__doc__ = __doc__.replace("Error, e", "Error as e")
cdef extern from "Python.h":
ctypedef class __builtin__.list [object PyListObject]:
......@@ -19,4 +18,4 @@ cdef extern from "Python.h":
cdef class Spam(list):
def __init__(self):
raise KeyError(u"This is not a spanish inquisition")
raise KeyError("This is not a spanish inquisition")
__doc__ = u"""
__doc__ = """
>>> s = Spam()
>>> s.get_tons()
17
>>> s.set_tons(42)
>>> s.get_tons()
42
"""
import platform
if not hasattr(platform, 'python_implementation') or platform.python_implementation() == 'CPython':
__doc__ += """
>>> s = None
42 tons of spam is history.
"""
......
......@@ -12,7 +12,10 @@ True
True
"""
import sys
from cpython.ref cimport PyObject
def get_refcount(obj):
return (<PyObject*>obj).ob_refcnt
cdef class RefCountInMeth(object):
cdef double value
......@@ -32,27 +35,27 @@ cdef class RefCountInMeth(object):
cdef int c_meth(self):
cdef int v
v = sys.getrefcount(self)
v = get_refcount(self)
return v
cdef int c_meth_if(self):
cdef int v
if 5>6:
v = 7
v = sys.getrefcount(self)
v = get_refcount(self)
return v
def chk_meth(self):
cdef int a,b
a = sys.getrefcount(self)
a = get_refcount(self)
b = self.c_meth()
return a==b
def chk_meth_if(self):
cdef int a,b
a = sys.getrefcount(self)
a = get_refcount(self)
b = self.c_meth_if()
return a==b
......
......@@ -7,9 +7,8 @@ def f(obj1, obj2, obj3, obj4):
True
>>> l is f(1, l, 2, 3)
False
>>> f(1, 42, 2, 3) #doctest: +ELLIPSIS
Traceback (most recent call last):
TypeError: ...unsliceable...
>>> try: f(1, 42, 2, 3)
... except TypeError: pass
"""
obj1 = obj2[:]
return obj1
......@@ -18,9 +17,8 @@ def g(obj1, obj2, obj3, obj4):
"""
>>> g(1, [1,2,3,4], 2, 3)
[3, 4]
>>> g(1, 42, 2, 3) #doctest: +ELLIPSIS
Traceback (most recent call last):
TypeError: ...unsliceable...
>>> try: g(1, 42, 2, 3)
... except TypeError: pass
"""
obj1 = obj2[obj3:]
return obj1
......@@ -29,9 +27,8 @@ def h(obj1, obj2, obj3, obj4):
"""
>>> h(1, [1,2,3,4], 2, 3)
[1, 2, 3]
>>> h(1, 42, 2, 3) #doctest: +ELLIPSIS
Traceback (most recent call last):
TypeError: ...unsliceable...
>>> try: h(1, 42, 2, 3)
... except TypeError: pass
"""
obj1 = obj2[:obj4]
return obj1
......@@ -40,9 +37,8 @@ def j(obj1, obj2, obj3, obj4):
"""
>>> j(1, [1,2,3,4], 2, 3)
[3]
>>> j(1, 42, 2, 3) #doctest: +ELLIPSIS
Traceback (most recent call last):
TypeError: ...unsliceable...
>>> try: j(1, 42, 2, 3)
... except TypeError: pass
"""
obj1 = obj2[obj3:obj4]
return obj1
......
......@@ -7,10 +7,8 @@ def test_constructor(x, y, color):
"""
>>> sorted(test_constructor(1,2,255).items())
[('color', 255), ('x', 1.0), ('y', 2.0)]
>>> test_constructor(1,None,255)
Traceback (most recent call last):
...
TypeError: a float is required
>>> try: test_constructor(1,None,255)
... except TypeError: pass
"""
cdef Point p = Point(x, y, color)
return p
......@@ -31,10 +29,8 @@ def test_dict_construction(x, y, color):
"""
>>> sorted(test_dict_construction(4, 5, 64).items())
[('color', 64), ('x', 4.0), ('y', 5.0)]
>>> test_dict_construction("foo", 5, 64)
Traceback (most recent call last):
...
TypeError: a float is required
>>> try: test_dict_construction("foo", 5, 64)
... except TypeError: pass
"""
cdef Point p = {'color': color, 'x': x, 'y': y}
return p
......
......@@ -69,7 +69,7 @@ def make_new_none(type t=None):
"""
>>> make_new_none() # doctest: +ELLIPSIS
Traceback (most recent call last):
TypeError: ...__new__(X): X is not a type object (NoneType)
TypeError: ... is not a type object (NoneType)
"""
m = t.__new__(t)
return m
......@@ -122,7 +122,7 @@ def make_new_none_typed(tuple t=None):
"""
>>> make_new_none_typed() # doctest: +ELLIPSIS
Traceback (most recent call last):
TypeError: ...__new__(X): X is not a type object (NoneType)
TypeError: ... is not a type object (NoneType)
"""
m = t.__new__(t)
return m
......@@ -133,7 +133,7 @@ def make_new_untyped(t):
"""
>>> make_new_untyped(None) # doctest: +ELLIPSIS
Traceback (most recent call last):
TypeError: ...__new__(X): X is not a type object (NoneType)
TypeError: ... is not a type object (NoneType)
"""
m = t.__new__(t)
return m
# mode: run
# ticket: 303
__doc__ = """
>>> readonly() #doctest: +ELLIPSIS
Traceback (most recent call last):
...
TypeError: ...
>>> try: readonly()
... except (TypeError, AttributeError): pass
"""
import sys
if sys.version_info >= (2,5):
__doc__ = __doc__.replace('TypeError:', 'AttributeError:')
cdef extern from "external_defs.h":
ctypedef float DoubleTypedef
......
......@@ -180,16 +180,13 @@ def unpack_typed(it):
>>> it.count
4
>>> unpack_typed((1, None, [1]))
Traceback (most recent call last):
TypeError: a float is required
>>> unpack_typed([1, None, [1]])
Traceback (most recent call last):
TypeError: a float is required
>>> try: unpack_typed((1, None, [1]))
... except TypeError: pass
>>> try: unpack_typed([1, None, [1]])
... except TypeError: pass
>>> it = ItCount([1, None, [1]])
>>> unpack_typed(it)
Traceback (most recent call last):
TypeError: a float is required
>>> try: unpack_typed(it)
... except TypeError: pass
>>> it.count
4
......@@ -211,16 +208,14 @@ def unpack_typed(it):
def failure_too_many(it):
"""
>>> a,b,c = [1,2,3,4] # doctest: +ELLIPSIS
Traceback (most recent call last):
ValueError: too many values to unpack...
>>> try: a,b,c = [1,2,3,4]
... except ValueError: pass
>>> failure_too_many([1,2,3,4])
Traceback (most recent call last):
ValueError: too many values to unpack (expected 3)
>>> a,b,c = [1,2,3,4] # doctest: +ELLIPSIS
Traceback (most recent call last):
ValueError: too many values to unpack...
>>> try: a,b,c = [1,2,3,4]
... except ValueError: pass
>>> failure_too_many((1,2,3,4))
Traceback (most recent call last):
ValueError: too many values to unpack (expected 3)
......@@ -244,16 +239,14 @@ def failure_too_many(it):
def failure_too_few(it):
"""
>>> a,b,c = [1,2]
Traceback (most recent call last):
ValueError: need more than 2 values to unpack
>>> try: a,b,c = [1,2]
... except ValueError: pass
>>> failure_too_few([1,2])
Traceback (most recent call last):
ValueError: need more than 2 values to unpack
>>> a,b,c = (1,2)
Traceback (most recent call last):
ValueError: need more than 2 values to unpack
>>> try: a,b,c = (1,2)
... except ValueError: pass
>>> failure_too_few((1,2))
Traceback (most recent call last):
ValueError: need more than 2 values to unpack
......
# ticket: 359
__doc__ = u"""
>>> py_string1.decode('ASCII') == 'test toast taste'
True
>>> py_string1 == py_string2 == py_string3
True
"""
cdef unsigned char* some_c_unstring = 'test toast taste'
py_string1 = some_c_unstring
def test_uchar_conversion():
"""
>>> py_string1, py_string2, py_string3 = test_uchar_conversion()
>>> print(py_string1.decode('iso8859-1'))
test toast taste
>>> print(py_string2.decode('iso8859-1'))
test toast taste
>>> print(py_string3.decode('iso8859-1'))
test toast taste
"""
cdef unsigned char* c_unstring_from_py = py_string1
cdef object py_string1 = some_c_unstring
py_string2 = c_unstring_from_py
cdef unsigned char* c_unstring_from_py = py_string1
cdef object py_string2 = c_unstring_from_py
cdef char* c_string_from_py = py_string2
cdef char* c_string_from_py = py_string2
cdef object py_string3 = c_string_from_py
py_string3 = c_string_from_py
return py_string1, py_string2, py_string3
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