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