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
91e66c04
Commit
91e66c04
authored
Jun 11, 2020
by
Xavier Thompson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Make cypclasses inherit from ancestors in MRO order
parent
6e7a55c1
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
100 additions
and
26 deletions
+100
-26
Cython/Compiler/ParseTreeTransforms.py
Cython/Compiler/ParseTreeTransforms.py
+0
-7
Cython/Compiler/Pipeline.py
Cython/Compiler/Pipeline.py
+0
-2
Cython/Compiler/PyrexTypes.py
Cython/Compiler/PyrexTypes.py
+12
-12
Cython/Compiler/Symtab.py
Cython/Compiler/Symtab.py
+88
-5
No files found.
Cython/Compiler/ParseTreeTransforms.py
View file @
91e66c04
...
...
@@ -2198,13 +2198,6 @@ if VALUE is not None:
return
property
class
ComputeMROTransform
(
CythonTransform
):
def
visit_CppClassNode
(
self
,
node
):
if
node
.
cypclass
:
node
.
entry
.
type
.
compute_mro
()
return
node
class
CalculateQualifiedNamesTransform
(
EnvTransform
):
"""
Calculate and store the '__qualname__' and the global
...
...
Cython/Compiler/Pipeline.py
View file @
91e66c04
...
...
@@ -143,7 +143,6 @@ def create_pipeline(context, mode, exclude_classes=()):
from
.Visitor
import
PrintTree
from
.ParseTreeTransforms
import
WithTransform
,
NormalizeTree
,
PostParse
,
PxdPostParse
from
.ParseTreeTransforms
import
ForwardDeclareTypes
,
InjectGilHandling
,
AnalyseDeclarationsTransform
from
.ParseTreeTransforms
import
ComputeMROTransform
from
.ParseTreeTransforms
import
AnalyseExpressionsTransform
,
FindInvalidUseOfFusedTypes
from
.ParseTreeTransforms
import
CreateClosureClasses
,
MarkClosureVisitor
,
DecoratorTransform
from
.ParseTreeTransforms
import
TrackNumpyAttributes
,
InterpretCompilerDirectives
,
TransformBuiltinMethods
...
...
@@ -198,7 +197,6 @@ def create_pipeline(context, mode, exclude_classes=()):
ForwardDeclareTypes
(
context
),
InjectGilHandling
(),
AnalyseDeclarationsTransform
(
context
),
ComputeMROTransform
(
context
),
AutoTestDictTransform
(
context
),
EmbedSignature
(
context
),
EarlyReplaceBuiltinCalls
(
context
),
## Necessary?
...
...
Cython/Compiler/PyrexTypes.py
View file @
91e66c04
...
...
@@ -4171,7 +4171,7 @@ def compute_mro_generic(cls):
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
#
_mro
[CppClassType] or None The Method Resolution Order of this cypclass according to Python
is_cyp_class
=
1
...
...
@@ -4179,27 +4179,27 @@ class CypClassType(CppClassType):
CppClassType
.
__init__
(
self
,
name
,
scope
,
cname
,
base_classes
,
templates
,
template_type
,
nogil
)
self
.
lock_mode
=
lock_mode
if
lock_mode
else
"autolock"
self
.
activable
=
activable
self
.
mro
=
None
self
.
_
mro
=
None
#
compute
the MRO for this cypclass
#
the mro is also computed for bases when needed
#
Return
the MRO for this cypclass
#
Compute all the mro needed when a previous computation is not available
# based on https://mail.python.org/pipermail/python-dev/2002-October/029176.html
def
compute_
mro
(
self
):
if
self
.
mro
is
not
None
:
return
self
.
mro
def
mro
(
self
):
if
self
.
_
mro
is
not
None
:
return
self
.
_
mro
if
self
.
base_classes
is
None
:
self
.
mro
=
[
self
]
return
self
.
mro
self
.
_
mro
=
[
self
]
return
self
.
_
mro
inputs
=
[[
self
]]
for
base
in
self
.
base_classes
:
if
base
.
is_cyp_class
:
base_mro
=
base
.
compute_
mro
()
base_mro
=
base
.
mro
()
else
:
base_mro
=
compute_mro_generic
(
base
)
inputs
.
append
(
base_mro
)
inputs
.
append
(
self
.
base_classes
)
self
.
mro
=
mro_C3_merge
(
inputs
)
return
self
.
mro
self
.
_
mro
=
mro_C3_merge
(
inputs
)
return
self
.
_
mro
def
empty_declaration_code
(
self
):
if
self
.
_empty_declaration
is
None
:
...
...
Cython/Compiler/Symtab.py
View file @
91e66c04
...
...
@@ -737,14 +737,24 @@ class Scope(object):
entry
.
already_declared_here
()
def
declare_inherited_attributes
(
entry
,
base_classes
):
for
base_class
in
base_classes
:
def
examine_base
(
base_class
)
:
if
base_class
is
PyrexTypes
.
error_type
or
base_class
is
PyrexTypes
.
cy_object_type
:
continu
e
return
Fals
e
if
base_class
.
scope
is
None
:
error
(
pos
,
"Cannot inherit from incomplete type"
)
else
:
declare_inherited_attributes
(
entry
,
base_class
.
base_classes
)
entry
.
type
.
scope
.
declare_inherited_cpp_attributes
(
base_class
)
return
False
return
True
if
cypclass
:
for
base_class
in
reversed
(
entry
.
type
.
mro
()):
if
examine_base
(
base_class
):
entry
.
type
.
scope
.
declare_inherited_cyp_attributes
(
base_class
)
else
:
for
base_class
in
base_classes
:
if
examine_base
(
base_class
):
declare_inherited_attributes
(
entry
,
base_class
.
base_classes
)
entry
.
type
.
scope
.
declare_inherited_cpp_attributes
(
base_class
)
if
scope
:
entry
.
type
.
set_scope
(
scope
)
declare_inherited_attributes
(
entry
,
base_classes
)
...
...
@@ -2997,6 +3007,79 @@ class CppClassScope(Scope):
entry
.
is_inherited
=
1
self
.
inherited_type_entries
.
append
(
entry
)
def
declare_inherited_cyp_attributes
(
self
,
base_class
):
base_scope
=
base_class
.
scope
template_type
=
base_class
while
getattr
(
template_type
,
'template_type'
,
None
):
template_type
=
template_type
.
template_type
if
getattr
(
template_type
,
'templates'
,
None
):
base_templates
=
[
T
.
name
for
T
in
template_type
.
templates
]
else
:
base_templates
=
()
# Declare entries for all the C++ attributes of an
# inherited type, with cnames modified appropriately
# to work with this type.
for
base_entry
in
base_scope
.
var_entries
:
base_entry_type
=
base_entry
.
type
#constructor/destructor is not inherited
if
base_entry
.
name
==
"<del>"
\
or
base_entry
.
name
in
(
"<constructor>"
,
"<alloc>"
,
"<active_self>"
,
"__activate__"
):
continue
elif
base_entry
.
name
==
"<init>"
and
not
self
.
lookup_here
(
"__new__"
):
wrapper_entry
=
self
.
declare_constructor_wrapper
(
base_entry_type
.
args
,
base_entry
.
pos
,
defining
=
1
,
has_varargs
=
base_entry_type
.
has_varargs
,
optional_arg_count
=
base_entry_type
.
optional_arg_count
,
op_arg_struct
=
getattr
(
base_entry_type
,
'op_arg_struct'
,
None
),
return_type
=
self
.
parent_type
)
wrapper_entry
.
is_inherited
=
1
elif
base_entry
.
name
==
"__new__"
:
# Rewrite first argument for __new__
alloc_type
=
PyrexTypes
.
CPtrType
(
PyrexTypes
.
CFuncType
(
self
.
parent_type
,
[],
nogil
=
1
))
alloc_arg
=
PyrexTypes
.
CFuncTypeArg
(
base_entry
.
type
.
args
[
0
].
name
,
alloc_type
,
base_entry
.
type
.
args
[
0
].
pos
,
cname
=
base_entry
.
type
.
args
[
0
].
cname
)
base_entry_type
=
PyrexTypes
.
CFuncType
(
base_entry_type
.
return_type
,
[
alloc_arg
]
+
base_entry_type
.
args
[
1
:],
nogil
=
1
,
has_varargs
=
base_entry_type
.
has_varargs
,
optional_arg_count
=
base_entry_type
.
optional_arg_count
)
if
hasattr
(
base_entry
.
type
,
'op_arg_struct'
):
base_entry_type
.
op_arg_struct
=
base_entry
.
type
.
op_arg_struct
base_entry_type
.
original_alloc_type
=
base_entry
.
type
.
original_alloc_type
if
base_entry
.
name
in
self
.
entries
:
del
self
.
entries
[
base_entry
.
name
]
del
self
.
entries
[
"<constructor>"
]
elif
"<init>"
in
self
.
entries
:
del
self
.
entries
[
"<constructor>"
]
wrapper_entry
=
self
.
declare_constructor_wrapper
(
base_entry_type
.
args
[
1
:],
base_entry
.
pos
,
defining
=
1
,
has_varargs
=
base_entry_type
.
has_varargs
,
optional_arg_count
=
base_entry_type
.
optional_arg_count
,
op_arg_struct
=
getattr
(
base_entry_type
,
'op_arg_struct'
,
None
),
return_type
=
base_entry_type
.
return_type
)
wrapper_entry
.
is_inherited
=
1
entry
=
self
.
declare
(
base_entry
.
name
,
base_entry
.
cname
,
base_entry_type
,
base_entry
.
pos
,
'extern'
)
entry
.
is_variable
=
1
entry
.
is_inherited
=
1
entry
.
is_cfunction
=
base_entry
.
is_cfunction
if
entry
.
is_cfunction
:
entry
.
func_cname
=
base_entry
.
func_cname
self
.
inherited_var_entries
.
append
(
entry
)
for
base_entry
in
base_scope
.
cfunc_entries
:
entry
=
self
.
declare_cfunction
(
base_entry
.
name
,
base_entry
.
type
,
base_entry
.
pos
,
base_entry
.
cname
,
base_entry
.
visibility
,
api
=
0
,
modifiers
=
base_entry
.
func_modifiers
,
utility_code
=
base_entry
.
utility_code
,
inheriting
=
1
)
entry
.
is_inherited
=
1
for
base_entry
in
base_scope
.
type_entries
:
if
base_entry
.
name
not
in
base_templates
:
entry
=
self
.
declare_type
(
base_entry
.
name
,
base_entry
.
type
,
base_entry
.
pos
,
base_entry
.
cname
,
base_entry
.
visibility
,
defining
=
0
)
entry
.
is_inherited
=
1
self
.
inherited_type_entries
.
append
(
entry
)
def
specialize
(
self
,
values
,
type_entry
):
scope
=
CppClassScope
(
self
.
name
,
self
.
outer_scope
)
scope
.
type
=
type_entry
...
...
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