Skip to content

Commit 5f5a34d

Browse files
committed
disambiguate set and frozenset methods in docs
in both search results and the general index
1 parent 96b7a2e commit 5f5a34d

File tree

2 files changed

+118
-0
lines changed

2 files changed

+118
-0
lines changed

Doc/conf.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
'misc_news',
3636
'pydoc_topics',
3737
'pyspecific',
38+
'set_frozenset_search',
3839
'sphinx.ext.coverage',
3940
'sphinx.ext.doctest',
4041
'sphinx.ext.extlinks',
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
"""Adjust set and frozenset methods in search index and general index."""
2+
3+
from sphinx import addnodes
4+
from sphinx.domains.python import ObjectEntry
5+
6+
COMMON_METHODS = {
7+
"isdisjoint",
8+
"issubset",
9+
"issuperset",
10+
"union",
11+
"intersection",
12+
"difference",
13+
"symmetric_difference",
14+
"copy",
15+
}
16+
17+
SET_ONLY_METHODS = {
18+
"update",
19+
"intersection_update",
20+
"difference_update",
21+
"symmetric_difference_update",
22+
"add",
23+
"remove",
24+
"discard",
25+
"pop",
26+
"clear",
27+
}
28+
29+
30+
def adjust_set_frozenset_method_anchors(app, doctree):
31+
"""
32+
Change all frozenset.method references to be set.method instead
33+
(old anchors are kept around so as not to break links)
34+
"""
35+
if app.env.path2doc(doctree['source']) != 'library/stdtypes':
36+
return
37+
38+
# adjust anchors in the text, adding set-based anchors
39+
for desc in doctree.traverse(addnodes.desc):
40+
for sig in desc.traverse(addnodes.desc_signature):
41+
if not sig.get('fullname', '').startswith('frozenset.'):
42+
continue
43+
name = sig['fullname'].rsplit('.', 1)[-1]
44+
if name not in COMMON_METHODS and name not in SET_ONLY_METHODS:
45+
continue
46+
47+
newname = f"set.{name}"
48+
for target in ('names', 'ids'):
49+
sig.get(target, []).insert(0, newname)
50+
sig['fullname'] = newname
51+
sig['class'] = "set"
52+
53+
54+
def index_set_frozenset_methods(app, env):
55+
"""
56+
Adjust search results for the built-in `set` and `frozenset` types so that
57+
mutation-oriented methods show up only under `set`, and other methods show
58+
up under both `set` and `frozenset`.
59+
60+
Also adjust the entries in the general index.
61+
"""
62+
domain = env.domains.get("py")
63+
64+
# add set methods to search index and remove the frozenset-based search
65+
# results for those methods that frozenset does not support
66+
for name in COMMON_METHODS | SET_ONLY_METHODS:
67+
oldname = f"frozenset.{name}"
68+
if oldname in domain.objects:
69+
newname = f"set.{name}"
70+
getter = (
71+
domain.objects.pop
72+
if name in SET_ONLY_METHODS
73+
else domain.objects.__getitem__
74+
)
75+
docname, objname, objtype, alias = getter(oldname)
76+
domain.objects[newname] = ObjectEntry(
77+
docname, newname, objtype, False
78+
)
79+
80+
# add set methods to general index and remove the frozenset-based entries
81+
# for those methods that frozenset does not support
82+
stddata = env.domaindata.get('index', {}).get('entries', None)
83+
if stddata is not None:
84+
for docname, entries in list(stddata.items()):
85+
new_entries = []
86+
for entry in entries:
87+
entrytype, entryname, target, ignored, key = entry
88+
if (
89+
target.startswith('frozenset.')
90+
and '(frozenset method)' in entryname
91+
):
92+
method = target.removeprefix('frozenset.')
93+
new_entries.append((
94+
entrytype,
95+
entryname.replace(
96+
'(frozenset method)', '(set method)'
97+
),
98+
f"set.{method}",
99+
ignored,
100+
key,
101+
))
102+
if method not in SET_ONLY_METHODS:
103+
new_entries.append(entry)
104+
else:
105+
new_entries.append(entry)
106+
107+
stddata[docname] = new_entries
108+
109+
110+
def setup(app):
111+
app.connect("doctree-read", adjust_set_frozenset_method_anchors)
112+
app.connect("env-updated", index_set_frozenset_methods)
113+
return {
114+
"version": "1.0",
115+
"parallel_read_safe": True,
116+
"parallel_write_safe": True,
117+
}

0 commit comments

Comments
 (0)