Commit fea7ad6e authored by Stefan Behnel's avatar Stefan Behnel

implement "@cython.inline" decorator for functions

parent ebc39e39
......@@ -9,6 +9,9 @@ Latest
Features added
--------------
* The ``inline`` function modifier is available as a decorator
``@cython.inline`` in pure mode.
* When cygdb is run in a virtualenv, it enables the same virtualenv
inside of the debugger. Patch by Marc Abramowitz.
......
......@@ -2539,7 +2539,7 @@ class DefNode(FuncDefNode):
self.num_required_kw_args = rk
self.num_required_args = r
def as_cfunction(self, cfunc=None, scope=None, overridable=True, returns=None):
def as_cfunction(self, cfunc=None, scope=None, overridable=True, returns=None, modifiers=None):
if self.star_arg:
error(self.star_arg.pos, "cdef function cannot have star argument")
if self.starstar_arg:
......@@ -2588,7 +2588,7 @@ class DefNode(FuncDefNode):
with_gil = cfunc_type.with_gil,
nogil = cfunc_type.nogil)
return CFuncDefNode(self.pos,
modifiers = [],
modifiers = modifiers or [],
base_type = CAnalysedBaseTypeNode(self.pos, type=cfunc_type.return_type),
declarator = declarator,
body = self.body,
......
......@@ -206,6 +206,7 @@ directive_types = {
'binding' : bool,
'cfunc' : None, # decorators do not take directive value
'ccall' : None,
'inline' : None,
'cclass' : None,
'returns' : type,
'set_initial_path': str,
......@@ -221,6 +222,7 @@ for key, val in directive_defaults.items():
directive_scopes = { # defaults to available everywhere
# 'module', 'function', 'class', 'with statement'
'final' : ('cclass', 'function'),
'inline' : ('function',),
'no_gc_clear' : ('cclass',),
'internal' : ('cclass',),
'autotestdict' : ('module',),
......
......@@ -2011,6 +2011,7 @@ class ExpandInplaceOperators(EnvTransform):
# In-place assignments can't happen within an expression.
return node
class AdjustDefByDirectives(CythonTransform, SkipDeclarations):
"""
Adjust function and class definitions by the decorator directives:
......@@ -2018,6 +2019,7 @@ class AdjustDefByDirectives(CythonTransform, SkipDeclarations):
@cython.cfunc
@cython.cclass
@cython.ccall
@cython.inline
"""
def visit_ModuleNode(self, node):
......@@ -2034,15 +2036,22 @@ class AdjustDefByDirectives(CythonTransform, SkipDeclarations):
return node
def visit_DefNode(self, node):
modifiers = []
if 'inline' in self.directives:
modifiers.append('inline')
if 'ccall' in self.directives:
node = node.as_cfunction(overridable=True, returns=self.directives.get('returns'))
node = node.as_cfunction(
overridable=True, returns=self.directives.get('returns'), modifiers=modifiers)
return self.visit(node)
if 'cfunc' in self.directives:
if self.in_py_class:
error(node.pos, "cfunc directive is not allowed here")
else:
node = node.as_cfunction(overridable=False, returns=self.directives.get('returns'))
node = node.as_cfunction(
overridable=False, returns=self.directives.get('returns'), modifiers=modifiers)
return self.visit(node)
if 'inline' in modifiers:
error(node.pos, "Python functions cannot be declared 'inline'")
self.visitchildren(node)
return node
......
......@@ -164,7 +164,8 @@ Use the ``@cython.cfunc`` decorator for :keyword:`cdef` functions
and the ``@cython.ccall`` decorators for :keyword:`cpdef` functions
respectively. To declare the argument types, use the
``@cython.locals()`` decorator. For the return type, use
``@cython.returns(a_type)``.
``@cython.returns(a_type)``. The C ``inline`` modifier is available
as ``@cython.inline`` decorator.
Here is an example of a :keyword:`cdef` function::
......
......@@ -173,6 +173,7 @@ def test_declare_c_types(n):
#z02 = cython.declare(cython.doublecomplex, n+1j)
#z03 = cython.declare(cython.longdoublecomplex, n+1j)
@cython.ccall
@cython.returns(cython.double)
def c_call(x):
......@@ -193,6 +194,30 @@ def c_call(x):
"""
return x
def call_ccall(x):
ret = c_call(x)
return ret, cython.typeof(ret)
@cython.cfunc
@cython.inline
@cython.returns(cython.double)
def cdef_inline(x):
"""
>>> result, return_type = call_cdef_inline(1)
>>> (not is_compiled and 'float') or type(return_type).__name__
'float'
>>> (not is_compiled and 'double') or return_type
'double'
>>> (is_compiled and 'int') or return_type
'int'
>>> result == 2.0 or result
True
"""
return x + 1
def call_cdef_inline(x):
ret = cdef_inline(x)
return ret, cython.typeof(ret)
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