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
becd5ce7
Commit
becd5ce7
authored
Oct 10, 2017
by
Robert Bradshaw
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Allow multiple bases for cdef classes.
parent
6a5a9c05
Changes
6
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
152 additions
and
92 deletions
+152
-92
Cython/Compiler/ModuleNode.py
Cython/Compiler/ModuleNode.py
+10
-12
Cython/Compiler/Nodes.py
Cython/Compiler/Nodes.py
+85
-65
Cython/Compiler/Parsing.py
Cython/Compiler/Parsing.py
+9
-14
Cython/Compiler/PyrexTypes.py
Cython/Compiler/PyrexTypes.py
+2
-0
tests/errors/subtyping_final_class.pyx
tests/errors/subtyping_final_class.pyx
+1
-1
tests/run/cdef_multiple_inheritance.pyx
tests/run/cdef_multiple_inheritance.pyx
+45
-0
No files found.
Cython/Compiler/ModuleNode.py
View file @
becd5ce7
...
...
@@ -2874,8 +2874,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
else
:
self
.
generate_base_type_import_code
(
env
,
entry
,
code
)
self
.
generate_exttype_vtable_init_code
(
entry
,
code
)
self
.
generate_type_ready_code
(
env
,
entry
,
code
)
self
.
generate_typeptr_assignment
_code
(
entry
,
code
)
if
entry
.
type
.
early_init
:
self
.
generate_type_ready
_code
(
entry
,
code
)
def
generate_base_type_import_code
(
self
,
env
,
entry
,
code
):
base_type
=
entry
.
type
.
base_type
...
...
@@ -2949,7 +2949,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
not
type
.
is_external
or
type
.
is_subclassed
,
error_code
))
def
generate_type_ready_code
(
self
,
env
,
entry
,
code
):
@
staticmethod
def
generate_type_ready_code
(
entry
,
code
):
# Generate a call to PyType_Ready for an extension
# type defined in this module.
type
=
entry
.
type
...
...
@@ -3041,6 +3042,12 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code
.
putln
(
'if (__Pyx_setup_reduce((PyObject*)&%s) < 0) %s'
%
(
typeobj_cname
,
code
.
error_goto
(
entry
.
pos
)))
# Generate code to initialise the typeptr of an extension
# type defined in this module to point to its type object.
if
type
.
typeobj_cname
:
code
.
putln
(
"%s = &%s;"
%
(
type
.
typeptr_cname
,
type
.
typeobj_cname
))
def
generate_exttype_vtable_init_code
(
self
,
entry
,
code
):
# Generate code to initialise the C method table of an
...
...
@@ -3071,15 +3078,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
cast
,
meth_entry
.
func_cname
))
def
generate_typeptr_assignment_code
(
self
,
entry
,
code
):
# Generate code to initialise the typeptr of an extension
# type defined in this module to point to its type object.
type
=
entry
.
type
if
type
.
typeobj_cname
:
code
.
putln
(
"%s = &%s;"
%
(
type
.
typeptr_cname
,
type
.
typeobj_cname
))
def
generate_cfunction_declaration
(
entry
,
env
,
code
,
definition
):
from_cy_utility
=
entry
.
used
and
entry
.
utility_code_definition
if
entry
.
used
and
entry
.
inline_func_in_pxd
or
(
not
entry
.
in_cinclude
and
(
...
...
Cython/Compiler/Nodes.py
View file @
becd5ce7
This diff is collapsed.
Click to expand it.
Cython/Compiler/Parsing.py
View file @
becd5ce7
...
...
@@ -3435,19 +3435,15 @@ def p_c_class_definition(s, pos, ctx):
as_name
=
class_name
objstruct_name
=
None
typeobj_name
=
None
base_class_module
=
None
base_class_name
=
None
bases
=
None
if
s
.
sy
==
'('
:
s
.
next
()
base_class_path
=
[
p_ident
(
s
)]
while
s
.
sy
==
'.'
:
s
.
next
()
base_class_path
.
append
(
p_ident
(
s
))
if
s
.
sy
==
','
:
s
.
error
(
"C class may only have one base class"
,
fatal
=
False
)
s
.
expect
(
')'
)
base_class_module
=
"."
.
join
(
base_class_path
[:
-
1
])
base_class_name
=
base_class_path
[
-
1
]
positional_args
,
keyword_args
=
p_call_parse_args
(
s
,
allow_genexp
=
False
)
if
keyword_args
:
s
.
error
(
"C classes cannot take keyword bases."
)
bases
,
_
=
p_call_build_packed_args
(
pos
,
positional_args
,
keyword_args
)
if
bases
is
None
:
bases
=
ExprNodes
.
TupleNode
(
pos
,
args
=
[])
if
s
.
sy
==
'['
:
if
ctx
.
visibility
not
in
(
'public'
,
'extern'
)
and
not
ctx
.
api
:
error
(
s
.
position
(),
"Name options only allowed for 'public', 'api', or 'extern' C class"
)
...
...
@@ -3487,8 +3483,7 @@ def p_c_class_definition(s, pos, ctx):
module_name
=
"."
.
join
(
module_path
),
class_name
=
class_name
,
as_name
=
as_name
,
base_class_module
=
base_class_module
,
base_class_name
=
base_class_name
,
bases
=
bases
,
objstruct_name
=
objstruct_name
,
typeobj_name
=
typeobj_name
,
in_pxd
=
ctx
.
level
==
'module_pxd'
,
...
...
Cython/Compiler/PyrexTypes.py
View file @
becd5ce7
...
...
@@ -1302,10 +1302,12 @@ class PyExtensionType(PyObjectType):
# vtabstruct_cname string Name of C method table struct
# vtabptr_cname string Name of pointer to C method table
# vtable_cname string Name of C method table definition
# early_init boolean Whether to initialize early (as opposed to during module execution).
# defered_declarations [thunk] Used to declare class hierarchies in order
is_extension_type
=
1
has_attributes
=
1
early_init
=
1
objtypedef_cname
=
None
...
...
tests/errors/subtyping_final_class.pyx
View file @
becd5ce7
...
...
@@ -10,5 +10,5 @@ cdef class SubType(FinalClass):
pass
_ERRORS
=
"""
9:
5
: Base class 'FinalClass' of type 'SubType' is final
9:
19
: Base class 'FinalClass' of type 'SubType' is final
"""
tests/run/cdef_multiple_inheritance.pyx
0 → 100644
View file @
becd5ce7
cdef
class
CBase
(
object
):
cdef
int
a
cdef
c_method
(
self
):
return
"CBase"
cpdef
cpdef
_method
(
self
):
return
"CBase"
class
PyBase
(
object
):
def
py_method
(
self
):
return
"PyBase"
cdef
class
Both
(
CBase
,
PyBase
):
cdef
dict
__dict__
"""
>>> b = Both()
>>> b.py_method()
'PyBase'
>>> b.cp_method()
'Both'
>>> b.call_c_method()
'Both'
>>> isinstance(b, CBase)
True
>>> isinstance(b, PyBase)
True
"""
cdef
c_method
(
self
):
return
"Both"
cpdef
cp_method
(
self
):
return
"Both"
def
call_c_method
(
self
):
return
self
.
c_method
()
cdef
class
BothSub
(
Both
):
"""
>>> b = BothSub()
>>> b.py_method()
'PyBase'
>>> b.cp_method()
'Both'
>>> b.call_c_method()
'Both'
"""
pass
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