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
5a76ba3e
Commit
5a76ba3e
authored
Jul 27, 2013
by
Stefan Behnel
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
prevent simple builtin typed exttype attributes from triggering GC support
parent
69561c17
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
135 additions
and
16 deletions
+135
-16
Cython/Compiler/PyrexTypes.py
Cython/Compiler/PyrexTypes.py
+8
-0
Cython/Compiler/Symtab.py
Cython/Compiler/Symtab.py
+18
-8
Cython/Compiler/TypeSlots.py
Cython/Compiler/TypeSlots.py
+8
-8
tests/run/cyclic_gc.pyx
tests/run/cyclic_gc.pyx
+101
-0
No files found.
Cython/Compiler/PyrexTypes.py
View file @
5a76ba3e
...
@@ -859,6 +859,7 @@ class PyObjectType(PyrexType):
...
@@ -859,6 +859,7 @@ class PyObjectType(PyrexType):
buffer_defaults
=
None
buffer_defaults
=
None
is_extern
=
False
is_extern
=
False
is_subclassed
=
False
is_subclassed
=
False
is_gc_simple
=
False
def
__str__
(
self
):
def
__str__
(
self
):
return
"Python object"
return
"Python object"
...
@@ -909,6 +910,12 @@ class PyObjectType(PyrexType):
...
@@ -909,6 +910,12 @@ class PyObjectType(PyrexType):
return
cname
return
cname
builtin_types_that_cannot_create_refcycles
=
set
([
'bool'
,
'int'
,
'long'
,
'float'
,
'complex'
,
'bytearray'
,
'bytes'
,
'unicode'
,
'str'
,
'basestring'
])
class
BuiltinObjectType
(
PyObjectType
):
class
BuiltinObjectType
(
PyObjectType
):
# objstruct_cname string Name of PyObject struct
# objstruct_cname string Name of PyObject struct
...
@@ -929,6 +936,7 @@ class BuiltinObjectType(PyObjectType):
...
@@ -929,6 +936,7 @@ class BuiltinObjectType(PyObjectType):
self
.
cname
=
cname
self
.
cname
=
cname
self
.
typeptr_cname
=
"(&%s)"
%
cname
self
.
typeptr_cname
=
"(&%s)"
%
cname
self
.
objstruct_cname
=
objstruct_cname
self
.
objstruct_cname
=
objstruct_cname
self
.
is_gc_simple
=
name
in
builtin_types_that_cannot_create_refcycles
def
set_scope
(
self
,
scope
):
def
set_scope
(
self
,
scope
):
self
.
scope
=
scope
self
.
scope
=
scope
...
...
Cython/Compiler/Symtab.py
View file @
5a76ba3e
...
@@ -1769,6 +1769,7 @@ class CClassScope(ClassScope):
...
@@ -1769,6 +1769,7 @@ class CClassScope(ClassScope):
# method_table_cname string
# method_table_cname string
# getset_table_cname string
# getset_table_cname string
# has_pyobject_attrs boolean Any PyObject attributes?
# has_pyobject_attrs boolean Any PyObject attributes?
# has_cyclic_pyobject_attrs boolean Any PyObject attributes that may need GC?
# property_entries [Entry]
# property_entries [Entry]
# defined boolean Defined in .pxd file
# defined boolean Defined in .pxd file
# implemented boolean Defined in .pyx file
# implemented boolean Defined in .pyx file
...
@@ -1776,24 +1777,30 @@ class CClassScope(ClassScope):
...
@@ -1776,24 +1777,30 @@ class CClassScope(ClassScope):
is_c_class_scope
=
1
is_c_class_scope
=
1
has_pyobject_attrs
=
False
has_cyclic_pyobject_attrs
=
False
defined
=
False
implemented
=
False
def
__init__
(
self
,
name
,
outer_scope
,
visibility
):
def
__init__
(
self
,
name
,
outer_scope
,
visibility
):
ClassScope
.
__init__
(
self
,
name
,
outer_scope
)
ClassScope
.
__init__
(
self
,
name
,
outer_scope
)
if
visibility
!=
'extern'
:
if
visibility
!=
'extern'
:
self
.
method_table_cname
=
outer_scope
.
mangle
(
Naming
.
methtab_prefix
,
name
)
self
.
method_table_cname
=
outer_scope
.
mangle
(
Naming
.
methtab_prefix
,
name
)
self
.
getset_table_cname
=
outer_scope
.
mangle
(
Naming
.
gstab_prefix
,
name
)
self
.
getset_table_cname
=
outer_scope
.
mangle
(
Naming
.
gstab_prefix
,
name
)
self
.
has_pyobject_attrs
=
0
self
.
property_entries
=
[]
self
.
property_entries
=
[]
self
.
inherited_var_entries
=
[]
self
.
inherited_var_entries
=
[]
self
.
defined
=
0
self
.
implemented
=
0
def
needs_gc
(
self
):
def
needs_gc
(
self
):
# If the type or any of its base types have Python-valued
# If the type or any of its base types have Python-valued
# C attributes, then it needs to participate in GC.
# C attributes, then it needs to participate in GC.
return
self
.
has_pyobject_attrs
or
\
if
self
.
has_cyclic_pyobject_attrs
:
(
self
.
parent_type
.
base_type
and
return
True
self
.
parent_type
.
base_type
.
scope
is
not
None
and
base_type
=
self
.
parent_type
.
base_type
self
.
parent_type
.
base_type
.
scope
.
needs_gc
())
if
base_type
and
base_type
.
scope
is
not
None
:
return
base_type
.
scope
.
needs_gc
()
elif
self
.
parent_type
.
is_builtin_type
:
return
not
self
.
parent_type
.
is_gc_simple
return
False
def
declare_var
(
self
,
name
,
type
,
pos
,
def
declare_var
(
self
,
name
,
type
,
pos
,
cname
=
None
,
visibility
=
'private'
,
cname
=
None
,
visibility
=
'private'
,
...
@@ -1819,7 +1826,10 @@ class CClassScope(ClassScope):
...
@@ -1819,7 +1826,10 @@ class CClassScope(ClassScope):
entry
.
is_variable
=
1
entry
.
is_variable
=
1
self
.
var_entries
.
append
(
entry
)
self
.
var_entries
.
append
(
entry
)
if
type
.
is_pyobject
and
name
!=
'__weakref__'
:
if
type
.
is_pyobject
and
name
!=
'__weakref__'
:
self
.
has_pyobject_attrs
=
1
self
.
has_pyobject_attrs
=
True
if
(
not
type
.
is_builtin_type
or
not
type
.
scope
or
type
.
scope
.
needs_gc
()):
self
.
has_cyclic_pyobject_attrs
=
True
if
visibility
not
in
(
'private'
,
'public'
,
'readonly'
):
if
visibility
not
in
(
'private'
,
'public'
,
'readonly'
):
error
(
pos
,
error
(
pos
,
"Attribute of extension type cannot be declared %s"
%
visibility
)
"Attribute of extension type cannot be declared %s"
%
visibility
)
...
...
Cython/Compiler/TypeSlots.py
View file @
5a76ba3e
...
@@ -319,10 +319,10 @@ class GCDependentSlot(InternalMethodSlot):
...
@@ -319,10 +319,10 @@ class GCDependentSlot(InternalMethodSlot):
def
slot_code
(
self
,
scope
):
def
slot_code
(
self
,
scope
):
if
not
scope
.
needs_gc
():
if
not
scope
.
needs_gc
():
return
"0"
return
"0"
if
not
scope
.
has_pyobject_attrs
:
if
not
scope
.
has_
cyclic_
pyobject_attrs
:
# if the type does not have object attributes, it can
# if the type does not have
GC relevant
object attributes, it can
# delegate GC methods to its parent - iff the parent
# delegate GC methods to its parent - iff the parent
functions
#
functions
are defined in the same module
# are defined in the same module
parent_type_scope
=
scope
.
parent_type
.
base_type
.
scope
parent_type_scope
=
scope
.
parent_type
.
base_type
.
scope
if
scope
.
parent_scope
is
parent_type_scope
.
parent_scope
:
if
scope
.
parent_scope
is
parent_type_scope
.
parent_scope
:
entry
=
scope
.
parent_scope
.
lookup_here
(
scope
.
parent_type
.
base_type
.
name
)
entry
=
scope
.
parent_scope
.
lookup_here
(
scope
.
parent_type
.
base_type
.
name
)
...
@@ -339,10 +339,10 @@ class ConstructorSlot(InternalMethodSlot):
...
@@ -339,10 +339,10 @@ class ConstructorSlot(InternalMethodSlot):
self
.
method
=
method
self
.
method
=
method
def
slot_code
(
self
,
scope
):
def
slot_code
(
self
,
scope
):
if
self
.
slot_name
!=
'tp_new'
\
if
(
self
.
slot_name
!=
'tp_new'
and
scope
.
parent_type
.
base_type
\
and
scope
.
parent_type
.
base_type
and
not
scope
.
has_pyobject_attrs
\
and
not
scope
.
has_pyobject_attrs
and
not
scope
.
lookup_here
(
self
.
method
):
and
not
scope
.
lookup_here
(
self
.
method
)
):
# if the type does not have object attributes, it can
# if the type does not have object attributes, it can
# delegate GC methods to its parent - iff the parent
# delegate GC methods to its parent - iff the parent
# functions are defined in the same module
# functions are defined in the same module
...
...
tests/run/cyclic_gc.pyx
0 → 100644
View file @
5a76ba3e
# mode: run
# tag: cyclicgc
cimport
cython
@
cython
.
test_fail_if_path_exists
(
'//CClassDefNode[@scope.has_cyclic_pyobject_attrs = True]'
)
@
cython
.
test_assert_path_exists
(
'//CClassDefNode'
,
'//CClassDefNode[@scope]'
,
'//CClassDefNode[@scope.has_cyclic_pyobject_attrs = False]'
)
cdef
class
ExtTypeNoGC
:
"""
>>> obj = ExtTypeNoGC()
>>> obj = ExtTypeNoGC()
>>> obj = ExtTypeNoGC()
>>> obj = ExtTypeNoGC()
>>> obj = ExtTypeNoGC()
>>> obj = ExtTypeNoGC()
"""
@
cython
.
test_fail_if_path_exists
(
'//CClassDefNode[@scope.has_cyclic_pyobject_attrs = True]'
)
@
cython
.
test_assert_path_exists
(
'//CClassDefNode'
,
'//CClassDefNode[@scope]'
,
'//CClassDefNode[@scope.has_cyclic_pyobject_attrs = False]'
)
cdef
class
ExtSubTypeNoGC
(
ExtTypeNoGC
):
"""
>>> obj = ExtSubTypeNoGC()
>>> obj = ExtSubTypeNoGC()
>>> obj = ExtSubTypeNoGC()
>>> obj = ExtSubTypeNoGC()
>>> obj = ExtSubTypeNoGC()
>>> obj = ExtSubTypeNoGC()
"""
@
cython
.
test_fail_if_path_exists
(
'//CClassDefNode[@scope.has_cyclic_pyobject_attrs = True]'
)
@
cython
.
test_assert_path_exists
(
'//CClassDefNode'
,
'//CClassDefNode[@scope]'
,
'//CClassDefNode[@scope.has_cyclic_pyobject_attrs = False]'
)
cdef
class
ExtTypePyArgsNoGC
:
"""
>>> obj = ExtTypePyArgsNoGC()
>>> obj = ExtTypePyArgsNoGC()
>>> obj = ExtTypePyArgsNoGC()
>>> obj = ExtTypePyArgsNoGC()
>>> obj = ExtTypePyArgsNoGC()
>>> obj = ExtTypePyArgsNoGC()
"""
cdef
bytes
b
cdef
str
s
cdef
unicode
u
@
cython
.
test_fail_if_path_exists
(
'//CClassDefNode[@scope.has_cyclic_pyobject_attrs = True]'
)
@
cython
.
test_assert_path_exists
(
'//CClassDefNode'
,
'//CClassDefNode[@scope]'
,
'//CClassDefNode[@scope.has_cyclic_pyobject_attrs = False]'
)
cdef
class
ExtSubTypePyArgsNoGC
(
ExtTypePyArgsNoGC
):
"""
>>> obj = ExtSubTypePyArgsNoGC()
>>> obj = ExtSubTypePyArgsNoGC()
>>> obj = ExtSubTypePyArgsNoGC()
>>> obj = ExtSubTypePyArgsNoGC()
>>> obj = ExtSubTypePyArgsNoGC()
>>> obj = ExtSubTypePyArgsNoGC()
"""
@
cython
.
test_fail_if_path_exists
(
'//CClassDefNode[@scope.has_cyclic_pyobject_attrs = False]'
)
@
cython
.
test_assert_path_exists
(
'//CClassDefNode'
,
'//CClassDefNode[@scope]'
,
'//CClassDefNode[@scope.has_cyclic_pyobject_attrs = True]'
)
cdef
class
ExtTypePyArgsWithGC
:
"""
>>> obj = ExtTypePyArgsWithGC()
>>> obj = ExtTypePyArgsWithGC()
>>> obj = ExtTypePyArgsWithGC()
>>> obj = ExtTypePyArgsWithGC()
>>> obj = ExtTypePyArgsWithGC()
>>> obj = ExtTypePyArgsWithGC()
"""
cdef
bytes
b
cdef
str
s
cdef
unicode
u
cdef
list
l
@
cython
.
test_fail_if_path_exists
(
'//CClassDefNode[@scope.has_cyclic_pyobject_attrs = True]'
)
@
cython
.
test_assert_path_exists
(
'//CClassDefNode'
,
'//CClassDefNode[@scope]'
,
'//CClassDefNode[@scope.has_cyclic_pyobject_attrs = False]'
)
cdef
class
ExtSubTypePyArgsWithGC
(
ExtTypePyArgsWithGC
):
"""
>>> obj = ExtSubTypePyArgsWithGC()
>>> obj = ExtSubTypePyArgsWithGC()
>>> obj = ExtSubTypePyArgsWithGC()
>>> obj = ExtSubTypePyArgsWithGC()
>>> obj = ExtSubTypePyArgsWithGC()
>>> obj = ExtSubTypePyArgsWithGC()
"""
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