Skip to content

Commit 4a40d7d

Browse files
authored
Merge pull request #425 from tiran/hook-docs
Add autodoc for hooks functions
2 parents 6414e0c + 7b7838d commit 4a40d7d

File tree

9 files changed

+169
-8
lines changed

9 files changed

+169
-8
lines changed

docs/conf.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
from importlib import metadata
22

3+
from sphinx.addnodes import desc_signature
4+
from sphinx.application import Sphinx
5+
from sphinx.domains.python import PyFunction
6+
from sphinx.ext.autodoc import FunctionDocumenter
7+
from sphinx.util.typing import ExtensionMetadata
8+
39
# Configuration file for the Sphinx documentation builder.
410
#
511
# For the full list of built-in configuration values, see the documentation:
@@ -20,6 +26,8 @@
2026
"sphinx_click",
2127
"myst_parser",
2228
"sphinxcontrib.autodoc_pydantic",
29+
"sphinx.ext.autodoc",
30+
"sphinx.ext.intersphinx",
2331
]
2432

2533
# Recognized suffixes
@@ -33,6 +41,13 @@
3341

3442
language = "English"
3543

44+
# references to Python stdlib and packaging
45+
intersphinx_mapping = {
46+
"python": ("https://docs.python.org/3", None),
47+
"packaging": ("https://packaging.pypa.io/en/stable/", None),
48+
"pyproject-hooks": ("https://pyproject-hooks.readthedocs.io/en/latest/", None),
49+
}
50+
3651
# -- Options for HTML output -------------------------------------------------
3752
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
3853

@@ -46,3 +61,34 @@
4661
autodoc_pydantic_model_show_config_summary = False
4762
autodoc_pydantic_model_show_validator_summary = False
4863
autodoc_pydantic_model_show_validator_members = False
64+
65+
# autodoc_typehints_format = "fully-qualified"
66+
67+
68+
class FromagerHookDocumenter(FunctionDocumenter):
69+
"""Documenter for 'autofromagehook' directive"""
70+
71+
objtype = "fromagerhook"
72+
73+
def format_name(self):
74+
name = super().format_name()
75+
if name.startswith("default_"):
76+
name = name[8:]
77+
return name
78+
79+
80+
class PyFromagerHook(PyFunction):
81+
""":py:fromagehook"""
82+
83+
def handle_signature(self, sig: str, signode: desc_signature) -> tuple[str, str]:
84+
# hack to remove module prefix from output
85+
self.options["module"] = None
86+
return super().handle_signature(sig, signode)
87+
88+
89+
def setup(app: Sphinx) -> ExtensionMetadata:
90+
app.setup_extension("sphinx.ext.autodoc")
91+
app.add_directive_to_domain("py", FromagerHookDocumenter.objtype, PyFromagerHook)
92+
app.add_autodocumenter(FromagerHookDocumenter)
93+
94+
return {"version": release, "parallel_read_safe": True}

docs/hooks.rst

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
Fromager hooks
2+
==============
3+
4+
Dependency hooks
5+
----------------
6+
7+
.. py:currentmodule:: fromager.dependencies
8+
9+
.. autofromagerhook:: default_get_build_system_dependencies
10+
11+
.. autofromagerhook:: default_get_build_backend_dependencies
12+
13+
.. autofromagerhook:: default_get_build_sdist_dependencies
14+
15+
16+
Finder hooks
17+
------------
18+
19+
.. py:currentmodule:: fromager.finders
20+
21+
.. autofromagerhook:: default_expected_source_archive_name
22+
23+
.. autofromagerhook:: default_expected_source_directory_name
24+
25+
26+
Resolver hooks
27+
--------------
28+
29+
.. currentmodule:: fromager.resolver
30+
31+
.. autofromagerhook:: default_resolver_provider
32+
33+
34+
Source hooks
35+
------------
36+
37+
.. currentmodule:: fromager.sources
38+
39+
.. autofromagerhook:: default_resolve_source
40+
41+
.. autofromagerhook:: default_download_source
42+
43+
.. autofromagerhook:: default_prepare_source
44+
45+
.. autofromagerhook:: default_build_sdist
46+
47+
48+
Wheel hooks
49+
-----------
50+
51+
.. currentmodule:: fromager.wheels
52+
53+
.. autofromagerhook:: default_build_wheel
54+
55+
.. autofromagerhook:: default_add_extra_metadata_to_wheels
56+
57+
58+
Additional types
59+
----------------
60+
61+
.. autoclass:: fromager.build_environment.BuildEnvironment
62+
.. autoclass:: fromager.context.WorkContext
63+
.. autoclass:: fromager.resolver.PyPIProvider
64+
.. autoclass:: fromager.resolver.GenericProvider
65+
.. autoclass:: fromager.resolver.GitHubTagProvider
66+
.. autofunction:: fromager.sources.prepare_new_source

