Commit b926c619 authored by Xavier Thompson's avatar Xavier Thompson

Protect the cypclass dict against active iterators being invalidated

parent 9bddff59
......@@ -2979,6 +2979,12 @@ class CppIteratorNode(ExprNode):
code.putln("++%s;" % self.result())
def generate_disposal_code(self, code):
# clean-up the iterator by assigning end to it
# this is only required if the iterator holds resources that must be released once iteration is complete
code.putln("%s = %s%send();" % (
self.result(),
self.cpp_sequence_cname or self.sequence.result(),
self.cpp_attribute_op))
if self.cpp_sequence_cname and self.sequence.type.is_cyp_class:
code.put_decref(self.cpp_sequence_cname, self.sequence.type)
super(CppIteratorNode, self).generate_disposal_code(code)
......
This diff is collapsed.
......@@ -136,8 +136,8 @@ def test_getitem_exception():
'Getting nonexistent item'
1
"""
d = cypdict[Index, Value]()
try:
d = cypdict[Index, Value]()
with nogil:
v = d[Index()]
with gil:
......@@ -152,8 +152,8 @@ def test_delitem_exception():
'Deleting nonexistent item'
1
"""
d = cypdict[Index, Value]()
try:
d = cypdict[Index, Value]()
with nogil:
del d[Index()]
with gil:
......@@ -162,3 +162,138 @@ def test_delitem_exception():
print(e)
return 1
def test_setitem_exception_dict_iterator():
"""
>>> test_setitem_exception_dict_iterator()
Modifying a dictionary with active iterators
1
"""
d = cypdict[Index, Value]()
iterator = d.begin()
try:
with nogil:
d[Index()] = Value()
with gil:
return 0
except RuntimeError as e:
print(e)
return 1
def test_setitem_exception_dict_keys_iterator():
"""
>>> test_setitem_exception_dict_keys_iterator()
Modifying a dictionary with active iterators
1
"""
d = cypdict[Index, Value]()
iterator = d.keys().begin()
try:
with nogil:
d[Index()] = Value()
with gil:
return 0
except RuntimeError as e:
print(e)
return 1
def test_setitem_exception_dict_values_iterator():
"""
>>> test_setitem_exception_dict_values_iterator()
Modifying a dictionary with active iterators
1
"""
d = cypdict[Index, Value]()
iterator = d.values().begin()
try:
with nogil:
d[Index()] = Value()
with gil:
return 0
except RuntimeError as e:
print(e)
return 1
def test_setitem_exception_dict_items_iterator():
"""
>>> test_setitem_exception_dict_items_iterator()
Modifying a dictionary with active iterators
1
"""
d = cypdict[Index, Value]()
iterator = d.items().begin()
try:
with nogil:
d[Index()] = Value()
with gil:
return 0
except RuntimeError as e:
print(e)
return 1
def test_setitem_after_dict_iterator():
"""
>>> test_setitem_after_dict_iterator()
1
"""
d = cypdict[Index, Value]()
for key in d:
pass
try:
with nogil:
d[Index()] = Value()
with gil:
return 1
except RuntimeError as e:
print(e)
return 0
def test_setitem_after_dict_keys_iterator():
"""
>>> test_setitem_after_dict_keys_iterator()
1
"""
d = cypdict[Index, Value]()
for key in d.keys():
pass
try:
with nogil:
d[Index()] = Value()
with gil:
return 1
except RuntimeError as e:
print(e)
return 0
def test_setitem_after_dict_values_iterator():
"""
>>> test_setitem_after_dict_values_iterator()
1
"""
d = cypdict[Index, Value]()
for value in d.values():
pass
try:
with nogil:
d[Index()] = Value()
with gil:
return 1
except RuntimeError as e:
print(e)
return 0
def test_setitem_after_dict_items_iterator():
"""
>>> test_setitem_after_dict_items_iterator()
1
"""
d = cypdict[Index, Value]()
for item in d.items():
pass
try:
with nogil:
d[Index()] = Value()
with gil:
return 1
except RuntimeError as e:
print(e)
return 0
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