Skip to content

Add doc_append #129

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Feb 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 20 additions & 3 deletions robotpy_build/hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,16 +137,28 @@ def _set_name(self, name, data, strip_prefixes=None, is_operator=False):

return name

def _process_doc(self, thing, data) -> typing.Optional[typing.List[str]]:
def _process_doc(
self, thing, data, append_prefix=""
) -> typing.Optional[typing.List[str]]:
doc = ""
doc_quoted: typing.Optional[typing.List[str]] = None

if data.doc is not None:
doc = data.doc
elif "doxygen" in thing:
doc = thing["doxygen"]
doc = sphinxify.process_raw(doc)

if data.doc_append is not None:
doc += f"\n{append_prefix}" + data.doc_append.replace(
"\n", f"\n{append_prefix}"
)

return self._quote_doc(doc)

def _quote_doc(
self, doc: typing.Optional[str]
) -> typing.Optional[typing.List[str]]:
doc_quoted: typing.Optional[typing.List[str]] = None
if doc:
# TODO
doc = doc.replace("\\", "\\\\").replace('"', '\\"')
Expand Down Expand Up @@ -210,7 +222,7 @@ def _enum_hook(self, en, enum_data):
v_data = EnumValue()
v["x_name"] = self._set_name(name, v_data, strip_prefixes)
v["data"] = v_data
v["x_doc_quoted"] = self._process_doc(v, v_data)
v["x_doc_quoted"] = self._process_doc(v, v_data, append_prefix=" ")

def header_hook(self, header, data):
"""Called for each header"""
Expand Down Expand Up @@ -244,6 +256,11 @@ def header_hook(self, header, data):
qualname = f"::{qualname}"
tmpl_data_d = tmpl_data.dict()
tmpl_data_d["x_qualname_"] = qualname.translate(self._qualname_trans)
tmpl_data_d["x_doc_set"] = self._quote_doc(tmpl_data.doc)
doc_add = tmpl_data.doc_append
if doc_add:
doc_add = f"\n{doc_add}"
tmpl_data_d["x_doc_add"] = self._quote_doc(doc_add)
self._add_subpackage(tmpl_data_d, tmpl_data)
templates[k] = tmpl_data_d

Expand Down
23 changes: 22 additions & 1 deletion robotpy_build/hooks_datacfg.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,12 @@ class FunctionData(Model):
#: Use this code instead of the generated code
cpp_code: Optional[str] = None

#: Docstring for the function
#: Docstring for the function, will attempt to convert Doxygen docs if omitted
doc: Optional[str] = None

#: Text to append to the (autoconverted) docstring for the function
doc_append: Optional[str] = None

#: If True, prepends an underscore to the python name
internal: bool = False

Expand Down Expand Up @@ -218,6 +221,9 @@ class PropData(Model):
#: Docstring for the property (only available on class properties)
doc: Optional[str] = None

#: Text to append to the (autoconverted) docstring
doc_append: Optional[str] = None


class EnumValue(Model):

Expand All @@ -230,12 +236,18 @@ class EnumValue(Model):
#: Docstring for the enum value
doc: Optional[str] = None

#: Text to append to the (autoconverted) docstring
doc_append: Optional[str] = None


class EnumData(Model):

#: Set your own docstring for the enum
doc: Optional[str] = None

#: Text to append to the (autoconverted) docstring
doc_append: Optional[str] = None

#: If set to True, this property is not made available to python
ignore: bool = False

Expand All @@ -256,6 +268,9 @@ class ClassData(Model):
#: Docstring for the class
doc: Optional[str] = None

#: Text to append to the (autoconverted) docstring
doc_append: Optional[str] = None

ignore: bool = False
ignored_bases: List[str] = []

Expand Down Expand Up @@ -384,6 +399,12 @@ class MyClass {};
#: If specified, put the template instantiation in a sub.pack.age
subpackage: Optional[str] = None

#: Set the docstring for the template instance
doc: Optional[str] = None

#: Text to append to the (autoconverted) docstring for the template instance
doc_append: Optional[str] = None


class HooksDataYaml(Model):
"""
Expand Down
7 changes: 5 additions & 2 deletions robotpy_build/templates/cls.cpp.j2
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,11 @@ void finish() {
{% endfor %}

{# templates #}
{% for _ in templates.items() %}
tmplCls{{ loop.index }}.finish();
{% for tdata in templates.values() %}
tmplCls{{ loop.index }}.finish(
{% if tdata.x_doc_set %}{{ pybind11.docv(tdata.x_doc_set) }}{% else %}NULL{% endif %},
{% if tdata.x_doc_add %}{{ pybind11.docv(tdata.x_doc_add) }}{% else %}NULL{% endif %}
);
{% endfor %}

{# class methods #}
Expand Down
9 changes: 8 additions & 1 deletion robotpy_build/templates/cls_tmpl_impl.hpp.j2
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,17 @@ bind_{{ cls.x_qualname_ }}(py::module &m, const char * clsName) :
clsName(clsName)
{}

void finish() {
void finish(const char * set_doc = NULL, const char * add_doc = NULL) {

{{ pybind11.cls_def(cls, cls.x_varname) }}

if (set_doc) {
{{ cls.x_varname }}.doc() = set_doc;
}
if (add_doc) {
{{ cls.x_varname }}.doc() = py::cast<std::string>({{ cls.x_varname }}.doc()) + add_doc;
}

{{ cls.data.template_inline_code }}
}

Expand Down
10 changes: 7 additions & 3 deletions robotpy_build/templates/pybind11.cpp.j2
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,15 @@
Macros for binding things with pybind11
#}

{%- macro docv(value) -%}
{%- for dq in value -%}
{{ dq }}{% if loop.nextitem is defined %}{{ '\n' }}{% endif %}
{%- endfor -%}
{%- endmacro -%}

{%- macro doc(o, pre, post) -%}
{%- if o.x_doc_quoted %}{{ pre }}
{% for dq in o.x_doc_quoted -%}
{{ dq }}{% if loop.nextitem is defined %}{{ '\n' }}{% endif %}
{%- endfor -%}{{ post }}
{{ docv(o.x_doc_quoted) }}{{ post }}
{%- endif -%}
{%- endmacro -%}

Expand Down
43 changes: 43 additions & 0 deletions tests/cpp/gen/ft/docstrings_append.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
enums:
DocAppendEnum:
doc_append: |
Useful extra information about this enum
values:
Value1:
doc_append: |
Useful extra information about this value
classes:
DocAppendClass:
shared_ptr: true
doc_append: |
Useful extra information about this sweet class
attributes:
sweet_var:
doc_append: |
Useful extra information about this sweet var
methods:
fn:
doc_append: |
Useful extra information about this fn

DocWithTemplate:
shared_ptr: true
template_params:
- T

templates:
DocTemplateSet:
qualname: DocWithTemplate
params:
- int
doc: |
Set docs to this

DocTemplateAppend:
qualname: DocWithTemplate
params:
- double
doc_append: |
Extra appended docs

1 change: 1 addition & 0 deletions tests/cpp/pyproject.toml.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ generate = [
{ abstract = "abstract.h" },
{ defaults = "defaults.h" },
{ docstrings = "docstrings.h" },
{ docstrings_append = "docstrings_append.h" },
{ enums = "enums.h" },
{ keepalive = "keepalive.h" },
{ ignore = "ignore.h" },
Expand Down
8 changes: 8 additions & 0 deletions tests/cpp/rpytest/ft/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,12 @@
Abstract,
ClassWithIgnored,
ClassWithTrampoline,
DocAppendClass,
DocAppendEnum,
DocClass,
DocEnum,
DocTemplateAppend,
DocTemplateSet,
EnumContainer,
EnumWithIgnored,
GCEnum,
Expand Down Expand Up @@ -62,8 +66,12 @@
"Abstract",
"ClassWithIgnored",
"ClassWithTrampoline",
"DocAppendClass",
"DocAppendEnum",
"DocClass",
"DocEnum",
"DocTemplateAppend",
"DocTemplateSet",
"EnumContainer",
"EnumWithIgnored",
"GCEnum",
Expand Down
34 changes: 34 additions & 0 deletions tests/cpp/rpytest/ft/include/docstrings_append.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#pragma once

/**
An enum that is documented

Maybe it's not great docs, but it's something.
*/
enum DocAppendEnum
{
/** value 1 doc */
Value1,
/** value 2 doc?? */
Value2,
};

/**
A class with documentation

The docs are way cool.
*/
struct DocAppendClass
{
/** Function with docstring for good measure */
void fn() {}

/** An awesome variable, use it for something */
int sweet_var;
};

/**
A templated class
*/
template <typename T>
struct DocWithTemplate {};
53 changes: 53 additions & 0 deletions tests/test_ft_docs.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,56 @@ def test_docstrings():
inspect.getdoc(ft.DocClass.sweet_var)
== "An awesome variable, use it for something"
)


def test_docstrings_append():

assert inspect.getdoc(ft.DocAppendEnum) == inspect.cleandoc(
"""
An enum that is documented
Maybe it's not great docs, but it's something.
Useful extra information about this enum


Members:

Value1 : value 1 doc
Useful extra information about this value


Value2 : value 2 doc??
"""
)

assert inspect.getdoc(ft.DocAppendClass) == inspect.cleandoc(
"""
A class with documentation
The docs are way cool.
Useful extra information about this sweet class
"""
)
assert inspect.getdoc(ft.DocAppendClass.fn) == inspect.cleandoc(
"""
fn(self: rpytest.ft._rpytest_ft.DocAppendClass) -> None

Function with docstring for good measure
Useful extra information about this fn
"""
)
assert inspect.getdoc(ft.DocAppendClass.sweet_var) == inspect.cleandoc(
"""
An awesome variable, use it for something
Useful extra information about this sweet var
"""
)


def test_docstrings_template():
assert inspect.getdoc(ft.DocTemplateSet) == "Set docs to this"

assert inspect.getdoc(ft.DocTemplateAppend) == inspect.cleandoc(
"""
A templated class
Extra appended docs
"""
)