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
Labels
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
nexedi
cython
Commits
52d40881
Commit
52d40881
authored
Jan 04, 2021
by
Xavier Thompson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix and refactor cypclass typecasts
parent
7677b120
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
303 additions
and
20 deletions
+303
-20
Cython/Compiler/ExprNodes.py
Cython/Compiler/ExprNodes.py
+15
-20
tests/run/cypclass_typecast.pyx
tests/run/cypclass_typecast.pyx
+288
-0
No files found.
Cython/Compiler/ExprNodes.py
View file @
52d40881
...
...
@@ -11004,11 +11004,11 @@ class TypecastNode(ExprNode):
imag_part
)
else
:
operand_type
=
self
.
operand
.
type
if
operand_type
.
is_cyp_class
:
if
self
.
overloaded
:
if
self
.
overloaded
:
if
operand_type
.
is_cyp_class
:
operand_result
=
'(*%s)'
%
operand_result
# use dynamic cast when dowcasting from a base to a cypclass
if
self
.
type
.
is_cyp_class
and
operand_type
in
self
.
type
.
mro
()
and
not
self
.
type
.
same_as
(
operand_type
):
elif
self
.
type
.
is_cyp_class
and
operand_type
in
self
.
type
.
mro
()
and
not
self
.
type
.
same_as
(
operand_type
):
# use dynamic cast when dowcasting from a base to a cypclass
return
self
.
type
.
dynamic_cast_code
(
operand_result
)
return
self
.
type
.
cast_code
(
operand_result
)
...
...
@@ -11033,22 +11033,17 @@ class TypecastNode(ExprNode):
self
.
operand
.
result
()))
code
.
put_incref
(
self
.
result
(),
self
.
ctype
())
elif
self
.
type
.
is_cyp_class
:
star
=
"*"
if
self
.
overloaded
else
""
operand_result
=
"%s%s"
%
(
star
,
self
.
operand
.
result
())
# use dynamic cast when dowcasting from a base to a cypclass
if
self
.
operand
.
type
in
self
.
type
.
mro
()
and
not
self
.
type
.
same_as
(
self
.
operand
.
type
):
code
.
putln
(
"%s = dynamic_cast<%s>(%s);"
%
(
self
.
result
(),
self
.
type
.
declaration_code
(
''
),
operand_result
))
else
:
code
.
putln
(
"%s = (%s)(%s);"
%
(
self
.
result
(),
self
.
type
.
declaration_code
(
''
),
operand_result
))
code
.
put_incref
(
self
.
result
(),
self
.
type
)
# self.overloaded is True
operand_type
=
self
.
operand
.
type
operand_result
=
self
.
operand
.
result
()
if
operand_type
.
is_cyp_class
:
operand_result
=
"*%s"
%
operand_result
code
.
putln
(
"%s = (%s)(%s);"
%
(
self
.
result
(),
self
.
type
.
declaration_code
(
''
),
operand_result
))
# the result is already a new reference
ERR_START
=
"Start may not be given"
...
...
tests/run/cypclass_typecast.pyx
0 → 100644
View file @
52d40881
# mode: run
# tag: cpp, cpp11, pthread
# cython: experimental_cpp_class_def=True, language_level=2
cdef
cypclass
Base
:
__dealloc__
(
self
)
with
gil
:
print
(
"Base destroyed"
)
cdef
cypclass
Derived
(
Base
):
__dealloc__
(
self
)
with
gil
:
print
(
"Derived destroyed"
)
def
test_upcast_name
():
"""
>>> test_upcast_name()
Derived destroyed
Base destroyed
0
"""
d
=
Derived
()
b
=
<
Base
>
d
if
Cy_GETREF
(
d
)
!=
3
:
return
-
1
del
b
if
Cy_GETREF
(
d
)
!=
2
:
return
-
2
return
0
def
test_upcast_and_drop_name
():
"""
>>> test_upcast_and_drop_name()
Derived destroyed
Base destroyed
0
"""
d
=
Derived
()
<
Base
>
d
if
Cy_GETREF
(
d
)
!=
2
:
return
-
1
return
0
def
test_upcast_constructed
():
"""
>>> test_upcast_constructed()
Derived destroyed
Base destroyed
0
"""
d
=
<
Base
>
Derived
()
if
Cy_GETREF
(
d
)
!=
2
:
return
-
1
return
0
def
test_upcast_and_drop_constructed
():
"""
>>> test_upcast_and_drop_constructed()
Derived destroyed
Base destroyed
0
"""
<
Base
>
Derived
()
return
0
def
test_downcast_name
():
"""
>>> test_downcast_name()
Derived destroyed
Base destroyed
0
"""
b
=
<
Base
>
Derived
()
d
=
<
Derived
>
b
if
Cy_GETREF
(
b
)
!=
3
:
return
-
1
del
b
if
Cy_GETREF
(
d
)
!=
2
:
return
-
2
return
0
def
test_downcast_and_drop_name
():
"""
>>> test_downcast_and_drop_name()
Derived destroyed
Base destroyed
0
"""
b
=
<
Base
>
Derived
()
<
Derived
>
b
if
Cy_GETREF
(
b
)
!=
2
:
return
-
1
return
0
def
test_downcast_constructed
():
"""
>>> test_downcast_constructed()
Derived destroyed
Base destroyed
0
"""
d
=
<
Derived
>
<
Base
>
Derived
()
if
Cy_GETREF
(
d
)
!=
2
:
return
-
1
return
0
def
test_downcast_and_drop_constructed
():
"""
>>> test_downcast_and_drop_constructed()
Derived destroyed
Base destroyed
0
"""
<
Derived
>
<
Base
>
Derived
()
return
0
def
test_failed_downcast
():
"""
>>> test_failed_downcast()
Base destroyed
0
"""
d
=
<
Derived
>
Base
()
if
d
is
not
NULL
:
return
-
1
return
0
cdef
cypclass
Convertible
:
Derived
__Derived__
(
self
)
with
gil
:
print
(
"Convertible -> Derived"
)
return
Derived
()
__dealloc__
(
self
)
with
gil
:
print
(
"Convertible destroyed"
)
def
test_convert_name
():
"""
>>> test_convert_name()
Convertible -> Derived
Convertible destroyed
Derived destroyed
Base destroyed
0
"""
c
=
Convertible
()
d
=
<
Derived
>
c
if
Cy_GETREF
(
c
)
!=
2
:
return
-
1
if
Cy_GETREF
(
d
)
!=
2
:
return
-
2
del
c
return
0
def
test_convert_and_drop_name
():
"""
>>> test_convert_and_drop_name()
Convertible -> Derived
Derived destroyed
Base destroyed
converted
Convertible destroyed
0
"""
c
=
Convertible
()
<
Derived
>
c
print
(
"converted"
)
if
Cy_GETREF
(
c
)
!=
2
:
return
-
1
return
0
def
test_convert_constructed
():
"""
>>> test_convert_constructed()
Convertible -> Derived
Convertible destroyed
converted
Derived destroyed
Base destroyed
0
"""
d
=
<
Derived
>
Convertible
()
print
(
"converted"
)
if
Cy_GETREF
(
d
)
!=
2
:
return
-
1
return
0
def
test_convert_and_drop_constructed
():
"""
>>> test_convert_and_drop_constructed()
Convertible -> Derived
Convertible destroyed
Derived destroyed
Base destroyed
converted
0
"""
<
Derived
>
Convertible
()
print
(
"converted"
)
return
0
cdef
cypclass
DerivedConvertible
(
Base
):
Base
__Base__
(
self
)
with
gil
:
print
(
"DerivedConvertible -> Base"
)
return
Base
()
__dealloc__
(
self
)
with
gil
:
print
(
"DerivedConvertible destroyed"
)
def
test_overloaded_upcast
():
"""
>>> test_overloaded_upcast()
DerivedConvertible -> Base
converted
DerivedConvertible destroyed
Base destroyed
Base destroyed
0
"""
d
=
DerivedConvertible
()
b
=
<
Base
>
d
print
(
"converted"
)
if
Cy_GETREF
(
d
)
!=
2
:
return
-
1
if
Cy_GETREF
(
b
)
!=
2
:
return
-
2
del
d
return
0
cdef
cypclass
BaseConvertible
cdef
cypclass
DerivedConverted
(
BaseConvertible
):
__dealloc__
(
self
)
with
gil
:
print
(
"DerivedConverted destroyed"
)
cdef
cypclass
BaseConvertible
:
DerivedConverted
__DerivedConverted__
(
self
)
with
gil
:
print
(
"BaseConvertible -> DerivedConverted"
)
return
DerivedConverted
()
__dealloc__
(
self
)
with
gil
:
print
(
"BaseConvertible destroyed"
)
def
test_overloaded_downcast
():
"""
>>> test_overloaded_downcast()
BaseConvertible -> DerivedConverted
converted
BaseConvertible destroyed
DerivedConverted destroyed
BaseConvertible destroyed
0
"""
b
=
BaseConvertible
()
d
=
<
DerivedConverted
>
b
print
(
"converted"
)
if
Cy_GETREF
(
d
)
!=
2
:
return
-
1
if
Cy_GETREF
(
b
)
!=
2
:
return
-
2
del
b
return
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