Commit fc6d7a7b authored by Stefan Behnel's avatar Stefan Behnel

Merge branch '0.22.x'

Conflicts:
	Cython/Utility/CythonFunction.c
	Cython/Utility/Generator.c
parents 5bd29d5e bf93c499
...@@ -81,6 +81,9 @@ Bugs fixed ...@@ -81,6 +81,9 @@ Bugs fixed
* Crash when returning values on generator termination. * Crash when returning values on generator termination.
* In some cases, exceptions raised during internal isinstance() checks were
not propagated.
* Runtime reported file paths of source files (e.g for profiling and tracing) * Runtime reported file paths of source files (e.g for profiling and tracing)
are now relative to the build root directory instead of the main source file. are now relative to the build root directory instead of the main source file.
......
...@@ -1058,13 +1058,17 @@ __pyx_FusedFunction_call(PyObject *func, PyObject *args, PyObject *kw) ...@@ -1058,13 +1058,17 @@ __pyx_FusedFunction_call(PyObject *func, PyObject *args, PyObject *kw)
#endif #endif
} }
if (self && !is_classmethod && !is_staticmethod && if (self && !is_classmethod && !is_staticmethod) {
!PyObject_IsInstance(self, binding_func->type)) { int is_instance = PyObject_IsInstance(self, binding_func->type);
if (unlikely(!is_instance)) {
PyErr_Format(PyExc_TypeError, PyErr_Format(PyExc_TypeError,
"First argument should be of type %.200s, got %.200s.", "First argument should be of type %.200s, got %.200s.",
((PyTypeObject *) binding_func->type)->tp_name, ((PyTypeObject *) binding_func->type)->tp_name,
self->ob_type->tp_name); self->ob_type->tp_name);
goto bad; goto bad;
} else if (unlikely(is_instance == -1)) {
goto bad;
}
} }
#if !CYTHON_COMPILING_IN_CPYTHON #if !CYTHON_COMPILING_IN_CPYTHON
Py_XDECREF(self); Py_XDECREF(self);
......
...@@ -144,11 +144,15 @@ static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject ...@@ -144,11 +144,15 @@ static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject
if (value && PyExceptionInstance_Check(value)) { if (value && PyExceptionInstance_Check(value)) {
instance_class = (PyObject*) Py_TYPE(value); instance_class = (PyObject*) Py_TYPE(value);
if (instance_class != type) { if (instance_class != type) {
if (PyObject_IsSubclass(instance_class, type)) { int is_subclass = PyObject_IsSubclass(instance_class, type);
if (!is_subclass) {
instance_class = NULL;
} else if (unlikely(is_subclass == -1)) {
// error on subclass test
goto bad;
} else {
// believe the instance // believe the instance
type = instance_class; type = instance_class;
} else {
instance_class = NULL;
} }
} }
} }
......
...@@ -104,6 +104,7 @@ static PyObject *__Pyx_Generator_Throw(PyObject *gen, PyObject *args); ...@@ -104,6 +104,7 @@ static PyObject *__Pyx_Generator_Throw(PyObject *gen, PyObject *args);
static int __Pyx_PyGen_FetchStopIterationValue(PyObject **pvalue) { static int __Pyx_PyGen_FetchStopIterationValue(PyObject **pvalue) {
PyObject *et, *ev, *tb; PyObject *et, *ev, *tb;
PyObject *value = NULL; PyObject *value = NULL;
int result;
__Pyx_ErrFetch(&et, &ev, &tb); __Pyx_ErrFetch(&et, &ev, &tb);
...@@ -117,6 +118,7 @@ static int __Pyx_PyGen_FetchStopIterationValue(PyObject **pvalue) { ...@@ -117,6 +118,7 @@ static int __Pyx_PyGen_FetchStopIterationValue(PyObject **pvalue) {
// most common case: plain StopIteration without or with separate argument // most common case: plain StopIteration without or with separate argument
if (likely(et == PyExc_StopIteration)) { if (likely(et == PyExc_StopIteration)) {
int error = 0;
#if PY_VERSION_HEX >= 0x030300A0 #if PY_VERSION_HEX >= 0x030300A0
if (ev && Py_TYPE(ev) == (PyTypeObject*)PyExc_StopIteration) { if (ev && Py_TYPE(ev) == (PyTypeObject*)PyExc_StopIteration) {
value = ((PyStopIterationObject *)ev)->value; value = ((PyStopIterationObject *)ev)->value;
...@@ -128,7 +130,7 @@ static int __Pyx_PyGen_FetchStopIterationValue(PyObject **pvalue) { ...@@ -128,7 +130,7 @@ static int __Pyx_PyGen_FetchStopIterationValue(PyObject **pvalue) {
return 0; return 0;
} }
#endif #endif
if (!ev || !PyObject_IsInstance(ev, PyExc_StopIteration)) { if (!ev || !(error = PyObject_IsInstance(ev, PyExc_StopIteration))) {
// PyErr_SetObject() and friends put the value directly into ev // PyErr_SetObject() and friends put the value directly into ev
if (!ev) { if (!ev) {
Py_INCREF(Py_None); Py_INCREF(Py_None);
...@@ -139,6 +141,10 @@ static int __Pyx_PyGen_FetchStopIterationValue(PyObject **pvalue) { ...@@ -139,6 +141,10 @@ static int __Pyx_PyGen_FetchStopIterationValue(PyObject **pvalue) {
*pvalue = ev; *pvalue = ev;
return 0; return 0;
} }
if (unlikely(error == -1)) {
// error during isinstance() check
return -1;
}
} else if (!PyErr_GivenExceptionMatches(et, PyExc_StopIteration)) { } else if (!PyErr_GivenExceptionMatches(et, PyExc_StopIteration)) {
__Pyx_ErrRestore(et, ev, tb); __Pyx_ErrRestore(et, ev, tb);
return -1; return -1;
...@@ -146,13 +152,19 @@ static int __Pyx_PyGen_FetchStopIterationValue(PyObject **pvalue) { ...@@ -146,13 +152,19 @@ static int __Pyx_PyGen_FetchStopIterationValue(PyObject **pvalue) {
// otherwise: normalise and check what that gives us // otherwise: normalise and check what that gives us
PyErr_NormalizeException(&et, &ev, &tb); PyErr_NormalizeException(&et, &ev, &tb);
if (unlikely(!PyObject_IsInstance(ev, PyExc_StopIteration))) { result = PyObject_IsInstance(ev, PyExc_StopIteration);
if (unlikely(!result)) {
// looks like normalisation failed - raise the new exception // looks like normalisation failed - raise the new exception
__Pyx_ErrRestore(et, ev, tb); __Pyx_ErrRestore(et, ev, tb);
return -1; return -1;
} }
Py_XDECREF(tb); Py_XDECREF(tb);
Py_DECREF(et); Py_DECREF(et);
if (unlikely(result == -1)) {
// error during isinstance() check
Py_DECREF(ev);
return -1;
}
#if PY_VERSION_HEX >= 0x030300A0 #if PY_VERSION_HEX >= 0x030300A0
value = ((PyStopIterationObject *)ev)->value; value = ((PyStopIterationObject *)ev)->value;
Py_INCREF(value); Py_INCREF(value);
......
...@@ -1422,6 +1422,8 @@ bad: ...@@ -1422,6 +1422,8 @@ bad:
static PyObject* __Pyx__PyNumber_MatrixMultiply(PyObject* x, PyObject* y, const char* op_name) { static PyObject* __Pyx__PyNumber_MatrixMultiply(PyObject* x, PyObject* y, const char* op_name) {
int right_is_subtype = PyObject_IsSubclass((PyObject*)Py_TYPE(y), (PyObject*)Py_TYPE(x)); int right_is_subtype = PyObject_IsSubclass((PyObject*)Py_TYPE(y), (PyObject*)Py_TYPE(x));
if (unlikely(right_is_subtype == -1))
return NULL;
if (right_is_subtype) { if (right_is_subtype) {
// to allow subtypes to override parent behaviour, try reversed operation first // to allow subtypes to override parent behaviour, try reversed operation first
// see note at https://docs.python.org/3/reference/datamodel.html#emulating-numeric-types // see note at https://docs.python.org/3/reference/datamodel.html#emulating-numeric-types
......
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