Skip to content

Commit fde2019

Browse files
committed
refactor: Prepare public filtering method feature
Issue-78: mkdocstrings#78
1 parent 9f43ed9 commit fde2019

File tree

29 files changed

+3475
-18
lines changed

29 files changed

+3475
-18
lines changed

docs/insiders/changelog.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
## mkdocstrings-python Insiders
44

5+
### 1.11.0 <small>March 20, 2025</small> { id="1.11.0" }
6+
7+
- [Filtering method: `public`][option-filters-public]
8+
59
### 1.10.0 <small>March 10, 2025</small> { id="1.10.0" }
610

711
- [Backlinks][backlinks]

docs/insiders/goals.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,6 @@ goals:
4545
- name: Backlinks
4646
ref: /usage/configuration/general/#backlinks
4747
since: 2025/03/10
48+
- name: "Filtering method: `public`"
49+
ref: /usage/configuration/members/#option-filters-public
50+
since: 2025/03/20

docs/usage/configuration/members.md

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -335,10 +335,21 @@ def function_c():
335335
[](){#option-filters}
336336
## `filters`
337337

338-
- **:octicons-package-24: Type <code><autoref identifier="list" optional>list</autoref>[<autoref identifier="str" optional>str</autoref>] | None</code> :material-equal: `["!^_[^_]"]`{ title="default value" }**
338+
- **:octicons-package-24: Type <code><autoref identifier="list" optional>list</autoref>[<autoref identifier="str" optional>str</autoref>] | <autoref identifier="typing.Literal" optional>Literal</autoref>["public"] | None</code> :material-equal: `["!^_[^_]"]`{ title="default value" }**
339339
<!-- - **:octicons-project-template-24: Template :material-null:** (N/A) -->
340340

341-
A list of filters applied to filter objects based on their name.
341+
A list of filters, or `"public"`.
342+
343+
**Filtering methods**
344+
345+
[](){#option-filters-public}
346+
347+
[:octicons-heart-fill-24:{ .pulse } Sponsors only](../../insiders/index.md){ .insiders } &mdash;
348+
[:octicons-tag-24: Insiders 1.11.0](../../insiders/changelog.md#1.11.0)
349+
350+
The `public` filtering method will include only public objects: those added to the `__all__` attribute of modules, or not starting with a single underscore. Special methods and attributes ("dunder" methods/attributes, starting and ending with two underscores), like `__init__`, `__call__`, `__mult__`, etc., are always considered public.
351+
352+
**List of filters**
342353

343354
Filters are regular expressions. These regular expressions are evaluated by Python
344355
and so must match the syntax supported by the [`re`][] module.
@@ -379,13 +390,13 @@ plugins:
379390
python:
380391
options:
381392
filters:
382-
- "!^_"
393+
- "!^_[^_]"
383394
```
384395

385396
```md title="or in docs/some_page.md (local configuration)"
386397
::: package.module
387398
options:
388-
filters: []
399+
filters: public
389400
```
390401

391402
```python title="package/module.py"

mkdocs.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ plugins:
160160
ignore_init_summary: true
161161
docstring_section_style: list
162162
extensions: [scripts/griffe_extensions.py]
163-
filters: ["!^_"]
163+
filters: public
164164
heading_level: 1
165165
inherited_members: true
166166
line_length: 88

src/mkdocstrings_handlers/python/_internal/config.py

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -432,14 +432,24 @@ class PythonInputOptions:
432432
] = field(default_factory=list)
433433

434434
filters: Annotated[
435-
list[str],
435+
list[str] | Literal["public"],
436436
_Field(
437437
group="members",
438-
description="""A list of filters applied to filter objects based on their name.
438+
description="""A list of filters, or `"public"`.
439+
440+
**List of filters**
439441
440442
A filter starting with `!` will exclude matching objects instead of including them.
441443
The `members` option takes precedence over `filters` (filters will still be applied recursively
442444
to lower members in the hierarchy).
445+
446+
**Filtering methods**
447+
448+
[:octicons-heart-fill-24:{ .pulse } Sponsors only](../insiders/index.md){ .insiders } &mdash;
449+
[:octicons-tag-24: Insiders 1.11.0](../insiders/changelog.md#1.11.0)
450+
451+
The `public` method will include only public objects:
452+
those added to `__all__` or not starting with an underscore (except for special methods/attributes).
443453
""",
444454
),
445455
] = field(default_factory=lambda: _DEFAULT_FILTERS.copy())
@@ -916,12 +926,12 @@ def from_data(cls, **data: Any) -> Self:
916926
class PythonOptions(PythonInputOptions): # type: ignore[override,unused-ignore]
917927
"""Final options passed as template context."""
918928

919-
filters: list[tuple[re.Pattern, bool]] = field( # type: ignore[assignment]
929+
filters: list[tuple[re.Pattern, bool]] | Literal["public"] = field( # type: ignore[assignment]
920930
default_factory=lambda: [
921931
(re.compile(filtr.removeprefix("!")), filtr.startswith("!")) for filtr in _DEFAULT_FILTERS
922932
],
923933
)
924-
"""A list of filters applied to filter objects based on their name."""
934+
"""A list of filters, or `"public"`."""
925935

926936
summary: SummaryOption = field(default_factory=SummaryOption)
927937
"""Whether to render summaries of modules, classes, functions (methods) and attributes."""
@@ -930,6 +940,11 @@ class PythonOptions(PythonInputOptions): # type: ignore[override,unused-ignore]
930940
def coerce(cls, **data: Any) -> MutableMapping[str, Any]:
931941
"""Create an instance from a dictionary."""
932942
if "filters" in data:
943+
# Non-insiders: transform back to default filters.
944+
# Next: `if "filters" in data and not isinstance(data["filters"], str):`.
945+
if data["filters"] == "public":
946+
data["filters"] = _DEFAULT_FILTERS
947+
# Filters are `None` or a sequence of strings (tests use tuples).
933948
data["filters"] = [
934949
(re.compile(filtr.removeprefix("!")), filtr.startswith("!")) for filtr in data["filters"] or ()
935950
]

src/mkdocstrings_handlers/python/_internal/rendering.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,7 @@ def _keep_object(name: str, filters: Sequence[tuple[Pattern, bool]]) -> bool:
399399
def do_filter_objects(
400400
objects_dictionary: dict[str, Object | Alias],
401401
*,
402-
filters: Sequence[tuple[Pattern, bool]] | None = None,
402+
filters: Sequence[tuple[Pattern, bool]] | Literal["public"] | None = None,
403403
members_list: bool | list[str] | None = None,
404404
inherited_members: bool | list[str] = False,
405405
keep_no_docstrings: bool = True,
@@ -408,7 +408,7 @@ def do_filter_objects(
408408
409409
Parameters:
410410
objects_dictionary: The dictionary of objects.
411-
filters: Filters to apply, based on members' names.
411+
filters: Filters to apply, based on members' names, or `"public"`.
412412
Each element is a tuple: a pattern, and a boolean indicating whether
413413
to reject the object if the pattern matches.
414414
members_list: An optional, explicit list of members to keep.
@@ -449,7 +449,9 @@ def do_filter_objects(
449449
]
450450

451451
# Use filters and docstrings.
452-
if filters:
452+
if filters == "public":
453+
objects = [obj for obj in objects if obj.is_public]
454+
elif filters:
453455
objects = [
454456
obj for obj in objects if _keep_object(obj.name, filters) or (inherited_members_specified and obj.inherited)
455457
]

src/mkdocstrings_handlers/python/templates/material/_base/children.html.jinja

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ Context:
4949
{% endif %}
5050
{% with heading_level = heading_level + extra_level %}
5151
{% for attribute in attributes|order_members(config.members_order, members_list) %}
52-
{% if members_list is not none or (not attribute.is_imported or attribute.is_public) %}
52+
{% if config.filters == "public" or members_list is not none or (not attribute.is_imported or attribute.is_public) %}
5353
{% include attribute|get_template with context %}
5454
{% endif %}
5555
{% endfor %}
@@ -69,7 +69,7 @@ Context:
6969
{% endif %}
7070
{% with heading_level = heading_level + extra_level %}
7171
{% for class in classes|order_members(config.members_order, members_list) %}
72-
{% if members_list is not none or (not class.is_imported or class.is_public) %}
72+
{% if config.filters == "public" or members_list is not none or (not class.is_imported or class.is_public) %}
7373
{% include class|get_template with context %}
7474
{% endif %}
7575
{% endfor %}
@@ -90,7 +90,7 @@ Context:
9090
{% with heading_level = heading_level + extra_level %}
9191
{% for function in functions|order_members(config.members_order, members_list) %}
9292
{% if not (obj.kind.value == "class" and function.name == "__init__" and config.merge_init_into_class) %}
93-
{% if members_list is not none or (not function.is_imported or function.is_public) %}
93+
{% if config.filters == "public" or members_list is not none or (not function.is_imported or function.is_public) %}
9494
{% include function|get_template with context %}
9595
{% endif %}
9696
{% endif %}
@@ -112,7 +112,7 @@ Context:
112112
{% endif %}
113113
{% with heading_level = heading_level + extra_level %}
114114
{% for module in modules|order_members("alphabetical", members_list) %}
115-
{% if members_list is not none or (not module.is_alias or module.is_public) %}
115+
{% if config.filters == "public" or members_list is not none or (not module.is_alias or module.is_public) %}
116116
{% include module|get_template with context %}
117117
{% endif %}
118118
{% endfor %}
@@ -137,7 +137,7 @@ Context:
137137

138138
{% if not (obj.is_class and child.name == "__init__" and config.merge_init_into_class) %}
139139

140-
{% if members_list is not none or child.is_public %}
140+
{% if config.filters == "public" or members_list is not none or child.is_public %}
141141
{% if child.is_attribute %}
142142
{% with attribute = child %}
143143
{% include attribute|get_template with context %}

tests/snapshots/__init__.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,5 +353,35 @@
353353
("inherited_members", ()),
354354
("members", ()),
355355
): external("a185e216dc7b*.html"),
356+
(("filters", "public"), ("inherited_members", ("method1",)), ("members", None)): external("6af55596d9c4*.html"),
357+
(("filters", "public"), ("inherited_members", ("method1",)), ("members", False)): external(
358+
"6abf5ddd819b*.html",
359+
),
360+
(("filters", "public"), ("inherited_members", ()), ("members", None)): external("6d72c524b827*.html"),
361+
(("filters", "public"), ("inherited_members", False), ("members", False)): external("9dab67183389*.html"),
362+
(("filters", "public"), ("inherited_members", ("method1",)), ("members", True)): external("6c0b7207df03*.html"),
363+
(("filters", "public"), ("inherited_members", True), ("members", ())): external("f48d651b3f1a*.html"),
364+
(("filters", "public"), ("inherited_members", ("method1",)), ("members", ("module_attribute",))): external(
365+
"408244423577*.html",
366+
),
367+
(("filters", "public"), ("inherited_members", True), ("members", None)): external("16295fa51a2c*.html"),
368+
(("filters", "public"), ("inherited_members", True), ("members", True)): external("37232379c426*.html"),
369+
(("filters", "public"), ("inherited_members", ()), ("members", ())): external("2e866eca9a45*.html"),
370+
(("filters", "public"), ("inherited_members", True), ("members", False)): external("ed5d07bcdbaa*.html"),
371+
(("filters", "public"), ("inherited_members", False), ("members", ())): external("135f57223e00*.html"),
372+
(("filters", "public"), ("inherited_members", False), ("members", None)): external("b4e20d5cd52e*.html"),
373+
(("filters", "public"), ("inherited_members", ()), ("members", False)): external("46daa7e60b98*.html"),
374+
(("filters", "public"), ("inherited_members", False), ("members", True)): external("a255ee80bf7a*.html"),
375+
(("filters", "public"), ("inherited_members", ()), ("members", True)): external("74e2496015e1*.html"),
376+
(("filters", "public"), ("inherited_members", True), ("members", ("module_attribute",))): external(
377+
"e254ae60f9af*.html",
378+
),
379+
(("filters", "public"), ("inherited_members", ("method1",)), ("members", ())): external("51d73351dc55*.html"),
380+
(("filters", "public"), ("inherited_members", ()), ("members", ("module_attribute",))): external(
381+
"d56d3aeae22b*.html",
382+
),
383+
(("filters", "public"), ("inherited_members", False), ("members", ("module_attribute",))): external(
384+
"80399c502938*.html",
385+
),
356386
},
357387
)
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<!--
2+
{
3+
"filters": "public",
4+
"inherited_members": false,
5+
"members": []
6+
}
7+
-->
8+
9+
<div class="doc doc-object doc-module">
10+
<h1 class="doc doc-heading" id="members_package">
11+
<code>
12+
members_package
13+
</code>
14+
</h1>
15+
<div class="doc doc-contents first">
16+
<p>
17+
Docstring for the package.
18+
</p>
19+
<div class="doc doc-children">
20+
</div>
21+
</div>
22+
</div>

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy