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
c95a2257
Commit
c95a2257
authored
4 years ago
by
Xavier Thompson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Compute the MRO for each cycplass
parent
f6a5ca9b
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
84 additions
and
0 deletions
+84
-0
Cython/Compiler/ParseTreeTransforms.py
Cython/Compiler/ParseTreeTransforms.py
+7
-0
Cython/Compiler/Pipeline.py
Cython/Compiler/Pipeline.py
+2
-0
Cython/Compiler/PyrexTypes.py
Cython/Compiler/PyrexTypes.py
+75
-0
No files found.
Cython/Compiler/ParseTreeTransforms.py
View file @
c95a2257
...
@@ -2117,6 +2117,13 @@ if VALUE is not None:
...
@@ -2117,6 +2117,13 @@ if VALUE is not None:
return
property
return
property
class
ComputeMROTransform
(
CythonTransform
):
def
visit_CppClassNode
(
self
,
node
):
if
node
.
cypclass
:
node
.
entry
.
type
.
compute_mro
()
return
node
class
CalculateQualifiedNamesTransform
(
EnvTransform
):
class
CalculateQualifiedNamesTransform
(
EnvTransform
):
"""
"""
Calculate and store the '__qualname__' and the global
Calculate and store the '__qualname__' and the global
...
...
This diff is collapsed.
Click to expand it.
Cython/Compiler/Pipeline.py
View file @
c95a2257
...
@@ -142,6 +142,7 @@ def create_pipeline(context, mode, exclude_classes=()):
...
@@ -142,6 +142,7 @@ def create_pipeline(context, mode, exclude_classes=()):
from
.Visitor
import
PrintTree
from
.Visitor
import
PrintTree
from
.ParseTreeTransforms
import
WithTransform
,
NormalizeTree
,
PostParse
,
PxdPostParse
from
.ParseTreeTransforms
import
WithTransform
,
NormalizeTree
,
PostParse
,
PxdPostParse
from
.ParseTreeTransforms
import
ForwardDeclareTypes
,
InjectGilHandling
,
AnalyseDeclarationsTransform
from
.ParseTreeTransforms
import
ForwardDeclareTypes
,
InjectGilHandling
,
AnalyseDeclarationsTransform
from
.ParseTreeTransforms
import
ComputeMROTransform
from
.ParseTreeTransforms
import
AnalyseExpressionsTransform
,
FindInvalidUseOfFusedTypes
from
.ParseTreeTransforms
import
AnalyseExpressionsTransform
,
FindInvalidUseOfFusedTypes
from
.ParseTreeTransforms
import
CreateClosureClasses
,
MarkClosureVisitor
,
DecoratorTransform
from
.ParseTreeTransforms
import
CreateClosureClasses
,
MarkClosureVisitor
,
DecoratorTransform
from
.ParseTreeTransforms
import
TrackNumpyAttributes
,
InterpretCompilerDirectives
,
TransformBuiltinMethods
from
.ParseTreeTransforms
import
TrackNumpyAttributes
,
InterpretCompilerDirectives
,
TransformBuiltinMethods
...
@@ -196,6 +197,7 @@ def create_pipeline(context, mode, exclude_classes=()):
...
@@ -196,6 +197,7 @@ def create_pipeline(context, mode, exclude_classes=()):
ForwardDeclareTypes
(
context
),
ForwardDeclareTypes
(
context
),
InjectGilHandling
(),
InjectGilHandling
(),
AnalyseDeclarationsTransform
(
context
),
AnalyseDeclarationsTransform
(
context
),
ComputeMROTransform
(
context
),
AutoTestDictTransform
(
context
),
AutoTestDictTransform
(
context
),
EmbedSignature
(
context
),
EmbedSignature
(
context
),
ReplacePropertyNode
(
context
),
ReplacePropertyNode
(
context
),
...
...
This diff is collapsed.
Click to expand it.
Cython/Compiler/PyrexTypes.py
View file @
c95a2257
...
@@ -3894,9 +3894,63 @@ class CppClassType(CType):
...
@@ -3894,9 +3894,63 @@ class CppClassType(CType):
if
constructor
is
not
None
and
best_match
([],
constructor
.
all_alternatives
())
is
None
:
if
constructor
is
not
None
and
best_match
([],
constructor
.
all_alternatives
())
is
None
:
error
(
pos
,
"C++ class must have a nullary constructor to be %s"
%
msg
)
error
(
pos
,
"C++ class must have a nullary constructor to be %s"
%
msg
)
# Merge procedure for the C3 linearisation used to produce the MRO
#
# sources:
# - https://www.python.org/download/releases/2.3/mro/
# - https://mail.python.org/pipermail/python-dev/2002-October/029176.html
# - https://github.com/mikeboers/C3Linearize/blob/master/c3linearize.py
#
def
mro_C3_merge
(
sequences
):
# make copies of the input lists to avoid side effect mutations
sequences
=
[
list
(
s
)
for
s
in
sequences
]
result
=
[]
while
True
:
# remove empty sequences from consideration
sequences
=
[
s
for
s
in
sequences
if
s
]
# the result is fully computed when there are no more sequences to examine
if
not
sequences
:
return
result
# find the first good head: a head of one of the sequences that is not in any tail
for
sequence
in
sequences
:
head
=
sequence
[
0
]
if
not
any
(
head
in
s
[
1
:]
for
s
in
sequences
):
break
else
:
error
(
None
,
"Inconsistent inheritance hierarchy for %s"
%
self
.
name
)
# make the head that was found the next element in the linearisation
result
.
append
(
head
)
# remove that head from consideration
for
seq
in
sequences
:
if
seq
[
0
]
==
head
:
del
seq
[
0
]
# Compute MRO for generic classes with minimal assumptions
#
# One assumption only:
# - if a class has bases, they are held in 'base_classes' attribute
#
def
compute_mro_generic
(
cls
):
print
(
"GENERIC C3 !!"
)
if
not
hasattr
(
cls
,
"base_classes"
)
or
cls
.
base_classes
is
None
:
return
[
cls
]
inputs
=
[[
cls
]]
for
base
in
cls
.
base_classes
:
inputs
.
append
(
compute_mro_generic
(
base
))
inputs
.
append
(
cls
.
base_classes
)
return
mro_C3_merge
(
inputs
)
class
CypClassType
(
CppClassType
):
class
CypClassType
(
CppClassType
):
# lock_mode string (tri-state: "nolock"/"checklock"/"autolock")
# lock_mode string (tri-state: "nolock"/"checklock"/"autolock")
# mro [CppClassType] or None The Method Resolution Order of this cypclass according to Python
is_cyp_class
=
1
is_cyp_class
=
1
...
@@ -3904,6 +3958,27 @@ class CypClassType(CppClassType):
...
@@ -3904,6 +3958,27 @@ class CypClassType(CppClassType):
CppClassType
.
__init__
(
self
,
name
,
scope
,
cname
,
base_classes
,
templates
,
template_type
,
nogil
)
CppClassType
.
__init__
(
self
,
name
,
scope
,
cname
,
base_classes
,
templates
,
template_type
,
nogil
)
self
.
lock_mode
=
lock_mode
if
lock_mode
else
"autolock"
self
.
lock_mode
=
lock_mode
if
lock_mode
else
"autolock"
self
.
activable
=
activable
self
.
activable
=
activable
self
.
mro
=
None
# compute the MRO for this cypclass
# the mro is also computed for bases when needed
# 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
if
self
.
base_classes
is
None
:
self
.
mro
=
[
self
]
return
self
.
mro
inputs
=
[[
self
]]
for
base
in
self
.
base_classes
:
if
base
.
is_cyp_class
:
base_mro
=
base
.
compute_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
def
empty_declaration_code
(
self
):
def
empty_declaration_code
(
self
):
if
self
.
_empty_declaration
is
None
:
if
self
.
_empty_declaration
is
None
:
...
...
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