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

@cython.cclass decorator for class

parent 4b61e74c
...@@ -546,6 +546,9 @@ class CFuncDeclaratorNode(CDeclaratorNode): ...@@ -546,6 +546,9 @@ class CFuncDeclaratorNode(CDeclaratorNode):
if name_declarator.cname: if name_declarator.cname:
error(self.pos, error(self.pos,
"Function argument cannot have C name specification") "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 ** # Turn *[] argument into **
if type.is_array: if type.is_array:
type = PyrexTypes.c_ptr_type(type.base_type) type = PyrexTypes.c_ptr_type(type.base_type)
......
...@@ -96,6 +96,7 @@ directive_types = { ...@@ -96,6 +96,7 @@ directive_types = {
'internal' : bool, # cdef class visibility in the module dict 'internal' : bool, # cdef class visibility in the module dict
'infer_types' : bool, # values can be True/None/False 'infer_types' : bool, # values can be True/None/False
'cfunc' : None, # decorators do not take directive value 'cfunc' : None, # decorators do not take directive value
'cclass' : None,
} }
for key, val in directive_defaults.items(): for key, val in directive_defaults.items():
......
...@@ -1411,6 +1411,10 @@ class AdjustDefByDirectives(CythonTransform, SkipDeclarations): ...@@ -1411,6 +1411,10 @@ class AdjustDefByDirectives(CythonTransform, SkipDeclarations):
return node return node
def visit_PyClassDefNode(self, node): def visit_PyClassDefNode(self, node):
if 'cclass' in self.directives:
node = node.as_cclass()
return self.visit(node)
else:
old_in_pyclass = self.in_py_class old_in_pyclass = self.in_py_class
self.in_py_class = True self.in_py_class = True
self.visitchildren(node) self.visitchildren(node)
......
...@@ -23,7 +23,7 @@ class _EmptyDecoratorAndManager(object): ...@@ -23,7 +23,7 @@ class _EmptyDecoratorAndManager(object):
def __exit__(self, exc_type, exc_value, traceback): def __exit__(self, exc_type, exc_value, traceback):
pass pass
cfunc = _EmptyDecoratorAndManager() cclass = cfunc = _EmptyDecoratorAndManager()
def inline(f, *args, **kwds): def inline(f, *args, **kwds):
if isinstance(f, basestring): 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 import cython
from cython import cfunc from cython import cfunc, cclass
@cython.test_assert_path_exists('//CFuncDefNode') @cython.test_assert_path_exists('//CFuncDefNode')
@cython.cfunc @cython.cfunc
...@@ -28,9 +28,50 @@ with cfunc: ...@@ -28,9 +28,50 @@ with cfunc:
def fwith2(a): def fwith2(a):
return a*4 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(): def test_with():
""" """
>>> 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