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
Kirill Smelkov
cython
Commits
30546e71
Commit
30546e71
authored
Mar 17, 2018
by
Stefan Behnel
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Only declare the C++ no-args constructor as "nogil" if the base classes allow it.
Closes #2157.
parent
edde08f7
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
45 additions
and
7 deletions
+45
-7
Cython/Compiler/ExprNodes.py
Cython/Compiler/ExprNodes.py
+1
-6
Cython/Compiler/PyrexTypes.py
Cython/Compiler/PyrexTypes.py
+17
-0
tests/run/cpp_classes.pyx
tests/run/cpp_classes.pyx
+27
-1
No files found.
Cython/Compiler/ExprNodes.py
View file @
30546e71
...
...
@@ -1729,12 +1729,7 @@ class NewExprNode(AtomicExprNode):
self
.
type
=
error_type
return
self
.
cpp_check
(
env
)
constructor
=
type
.
scope
.
lookup
(
u'<init>'
)
if
constructor
is
None
:
func_type
=
PyrexTypes
.
CFuncType
(
type
,
[],
exception_check
=
'+'
,
nogil
=
True
)
type
.
scope
.
declare_cfunction
(
u'<init>'
,
func_type
,
self
.
pos
)
constructor
=
type
.
scope
.
lookup
(
u'<init>'
)
constructor
=
type
.
get_constructor
(
self
.
pos
)
self
.
class_type
=
type
self
.
entry
=
constructor
self
.
type
=
constructor
.
type
...
...
Cython/Compiler/PyrexTypes.py
View file @
30546e71
...
...
@@ -3817,6 +3817,23 @@ class CppClassType(CType):
func_type
=
func_type
.
base_type
return
func_type
.
return_type
def
get_constructor
(
self
,
pos
):
constructor
=
self
.
scope
.
lookup
(
'<init>'
)
if
constructor
is
not
None
:
return
constructor
# Otherwise: automatically declare no-args default constructor.
# Make it "nogil" if the base classes allow it.
nogil
=
True
for
base
in
self
.
base_classes
:
base_constructor
=
base
.
scope
.
lookup
(
'<init>'
)
if
base_constructor
and
not
base_constructor
.
type
.
nogil
:
nogil
=
False
break
func_type
=
CFuncType
(
self
,
[],
exception_check
=
'+'
,
nogil
=
nogil
)
return
self
.
scope
.
declare_cfunction
(
u'<init>'
,
func_type
,
pos
)
def
check_nullary_constructor
(
self
,
pos
,
msg
=
"stack allocated"
):
constructor
=
self
.
scope
.
lookup
(
u'<init>'
)
if
constructor
is
not
None
and
best_match
([],
constructor
.
all_alternatives
())
is
None
:
...
...
tests/run/cpp_classes.pyx
View file @
30546e71
...
...
@@ -9,7 +9,7 @@ cdef extern from "shapes.h" namespace "shapes":
float
area
()
cdef
cppclass
Ellipse
(
Shape
):
Ellipse
(
int
a
,
int
b
)
except
+
Ellipse
(
int
a
,
int
b
)
nogil
except
+
cdef
cppclass
Circle
(
Ellipse
):
int
radius
...
...
@@ -32,6 +32,7 @@ cdef extern from "shapes.h" namespace "shapes":
int
constructor_count
,
destructor_count
def
test_new_del
():
"""
>>> test_new_del()
...
...
@@ -45,6 +46,7 @@ def test_new_del():
del
rect
,
circ
print
constructor_count
-
c
,
destructor_count
-
d
def
test_default_constructor
():
"""
>>> test_default_constructor()
...
...
@@ -56,6 +58,20 @@ def test_default_constructor():
finally
:
del
shape
def
test_constructor_nogil
():
"""
>>> test_constructor_nogil()
True
"""
with
nogil
:
shape
=
new
Ellipse
(
4
,
5
)
try
:
return
62
<
shape
.
area
()
<
63
or
shape
.
area
()
finally
:
del
shape
def
test_rect_area
(
w
,
h
):
"""
>>> test_rect_area(3, 4)
...
...
@@ -67,6 +83,7 @@ def test_rect_area(w, h):
finally
:
del
rect
def
test_overload_bint_int
():
"""
>>> test_overload_bint_int()
...
...
@@ -83,6 +100,7 @@ def test_overload_bint_int():
del
rect1
del
rect2
def
test_square_area
(
w
):
"""
>>> test_square_area(15)
...
...
@@ -95,6 +113,7 @@ def test_square_area(w):
finally
:
del
sqr
cdef
double
get_area
(
Rectangle
s
):
return
s
.
area
()
...
...
@@ -110,6 +129,7 @@ def test_value_call(int w):
finally
:
del
sqr
def
get_destructor_count
():
return
destructor_count
...
...
@@ -126,6 +146,7 @@ def test_stack_allocation(int w, int h):
print
rect
.
method
(
<
int
>
5
)
return
destructor_count
cdef
class
EmptyHolder
:
cdef
Empty
empty
...
...
@@ -148,6 +169,7 @@ def test_class_member():
assert
destructor_count
-
start_destructor_count
==
2
,
\
destructor_count
-
start_destructor_count
def
test_derived_class_member
():
"""
>>> test_derived_class_member()
...
...
@@ -161,6 +183,7 @@ def test_derived_class_member():
assert
destructor_count
-
start_destructor_count
==
2
,
\
destructor_count
-
start_destructor_count
cdef
class
TemplateClassMember
:
cdef
vector
[
int
]
x
cdef
vector
[
vector
[
Empty
]]
vec
...
...
@@ -190,6 +213,9 @@ cdef int f(int x):
return
x
def
test_nested_del
():
"""
>>> test_nested_del()
"""
cdef
vector
[
vector_int_ptr
]
v
v
.
push_back
(
new
vector
[
int
]())
del
v
[
0
]
...
...
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