Commit 2c71d548 authored by scoder's avatar scoder

Merge pull request #106 from vitek/master

Regression fixes
parents 7ef9c72f d099cfe2
......@@ -1789,10 +1789,8 @@ class AnalyseExpressionsTransform(CythonTransform):
return node
def visit_AttributeNode(self, node):
# Note: Expression analysis for attributes has already happened
# at this point (by recursive calls starting from FuncDefNode)
#print node.dump()
#return node
self.visitchildren(node)
type = node.obj.type
if type.is_extension_type and type.objstruct_cname == 'PyArrayObject':
from NumpySupport import numpy_transform_attribute_node
......
......@@ -23,6 +23,7 @@ static CYTHON_INLINE PyObject* __Pyx_Generator_Yield_From(__pyx_GeneratorObject
//////////////////// Generator.proto ////////////////////
#define __Pyx_Generator_USED
#include <structmember.h>
#include <frameobject.h>
typedef PyObject *(*__pyx_generator_body_t)(PyObject *, PyObject *);
......@@ -186,19 +187,43 @@ PyObject *__Pyx_Generator_SendEx(__pyx_GeneratorObject *self, PyObject *value) {
}
if (value)
__Pyx_ExceptionSwap(&self->exc_type, &self->exc_value, &self->exc_traceback);
else
if (value) {
/* Generators always return to their most recent caller, not
* necessarily their creator. */
if (self->exc_traceback) {
PyThreadState *tstate = PyThreadState_GET();
PyTracebackObject *tb = (PyTracebackObject *) self->exc_traceback;
PyFrameObject *f = tb->tb_frame;
Py_XINCREF(tstate->frame);
assert(f->f_back == NULL);
f->f_back = tstate->frame;
}
__Pyx_ExceptionSwap(&self->exc_type, &self->exc_value,
&self->exc_traceback);
} else {
__Pyx_Generator_ExceptionClear(self);
}
self->is_running = 1;
retval = self->body((PyObject *) self, value);
self->is_running = 0;
if (retval)
__Pyx_ExceptionSwap(&self->exc_type, &self->exc_value, &self->exc_traceback);
else
if (retval) {
__Pyx_ExceptionSwap(&self->exc_type, &self->exc_value,
&self->exc_traceback);
/* 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. */
if (self->exc_traceback) {
PyTracebackObject *tb = (PyTracebackObject *) self->exc_traceback;
PyFrameObject *f = tb->tb_frame;
Py_CLEAR(f->f_back);
}
} else {
__Pyx_Generator_ExceptionClear(self);
}
return retval;
}
......@@ -546,7 +571,7 @@ static PyTypeObject __pyx_GeneratorType_type = {
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags*/
0, /*tp_doc*/
(traverseproc) __Pyx_Generator_traverse, /*tp_traverse*/
(inquiry) __Pyx_Generator_clear, /*tp_clear*/
0, /*tp_clear*/
0, /*tp_richcompare*/
offsetof(__pyx_GeneratorObject, gi_weakreflist), /* tp_weaklistoffse */
PyObject_SelfIter, /*tp_iter*/
......
# mode: run
# tags: lambda, attribute, regression
class TestClass(object):
bar = 123
def test_attribute_and_lambda(f):
"""
>>> test_attribute_and_lambda(lambda _: TestClass())
123
"""
return f(lambda x: x).bar
# mode: run
# tags: generator
import sys
def _next(it):
if sys.version_info[0] >= 3:
return next(it)
else:
return it.next()
def test_generator_frame_cycle():
"""
>>> test_generator_frame_cycle()
("I'm done",)
"""
testit = []
def whoo():
try:
yield
except:
yield
finally:
testit.append("I'm done")
g = whoo()
_next(g)
# Frame object cycle
eval('g.throw(ValueError)', {'g': g})
del g
return tuple(testit)
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