Skip to content

Commit d1c23a0

Browse files
Add per-event overloads to EventManager.connect() (#12787)
Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com>
1 parent c9d3414 commit d1c23a0

File tree

2 files changed

+312
-2
lines changed

2 files changed

+312
-2
lines changed

.flake8

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,5 +33,6 @@ exclude =
3333
doc/usage/extensions/example*.py,
3434
per-file-ignores =
3535
doc/conf.py:W605
36+
sphinx/events.py:E704,
3637
tests/test_extensions/ext_napoleon_pep526_data_google.py:MLL001,
3738
tests/test_extensions/ext_napoleon_pep526_data_numpy.py:MLL001,

sphinx/events.py

Lines changed: 311 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,27 @@
77

88
from collections import defaultdict
99
from operator import attrgetter
10-
from typing import TYPE_CHECKING, Any, NamedTuple
10+
from typing import TYPE_CHECKING, NamedTuple, overload
1111

1212
from sphinx.errors import ExtensionError, SphinxError
1313
from sphinx.locale import __
1414
from sphinx.util import logging
1515
from sphinx.util.inspect import safe_getattr
1616

1717
if TYPE_CHECKING:
18-
from collections.abc import Callable
18+
from collections.abc import Callable, Iterable, Sequence, Set
19+
from pathlib import Path
20+
from typing import Any, Literal
1921

22+
from docutils import nodes
23+
24+
from sphinx import addnodes
2025
from sphinx.application import Sphinx
26+
from sphinx.builders import Builder
27+
from sphinx.config import Config
28+
from sphinx.domains import Domain
29+
from sphinx.environment import BuildEnvironment
30+
from sphinx.ext.todo import todo_node
2131

2232

2333
logger = logging.getLogger(__name__)
@@ -66,6 +76,305 @@ def add(self, name: str) -> None:
6676
raise ExtensionError(__('Event %r already present') % name)
6777
self.events[name] = ''
6878

79+
# ---- Core events -------------------------------------------------------
80+
81+
@overload
82+
def connect(
83+
self,
84+
name: Literal['config-inited'],
85+
callback: Callable[[Sphinx, Config], None],
86+
priority: int,
87+
) -> int: ...
88+
89+
@overload
90+
def connect(
91+
self,
92+
name: Literal['builder-inited'],
93+
callback: Callable[[Sphinx], None],
94+
priority: int,
95+
) -> int: ...
96+
97+
@overload
98+
def connect(
99+
self,
100+
name: Literal['env-get-outdated'],
101+
callback: Callable[
102+
[Sphinx, BuildEnvironment, Set[str], Set[str], Set[str]], Sequence[str]
103+
],
104+
priority: int,
105+
) -> int: ...
106+
107+
@overload
108+
def connect(
109+
self,
110+
name: Literal['env-before-read-docs'],
111+
callback: Callable[[Sphinx, BuildEnvironment, list[str]], None],
112+
priority: int,
113+
) -> int: ...
114+
115+
@overload
116+
def connect(
117+
self,
118+
name: Literal['env-purge-doc'],
119+
callback: Callable[[Sphinx, BuildEnvironment, str], None],
120+
priority: int,
121+
) -> int: ...
122+
123+
@overload
124+
def connect(
125+
self,
126+
name: Literal['source-read'],
127+
callback: Callable[[Sphinx, str, list[str]], None],
128+
priority: int,
129+
) -> int: ...
130+
131+
@overload
132+
def connect(
133+
self,
134+
name: Literal['include-read'],
135+
callback: Callable[[Sphinx, Path, str, list[str]], None],
136+
priority: int,
137+
) -> int: ...
138+
139+
@overload
140+
def connect(
141+
self,
142+
name: Literal['doctree-read'],
143+
callback: Callable[[Sphinx, nodes.document], None],
144+
priority: int,
145+
) -> int: ...
146+
147+
@overload
148+
def connect(
149+
self,
150+
name: Literal['env-merge-info'],
151+
callback: Callable[
152+
[Sphinx, BuildEnvironment, list[str], BuildEnvironment], None
153+
],
154+
priority: int,
155+
) -> int: ...
156+
157+
@overload
158+
def connect(
159+
self,
160+
name: Literal['env-updated'],
161+
callback: Callable[[Sphinx, BuildEnvironment], str],
162+
priority: int,
163+
) -> int: ...
164+
165+
@overload
166+
def connect(
167+
self,
168+
name: Literal['env-get-updated'],
169+
callback: Callable[[Sphinx, BuildEnvironment], Iterable[str]],
170+
priority: int,
171+
) -> int: ...
172+
173+
@overload
174+
def connect(
175+
self,
176+
name: Literal['env-check-consistency'],
177+
callback: Callable[[Sphinx, BuildEnvironment], None],
178+
priority: int,
179+
) -> int: ...
180+
181+
@overload
182+
def connect(
183+
self,
184+
name: Literal['write-started'],
185+
callback: Callable[[Sphinx, Builder], None],
186+
priority: int,
187+
) -> int: ...
188+
189+
@overload
190+
def connect(
191+
self,
192+
name: Literal['doctree-resolved'],
193+
callback: Callable[[Sphinx, nodes.document, str], None],
194+
priority: int,
195+
) -> int: ...
196+
197+
@overload
198+
def connect(
199+
self,
200+
name: Literal['missing-reference'],
201+
callback: Callable[
202+
[Sphinx, BuildEnvironment, addnodes.pending_xref, nodes.TextElement],
203+
nodes.reference | None,
204+
],
205+
priority: int,
206+
) -> int: ...
207+
208+
@overload
209+
def connect(
210+
self,
211+
name: Literal['warn-missing-reference'],
212+
callback: Callable[[Sphinx, Domain, addnodes.pending_xref], bool | None],
213+
priority: int,
214+
) -> int: ...
215+
216+
@overload
217+
def connect(
218+
self,
219+
name: Literal['build-finished'],
220+
callback: Callable[[Sphinx, Exception | None], None],
221+
priority: int,
222+
) -> int: ...
223+
224+
# ---- Events from builtin builders --------------------------------------
225+
226+
@overload
227+
def connect(
228+
self,
229+
name: Literal['html-collect-pages'],
230+
callback: Callable[[Sphinx], Iterable[tuple[str, dict[str, Any], str]]],
231+
priority: int,
232+
) -> int: ...
233+
234+
@overload
235+
def connect(
236+
self,
237+
name: Literal['html-page-context'],
238+
callback: Callable[
239+
[Sphinx, str, str, dict[str, Any], nodes.document], str | None
240+
],
241+
priority: int,
242+
) -> int: ...
243+
244+
@overload
245+
def connect(
246+
self,
247+
name: Literal['linkcheck-process-uri'],
248+
callback: Callable[[Sphinx, str], str | None],
249+
priority: int,
250+
) -> int: ...
251+
252+
# ---- Events from builtin extensions-- ----------------------------------
253+
254+
@overload
255+
def connect(
256+
self,
257+
name: Literal['object-description-transform'],
258+
callback: Callable[[Sphinx, str, str, addnodes.desc_content], None],
259+
priority: int,
260+
) -> int: ...
261+
262+
# ---- Events from first-party extensions --------------------------------
263+
264+
@overload
265+
def connect(
266+
self,
267+
name: Literal['autodoc-process-docstring'],
268+
callback: Callable[
269+
[
270+
Sphinx,
271+
Literal[
272+
'module', 'class', 'exception', 'function', 'method', 'attribute'
273+
],
274+
str,
275+
Any,
276+
dict[str, bool],
277+
Sequence[str],
278+
],
279+
None,
280+
],
281+
priority: int,
282+
) -> int: ...
283+
284+
@overload
285+
def connect(
286+
self,
287+
name: Literal['autodoc-before-process-signature'],
288+
callback: Callable[[Sphinx, Any, bool], None],
289+
priority: int,
290+
) -> int: ...
291+
292+
@overload
293+
def connect(
294+
self,
295+
name: Literal['autodoc-process-signature'],
296+
callback: Callable[
297+
[
298+
Sphinx,
299+
Literal[
300+
'module', 'class', 'exception', 'function', 'method', 'attribute'
301+
],
302+
str,
303+
Any,
304+
dict[str, bool],
305+
str | None,
306+
str | None,
307+
],
308+
tuple[str | None, str | None] | None,
309+
],
310+
priority: int,
311+
) -> int: ...
312+
313+
@overload
314+
def connect(
315+
self,
316+
name: Literal['autodoc-process-bases'],
317+
callback: Callable[[Sphinx, str, Any, dict[str, bool], list[str]], None],
318+
priority: int,
319+
) -> int: ...
320+
321+
@overload
322+
def connect(
323+
self,
324+
name: Literal['autodoc-skip-member'],
325+
callback: Callable[
326+
[
327+
Sphinx,
328+
Literal[
329+
'module', 'class', 'exception', 'function', 'method', 'attribute'
330+
],
331+
str,
332+
Any,
333+
bool,
334+
dict[str, bool],
335+
],
336+
bool,
337+
],
338+
priority: int,
339+
) -> int: ...
340+
341+
@overload
342+
def connect(
343+
self,
344+
name: Literal['todo-defined'],
345+
callback: Callable[[Sphinx, todo_node], None],
346+
priority: int,
347+
) -> int: ...
348+
349+
@overload
350+
def connect(
351+
self,
352+
name: Literal['viewcode-find-source'],
353+
callback: Callable[
354+
[Sphinx, str],
355+
tuple[str, dict[str, tuple[Literal['class', 'def', 'other'], int, int]]],
356+
],
357+
priority: int,
358+
) -> int: ...
359+
360+
@overload
361+
def connect(
362+
self,
363+
name: Literal['viewcode-follow-imported'],
364+
callback: Callable[[Sphinx, str, str], str | None],
365+
priority: int,
366+
) -> int: ...
367+
368+
# ---- Catch-all ---------------------------------------------------------
369+
370+
@overload
371+
def connect(
372+
self,
373+
name: str,
374+
callback: Callable[..., Any],
375+
priority: int,
376+
) -> int: ...
377+
69378
def connect(self, name: str, callback: Callable, priority: int) -> int:
70379
"""Connect a handler to specific event."""
71380
if name not in self.events:

0 commit comments

Comments
 (0)