docs/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ those special cases directly into fromager.
2828

2929
using.md
3030
customization.md
31+
hooks.rst
3132
config-reference.rst
3233
cli.rst
3334
develop.md

src/fromager/dependencies.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,10 @@ def default_get_build_system_dependencies(
7070
sdist_root_dir: pathlib.Path,
7171
build_dir: pathlib.Path,
7272
) -> typing.Iterable[str]:
73+
"""Get build system requirements
74+
75+
Defaults to ``pyproject.toml`` ``[build-system] requires``.
76+
"""
7377
pyproject_toml = get_pyproject_contents(build_dir)
7478
return typing.cast(list[str], get_build_backend(pyproject_toml)["requires"])
7579

@@ -115,6 +119,11 @@ def default_get_build_backend_dependencies(
115119
sdist_root_dir: pathlib.Path,
116120
build_dir: pathlib.Path,
117121
) -> typing.Iterable[str]:
122+
"""Get build backend dependencies
123+
124+
Defaults to result of hook call
125+
:meth:`~pyproject_hooks.BuildBackendHookCaller.get_requires_for_build_wheel`
126+
"""
118127
pbi = ctx.package_build_info(req)
119128
pyproject_toml = get_pyproject_contents(build_dir)
120129
extra_environ = pbi.get_extra_environ()
@@ -165,6 +174,11 @@ def default_get_build_sdist_dependencies(
165174
sdist_root_dir: pathlib.Path,
166175
build_dir: pathlib.Path,
167176
) -> typing.Iterable[str]:
177+
"""Get build sdist dependencies
178+
179+
Defaults to result of hook call
180+
:meth:`~pyproject_hooks.BuildBackendHookCaller.get_requires_for_build_wheel`
181+
"""
168182
pbi = ctx.package_build_info(req)
169183
pyproject_toml = get_pyproject_contents(build_dir)
170184
extra_environ = pbi.get_extra_environ()

src/fromager/finders.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ def _dist_name_to_filename(dist_name: str) -> str:
2121
return re.sub(r"[^\w\d.]+", "_", canonical_name, flags=re.UNICODE)
2222

2323

