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
835010c7
Commit
835010c7
authored
Nov 02, 2011
by
Mark Florisson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Support fused static- and classmethods + super()
parent
f66909db
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
130 additions
and
11 deletions
+130
-11
Cython/Compiler/ExprNodes.py
Cython/Compiler/ExprNodes.py
+5
-3
Cython/Utility/CythonFunction.c
Cython/Utility/CythonFunction.c
+30
-8
tests/run/fused_def.pyx
tests/run/fused_def.pyx
+95
-0
No files found.
Cython/Compiler/ExprNodes.py
View file @
835010c7
...
@@ -5947,8 +5947,10 @@ class PyCFunctionNode(ExprNode, ModuleNameMixin):
...
@@ -5947,8 +5947,10 @@ class PyCFunctionNode(ExprNode, ModuleNameMixin):
def
generate_cyfunction_code
(
self
,
code
):
def
generate_cyfunction_code
(
self
,
code
):
if
self
.
specialized_cpdefs
:
if
self
.
specialized_cpdefs
:
constructor
=
"__pyx_FusedFunction_NewEx"
constructor
=
"__pyx_FusedFunction_NewEx"
def_node
=
self
.
specialized_cpdefs
[
0
]
else
:
else
:
constructor
=
"__Pyx_CyFunction_NewEx"
constructor
=
"__Pyx_CyFunction_NewEx"
def_node
=
self
.
def_node
if
self
.
code_object
:
if
self
.
code_object
:
code_object_result
=
self
.
code_object
.
py_result
()
code_object_result
=
self
.
code_object
.
py_result
()
...
@@ -5956,9 +5958,9 @@ class PyCFunctionNode(ExprNode, ModuleNameMixin):
...
@@ -5956,9 +5958,9 @@ class PyCFunctionNode(ExprNode, ModuleNameMixin):
code_object_result
=
'NULL'
code_object_result
=
'NULL'
flags
=
[]
flags
=
[]
if
self
.
def_node
.
is_staticmethod
:
if
def_node
.
is_staticmethod
:
flags
.
append
(
'__Pyx_CYFUNCTION_STATICMETHOD'
)
flags
.
append
(
'__Pyx_CYFUNCTION_STATICMETHOD'
)
elif
self
.
def_node
.
is_classmethod
:
elif
def_node
.
is_classmethod
:
flags
.
append
(
'__Pyx_CYFUNCTION_CLASSMETHOD'
)
flags
.
append
(
'__Pyx_CYFUNCTION_CLASSMETHOD'
)
if
flags
:
if
flags
:
flags
=
' | '
.
join
(
flags
)
flags
=
' | '
.
join
(
flags
)
...
@@ -5979,7 +5981,7 @@ class PyCFunctionNode(ExprNode, ModuleNameMixin):
...
@@ -5979,7 +5981,7 @@ class PyCFunctionNode(ExprNode, ModuleNameMixin):
code
.
put_gotref
(
self
.
py_result
())
code
.
put_gotref
(
self
.
py_result
())
if
self
.
def_node
.
requires_classobj
:
if
def_node
.
requires_classobj
:
assert
code
.
pyclass_stack
,
"pyclass_stack is empty"
assert
code
.
pyclass_stack
,
"pyclass_stack is empty"
class_node
=
code
.
pyclass_stack
[
-
1
]
class_node
=
code
.
pyclass_stack
[
-
1
]
code
.
put_incref
(
self
.
py_result
(),
py_object_type
)
code
.
put_incref
(
self
.
py_result
(),
py_object_type
)
...
...
Cython/Utility/CythonFunction.c
View file @
835010c7
...
@@ -472,7 +472,7 @@ __pyx_FusedFunction_descr_get(PyObject *self, PyObject *obj, PyObject *type)
...
@@ -472,7 +472,7 @@ __pyx_FusedFunction_descr_get(PyObject *self, PyObject *obj, PyObject *type)
func
=
(
__pyx_FusedFunctionObject
*
)
self
;
func
=
(
__pyx_FusedFunctionObject
*
)
self
;
if
(
func
->
self
)
{
if
(
func
->
self
||
func
->
func
.
flags
&
__Pyx_CYFUNCTION_STATICMETHOD
)
{
/* Do not allow rebinding */
/* Do not allow rebinding */
Py_INCREF
(
self
);
Py_INCREF
(
self
);
return
self
;
return
self
;
...
@@ -490,12 +490,18 @@ __pyx_FusedFunction_descr_get(PyObject *self, PyObject *obj, PyObject *type)
...
@@ -490,12 +490,18 @@ __pyx_FusedFunction_descr_get(PyObject *self, PyObject *obj, PyObject *type)
if
(
!
meth
)
if
(
!
meth
)
return
NULL
;
return
NULL
;
Py_XINCREF
(
func
->
func
.
func_classobj
);
meth
->
func
.
func_classobj
=
func
->
func
.
func_classobj
;
Py_XINCREF
(
func
->
__signatures__
);
Py_XINCREF
(
func
->
__signatures__
);
meth
->
__signatures__
=
func
->
__signatures__
;
meth
->
__signatures__
=
func
->
__signatures__
;
Py_XINCREF
(
type
);
Py_XINCREF
(
type
);
meth
->
type
=
type
;
meth
->
type
=
type
;
if
(
func
->
func
.
flags
&
__Pyx_CYFUNCTION_CLASSMETHOD
)
obj
=
type
;
Py_XINCREF
(
obj
);
Py_XINCREF
(
obj
);
meth
->
self
=
obj
;
meth
->
self
=
obj
;
...
@@ -554,9 +560,16 @@ __pyx_err:
...
@@ -554,9 +560,16 @@ __pyx_err:
unbound_result_func
=
PyObject_GetItem
(
self
->
__signatures__
,
signature
);
unbound_result_func
=
PyObject_GetItem
(
self
->
__signatures__
,
signature
);
if
(
unbound_result_func
)
if
(
unbound_result_func
)
{
__pyx_FusedFunctionObject
*
unbound
=
(
__pyx_FusedFunctionObject
*
)
unbound_result_func
;
Py_CLEAR
(
unbound
->
func
.
func_classobj
);
Py_XINCREF
(
self
->
func
.
func_classobj
);
unbound
->
func
.
func_classobj
=
self
->
func
.
func_classobj
;
result_func
=
__pyx_FusedFunction_descr_get
(
unbound_result_func
,
result_func
=
__pyx_FusedFunction_descr_get
(
unbound_result_func
,
self
->
self
,
self
->
type
);
self
->
self
,
self
->
type
);
}
Py_DECREF
(
signature
);
Py_DECREF
(
signature
);
Py_XDECREF
(
unbound_result_func
);
Py_XDECREF
(
unbound_result_func
);
...
@@ -576,11 +589,13 @@ __pyx_FusedFunction_call(PyObject *func, PyObject *args, PyObject *kw)
...
@@ -576,11 +589,13 @@ __pyx_FusedFunction_call(PyObject *func, PyObject *args, PyObject *kw)
__pyx_FusedFunctionObject
*
binding_func
=
(
__pyx_FusedFunctionObject
*
)
func
;
__pyx_FusedFunctionObject
*
binding_func
=
(
__pyx_FusedFunctionObject
*
)
func
;
Py_ssize_t
argc
=
PyTuple_GET_SIZE
(
args
);
Py_ssize_t
argc
=
PyTuple_GET_SIZE
(
args
);
PyObject
*
new_args
=
NULL
;
PyObject
*
new_args
=
NULL
;
Py
Object
*
new_func
=
NULL
;
__pyx_FusedFunction
Object
*
new_func
=
NULL
;
PyObject
*
result
=
NULL
;
PyObject
*
result
=
NULL
;
PyObject
*
self
=
NULL
;
PyObject
*
self
=
NULL
;
int
is_staticmethod
=
binding_func
->
func
.
flags
&
__Pyx_CYFUNCTION_STATICMETHOD
;
int
is_classmethod
=
binding_func
->
func
.
flags
&
__Pyx_CYFUNCTION_CLASSMETHOD
;
if
(
binding_func
->
self
)
{
if
(
binding_func
->
self
&&
!
is_staticmethod
)
{
/* Bound method call, put 'self' in the args tuple */
/* Bound method call, put 'self' in the args tuple */
Py_ssize_t
i
;
Py_ssize_t
i
;
new_args
=
PyTuple_New
(
argc
+
1
);
new_args
=
PyTuple_New
(
argc
+
1
);
...
@@ -598,7 +613,7 @@ __pyx_FusedFunction_call(PyObject *func, PyObject *args, PyObject *kw)
...
@@ -598,7 +613,7 @@ __pyx_FusedFunction_call(PyObject *func, PyObject *args, PyObject *kw)
}
}
args
=
new_args
;
args
=
new_args
;
}
else
if
(
binding_func
->
type
)
{
}
else
if
(
binding_func
->
type
&&
!
is_staticmethod
)
{
/* Unbound method call */
/* Unbound method call */
if
(
argc
<
1
)
{
if
(
argc
<
1
)
{
PyErr_Format
(
PyExc_TypeError
,
"Need at least one argument, 0 given."
);
PyErr_Format
(
PyExc_TypeError
,
"Need at least one argument, 0 given."
);
...
@@ -607,7 +622,8 @@ __pyx_FusedFunction_call(PyObject *func, PyObject *args, PyObject *kw)
...
@@ -607,7 +622,8 @@ __pyx_FusedFunction_call(PyObject *func, PyObject *args, PyObject *kw)
self
=
PyTuple_GET_ITEM
(
args
,
0
);
self
=
PyTuple_GET_ITEM
(
args
,
0
);
}
}
if
(
self
&&
!
PyObject_IsInstance
(
self
,
binding_func
->
type
))
{
if
(
self
&&
!
is_classmethod
&&
!
is_staticmethod
&&
!
PyObject_IsInstance
(
self
,
binding_func
->
type
))
{
PyErr_Format
(
PyExc_TypeError
,
PyErr_Format
(
PyExc_TypeError
,
"First argument should be of type %s, got %s."
,
"First argument should be of type %s, got %s."
,
((
PyTypeObject
*
)
binding_func
->
type
)
->
tp_name
,
((
PyTypeObject
*
)
binding_func
->
type
)
->
tp_name
,
...
@@ -625,11 +641,17 @@ __pyx_FusedFunction_call(PyObject *func, PyObject *args, PyObject *kw)
...
@@ -625,11 +641,17 @@ __pyx_FusedFunction_call(PyObject *func, PyObject *args, PyObject *kw)
if
(
!
tup
)
if
(
!
tup
)
goto
__pyx_err
;
goto
__pyx_err
;
func
=
new_func
=
PyCFunction_Call
(
func
,
tup
,
NULL
);
new_func
=
(
__pyx_FusedFunctionObject
*
)
PyCFunction_Call
(
func
,
tup
,
NULL
);
Py_DECREF
(
tup
);
Py_DECREF
(
tup
);
if
(
!
new_func
)
if
(
!
new_func
)
goto
__pyx_err
;
goto
__pyx_err
;
Py_CLEAR
(
new_func
->
func
.
func_classobj
);
Py_XINCREF
(
binding_func
->
func
.
func_classobj
);
new_func
->
func
.
func_classobj
=
binding_func
->
func
.
func_classobj
;
func
=
(
PyObject
*
)
new_func
;
}
}
result
=
PyCFunction_Call
(
func
,
args
,
kw
);
result
=
PyCFunction_Call
(
func
,
args
,
kw
);
...
...
tests/run/fused_def.pyx
View file @
835010c7
...
@@ -128,3 +128,98 @@ def args_kwargs(fused_t obj, cython.floating myf = 1.2, *args, **kwargs):
...
@@ -128,3 +128,98 @@ def args_kwargs(fused_t obj, cython.floating myf = 1.2, *args, **kwargs):
"""
"""
print
cython
.
typeof
(
obj
),
cython
.
typeof
(
myf
)
print
cython
.
typeof
(
obj
),
cython
.
typeof
(
myf
)
print
obj
,
"%.2f"
%
myf
,
"%.2f"
%
f
,
args
,
kwargs
print
obj
,
"%.2f"
%
myf
,
"%.2f"
%
f
,
args
,
kwargs
class
BaseClass
(
object
):
"""
Test fused class/static/normal methods and super() without args
"""
@
staticmethod
def
mystaticmethod
(
cython
.
integral
arg1
):
print
cython
.
typeof
(
arg1
),
arg1
@
classmethod
def
myclassmethod
(
cls
,
cython
.
integral
arg1
):
print
cls
,
cython
.
typeof
(
arg1
),
arg1
def
normalmethod
(
self
,
cython
.
integral
arg1
):
print
self
,
cython
.
typeof
(
arg1
),
arg1
def
__repr__
(
self
):
return
"<%s.%s object>"
%
(
__name__
,
type
(
self
).
__name__
)
class
SubClass
(
BaseClass
):
@
staticmethod
def
mystaticmethod
(
cython
.
integral
arg1
):
print
cython
.
typeof
(
arg1
),
arg1
super
().
mystaticmethod
(
arg1
+
1
)
@
classmethod
def
myclassmethod
(
cls
,
cython
.
integral
arg1
):
print
cls
,
cython
.
typeof
(
arg1
),
arg1
super
().
myclassmethod
(
arg1
+
1
)
def
normalmethod
(
self
,
cython
.
integral
arg1
):
print
self
,
cython
.
typeof
(
arg1
),
arg1
super
().
normalmethod
(
arg1
+
1
)
class
SubSubClass
(
SubClass
):
pass
def
test_fused_def_super
():
"""
>>> test_fused_def_super()
<class 'fused_def.SubClass'> long 14
<class 'fused_def.SubClass'> long 15
<class 'fused_def.SubClass'> long 15
<class 'fused_def.SubClass'> long 16
<class 'fused_def.SubClass'> short 16
<class 'fused_def.SubClass'> long 17
<class 'fused_def.SubClass'> short 17
<class 'fused_def.SubClass'> long 18
<fused_def.SubClass object> long 18
<fused_def.SubClass object> long 19
<fused_def.SubClass object> long 19
<fused_def.SubClass object> long 20
<fused_def.SubClass object> short 20
<fused_def.SubClass object> long 21
<fused_def.SubClass object> short 21
<fused_def.SubClass object> long 22
"""
obj
=
SubClass
()
cls
=
SubClass
#obj.mystaticmethod(10)
#cls.mystaticmethod(11)
#obj.mystaticmethod[cy.short](12)
#cls.mystaticmethod[cy.short](13)
obj
.
myclassmethod
(
14
)
cls
.
myclassmethod
(
15
)
obj
.
myclassmethod
[
cy
.
short
](
16
)
cls
.
myclassmethod
[
cy
.
short
](
17
)
obj
.
normalmethod
(
18
)
cls
.
normalmethod
(
obj
,
19
)
obj
.
normalmethod
[
cy
.
short
](
20
)
cls
.
normalmethod
[
cy
.
short
](
obj
,
21
)
def
test_fused_def_classmethod
():
"""
>>> test_fused_def_classmethod()
<class 'fused_def.SubSubClass'> long 10
<class 'fused_def.SubSubClass'> long 11
<class 'fused_def.SubSubClass'> long 11
<class 'fused_def.SubSubClass'> long 12
<class 'fused_def.SubSubClass'> short 12
<class 'fused_def.SubSubClass'> long 13
<class 'fused_def.SubSubClass'> short 13
<class 'fused_def.SubSubClass'> long 14
"""
SubSubClass
().
myclassmethod
(
10
)
SubSubClass
.
myclassmethod
(
11
)
SubSubClass
().
myclassmethod
[
cy
.
short
](
12
)
SubSubClass
.
myclassmethod
[
cy
.
short
](
13
)
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