Commit bb08f812 authored by Nikita Nemkin's avatar Nikita Nemkin

Attribute docstrings support for cdef public attributes.

parent b3201262
......@@ -127,7 +127,6 @@ class EmbedSignature(CythonTransform):
else:
return signature
def __call__(self, node):
if not Options.docstrings:
return node
......@@ -206,8 +205,25 @@ class EmbedSignature(CythonTransform):
old_doc = node.py_func.entry.doc
else:
old_doc = None
new_doc = self._embed_signature(signature, old_doc)
new_doc = self._embed_signature(signature, old_doc)
node.entry.doc = EncodedString(new_doc)
if hasattr(node, 'py_func') and node.py_func is not None:
node.py_func.entry.doc = EncodedString(new_doc)
return node
def visit_PropertyNode(self, node):
if not self.current_directives['embedsignature']:
return node
entry = node.entry
if entry.visibility == 'public':
# property synthesised from a cdef public attribute
type_name = entry.type.declaration_code("", for_display=1)
if not entry.type.is_pyobject:
type_name = "'%s'" % type_name
elif entry.type.is_extension_type:
type_name = entry.type.module_name + '.' + type_name
signature = '%s: %s' % (entry.name, type_name)
new_doc = self._embed_signature(signature, entry.doc)
entry.doc = EncodedString(new_doc)
return node
......@@ -1202,6 +1202,8 @@ class CVarDefNode(StatNode):
self.entry = dest_scope.declare_var(name, type, declarator.pos,
cname=cname, visibility=visibility, in_pxd=self.in_pxd,
api=self.api, is_cdef=1)
if Options.docstrings:
self.entry.doc = embed_position(self.pos, self.doc)
class CStructOrUnionDefNode(StatNode):
......@@ -4286,15 +4288,15 @@ class PropertyNode(StatNode):
#
# name string
# doc EncodedString or None Doc string
# entry Symtab.Entry
# body StatListNode
child_attrs = ["body"]
def analyse_declarations(self, env):
entry = env.declare_property(self.name, self.doc, self.pos)
if entry:
entry.scope.directives = env.directives
self.body.analyse_declarations(entry.scope)
self.entry = env.declare_property(self.name, self.doc, self.pos)
self.entry.scope.directives = env.directives
self.body.analyse_declarations(self.entry.scope)
def analyse_expressions(self, env):
self.body = self.body.analyse_expressions(env)
......
......@@ -1800,23 +1800,7 @@ if VALUE is not None:
attribute=entry.name),
}, pos=entry.pos).stats[0]
property.name = entry.name
# ---------------------------------------
# XXX This should go to AutoDocTransforms
# ---------------------------------------
if (Options.docstrings and
self.current_directives['embedsignature']):
attr_name = entry.name
type_name = entry.type.declaration_code("", for_display=1)
default_value = ''
if not entry.type.is_pyobject:
type_name = "'%s'" % type_name
elif entry.type.is_extension_type:
type_name = entry.type.module_name + '.' + type_name
if entry.init is not None:
default_value = ' = ' + entry.init
docstring = attr_name + ': ' + type_name + default_value
property.doc = EncodedString(docstring)
# ---------------------------------------
property.doc = entry.doc
return property
......
......@@ -2808,11 +2808,19 @@ def p_c_func_or_var_declaration(s, pos, ctx):
assignable = 1, nonempty = 1)
declarators.append(declarator)
s.expect_newline("Syntax error in C variable declaration")
if ctx.level == 'c_class':
doc_pos = s.position()
doc = p_doc_string(s)
if doc and ctx.visibility not in ('public', 'readonly'):
warning(doc_pos, "Private attributes don't support docstrings.", 1)
else:
doc = None
result = Nodes.CVarDefNode(pos,
visibility = ctx.visibility,
base_type = base_type,
declarators = declarators,
in_pxd = ctx.level in ('module_pxd', 'c_class_pxd'),
doc = doc,
api = ctx.api,
modifiers = modifiers,
overridable = ctx.overridable)
......
# mode: error
# tag: werror
cdef class A:
cdef a
"""docstring"""
cdef int b
"""docstring"""
cdef public c
"""docstring"""
cdef public dict d
"""docstring"""
cdef readonly e
"""docstring"""
cdef readonly list e
"""docstring"""
_ERRORS = """
6:4: Private attributes don't support docstrings.
9:4: Private attributes don't support docstrings.
"""
......@@ -7,13 +7,24 @@ __doc__ = ur"""
>>> print (Ext.attr0.__doc__)
attr0: 'int'
attr0 docstring
>>> print (Ext.attr1.__doc__)
attr1: object
attr1 docstring
>>> print (Ext.attr2.__doc__)
attr2: list
>>> print (Ext.attr3.__doc__)
attr3: embedsignatures.Ext
>>> print (Ext.prop0.__doc__)
prop0 docstring
>>> print (Ext.prop1.__doc__)
None
>>> print (Ext.attr4.__doc__)
attr4 docstring
>>> print (Ext.attr5.__doc__)
attr5 docstring
>>> print (Ext.a.__doc__)
Ext.a(self)
......@@ -166,12 +177,36 @@ __doc__ = ur"""
cdef class Ext:
cdef public int attr0
"""attr0 docstring"""
cdef public attr1
"""attr1 docstring"""
cdef public list attr2
cdef public Ext attr3
cdef int attr4
cdef attr5
"""private attr5 docstring"""
CONST1, CONST2 = 1, 2
property prop0:
"""prop0 docstring"""
def __get__(self):
return self.attr0
property prop1:
def __get__(self):
return self.attr1
property attr4:
"""attr4 docstring"""
def __get__(self):
return self.attr4
property attr5:
"""attr5 docstring"""
def __get__(self):
return self.attr4
def __init__(self, a, b, c=None):
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