Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Gwenaël Samain
cython
Commits
45a17f1a
Commit
45a17f1a
authored
Aug 06, 2013
by
Stefan Behnel
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
revert actual tp_finalize() usages, needs more thought
parent
abe914c4
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
83 additions
and
197 deletions
+83
-197
CHANGES.rst
CHANGES.rst
+0
-4
Cython/Compiler/ModuleNode.py
Cython/Compiler/ModuleNode.py
+54
-103
Cython/Compiler/Symtab.py
Cython/Compiler/Symtab.py
+20
-28
Cython/Compiler/TypeSlots.py
Cython/Compiler/TypeSlots.py
+2
-18
Cython/Utility/CythonFunction.c
Cython/Utility/CythonFunction.c
+2
-2
Cython/Utility/ExtensionTypes.c
Cython/Utility/ExtensionTypes.c
+0
-21
Cython/Utility/Generator.c
Cython/Utility/Generator.c
+5
-17
Cython/Utility/ModuleSetupCode.c
Cython/Utility/ModuleSetupCode.c
+0
-4
No files found.
CHANGES.rst
View file @
45a17f1a
...
@@ -8,10 +8,6 @@ Cython Changelog
...
@@ -8,10 +8,6 @@ Cython Changelog
Features added
Features added
--------------
--------------
* Starting with CPython 3.4, the user provided finalisation code in the
``__dealloc__()`` special method is called by ``tp_finalize()`` instead
of ``tp_dealloc()`` to provide a safer execution environment.
* During cyclic garbage collection, attributes of extension types that
* During cyclic garbage collection, attributes of extension types that
cannot create reference cycles due to their type (e.g. strings) are
cannot create reference cycles due to their type (e.g. strings) are
no longer considered for traversal or clearing.
no longer considered for traversal or clearing.
...
...
Cython/Compiler/ModuleNode.py
View file @
45a17f1a
...
@@ -1006,7 +1006,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -1006,7 +1006,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
if
scope
:
# could be None if there was an error
if
scope
:
# could be None if there was an error
self
.
generate_exttype_vtable
(
scope
,
code
)
self
.
generate_exttype_vtable
(
scope
,
code
)
self
.
generate_new_function
(
scope
,
code
,
entry
)
self
.
generate_new_function
(
scope
,
code
,
entry
)
self
.
generate_finalize_function
(
scope
,
code
)
self
.
generate_dealloc_function
(
scope
,
code
)
self
.
generate_dealloc_function
(
scope
,
code
)
if
scope
.
needs_gc
():
if
scope
.
needs_gc
():
self
.
generate_traverse_function
(
scope
,
code
,
entry
)
self
.
generate_traverse_function
(
scope
,
code
,
entry
)
...
@@ -1175,37 +1174,30 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -1175,37 +1174,30 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
if
tp_slot
.
slot_code
(
scope
)
!=
slot_func
:
if
tp_slot
.
slot_code
(
scope
)
!=
slot_func
:
return
# never used
return
# never used
cpp_class_attrs
=
[
entry
for
entry
in
scope
.
var_entries
if
entry
.
type
.
is_cpp_class
]
needs_finalisation
=
scope
.
needs_finalisation
()
needs_gc
=
scope
.
needs_gc
()
slot_func_cname
=
scope
.
mangle_internal
(
"tp_dealloc"
)
slot_func_cname
=
scope
.
mangle_internal
(
"tp_dealloc"
)
code
.
putln
(
""
)
code
.
putln
(
""
)
code
.
putln
(
code
.
putln
(
"static void %s(PyObject *o) {"
%
slot_func_cname
)
"static void %s(PyObject *o) {"
%
slot_func_cname
)
if
cpp_class_attrs
:
weakref_slot
=
scope
.
lookup_here
(
"__weakref__"
)
_
,
(
py_attrs
,
_
,
memoryview_slices
)
=
scope
.
get_refcounted_entries
()
cpp_class_attrs
=
[
entry
for
entry
in
scope
.
var_entries
if
entry
.
type
.
is_cpp_class
]
if
(
py_attrs
or
cpp_class_attrs
or
memoryview_slices
or
weakref_slot
in
scope
.
var_entries
):
self
.
generate_self_cast
(
scope
,
code
)
self
.
generate_self_cast
(
scope
,
code
)
if
needs_finalisation
:
# We must mark ths object as (gc) untracked while tearing it down, lest
# before Py3.4, tp_finalize() isn't available, so this is
# the garbage collection is invoked while running this destructor.
# the earliest possible time where we can call it ourselves
if
scope
.
needs_gc
():
code
.
putln
(
"#if PY_VERSION_HEX < 0x030400a1"
)
if
needs_gc
:
# We must mark ths object as (gc) untracked while tearing
# it down, lest the garbage collection is invoked while
# running this destructor.
code
.
putln
(
"PyObject_GC_UnTrack(o);"
)
code
.
putln
(
"PyObject_GC_UnTrack(o);"
)
slot_func_cname
=
scope
.
mangle_internal
(
"tp_finalize"
)
code
.
putln
(
"%s(o);"
%
slot_func_cname
)
if
needs_gc
and
base_type
:
# The base class deallocator probably expects this to be
# tracked, so undo the untracking above.
code
.
putln
(
"PyObject_GC_Track(o);"
)
code
.
putln
(
"#endif"
)
if
needs_gc
and
not
base_type
:
# call the user's __dealloc__
code
.
putln
(
"PyObject_GC_UnTrack(o);"
)
self
.
generate_usr_dealloc_call
(
scope
,
code
)
if
weakref_slot
in
scope
.
var_entries
:
code
.
putln
(
"if (p->__weakref__) PyObject_ClearWeakRefs(o);"
)
for
entry
in
cpp_class_attrs
:
for
entry
in
cpp_class_attrs
:
split_cname
=
entry
.
type
.
cname
.
split
(
'::'
)
split_cname
=
entry
.
type
.
cname
.
split
(
'::'
)
...
@@ -1214,10 +1206,23 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -1214,10 +1206,23 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
while
destructor_name
.
count
(
'<'
)
!=
destructor_name
.
count
(
'>'
):
while
destructor_name
.
count
(
'<'
)
!=
destructor_name
.
count
(
'>'
):
destructor_name
=
split_cname
.
pop
()
+
'::'
+
destructor_name
destructor_name
=
split_cname
.
pop
()
+
'::'
+
destructor_name
destructor_name
=
destructor_name
.
split
(
'<'
,
1
)[
0
]
destructor_name
=
destructor_name
.
split
(
'<'
,
1
)[
0
]
code
.
putln
(
"p->%s.%s::~%s();"
%
(
code
.
putln
(
"p->%s.%s::~%s();"
%
entry
.
cname
,
entry
.
type
.
declaration_code
(
""
),
destructor_name
))
(
entry
.
cname
,
entry
.
type
.
declaration_code
(
""
),
destructor_name
))
for
entry
in
py_attrs
:
code
.
put_xdecref_clear
(
"p->%s"
%
entry
.
cname
,
entry
.
type
,
nanny
=
False
,
clear_before_decref
=
True
)
for
entry
in
memoryview_slices
:
code
.
put_xdecref_memoryviewslice
(
"p->%s"
%
entry
.
cname
,
have_gil
=
True
)
if
base_type
:
if
base_type
:
# The base class deallocator probably expects this to be tracked, so
# undo the untracking above.
if
scope
.
needs_gc
():
code
.
putln
(
"PyObject_GC_Track(o);"
)
tp_dealloc
=
TypeSlots
.
get_base_slot_function
(
scope
,
tp_slot
)
tp_dealloc
=
TypeSlots
.
get_base_slot_function
(
scope
,
tp_slot
)
if
tp_dealloc
is
not
None
:
if
tp_dealloc
is
not
None
:
code
.
putln
(
"%s(o);"
%
tp_dealloc
)
code
.
putln
(
"%s(o);"
%
tp_dealloc
)
...
@@ -1229,8 +1234,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -1229,8 +1234,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
# the module cleanup, which may already have cleared it.
# the module cleanup, which may already have cleared it.
# In that case, fall back to traversing the type hierarchy.
# In that case, fall back to traversing the type hierarchy.
base_cname
=
base_type
.
typeptr_cname
base_cname
=
base_type
.
typeptr_cname
code
.
putln
(
"if (likely(%s)) %s->tp_dealloc(o); "
code
.
putln
(
"if (likely(%s)) %s->tp_dealloc(o); else __Pyx_call_next_tp_dealloc(o, %s);"
%
(
"else __Pyx_call_next_tp_dealloc(o, %s);"
%
(
base_cname
,
base_cname
,
slot_func_cname
))
base_cname
,
base_cname
,
slot_func_cname
))
code
.
globalstate
.
use_utility_code
(
code
.
globalstate
.
use_utility_code
(
UtilityCode
.
load_cached
(
"CallNextTpDealloc"
,
"ExtensionTypes.c"
))
UtilityCode
.
load_cached
(
"CallNextTpDealloc"
,
"ExtensionTypes.c"
))
...
@@ -1252,81 +1256,28 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -1252,81 +1256,28 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code
.
putln
(
code
.
putln
(
"}"
)
"}"
)
def
generate_finalize_function
(
self
,
scope
,
code
):
def
generate_usr_dealloc_call
(
self
,
scope
,
code
):
if
not
scope
.
needs_finalisation
():
return
weakref_slot
=
scope
.
lookup_here
(
"__weakref__"
)
if
weakref_slot
not
in
scope
.
var_entries
:
weakref_slot
=
None
_
,
(
py_attrs
,
_
,
memoryview_slices
)
=
scope
.
get_refcounted_entries
()
slot_func_cname
=
scope
.
mangle_internal
(
"tp_finalize"
)
code
.
putln
(
""
)
code
.
putln
(
"static void %s(PyObject *o) {"
%
slot_func_cname
)
if
py_attrs
or
memoryview_slices
or
weakref_slot
:
self
.
generate_self_cast
(
scope
,
code
)
entry
=
scope
.
lookup_here
(
"__dealloc__"
)
entry
=
scope
.
lookup_here
(
"__dealloc__"
)
if
entry
:
if
entry
:
code
.
putln
(
"PyObject *etype, *eval, *etb;"
)
code
.
putln
(
code
.
putln
(
"PyErr_Fetch(&etype, &eval, &etb);"
)
"{"
)
code
.
putln
(
code
.
putln
(
"#if PY_VERSION_HEX < 0x030400a1"
)
"PyObject *etype, *eval, *etb;"
)
code
.
putln
(
"++Py_REFCNT(o);"
)
code
.
putln
(
code
.
putln
(
"#endif"
)
"PyErr_Fetch(&etype, &eval, &etb);"
)
code
.
putln
(
code
.
putln
(
"%s(o);"
%
entry
.
func_cname
)
"++Py_REFCNT(o);"
)
code
.
putln
(
"if (PyErr_Occurred()) PyErr_WriteUnraisable(o);"
)
code
.
putln
(
"%s(o);"
%
code
.
putln
(
"#if PY_VERSION_HEX < 0x030400a1"
)
entry
.
func_cname
)
code
.
putln
(
"--Py_REFCNT(o);"
)
code
.
putln
(
code
.
putln
(
"#endif"
)
"if (PyErr_Occurred()) PyErr_WriteUnraisable(o);"
)
code
.
putln
(
code
.
putln
(
"PyErr_Restore(etype, eval, etb);"
)
"--Py_REFCNT(o);"
)
code
.
putln
(
if
weakref_slot
:
"PyErr_Restore(etype, eval, etb);"
)
# Not using a preprocessor test here to avoid warning about
code
.
putln
(
# "unused variable p". Py3.4+ already cleared the weak refs
"}"
)
# when we get here.
# FIXME: so did Py<3.4 I think? Isn't this redundant?
code
.
putln
(
"if ((PY_VERSION_HEX < 0x030400a1) && p->__weakref__) "
"PyObject_ClearWeakRefs(o);"
)
for
entry
in
py_attrs
:
code
.
put_xdecref_clear
(
"p->%s"
%
entry
.
cname
,
entry
.
type
,
nanny
=
False
,
clear_before_decref
=
True
)
for
entry
in
memoryview_slices
:
code
.
put_xdecref_memoryviewslice
(
"p->%s"
%
entry
.
cname
,
have_gil
=
True
)
base_type
=
scope
.
parent_type
.
base_type
if
base_type
:
code
.
putln
(
"#if PY_VERSION_HEX >= 0x030400a1"
)
# need to call base_type method
tp_finalize
=
TypeSlots
.
get_base_slot_function
(
scope
,
TypeSlots
.
FinaliserSlot
())
if
tp_finalize
is
not
None
:
code
.
putln
(
"%s(o);"
%
tp_finalize
)
elif
base_type
.
is_builtin_type
:
code
.
putln
(
"if (%s->tp_finalize) %s->tp_finalize(o);"
%
(
base_type
.
typeptr_cname
,
base_type
.
typeptr_cname
))
else
:
# This is an externally defined type. Calling through the
# cimported base type pointer directly interacts badly with
# the module cleanup, which may already have cleared it.
# In that case, fall back to traversing the type hierarchy.
base_cname
=
base_type
.
typeptr_cname
code
.
putln
(
"if (likely(%s && %s->tp_finalize)) %s->tp_finalize(o); "
"else __Pyx_call_next_tp_finalize(o, %s);"
%
(
base_cname
,
base_cname
,
base_cname
,
slot_func_cname
))
code
.
globalstate
.
use_utility_code
(
UtilityCode
.
load_cached
(
"CallNextTpFinalize"
,
"ExtensionTypes.c"
))
code
.
putln
(
"#endif"
)
code
.
putln
(
"}"
)
def
generate_traverse_function
(
self
,
scope
,
code
,
cclass_entry
):
def
generate_traverse_function
(
self
,
scope
,
code
,
cclass_entry
):
tp_slot
=
TypeSlots
.
GCDependentSlot
(
"tp_traverse"
)
tp_slot
=
TypeSlots
.
GCDependentSlot
(
"tp_traverse"
)
...
...
Cython/Compiler/Symtab.py
View file @
45a17f1a
...
@@ -832,6 +832,25 @@ class Scope(object):
...
@@ -832,6 +832,25 @@ class Scope(object):
def
add_include_file
(
self
,
filename
):
def
add_include_file
(
self
,
filename
):
self
.
outer_scope
.
add_include_file
(
filename
)
self
.
outer_scope
.
add_include_file
(
filename
)
def
get_refcounted_entries
(
self
,
include_weakref
=
False
,
include_gc_simple
=
True
):
py_attrs
=
[]
py_buffers
=
[]
memoryview_slices
=
[]
for
entry
in
self
.
var_entries
:
if
entry
.
type
.
is_pyobject
:
if
include_weakref
or
entry
.
name
!=
"__weakref__"
:
if
include_gc_simple
or
not
entry
.
type
.
is_gc_simple
:
py_attrs
.
append
(
entry
)
elif
entry
.
type
==
PyrexTypes
.
c_py_buffer_type
:
py_buffers
.
append
(
entry
)
elif
entry
.
type
.
is_memoryviewslice
:
memoryview_slices
.
append
(
entry
)
have_entries
=
py_attrs
or
py_buffers
or
memoryview_slices
return
have_entries
,
(
py_attrs
,
py_buffers
,
memoryview_slices
)
class
PreImportScope
(
Scope
):
class
PreImportScope
(
Scope
):
...
@@ -1785,33 +1804,6 @@ class CClassScope(ClassScope):
...
@@ -1785,33 +1804,6 @@ class CClassScope(ClassScope):
return
not
self
.
parent_type
.
is_gc_simple
return
not
self
.
parent_type
.
is_gc_simple
return
False
return
False
def
get_refcounted_entries
(
self
,
include_weakref
=
False
,
include_gc_simple
=
True
):
py_attrs
=
[]
py_buffers
=
[]
memoryview_slices
=
[]
for
entry
in
self
.
var_entries
:
if
entry
.
type
.
is_pyobject
:
if
include_weakref
or
entry
.
name
!=
"__weakref__"
:
if
include_gc_simple
or
not
entry
.
type
.
is_gc_simple
:
py_attrs
.
append
(
entry
)
elif
entry
.
type
==
PyrexTypes
.
c_py_buffer_type
:
py_buffers
.
append
(
entry
)
elif
entry
.
type
.
is_memoryviewslice
:
memoryview_slices
.
append
(
entry
)
have_entries
=
py_attrs
or
py_buffers
or
memoryview_slices
return
have_entries
,
(
py_attrs
,
py_buffers
,
memoryview_slices
)
def
needs_finalisation
(
self
):
if
self
.
lookup_here
(
"__dealloc__"
):
return
True
has_gc_entries
,
_
=
self
.
get_refcounted_entries
(
include_weakref
=
True
)
if
has_gc_entries
:
return
True
return
False
def
declare_var
(
self
,
name
,
type
,
pos
,
def
declare_var
(
self
,
name
,
type
,
pos
,
cname
=
None
,
visibility
=
'private'
,
cname
=
None
,
visibility
=
'private'
,
api
=
0
,
in_pxd
=
0
,
is_cdef
=
0
):
api
=
0
,
in_pxd
=
0
,
is_cdef
=
0
):
...
@@ -1873,6 +1865,7 @@ class CClassScope(ClassScope):
...
@@ -1873,6 +1865,7 @@ class CClassScope(ClassScope):
self
.
namespace_cname
=
"(PyObject *)%s"
%
self
.
parent_type
.
typeptr_cname
self
.
namespace_cname
=
"(PyObject *)%s"
%
self
.
parent_type
.
typeptr_cname
return
entry
return
entry
def
declare_pyfunction
(
self
,
name
,
pos
,
allow_redefine
=
False
):
def
declare_pyfunction
(
self
,
name
,
pos
,
allow_redefine
=
False
):
# Add an entry for a method.
# Add an entry for a method.
if
name
in
(
'__eq__'
,
'__ne__'
,
'__lt__'
,
'__gt__'
,
'__le__'
,
'__ge__'
):
if
name
in
(
'__eq__'
,
'__ne__'
,
'__lt__'
,
'__gt__'
,
'__le__'
,
'__ge__'
):
...
@@ -2040,7 +2033,6 @@ class CClassScope(ClassScope):
...
@@ -2040,7 +2033,6 @@ class CClassScope(ClassScope):
if
base_entry
.
utility_code
:
if
base_entry
.
utility_code
:
entry
.
utility_code
=
base_entry
.
utility_code
entry
.
utility_code
=
base_entry
.
utility_code
class
CppClassScope
(
Scope
):
class
CppClassScope
(
Scope
):
# Namespace of a C++ class.
# Namespace of a C++ class.
...
...
Cython/Compiler/TypeSlots.py
View file @
45a17f1a
...
@@ -331,21 +331,6 @@ class GCDependentSlot(InternalMethodSlot):
...
@@ -331,21 +331,6 @@ class GCDependentSlot(InternalMethodSlot):
return
InternalMethodSlot
.
slot_code
(
self
,
scope
)
return
InternalMethodSlot
.
slot_code
(
self
,
scope
)
class
FinaliserSlot
(
InternalMethodSlot
):
"""
Descriptor for tp_finalize().
"""
def
__init__
(
self
):
InternalMethodSlot
.
__init__
(
self
,
'tp_finalize'
,
ifdef
=
"PY_VERSION_HEX >= 0x030400a1"
)
def
slot_code
(
self
,
scope
):
if
not
scope
.
needs_finalisation
():
return
'0'
return
InternalMethodSlot
.
slot_code
(
self
,
scope
)
class
ConstructorSlot
(
InternalMethodSlot
):
class
ConstructorSlot
(
InternalMethodSlot
):
# Descriptor for tp_new and tp_dealloc.
# Descriptor for tp_new and tp_dealloc.
...
@@ -405,8 +390,6 @@ class TypeFlagsSlot(SlotDescriptor):
...
@@ -405,8 +390,6 @@ class TypeFlagsSlot(SlotDescriptor):
value
+=
"|Py_TPFLAGS_BASETYPE"
value
+=
"|Py_TPFLAGS_BASETYPE"
if
scope
.
needs_gc
():
if
scope
.
needs_gc
():
value
+=
"|Py_TPFLAGS_HAVE_GC"
value
+=
"|Py_TPFLAGS_HAVE_GC"
if
scope
.
needs_finalisation
():
value
+=
"|Py_TPFLAGS_HAVE_FINALIZE"
return
value
return
value
...
@@ -805,7 +788,8 @@ slot_table = (
...
@@ -805,7 +788,8 @@ slot_table = (
EmptySlot
(
"tp_weaklist"
),
EmptySlot
(
"tp_weaklist"
),
EmptySlot
(
"tp_del"
),
EmptySlot
(
"tp_del"
),
EmptySlot
(
"tp_version_tag"
,
ifdef
=
"PY_VERSION_HEX >= 0x02060000"
),
EmptySlot
(
"tp_version_tag"
,
ifdef
=
"PY_VERSION_HEX >= 0x02060000"
),
FinaliserSlot
(),
# 'tp_finalize'
# TODO: change __dealloc__ to be called by tp_finalize (PEP 442)
EmptySlot
(
"tp_finalize"
,
ifdef
=
"PY_VERSION_HEX >= 0x03040a00"
),
)
)
#------------------------------------------------------------------------------------------
#------------------------------------------------------------------------------------------
...
...
Cython/Utility/CythonFunction.c
View file @
45a17f1a
...
@@ -634,7 +634,7 @@ static PyTypeObject __pyx_CyFunctionType_type = {
...
@@ -634,7 +634,7 @@ static PyTypeObject __pyx_CyFunctionType_type = {
#if PY_VERSION_HEX >= 0x02060000
#if PY_VERSION_HEX >= 0x02060000
0
,
/*tp_version_tag*/
0
,
/*tp_version_tag*/
#endif
#endif
#if PY_VERSION_HEX >= 0x03040
0a1
#if PY_VERSION_HEX >= 0x03040
a00
0
,
/*tp_finalize*/
0
,
/*tp_finalize*/
#endif
#endif
};
};
...
@@ -1082,7 +1082,7 @@ static PyTypeObject __pyx_FusedFunctionType_type = {
...
@@ -1082,7 +1082,7 @@ static PyTypeObject __pyx_FusedFunctionType_type = {
#if PY_VERSION_HEX >= 0x02060000
#if PY_VERSION_HEX >= 0x02060000
0
,
/*tp_version_tag*/
0
,
/*tp_version_tag*/
#endif
#endif
#if PY_VERSION_HEX >= 0x03040
0a1
#if PY_VERSION_HEX >= 0x03040
a00
0
,
/*tp_finalize*/
0
,
/*tp_finalize*/
#endif
#endif
};
};
...
...
Cython/Utility/ExtensionTypes.c
View file @
45a17f1a
...
@@ -16,27 +16,6 @@ static void __Pyx_call_next_tp_dealloc(PyObject* obj, destructor current_tp_deal
...
@@ -16,27 +16,6 @@ static void __Pyx_call_next_tp_dealloc(PyObject* obj, destructor current_tp_deal
type
->
tp_dealloc
(
obj
);
type
->
tp_dealloc
(
obj
);
}
}
/////////////// CallNextTpFinalize.proto ///////////////
#if PY_VERSION_HEX >= 0x030400a1
static
void
__Pyx_call_next_tp_finalize
(
PyObject
*
obj
,
destructor
current_tp_finalize
);
#endif
/////////////// CallNextTpFinalize ///////////////
#if PY_VERSION_HEX >= 0x030400a1
static
void
__Pyx_call_next_tp_finalize
(
PyObject
*
obj
,
destructor
current_tp_finalize
)
{
PyTypeObject
*
type
=
Py_TYPE
(
obj
);
/* try to find the first parent type that has a different tp_finalize() function */
while
(
type
&&
type
->
tp_finalize
!=
current_tp_finalize
)
type
=
type
->
tp_base
;
while
(
type
&&
(
!
type
->
tp_finalize
||
type
->
tp_finalize
==
current_tp_finalize
))
type
=
type
->
tp_base
;
if
(
type
)
type
->
tp_finalize
(
obj
);
}
#endif
/////////////// CallNextTpTraverse.proto ///////////////
/////////////// CallNextTpTraverse.proto ///////////////
static
int
__Pyx_call_next_tp_traverse
(
PyObject
*
obj
,
visitproc
v
,
void
*
a
,
traverseproc
current_tp_traverse
);
static
int
__Pyx_call_next_tp_traverse
(
PyObject
*
obj
,
visitproc
v
,
void
*
a
,
traverseproc
current_tp_traverse
);
...
...
Cython/Utility/Generator.c
View file @
45a17f1a
...
@@ -460,20 +460,16 @@ static void __Pyx_Generator_dealloc(PyObject *self) {
...
@@ -460,20 +460,16 @@ static void __Pyx_Generator_dealloc(PyObject *self) {
PyObject_GC_UnTrack
(
gen
);
PyObject_GC_UnTrack
(
gen
);
if
(
gen
->
gi_weakreflist
!=
NULL
)
if
(
gen
->
gi_weakreflist
!=
NULL
)
PyObject_ClearWeakRefs
(
self
);
PyObject_ClearWeakRefs
(
self
);
PyObject_GC_Track
(
self
);
if
(
gen
->
resume_label
>
0
)
{
if
(
gen
->
resume_label
>
0
)
{
/* Generator is paused, so we need to close */
/* Generator is paused, so we need to close */
PyObject_GC_Track
(
self
);
#if PY_VERSION_HEX >= 0x030400a1
if
(
PyObject_CallFinalizerFromDealloc
(
self
))
#else
Py_TYPE
(
gen
)
->
tp_del
(
self
);
Py_TYPE
(
gen
)
->
tp_del
(
self
);
if
(
self
->
ob_refcnt
>
0
)
if
(
self
->
ob_refcnt
>
0
)
#endif
return
;
/* resurrected. :( */
return
;
/* resurrected. :( */
PyObject_GC_UnTrack
(
self
);
}
}
PyObject_GC_UnTrack
(
self
);
__Pyx_Generator_clear
(
self
);
__Pyx_Generator_clear
(
self
);
PyObject_GC_Del
(
gen
);
PyObject_GC_Del
(
gen
);
}
}
...
@@ -486,11 +482,9 @@ static void __Pyx_Generator_del(PyObject *self) {
...
@@ -486,11 +482,9 @@ static void __Pyx_Generator_del(PyObject *self) {
if
(
gen
->
resume_label
<=
0
)
if
(
gen
->
resume_label
<=
0
)
return
;
return
;
#if PY_VERSION_HEX < 0x030400a1
/* Temporarily resurrect the object. */
/* Temporarily resurrect the object. */
assert
(
self
->
ob_refcnt
==
0
);
assert
(
self
->
ob_refcnt
==
0
);
self
->
ob_refcnt
=
1
;
self
->
ob_refcnt
=
1
;
#endif
/* Save the current exception, if any. */
/* Save the current exception, if any. */
__Pyx_ErrFetch
(
&
error_type
,
&
error_value
,
&
error_traceback
);
__Pyx_ErrFetch
(
&
error_type
,
&
error_value
,
&
error_traceback
);
...
@@ -505,7 +499,6 @@ static void __Pyx_Generator_del(PyObject *self) {
...
@@ -505,7 +499,6 @@ static void __Pyx_Generator_del(PyObject *self) {
/* Restore the saved exception. */
/* Restore the saved exception. */
__Pyx_ErrRestore
(
error_type
,
error_value
,
error_traceback
);
__Pyx_ErrRestore
(
error_type
,
error_value
,
error_traceback
);
#if PY_VERSION_HEX < 0x030400a1
/* Undo the temporary resurrection; can't use DECREF here, it would
/* Undo the temporary resurrection; can't use DECREF here, it would
* cause a recursive call.
* cause a recursive call.
*/
*/
...
@@ -539,7 +532,6 @@ static void __Pyx_Generator_del(PyObject *self) {
...
@@ -539,7 +532,6 @@ static void __Pyx_Generator_del(PyObject *self) {
--
Py_TYPE
(
self
)
->
tp_frees
;
--
Py_TYPE
(
self
)
->
tp_frees
;
--
Py_TYPE
(
self
)
->
tp_allocs
;
--
Py_TYPE
(
self
)
->
tp_allocs
;
#endif
#endif
#endif
}
}
static
PyMemberDef
__pyx_Generator_memberlist
[]
=
{
static
PyMemberDef
__pyx_Generator_memberlist
[]
=
{
...
@@ -586,7 +578,7 @@ static PyTypeObject __pyx_GeneratorType_type = {
...
@@ -586,7 +578,7 @@ static PyTypeObject __pyx_GeneratorType_type = {
0
,
/*tp_getattro*/
0
,
/*tp_getattro*/
0
,
/*tp_setattro*/
0
,
/*tp_setattro*/
0
,
/*tp_as_buffer*/
0
,
/*tp_as_buffer*/
Py_TPFLAGS_DEFAULT
|
Py_TPFLAGS_HAVE_GC
|
Py_TPFLAGS_HAVE_FINALIZE
,
/* tp_flags*/
Py_TPFLAGS_DEFAULT
|
Py_TPFLAGS_HAVE_GC
,
/* tp_flags*/
0
,
/*tp_doc*/
0
,
/*tp_doc*/
(
traverseproc
)
__Pyx_Generator_traverse
,
/*tp_traverse*/
(
traverseproc
)
__Pyx_Generator_traverse
,
/*tp_traverse*/
0
,
/*tp_clear*/
0
,
/*tp_clear*/
...
@@ -612,16 +604,12 @@ static PyTypeObject __pyx_GeneratorType_type = {
...
@@ -612,16 +604,12 @@ static PyTypeObject __pyx_GeneratorType_type = {
0
,
/*tp_cache*/
0
,
/*tp_cache*/
0
,
/*tp_subclasses*/
0
,
/*tp_subclasses*/
0
,
/*tp_weaklist*/
0
,
/*tp_weaklist*/
#if PY_VERSION_HEX >= 0x030400a1
0
,
#else
__Pyx_Generator_del
,
/*tp_del*/
__Pyx_Generator_del
,
/*tp_del*/
#endif
#if PY_VERSION_HEX >= 0x02060000
#if PY_VERSION_HEX >= 0x02060000
0
,
/*tp_version_tag*/
0
,
/*tp_version_tag*/
#endif
#endif
#if PY_VERSION_HEX >= 0x03040
0a1
#if PY_VERSION_HEX >= 0x03040
a00
__Pyx_Generator_del
,
/*tp_finalize*/
0
,
/*tp_finalize*/
#endif
#endif
};
};
...
...
Cython/Utility/ModuleSetupCode.c
View file @
45a17f1a
...
@@ -128,10 +128,6 @@
...
@@ -128,10 +128,6 @@
#define Py_TPFLAGS_HAVE_VERSION_TAG 0
#define Py_TPFLAGS_HAVE_VERSION_TAG 0
#endif
#endif
#if PY_VERSION_HEX < 0x030400a1 && !defined(Py_TPFLAGS_HAVE_FINALIZE)
#define Py_TPFLAGS_HAVE_FINALIZE 0
#endif
/* new Py3.3 unicode type (PEP 393) */
/* new Py3.3 unicode type (PEP 393) */
#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND)
#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND)
#define CYTHON_PEP393_ENABLED 1
#define CYTHON_PEP393_ENABLED 1
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment