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
a6ec7fb9
Commit
a6ec7fb9
authored
Nov 13, 2018
by
mattip
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ENH: handle c-level property decorator to produce a cfunc call
parent
fdddf34e
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
41 additions
and
19 deletions
+41
-19
Cython/Compiler/ExprNodes.py
Cython/Compiler/ExprNodes.py
+10
-1
Cython/Compiler/Nodes.py
Cython/Compiler/Nodes.py
+6
-1
Cython/Compiler/ParseTreeTransforms.py
Cython/Compiler/ParseTreeTransforms.py
+8
-9
Cython/Compiler/Symtab.py
Cython/Compiler/Symtab.py
+17
-8
No files found.
Cython/Compiler/ExprNodes.py
View file @
a6ec7fb9
...
...
@@ -6976,7 +6976,10 @@ class AttributeNode(ExprNode):
self
.
obj
=
self
.
obj
.
analyse_types
(
env
)
self
.
analyse_attribute
(
env
)
if
self
.
entry
and
self
.
entry
.
is_cmethod
and
not
self
.
is_called
:
# error(self.pos, "C method can only be called")
# It must be a property method. This should be done at a different level??
self
.
is_called
=
1
self
.
op
=
''
self
.
result_ctype
=
self
.
type
.
return_type
pass
## Reference to C array turns into pointer to first element.
#while self.type.is_array:
...
...
@@ -7146,6 +7149,8 @@ class AttributeNode(ExprNode):
obj_code
=
obj
.
result_as
(
obj
.
type
)
#print "...obj_code =", obj_code ###
if
self
.
entry
and
self
.
entry
.
is_cmethod
:
if
getattr
(
self
.
entry
.
type
,
'is_cgetter'
,
False
):
return
"%s(%s)"
%
(
self
.
entry
.
func_cname
,
obj_code
)
if
obj
.
type
.
is_extension_type
and
not
self
.
entry
.
is_builtin_cmethod
:
if
self
.
entry
.
final_func_cname
:
return
self
.
entry
.
final_func_cname
...
...
@@ -11223,6 +11228,10 @@ class NumBinopNode(BinopNode):
self
.
operand2
=
self
.
operand2
.
coerce_to
(
self
.
type
,
env
)
def
compute_c_result_type
(
self
,
type1
,
type2
):
if
type1
.
is_cfunction
and
type1
.
is_cgetter
:
type1
=
type1
.
return_type
if
type2
.
is_cfunction
and
type2
.
is_cgetter
:
type2
=
type2
.
return_type
if
self
.
c_types_okay
(
type1
,
type2
):
widest_type
=
PyrexTypes
.
widest_numeric_type
(
type1
,
type2
)
if
widest_type
is
PyrexTypes
.
c_bint_type
:
...
...
Cython/Compiler/Nodes.py
View file @
a6ec7fb9
...
...
@@ -2422,11 +2422,16 @@ class CFuncDefNode(FuncDefNode):
type
.
is_const_method
=
self
.
is_const_method
type
.
is_static_method
=
self
.
is_static_method
property
=
False
if
self
.
decorators
:
for
_node
in
self
.
decorators
:
if
_node
.
decorator
.
is_name
and
_node
.
decorator
.
name
==
'property'
:
property
=
True
self
.
entry
=
env
.
declare_cfunction
(
name
,
type
,
self
.
pos
,
cname
=
cname
,
visibility
=
self
.
visibility
,
api
=
self
.
api
,
defining
=
self
.
body
is
not
None
,
modifiers
=
self
.
modifiers
,
overridable
=
self
.
overridable
)
overridable
=
self
.
overridable
,
property
=
property
)
self
.
entry
.
inline_func_in_pxd
=
self
.
inline_in_pxd
self
.
return_type
=
type
.
return_type
if
self
.
return_type
.
is_array
and
self
.
visibility
!=
'extern'
:
...
...
Cython/Compiler/ParseTreeTransforms.py
View file @
a6ec7fb9
...
...
@@ -2243,21 +2243,20 @@ class ReplacePropertyNode(CythonTransform):
def
visit_CFuncDefNode
(
self
,
node
):
if
not
node
.
decorators
:
return
node
# transform @property decorators
# transform @property decorators on ctypedef class functions
for
decorator_node
in
node
.
decorators
[::
-
1
]:
decorator
=
decorator_node
.
decorator
if
decorator
.
is_name
and
decorator
.
name
==
'property'
:
if
len
(
node
.
decorators
)
>
1
:
return
self
.
_reject_decorated_property
(
node
,
decorator_node
)
name
=
node
.
declarator
.
base
.
name
node
.
name
=
name
#EncodedString('__get__')
newstats
=
node
.
body
.
analyse_expressions
(
node
.
local_scope
)
n
ewnode
=
newstats
.
stats
[
0
].
valu
e
newnode
.
name
=
nam
e
# Mark the node as a cgetter
node
.
type
.
is_cgetter
=
True
# Add a func_cname to be output instead of the attribute
n
ode
.
entry
.
func_cname
=
node
.
body
.
stats
[
0
].
value
.
function
.
nam
e
# done - remove the decorator nod
e
node
.
decorators
.
remove
(
decorator_node
)
return
[
n
ewn
ode
]
# XXX still need to update everywhere that used the old node
return
[
node
]
class
FindInvalidUseOfFusedTypes
(
CythonTransform
):
...
...
Cython/Compiler/Symtab.py
View file @
a6ec7fb9
...
...
@@ -752,7 +752,8 @@ class Scope(object):
def
declare_cfunction
(
self
,
name
,
type
,
pos
,
cname
=
None
,
visibility
=
'private'
,
api
=
0
,
in_pxd
=
0
,
defining
=
0
,
modifiers
=
(),
utility_code
=
None
,
overridable
=
False
):
defining
=
0
,
modifiers
=
(),
utility_code
=
None
,
overridable
=
False
,
property
=
False
):
# Add an entry for a C function.
if
not
cname
:
if
visibility
!=
'private'
or
api
:
...
...
@@ -829,7 +830,8 @@ class Scope(object):
type
.
entry
=
entry
return
entry
def
add_cfunction
(
self
,
name
,
type
,
pos
,
cname
,
visibility
,
modifiers
,
inherited
=
False
):
def
add_cfunction
(
self
,
name
,
type
,
pos
,
cname
,
visibility
,
modifiers
,
inherited
=
False
,
property
=
False
):
# Add a C function entry without giving it a func_cname.
entry
=
self
.
declare
(
name
,
cname
,
type
,
pos
,
visibility
)
entry
.
is_cfunction
=
1
...
...
@@ -837,6 +839,8 @@ class Scope(object):
entry
.
func_modifiers
=
modifiers
if
inherited
or
type
.
is_fused
:
self
.
cfunc_entries
.
append
(
entry
)
elif
property
:
self
.
property_entries
.
append
(
entry
)
else
:
# For backwards compatibility reasons, we must keep all non-fused methods
# before all fused methods, but separately for each type.
...
...
@@ -1435,7 +1439,8 @@ class ModuleScope(Scope):
def
declare_cfunction
(
self
,
name
,
type
,
pos
,
cname
=
None
,
visibility
=
'private'
,
api
=
0
,
in_pxd
=
0
,
defining
=
0
,
modifiers
=
(),
utility_code
=
None
,
overridable
=
False
):
defining
=
0
,
modifiers
=
(),
utility_code
=
None
,
overridable
=
False
,
property
=
False
):
if
not
defining
and
'inline'
in
modifiers
:
# TODO(github/1736): Make this an error.
warning
(
pos
,
"Declarations should not be declared inline."
,
1
)
...
...
@@ -1459,7 +1464,7 @@ class ModuleScope(Scope):
self
,
name
,
type
,
pos
,
cname
=
cname
,
visibility
=
visibility
,
api
=
api
,
in_pxd
=
in_pxd
,
defining
=
defining
,
modifiers
=
modifiers
,
utility_code
=
utility_code
,
overridable
=
overridable
)
overridable
=
overridable
,
property
=
property
)
return
entry
def
declare_global
(
self
,
name
,
pos
):
...
...
@@ -2214,7 +2219,8 @@ class CClassScope(ClassScope):
def
declare_cfunction
(
self
,
name
,
type
,
pos
,
cname
=
None
,
visibility
=
'private'
,
api
=
0
,
in_pxd
=
0
,
defining
=
0
,
modifiers
=
(),
utility_code
=
None
,
overridable
=
False
):
defining
=
0
,
modifiers
=
(),
utility_code
=
None
,
overridable
=
False
,
property
=
False
):
if
get_special_method_signature
(
name
)
and
not
self
.
parent_type
.
is_builtin_type
:
error
(
pos
,
"Special methods must be declared with 'def', not 'cdef'"
)
args
=
type
.
args
...
...
@@ -2258,7 +2264,8 @@ class CClassScope(ClassScope):
error
(
pos
,
"C method '%s' not previously declared in definition part of"
" extension type '%s'"
%
(
name
,
self
.
class_name
))
entry
=
self
.
add_cfunction
(
name
,
type
,
pos
,
cname
,
visibility
,
modifiers
)
entry
=
self
.
add_cfunction
(
name
,
type
,
pos
,
cname
,
visibility
,
modifiers
,
property
=
property
)
if
defining
:
entry
.
func_cname
=
self
.
mangle
(
Naming
.
func_prefix
,
name
)
entry
.
utility_code
=
utility_code
...
...
@@ -2274,11 +2281,13 @@ class CClassScope(ClassScope):
return
entry
def
add_cfunction
(
self
,
name
,
type
,
pos
,
cname
,
visibility
,
modifiers
,
inherited
=
False
):
def
add_cfunction
(
self
,
name
,
type
,
pos
,
cname
,
visibility
,
modifiers
,
inherited
=
False
,
property
=
False
):
# Add a cfunction entry without giving it a func_cname.
prev_entry
=
self
.
lookup_here
(
name
)
entry
=
ClassScope
.
add_cfunction
(
self
,
name
,
type
,
pos
,
cname
,
visibility
,
modifiers
,
inherited
=
inherited
)
visibility
,
modifiers
,
inherited
=
inherited
,
property
=
property
)
entry
.
is_cmethod
=
1
entry
.
prev_entry
=
prev_entry
return
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