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
Xavier Thompson
cython
Commits
d784e746
Commit
d784e746
authored
4 years ago
by
Xavier Thompson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Make cypclass wrappers mirror single inheritance of underlying cypclass
parent
7fb4f606
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
65 additions
and
10 deletions
+65
-10
Cython/Compiler/CypclassWrapper.py
Cython/Compiler/CypclassWrapper.py
+36
-6
Cython/Compiler/Nodes.py
Cython/Compiler/Nodes.py
+10
-2
Cython/Compiler/PyrexTypes.py
Cython/Compiler/PyrexTypes.py
+17
-2
Cython/Compiler/Symtab.py
Cython/Compiler/Symtab.py
+2
-0
No files found.
Cython/Compiler/CypclassWrapper.py
View file @
d784e746
...
...
@@ -102,6 +102,7 @@ class CypclassWrapperInjection(VisitorTransform):
def
__call__
(
self
,
root
):
self
.
cypclass_wrappers_stack
=
[]
self
.
nesting_stack
=
[]
self
.
module_scope
=
root
.
scope
return
super
(
CypclassWrapperInjection
,
self
).
__call__
(
root
)
def
visit_Node
(
self
,
node
):
...
...
@@ -154,17 +155,45 @@ class CypclassWrapperInjection(VisitorTransform):
if
not
node_has_suite
:
return
None
if
len
(
node
.
base_classes
)
>
1
:
return
None
# TODO: take nesting into account for the name
cclass_name
=
EncodedString
(
"%s_cyp_wrapper"
%
node
.
name
)
from
.ExprNodes
import
TupleNode
cclass_bases
=
TupleNode
(
node
.
pos
,
args
=
[])
bases_args
=
[]
if
node
.
base_classes
:
first_base
=
node
.
base_classes
[
0
]
if
isinstance
(
first_base
,
Nodes
.
CSimpleBaseTypeNode
)
and
first_base
.
templates
is
None
:
first_base_name
=
first_base
.
name
builtin_entry
=
self
.
module_scope
.
lookup
(
first_base_name
)
if
builtin_entry
is
not
None
:
return
wrapped_first_base
=
Nodes
.
CSimpleBaseTypeNode
(
first_base
.
pos
,
name
=
"%s_cyp_wrapper"
%
first_base_name
,
module_path
=
[],
is_basic_c_type
=
first_base
.
is_basic_c_type
,
signed
=
first_base
.
signed
,
complex
=
first_base
.
complex
,
longness
=
first_base
.
longness
,
is_self_arg
=
first_base
.
is_self_arg
,
templates
=
None
)
bases_args
.
append
(
wrapped_first_base
)
cclass_bases
=
TupleNode
(
node
.
pos
,
args
=
bases_args
)
# the underlying cyobject must come first thing after PyObject_HEAD in the memory layout
# long term, only the base class will declare the underlying attribute
stats
=
[]
if
not
bases_args
:
underlying_cyobject
=
self
.
synthesize_underlying_cyobject_attribute
(
node
)
stats
=
[
underlying_cyobject
]
stats
.
append
(
underlying_cyobject
)
cclass_body
=
Nodes
.
StatListNode
(
pos
=
node
.
pos
,
stats
=
stats
)
cclass_doc
=
EncodedString
(
"Python Object wrapper for underlying cypclass %s"
%
node
.
name
)
wrapper
=
Nodes
.
CypclassWrapperDefNode
(
...
...
@@ -182,7 +211,7 @@ class CypclassWrapperInjection(VisitorTransform):
in_pxd
=
node
.
in_pxd
,
doc
=
cclass_doc
,
body
=
cclass_body
,
wrapped_cypclass
=
node
wrapped_cypclass
=
node
,
)
return
wrapper
...
...
@@ -717,9 +746,10 @@ def generate_cyp_class_wrapper_definition(type, wrapper_entry, constructor_entry
# initialise PyObject fields
if
is_new_return_type
and
type
.
wrapper_type
:
objstruct_cname
=
type
.
wrapper_type
.
objstruct_cname
cclass_wrapper_base
=
type
.
wrapped_base_type
.
wrapper_type
code
.
putln
(
"if(self) {"
)
code
.
putln
(
"%s * wrapper = new %s();"
%
(
objstruct_cname
,
objstruct_cname
))
code
.
putln
(
"
wrapper->nogil_cyobject = self;"
)
code
.
putln
(
"
((%s *)wrapper)->nogil_cyobject = self;"
%
cclass_wrapper_base
.
objstruct_cname
)
code
.
putln
(
"PyObject * wrapper_as_py = (PyObject *) wrapper;"
)
code
.
putln
(
"wrapper_as_py->ob_refcnt = 0;"
)
code
.
putln
(
"wrapper_as_py->ob_type = %s;"
%
type
.
wrapper_type
.
typeptr_cname
)
...
...
This diff is collapsed.
Click to expand it.
Cython/Compiler/Nodes.py
View file @
d784e746
...
...
@@ -5441,7 +5441,15 @@ class CypclassWrapperDefNode(CClassDefNode):
# > access the method of the underlying cyobject from the self argument of the wrapper method
underlying_obj
=
ExprNodes
.
AttributeNode
(
cfunc_method
.
pos
,
obj
=
self_obj
,
attribute
=
underlying_name
)
cfunc
=
ExprNodes
.
AttributeNode
(
cfunc_method
.
pos
,
obj
=
underlying_obj
,
attribute
=
cfunc_name
)
empty_declarator
=
CNameDeclaratorNode
(
cfunc_method
.
pos
,
name
=
""
,
cname
=
None
)
cast_underlying_obj
=
ExprNodes
.
TypecastNode
(
cfunc_method
.
pos
,
type
=
self
.
wrapped_cypclass
.
entry
.
type
,
operand
=
underlying_obj
,
typecheck
=
False
)
cfunc
=
ExprNodes
.
AttributeNode
(
cfunc_method
.
pos
,
obj
=
cast_underlying_obj
,
attribute
=
cfunc_name
)
# > call to the underlying method
c_call
=
ExprNodes
.
SimpleCallNode
(
...
...
This diff is collapsed.
Click to expand it.
Cython/Compiler/PyrexTypes.py
View file @
d784e746
...
...
@@ -3961,16 +3961,31 @@ class CypClassType(CppClassType):
# lock_mode string (tri-state: "nolock"/"checklock"/"autolock")
# _mro [CppClassType] or None the Method Resolution Order of this cypclass according to Python
# wrapper_type PyExtensionType or None the type of the cclass wrapper
# wrapped_base_type CypClassType or None the type of the oldest wrapped cypclass base
is_cyp_class
=
1
to_py_function
=
None
def
__init__
(
self
,
name
,
scope
,
cname
,
base_classes
,
templates
=
None
,
template_type
=
None
,
nogil
=
0
,
lock_mode
=
None
,
activable
=
False
):
CppClassType
.
__init__
(
self
,
name
,
scope
,
cname
,
base_classes
,
templates
,
template_type
,
nogil
)
if
base_classes
:
self
.
find_wrapped_base_type
(
base_classes
)
self
.
lock_mode
=
lock_mode
if
lock_mode
else
"autolock"
self
.
activable
=
activable
self
.
_mro
=
None
self
.
wrapper_type
=
None
# set during
self
.
wrapper_type
=
None
self
.
wrapped_base_type
=
None
def
find_wrapped_base_type
(
self
,
base_classes
):
first_wrapped_cypclass_base
=
None
for
base_type
in
base_classes
:
if
base_type
.
is_cyp_class
and
base_type
.
wrapper_type
:
first_wrapped_cypclass_base
=
base_type
break
if
first_wrapped_cypclass_base
:
self
.
wrapped_base_type
=
first_wrapped_cypclass_base
.
wrapped_base_type
else
:
self
.
wrapped_base_type
=
self
# Return the MRO for this cypclass
# Compute all the mro needed when a previous computation is not available
...
...
@@ -4005,7 +4020,7 @@ class CypClassType(CppClassType):
def
create_from_py_utility_code
(
self
,
env
):
if
not
self
.
wrapper_type
:
return
False
wrapper_objstruct
=
self
.
wrapper_type
.
objstruct_cname
wrapper_objstruct
=
self
.
wrappe
d_base_type
.
wrappe
r_type
.
objstruct_cname
underlying_type_name
=
self
.
cname
self
.
from_py_function
=
"__Pyx_PyObject_AsCyObject<%s, %s>"
%
(
wrapper_objstruct
,
underlying_type_name
)
return
True
...
...
This diff is collapsed.
Click to expand it.
Cython/Compiler/Symtab.py
View file @
d784e746
...
...
@@ -735,6 +735,8 @@ class Scope(object):
entry
.
already_declared_here
()
else
:
entry
.
type
.
base_classes
=
base_classes
if
cypclass
:
entry
.
type
.
find_wrapped_base_type
(
base_classes
)
if
templates
or
entry
.
type
.
templates
:
if
templates
!=
entry
.
type
.
templates
:
error
(
pos
,
"Template parameters do not match previous declaration"
)
...
...
This diff is collapsed.
Click to expand it.
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