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): ...@@ -127,7 +127,6 @@ class EmbedSignature(CythonTransform):
else: else:
return signature return signature
def __call__(self, node): def __call__(self, node):
if not Options.docstrings: if not Options.docstrings:
return node return node
...@@ -206,8 +205,25 @@ class EmbedSignature(CythonTransform): ...@@ -206,8 +205,25 @@ class EmbedSignature(CythonTransform):
old_doc = node.py_func.entry.doc old_doc = node.py_func.entry.doc
else: else:
old_doc = None 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) node.entry.doc = EncodedString(new_doc)
if hasattr(node, 'py_func') and node.py_func is not None: if hasattr(node, 'py_func') and node.py_func is not None:
node.py_func.entry.doc = EncodedString(new_doc) node.py_func.entry.doc = EncodedString(new_doc)
return node 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): ...@@ -1202,6 +1202,8 @@ class CVarDefNode(StatNode):
self.entry = dest_scope.declare_var(name, type, declarator.pos, self.entry = dest_scope.declare_var(name, type, declarator.pos,
cname=cname, visibility=visibility, in_pxd=self.in_pxd, cname=cname, visibility=visibility, in_pxd=self.in_pxd,
api=self.api, is_cdef=1) api=self.api, is_cdef=1)
if Options.docstrings:
self.entry.doc = embed_position(self.pos, self.doc)
class CStructOrUnionDefNode(StatNode): class CStructOrUnionDefNode(StatNode):
...@@ -4286,15 +4288,15 @@ class PropertyNode(StatNode): ...@@ -4286,15 +4288,15 @@ class PropertyNode(StatNode):
# #
# name string # name string
# doc EncodedString or None Doc string # doc EncodedString or None Doc string
# entry Symtab.Entry
# body StatListNode # body StatListNode
child_attrs = ["body"] child_attrs = ["body"]
def analyse_declarations(self, env): def analyse_declarations(self, env):
entry = env.declare_property(self.name, self.doc, self.pos) self.entry = env.declare_property(self.name, self.doc, self.pos)
if entry: self.entry.scope.directives = env.directives
entry.scope.directives = env.directives self.body.analyse_declarations(self.entry.scope)
self.body.analyse_declarations(entry.scope)
def analyse_expressions(self, env): def analyse_expressions(self, env):
self.body = self.body.analyse_expressions(env) self.body = self.body.analyse_expressions(env)
......
...@@ -1800,23 +1800,7 @@ if VALUE is not None: ...@@ -1800,23 +1800,7 @@ if VALUE is not None:
attribute=entry.name), attribute=entry.name),
}, pos=entry.pos).stats[0] }, pos=entry.pos).stats[0]
property.name = entry.name property.name = entry.name
# --------------------------------------- property.doc = entry.doc
# 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)
# ---------------------------------------
return property return property
......
...@@ -2808,11 +2808,19 @@ def p_c_func_or_var_declaration(s, pos, ctx): ...@@ -2808,11 +2808,19 @@ def p_c_func_or_var_declaration(s, pos, ctx):
assignable = 1, nonempty = 1) assignable = 1, nonempty = 1)
declarators.append(declarator) declarators.append(declarator)
s.expect_newline("Syntax error in C variable declaration") 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, result = Nodes.CVarDefNode(pos,
visibility = ctx.visibility, visibility = ctx.visibility,
base_type = base_type, base_type = base_type,
declarators = declarators, declarators = declarators,
in_pxd = ctx.level in ('module_pxd', 'c_class_pxd'), in_pxd = ctx.level in ('module_pxd', 'c_class_pxd'),
doc = doc,
api = ctx.api, api = ctx.api,
modifiers = modifiers, modifiers = modifiers,
overridable = ctx.overridable) 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""" ...@@ -7,13 +7,24 @@ __doc__ = ur"""
>>> print (Ext.attr0.__doc__) >>> print (Ext.attr0.__doc__)
attr0: 'int' attr0: 'int'
attr0 docstring
>>> print (Ext.attr1.__doc__) >>> print (Ext.attr1.__doc__)
attr1: object attr1: object
attr1 docstring
>>> print (Ext.attr2.__doc__) >>> print (Ext.attr2.__doc__)
attr2: list attr2: list
>>> print (Ext.attr3.__doc__) >>> print (Ext.attr3.__doc__)
attr3: embedsignatures.Ext 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__) >>> print (Ext.a.__doc__)
Ext.a(self) Ext.a(self)
...@@ -166,12 +177,36 @@ __doc__ = ur""" ...@@ -166,12 +177,36 @@ __doc__ = ur"""
cdef class Ext: cdef class Ext:
cdef public int attr0 cdef public int attr0
"""attr0 docstring"""
cdef public attr1 cdef public attr1
"""attr1 docstring"""
cdef public list attr2 cdef public list attr2
cdef public Ext attr3 cdef public Ext attr3
cdef int attr4
cdef attr5
"""private attr5 docstring"""
CONST1, CONST2 = 1, 2 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): def __init__(self, a, b, c=None):
pass 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