Commit b3201262 authored by Nikita Nemkin's avatar Nikita Nemkin

Show attribute access and binary operations in default values in autogenerated signatures.

parent 58131b68
...@@ -11,6 +11,40 @@ class EmbedSignature(CythonTransform): ...@@ -11,6 +11,40 @@ class EmbedSignature(CythonTransform):
self.class_name = None self.class_name = None
self.class_node = None self.class_node = None
unop_precedence = 11
binop_precedence = {
'or': 1,
'and': 2,
'not': 3,
'in': 4, 'not in': 4, 'is': 4, 'is not': 4, '<': 4, '<=': 4, '>': 4, '>=': 4, '!=': 4, '==': 4,
'|': 5,
'^': 6,
'&': 7,
'<<': 8, '>>': 8,
'+': 9, '-': 9,
'*': 10, '/': 10, '//': 10, '%': 10,
# unary: '+': 11, '-': 11, '~': 11
'**': 12}
def _fmt_expr_node(self, node, precedence=0):
if isinstance(node, ExprNodes.BinopNode) and not node.inplace:
new_prec = self.binop_precedence.get(node.operator, 0)
result = '%s %s %s' % (self._fmt_expr_node(node.operand1, new_prec),
node.operator,
self._fmt_expr_node(node.operand2, new_prec))
if precedence > new_prec:
result = '(%s)' % result
elif isinstance(node, ExprNodes.UnopNode):
result = '%s%s' % (node.operator,
self._fmt_expr_node(node.operand, self.unop_precedence))
if precedence > self.unop_precedence:
result = '(%s)' % result
elif isinstance(node, ExprNodes.AttributeNode):
result = '%s.%s' % (self._fmt_expr_node(node.obj), node.attribute)
else:
result = node.name
return result
def _fmt_arg_defv(self, arg): def _fmt_arg_defv(self, arg):
default_val = arg.default default_val = arg.default
if not default_val: if not default_val:
...@@ -31,8 +65,8 @@ class EmbedSignature(CythonTransform): ...@@ -31,8 +65,8 @@ class EmbedSignature(CythonTransform):
return repr_val return repr_val
except Exception: except Exception:
try: try:
return default_val.name # XXX return self._fmt_expr_node(default_val)
except AttributeError: except AttributeError, e:
return '<???>' return '<???>'
def _fmt_arg(self, arg): def _fmt_arg(self, arg):
......
...@@ -150,6 +150,17 @@ __doc__ = ur""" ...@@ -150,6 +150,17 @@ __doc__ = ur"""
>>> print (f_my_f.__doc__) >>> print (f_my_f.__doc__)
f_my_f(MyFloat f) -> MyFloat f_my_f(MyFloat f) -> MyFloat
>>> print (f_defexpr1.__doc__)
f_defexpr1(int x=FLAG1, int y=FLAG2)
>>> print (f_defexpr2.__doc__)
f_defexpr2(int x=FLAG1 | FLAG2, y=FLAG1 & FLAG2)
>>> print (f_defexpr3.__doc__)
f_defexpr3(int x=Ext.CONST1, f=__builtins__.abs)
>>> print (f_defexpr4.__doc__)
f_defexpr4(int x=(Ext.CONST1 + FLAG1) * Ext.CONST2)
""" """
cdef class Ext: cdef class Ext:
...@@ -159,6 +170,8 @@ cdef class Ext: ...@@ -159,6 +170,8 @@ cdef class Ext:
cdef public list attr2 cdef public list attr2
cdef public Ext attr3 cdef public Ext attr3
CONST1, CONST2 = 1, 2
def __init__(self, a, b, c=None): def __init__(self, a, b, c=None):
pass pass
...@@ -307,3 +320,19 @@ cpdef MyInt f_my_i(MyInt i): ...@@ -307,3 +320,19 @@ cpdef MyInt f_my_i(MyInt i):
ctypedef float MyFloat ctypedef float MyFloat
cpdef MyFloat f_my_f(MyFloat f): cpdef MyFloat f_my_f(MyFloat f):
return f return f
cdef enum:
FLAG1
FLAG2
cpdef f_defexpr1(int x = FLAG1, int y = FLAG2):
pass
cpdef f_defexpr2(int x = FLAG1 | FLAG2, y = FLAG1 & FLAG2):
pass
cpdef f_defexpr3(int x = Ext.CONST1, f = __builtins__.abs):
pass
cpdef f_defexpr4(int x = (Ext.CONST1 + FLAG1) * Ext.CONST2):
pass
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