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
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
Hide 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):
def
generate_cyfunction_code
(
self
,
code
):
if
self
.
specialized_cpdefs
:
constructor
=
"__pyx_FusedFunction_NewEx"
def_node
=
self
.
specialized_cpdefs
[
0
]
else
:
constructor
=
"__Pyx_CyFunction_NewEx"
def_node
=
self
.
def_node
if
self
.
code_object
:
code_object_result
=
self
.
code_object
.
py_result
()
...
...
@@ -5956,9 +5958,9 @@ class PyCFunctionNode(ExprNode, ModuleNameMixin):
code_object_result
=
'NULL'
flags
=
[]
if
self
.
def_node
.
is_staticmethod
:
if
def_node
.
is_staticmethod
:
flags
.
append
(
'__Pyx_CYFUNCTION_STATICMETHOD'
)
elif
self
.
def_node
.
is_classmethod
:
elif
def_node
.
is_classmethod
:
flags
.
append
(
'__Pyx_CYFUNCTION_CLASSMETHOD'
)
if
flags
:
flags
=
' | '
.
join
(
flags
)
...
...
@@ -5979,7 +5981,7 @@ class PyCFunctionNode(ExprNode, ModuleNameMixin):
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"
class_node
=
code
.
pyclass_stack
[
-
1
]
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)
func
=
(
__pyx_FusedFunctionObject
*
)
self
;
if
(
func
->
self
)
{
if
(
func
->
self
||
func
->
func
.
flags
&
__Pyx_CYFUNCTION_STATICMETHOD
)
{
/* Do not allow rebinding */
Py_INCREF
(
self
);
return
self
;
...
...
@@ -490,12 +490,18 @@ __pyx_FusedFunction_descr_get(PyObject *self, PyObject *obj, PyObject *type)
if
(
!
meth
)
return
NULL
;
Py_XINCREF
(
func
->
func
.
func_classobj
);
meth
->
func
.
func_classobj
=
func
->
func
.
func_classobj
;
Py_XINCREF
(
func
->
__signatures__
);
meth
->
__signatures__
=
func
->
__signatures__
;
Py_XINCREF
(
type
);
meth
->
type
=
type
;
if
(
func
->
func
.
flags
&
__Pyx_CYFUNCTION_CLASSMETHOD
)
obj
=
type
;
Py_XINCREF
(
obj
);
meth
->
self
=
obj
;
...
...
@@ -554,9 +560,16 @@ __pyx_err:
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
,
self
->
self
,
self
->
type
);
self
->
self
,
self
->
type
);
}
Py_DECREF
(
signature
);
Py_XDECREF
(
unbound_result_func
);
...
...
@@ -576,11 +589,13 @@ __pyx_FusedFunction_call(PyObject *func, PyObject *args, PyObject *kw)
__pyx_FusedFunctionObject
*
binding_func
=
(
__pyx_FusedFunctionObject
*
)
func
;
Py_ssize_t
argc
=
PyTuple_GET_SIZE
(
args
);
PyObject
*
new_args
=
NULL
;
Py
Object
*
new_func
=
NULL
;
__pyx_FusedFunction
Object
*
new_func
=
NULL
;
PyObject
*
result
=
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 */
Py_ssize_t
i
;
new_args
=
PyTuple_New
(
argc
+
1
);
...
...
@@ -598,7 +613,7 @@ __pyx_FusedFunction_call(PyObject *func, PyObject *args, PyObject *kw)
}
args
=
new_args
;
}
else
if
(
binding_func
->
type
)
{
}
else
if
(
binding_func
->
type
&&
!
is_staticmethod
)
{
/* Unbound method call */
if
(
argc
<
1
)
{
PyErr_Format
(
PyExc_TypeError
,
"Need at least one argument, 0 given."
);
...
...
@@ -607,7 +622,8 @@ __pyx_FusedFunction_call(PyObject *func, PyObject *args, PyObject *kw)
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
,
"First argument should be of type %s, got %s."
,
((
PyTypeObject
*
)
binding_func
->
type
)
->
tp_name
,
...
...
@@ -625,11 +641,17 @@ __pyx_FusedFunction_call(PyObject *func, PyObject *args, PyObject *kw)
if
(
!
tup
)
goto
__pyx_err
;
func
=
new_func
=
PyCFunction_Call
(
func
,
tup
,
NULL
);
new_func
=
(
__pyx_FusedFunctionObject
*
)
PyCFunction_Call
(
func
,
tup
,
NULL
);
Py_DECREF
(
tup
);
if
(
!
new_func
)
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
);
...
...
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):
"""
print
cython
.
typeof
(
obj
),
cython
.
typeof
(
myf
)
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