Commit 7f563ed4 authored by Haoyu Bai's avatar Haoyu Bai

@cython.cclass decorator for class

parent 4b61e74c
......@@ -546,6 +546,9 @@ class CFuncDeclaratorNode(CDeclaratorNode):
if name_declarator.cname:
error(self.pos,
"Function argument cannot have C name specification")
if i==0 and env.is_c_class_scope and type.is_unspecified:
# fix the type of self
type = env.parent_type
# Turn *[] argument into **
if type.is_array:
type = PyrexTypes.c_ptr_type(type.base_type)
......
......@@ -96,6 +96,7 @@ directive_types = {
'internal' : bool, # cdef class visibility in the module dict
'infer_types' : bool, # values can be True/None/False
'cfunc' : None, # decorators do not take directive value
'cclass' : None,
}
for key, val in directive_defaults.items():
......
......@@ -1411,11 +1411,15 @@ class AdjustDefByDirectives(CythonTransform, SkipDeclarations):
return node
def visit_PyClassDefNode(self, node):
old_in_pyclass = self.in_py_class
self.in_py_class = True
self.visitchildren(node)
self.in_py_class = old_in_pyclass
return node
if 'cclass' in self.directives:
node = node.as_cclass()
return self.visit(node)
else:
old_in_pyclass = self.in_py_class
self.in_py_class = True
self.visitchildren(node)
self.in_py_class = old_in_pyclass
return node
def visit_CClassDefNode(self, node):
old_in_pyclass = self.in_py_class
......
......@@ -23,7 +23,7 @@ class _EmptyDecoratorAndManager(object):
def __exit__(self, exc_type, exc_value, traceback):
pass
cfunc = _EmptyDecoratorAndManager()
cclass = cfunc = _EmptyDecoratorAndManager()
def inline(f, *args, **kwds):
if isinstance(f, basestring):
......
class Pyclass(object):
cdef bad(self):
pass
_ERRORS = """
2:9: cdef statement not allowed here
"""
import cython
class Pyclass(object):
@cython.cfunc
def bad(self):
pass
_ERRORS = """
5:4: cfunc directive is not allowed here
"""
import cython
from cython import cfunc
from cython import cfunc, cclass
@cython.test_assert_path_exists('//CFuncDefNode')
@cython.cfunc
......@@ -28,9 +28,50 @@ with cfunc:
def fwith2(a):
return a*4
with cclass:
@cython.test_assert_path_exists('//CClassDefNode')
class Egg(object):
pass
@cython.test_assert_path_exists('//CClassDefNode')
class BigEgg(object):
@cython.test_assert_path_exists('//CFuncDefNode')
@cython.cfunc
def f(self, a):
return a*10
def test_with():
"""
>>> test_with()
(3, 4)
(3, 4, 50)
"""
return fwith1(1), fwith2(1), BigEgg().f(5)
@cython.test_assert_path_exists('//CClassDefNode')
@cython.cclass
class PureFoo(object):
a = cython.declare(cython.double)
def __init__(self, a):
self.a = a
def __call__(self):
return self.a
@cython.test_assert_path_exists('//CFuncDefNode')
@cython.cfunc
def puremeth(self, a):
return a*2
def test_method():
"""
>>> test_method()
4
True
"""
return fwith1(1), fwith2(1)
x = PureFoo(2)
print(x.puremeth(2))
if cython.compiled:
print(isinstance(x(), float))
else:
print(True)
return
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment