Skip to content

Commit

Permalink
introduce @public marker to explicitly mark members as public (#655)
Browse files Browse the repository at this point in the history
  • Loading branch information
tmeyier committed Jan 17, 2024
1 parent 8750631 commit 3b30281
Show file tree
Hide file tree
Showing 6 changed files with 156 additions and 29 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

## Unreleased: pdoc next

- Private methods can now be included in the documentation by adding `@public` to the docstring.
This complements the existing `@private` annotation.
([#655](https://github.com/mitmproxy/pdoc/pull/655), @tmeyier)
- pdoc now correctly extracts the source_file of wrapped functions.
([#657](https://github.com/mitmproxy/pdoc/pull/657), @tmeyier)

Expand Down
17 changes: 10 additions & 7 deletions pdoc/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,18 +176,21 @@ class GoldenRetriever(Dog):
The public interface of a module is determined through one of two
ways.
- If `__all__` is defined in the module, then all identifiers in that list will be considered public.
No other identifiers will be considered public.
- If `__all__` is not defined, then pdoc will consider all members public that
1. do not start with an underscore,
2. don't have `@private` in their docstring,
2. and are defined in the current module (i.e. they are not imported).
- If `__all__` is not defined, then pdoc will consider all items public that do not start with an
underscore and that are defined in the current module (i.e. they are not imported).
If you want to override the default behavior for a particular item,
you can do so by including an annotation in its docstring:
- `@private` hides an item unconditionally.
- <code>&#64;public</code> shows an item unconditionally.
In general, we recommend keeping these conventions:
In general, we recommend keeping the following conventions:
- If you want to document a private member, consider making it public.
- If you want to hide a public member, consider making it private or add `@private` to their docstring,
- If you want to hide a public member, consider making it private.
- If you want to document a special `__dunder__` method, the recommended way to do so is
to not document the dunder method specifically, but to add some usage examples in the class documentation.
Expand Down
11 changes: 7 additions & 4 deletions pdoc/templates/default/module.html.jinja2
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ See https://pdoc.dev/docs/pdoc/render_helpers.html#DefaultMacroExtension for an
{% enddefaultmacro %}
{% defaultmacro docstring(var) %}
{% if var.docstring %}
<div class="docstring">{{ var.docstring | to_markdown | to_html | linkify(namespace=var.qualname) }}</div>
<div class="docstring">{{ var.docstring | replace("@public", "") | to_markdown | to_html | linkify(namespace=var.qualname) }}</div>
{% endif %}
{% enddefaultmacro %}
{% defaultmacro nav_members(members) %}
Expand Down Expand Up @@ -239,10 +239,13 @@ See https://pdoc.dev/docs/pdoc/render_helpers.html#DefaultMacroExtension for an
Implementing this as a macro makes it very easy to override with a custom template, see
https://github.com/mitmproxy/pdoc/tree/main/examples/custom-template.
#}
{% if not include_undocumented and not doc.docstring %}
{# hide members that are undocumented if include_undocumented has been toggled off. #}
{% elif doc.docstring and "@private" in doc.docstring %}
{% if "@private" in doc.docstring %}
{# hide members explicitly marked as @private #}
{% elif "@public" in doc.docstring %}
{# show members explicitly marked as @public #}
true
{% elif not include_undocumented and not doc.docstring %}
{# hide members that are undocumented if include_undocumented has been toggled off. #}
{% elif doc.name == "__init__" and (doc.docstring or (doc.kind == "function" and doc.signature_without_self.parameters)) %}
{# show constructors that have a docstring or at least one extra argument #}
true
Expand Down
117 changes: 103 additions & 14 deletions test/testdata/visibility.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@

<h2>API Documentation</h2>
<ul class="memberlist">
<li>
<a class="function" href="#__private_func_explicitly_public">__private_func_explicitly_public</a>
</li>
<li>
<a class="function" href="#public_func">public_func</a>
</li>
</ul>


Expand All @@ -39,31 +45,114 @@ <h2>API Documentation</h2>
<h1 class="modulename">
visibility </h1>

<div class="docstring"><p>Example where no children should be rendered.</p>
<div class="docstring"><p>Example where only the these children should be rendered:</p>

<ul>
<li><code><a href="#__private_func_explicitly_public">__private_func_explicitly_public</a></code> and</li>
<li><code><a href="#public_func">public_func</a></code></li>
</ul>
</div>

<input id="mod-visibility-view-source" class="view-source-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">

<label class="view-source-button" for="mod-visibility-view-source"><span>View Source</span></label>

<div class="pdoc-code codehilite"><pre><span></span><span id="L-1"><a href="#L-1"><span class="linenos"> 1</span></a><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-2"><a href="#L-2"><span class="linenos"> 2</span></a><span class="sd">Example where no children should be rendered.</span>
</span><span id="L-3"><a href="#L-3"><span class="linenos"> 3</span></a><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-4"><a href="#L-4"><span class="linenos"> 4</span></a>
</span><span id="L-5"><a href="#L-5"><span class="linenos"> 5</span></a>
</span><span id="L-6"><a href="#L-6"><span class="linenos"> 6</span></a><span class="k">class</span> <span class="nc">Undocumented</span><span class="p">:</span>
</span><span id="L-7"><a href="#L-7"><span class="linenos"> 7</span></a> <span class="c1"># Not shown because no docstring.</span>
</span><span id="L-8"><a href="#L-8"><span class="linenos"> 8</span></a> <span class="k">pass</span>
</span><span id="L-9"><a href="#L-9"><span class="linenos"> 9</span></a>
</span><span id="L-10"><a href="#L-10"><span class="linenos">10</span></a>
</span><span id="L-11"><a href="#L-11"><span class="linenos">11</span></a><span class="k">def</span> <span class="nf">my_func</span><span class="p">():</span>
</span><span id="L-12"><a href="#L-12"><span class="linenos">12</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-13"><a href="#L-13"><span class="linenos">13</span></a><span class="sd"> This is a public method that&#39;s not shown because it&#39;s marked as @private.</span>
</span><span id="L-14"><a href="#L-14"><span class="linenos">14</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="L-2"><a href="#L-2"><span class="linenos"> 2</span></a><span class="sd">Example where only the these children should be rendered:</span>
</span><span id="L-3"><a href="#L-3"><span class="linenos"> 3</span></a><span class="sd"> * `__private_func_explicitly_public` and</span>
</span><span id="L-4"><a href="#L-4"><span class="linenos"> 4</span></a><span class="sd"> * `public_func` </span>
</span><span id="L-5"><a href="#L-5"><span class="linenos"> 5</span></a><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-6"><a href="#L-6"><span class="linenos"> 6</span></a>
</span><span id="L-7"><a href="#L-7"><span class="linenos"> 7</span></a>
</span><span id="L-8"><a href="#L-8"><span class="linenos"> 8</span></a><span class="k">class</span> <span class="nc">Undocumented</span><span class="p">:</span>
</span><span id="L-9"><a href="#L-9"><span class="linenos"> 9</span></a> <span class="c1"># Not shown because no docstring.</span>
</span><span id="L-10"><a href="#L-10"><span class="linenos">10</span></a> <span class="k">pass</span>
</span><span id="L-11"><a href="#L-11"><span class="linenos">11</span></a>
</span><span id="L-12"><a href="#L-12"><span class="linenos">12</span></a>
</span><span id="L-13"><a href="#L-13"><span class="linenos">13</span></a><span class="k">def</span> <span class="nf">public_func_marked_private</span><span class="p">():</span>
</span><span id="L-14"><a href="#L-14"><span class="linenos">14</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-15"><a href="#L-15"><span class="linenos">15</span></a><span class="sd"> This is a public method that&#39;s not shown because it&#39;s marked as @private.</span>
</span><span id="L-16"><a href="#L-16"><span class="linenos">16</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="L-17"><a href="#L-17"><span class="linenos">17</span></a>
</span><span id="L-18"><a href="#L-18"><span class="linenos">18</span></a>
</span><span id="L-19"><a href="#L-19"><span class="linenos">19</span></a><span class="k">def</span> <span class="nf">_protected_func</span><span class="p">():</span>
</span><span id="L-20"><a href="#L-20"><span class="linenos">20</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-21"><a href="#L-21"><span class="linenos">21</span></a><span class="sd"> This is a protected method that&#39;s not shown because its name starts with _.</span>
</span><span id="L-22"><a href="#L-22"><span class="linenos">22</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="L-23"><a href="#L-23"><span class="linenos">23</span></a>
</span><span id="L-24"><a href="#L-24"><span class="linenos">24</span></a>
</span><span id="L-25"><a href="#L-25"><span class="linenos">25</span></a><span class="k">def</span> <span class="nf">__private_func</span><span class="p">():</span>
</span><span id="L-26"><a href="#L-26"><span class="linenos">26</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-27"><a href="#L-27"><span class="linenos">27</span></a><span class="sd"> This is a private method that&#39;s not shown because its name starts with __.</span>
</span><span id="L-28"><a href="#L-28"><span class="linenos">28</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="L-29"><a href="#L-29"><span class="linenos">29</span></a>
</span><span id="L-30"><a href="#L-30"><span class="linenos">30</span></a>
</span><span id="L-31"><a href="#L-31"><span class="linenos">31</span></a><span class="k">def</span> <span class="nf">__private_func_explicitly_public</span><span class="p">():</span>
</span><span id="L-32"><a href="#L-32"><span class="linenos">32</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;@public</span>
</span><span id="L-33"><a href="#L-33"><span class="linenos">33</span></a><span class="sd"> This is a private method that&#39;s shown because it is explicitly marked</span>
</span><span id="L-34"><a href="#L-34"><span class="linenos">34</span></a><span class="sd"> as public.</span>
</span><span id="L-35"><a href="#L-35"><span class="linenos">35</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span><span id="L-36"><a href="#L-36"><span class="linenos">36</span></a>
</span><span id="L-37"><a href="#L-37"><span class="linenos">37</span></a>
</span><span id="L-38"><a href="#L-38"><span class="linenos">38</span></a><span class="k">def</span> <span class="nf">public_func</span><span class="p">():</span>
</span><span id="L-39"><a href="#L-39"><span class="linenos">39</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="L-40"><a href="#L-40"><span class="linenos">40</span></a><span class="sd"> This is another public method that&#39;s shown. It should show without additional</span>
</span><span id="L-41"><a href="#L-41"><span class="linenos">41</span></a><span class="sd"> whitespace above.</span>
</span><span id="L-42"><a href="#L-42"><span class="linenos">42</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span></pre></div>


</section>
<section id="__private_func_explicitly_public">
<input id="__private_func_explicitly_public-view-source" class="view-source-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<div class="attr function">

<span class="def">def</span>
<span class="name">__private_func_explicitly_public</span><span class="signature pdoc-code condensed">(<span class="return-annotation">):</span></span>

<label class="view-source-button" for="__private_func_explicitly_public-view-source"><span>View Source</span></label>

</div>
<a class="headerlink" href="#__private_func_explicitly_public"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="__private_func_explicitly_public-32"><a href="#__private_func_explicitly_public-32"><span class="linenos">32</span></a><span class="k">def</span> <span class="nf">__private_func_explicitly_public</span><span class="p">():</span>
</span><span id="__private_func_explicitly_public-33"><a href="#__private_func_explicitly_public-33"><span class="linenos">33</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;@public</span>
</span><span id="__private_func_explicitly_public-34"><a href="#__private_func_explicitly_public-34"><span class="linenos">34</span></a><span class="sd"> This is a private method that&#39;s shown because it is explicitly marked</span>
</span><span id="__private_func_explicitly_public-35"><a href="#__private_func_explicitly_public-35"><span class="linenos">35</span></a><span class="sd"> as public.</span>
</span><span id="__private_func_explicitly_public-36"><a href="#__private_func_explicitly_public-36"><span class="linenos">36</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span></pre></div>


<div class="docstring"><p>This is a private method that's shown because it is explicitly marked
as public.</p>
</div>


</section>
<section id="public_func">
<input id="public_func-view-source" class="view-source-toggle-state" type="checkbox" aria-hidden="true" tabindex="-1">
<div class="attr function">

<span class="def">def</span>
<span class="name">public_func</span><span class="signature pdoc-code condensed">(<span class="return-annotation">):</span></span>

<label class="view-source-button" for="public_func-view-source"><span>View Source</span></label>

</div>
<a class="headerlink" href="#public_func"></a>
<div class="pdoc-code codehilite"><pre><span></span><span id="public_func-39"><a href="#public_func-39"><span class="linenos">39</span></a><span class="k">def</span> <span class="nf">public_func</span><span class="p">():</span>
</span><span id="public_func-40"><a href="#public_func-40"><span class="linenos">40</span></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
</span><span id="public_func-41"><a href="#public_func-41"><span class="linenos">41</span></a><span class="sd"> This is another public method that&#39;s shown. It should show without additional</span>
</span><span id="public_func-42"><a href="#public_func-42"><span class="linenos">42</span></a><span class="sd"> whitespace above.</span>
</span><span id="public_func-43"><a href="#public_func-43"><span class="linenos">43</span></a><span class="sd"> &quot;&quot;&quot;</span>
</span></pre></div>


<div class="docstring"><p>This is another public method that's shown. It should show without additional
whitespace above.</p>
</div>


</section>
</main>
</body>
</html>
32 changes: 30 additions & 2 deletions test/testdata/visibility.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
"""
Example where no children should be rendered.
Example where only the these children should be rendered:
* `__private_func_explicitly_public` and
* `public_func`
"""


Expand All @@ -8,7 +10,33 @@ class Undocumented:
pass


def my_func():
def public_func_marked_private():
"""
This is a public method that's not shown because it's marked as @private.
"""


def _protected_func():
"""
This is a protected method that's not shown because its name starts with _.
"""


def __private_func():
"""
This is a private method that's not shown because its name starts with __.
"""


def __private_func_explicitly_public():
"""@public
This is a private method that's shown because it is explicitly marked
as public.
"""


def public_func():
"""
This is another public method that's shown. It should show without additional
whitespace above.
"""
5 changes: 3 additions & 2 deletions test/testdata/visibility.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<module visibility # Example where no chi
<module visibility # Example where only t
<class visibility.Undocumented
<method def __init__(): ...>
>
<function def my_func(): ... # This is a public met…>
<function def public_func_marked_private(): ... # This is a public met…>
<function def public_func(): ... # This is another publ…>
>

0 comments on commit 3b30281

Please sign in to comment.