24-
def _check_archive_name_in_settings(
24+
def default_expected_source_archive_name(
2525
ctx: context.WorkContext,
2626
req: Requirement,
2727
dist_version: str,
@@ -39,7 +39,7 @@ def find_sdist(
3939
sdist_file_name = overrides.find_and_invoke(
4040
req.name,
4141
"expected_source_archive_name",
42-
_check_archive_name_in_settings,
42+
default_expected_source_archive_name,
4343
req=req,
4444
dist_version=dist_version,
4545
ctx=ctx,
@@ -126,6 +126,10 @@ def find_wheel(
126126
return None
127127

128128

129+
def default_expected_source_directory_name(req: Requirement, dist_version: str) -> str:
130+
raise NotImplementedError
131+
132+
129133
def find_source_dir(
130134
ctx: context.WorkContext,
131135
work_dir: pathlib.Path,
@@ -148,7 +152,7 @@ def find_source_dir(
148152
sdist_name = overrides.find_and_invoke(
149153
req.name,
150154
"expected_source_archive_name",
151-
_check_archive_name_in_settings,
155+
default_expected_source_archive_name,
152156
req=req,
153157
dist_version=dist_version,
154158
ctx=ctx,

src/fromager/resolver.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,8 @@ def default_resolver_provider(
6767
sdist_server_url: str,
6868
include_sdists: bool,
6969
include_wheels: bool,
70-
) -> "PyPIProvider":
70+
) -> "PyPIProvider | GenericProvider | GitHubTagProvider":
71+
"""Lookup resolver provider to resolve package versions"""
7172
return PyPIProvider(
7273
include_sdists=include_sdists,
7374
include_wheels=include_wheels,
@@ -254,6 +255,8 @@ def find_matches(
254255

255256

256257
class PyPIProvider(BaseProvider):
258+
"""Lookup package and versions from a simple Python index (PyPI)"""
259+
257260
def __init__(
258261
self,
259262
include_sdists: bool = True,
@@ -331,6 +334,8 @@ def find_matches(
331334

332335

333336
class GenericProvider(BaseProvider):
337+
"""Lookup package and version by using a callback"""
338+
334339
def __init__(
335340
self,
336341
version_source: VersionSource,
@@ -401,6 +406,11 @@ def find_matches(
401406

402407

403408
class GitHubTagProvider(GenericProvider):
409+
"""Lookup package and versions from a GitHub repository tags
410+
411+
Supports :envvar:`GITHUB_TOKEN` for authentication.
412+
"""
413+
404414
def __init__(
405415
self, organization: str, repo: str, constraints: Constraints | None = None
406416
):

src/fromager/sources.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,10 @@ def default_prepare_source(
381381
source_filename: pathlib.Path,
382382
version: Version,
383383
) -> tuple[pathlib.Path, bool]:
384+
"""Unpack and modify sdist sources
385+
386+
Calls :func:`~fromager.sources.prepare_new_source` by default.
387+
"""
384388
source_root_dir, is_new = unpack_source(
385389
ctx=ctx,
386390
req=req,
@@ -405,7 +409,11 @@ def prepare_new_source(
405409
) -> None:
406410
"""Default steps for new sources
407411
408-
`default_prepare_source` runs this function when the sources are new.
412+
- patch sources
413+
- apply project overrides from settings
414+
- vendor Rust dependencies
415+
416+
:func:`~default_prepare_source` runs this function when the sources are new.
409417
"""
410418
patch_source(ctx, source_root_dir, req, version)
411419
pyproject.apply_project_override(
@@ -423,6 +431,7 @@ def build_sdist(
423431
sdist_root_dir: pathlib.Path,
424432
build_env: build_environment.BuildEnvironment,
425433
) -> pathlib.Path:
434+
"""Build source distribution"""
426435
pbi = ctx.package_build_info(req)
427436
build_dir = pbi.build_dir(sdist_root_dir)
428437

src/fromager/wheels.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,17 @@ def _extra_metadata_elfdeps(
101101
return elfinfos
102102

103103

104+
def default_add_extra_metadata_to_wheels(
105+
ctx: context.WorkContext,
106+
req: Requirement,
107+
version: Version,
108+
extra_environ: dict[str, str],
109+
sdist_root_dir: pathlib.Path,
110+
dist_info_dir: pathlib.Path,
111+
) -> dict[str, typing.Any]:
112+
raise NotImplementedError
113+
114+
104115
def add_extra_metadata_to_wheels(
105116
ctx: context.WorkContext,
106117
req: Requirement,

tox.ini

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tox]
22
minversion = 3.2.0
3-
envlist=py,linter,mypy,coverage-report
3+
envlist=py,linter,mypy,docs,coverage-report
44

55
[testenv]
66
extras = test
@@ -39,8 +39,8 @@ base_python=python3.11
3939
deps=
4040
ruff
4141
commands =
42-
ruff format src tests
43-
ruff check --fix src tests
42+
ruff format src tests docs
43+
ruff check --fix src tests docs
4444
skip_install = true
4545
skip_sdist = true
4646

0 commit comments

Comments
 (0)