Verify Rez inventory domains
Inventory verification
The published stable inventory is:
https://docs.rez-project.io/en/stable/objects.inv
It is a valid Sphinx inventory v2 for Rez 3.4.0, containing 3,726 objects.
| Domain | Entries | Object types |
|---|---|---|
py |
2,867 | attribute, class, data, exception, function, method, module, property |
std |
779 | cmdoption, doc, envvar, label |
rex |
46 | attribute (25), function (21) |
pkgdef |
34 | attribute (28), function (6) |
Custom domains are present
Both Rez custom domains defined and registered in docs/rez_sphinxext.py are included:
rex— examples:rex:function:alias,rex:function:setenv,rex:attribute:this.rootpkgdef— examples:pkgdef:attribute:requires,pkgdef:attribute:variants,pkgdef:function:commands
Their registration is visible here.
I also checked /en/latest/objects.inv. It contains the same custom-domain entries: 46 rex and 34 pkgdef objects.
One URL caveat: https://docs.rez-project.io/objects.inv redirects to a 404. Intersphinx consumers should use the versioned URL, preferably:
intersphinx_mapping = {
"rez": ("https://docs.rez-project.io/en/stable/", None),
}
Conclusion: both custom Rez domains are successfully represented in the published Sphinx inventory.
Result: inventory alone is not sufficient
I created an isolated Sphinx project outside the repository and configured:
extensions = ["sphinx.ext.intersphinx"]
intersphinx_mapping = {
"rez": ("https://docs.rez-project.io/en/stable/", None),
}
I then attempted these references:
:external+rez:rex:func:`alias`
:external+rez:rex:attr:`this.root`
:external+rez:pkgdef:func:`commands`
:external+rez:pkgdef:attr:`requires`
With only intersphinx enabled, the build failed under -W:
WARNING: domain for external cross-reference not found: 'rex'
WARNING: domain for external cross-reference not found: 'pkgdef'
A normal Python-domain control reference resolved successfully, proving that the inventory itself was loaded correctly.
Registering compatible domains makes the links work
I repeated the test after registering rex and pkgdef domains compatible with Rez’s Python-derived domains. The Sphinx build then completed with zero warnings, producing these links:
https://docs.rez-project.io/en/stable/package_commands.html#alias
https://docs.rez-project.io/en/stable/package_commands.html#this.root
https://docs.rez-project.io/en/stable/package_definition.html#commands
https://docs.rez-project.io/en/stable/package_definition.html#requires
I also fetched the target pages and verified that all four fragment IDs exist.
Conclusion
The published inventory is correct and contains the custom objects, but Sphinx does not dynamically register unknown domains from an intersphinx inventory.
A consuming project must have both:
- The Rez intersphinx mapping.
- An extension that registers the
rexandpkgdefdomains and their roles.
Currently, Rez’s domains are defined in docs/rez_sphinxext.py, which is a documentation-local extension rather than an obvious reusable extension for downstream projects.
The robust solution would be to expose the domain definitions as an installable Sphinx extension. A consumer could then use something like:
extensions = [
"sphinx.ext.intersphinx",
"rez.sphinxext", # hypothetical reusable extension
]
intersphinx_mapping = {
"rez": ("https://docs.rez-project.io/en/stable/", None),
}
Then these explicit references would work:
:external+rez:rex:func:`alias`
:external+rez:pkgdef:attr:`requires`
So your concern is valid: another project cannot currently reference the custom domains using intersphinx alone, despite their presence in objects.inv.
Confirmed without consumer_domains.py
I reran the test from scratch with only:
conf.pyindex.rstsphinx.ext.intersphinx
The inventory was fetched directly from the published URL:
loading intersphinx inventory 'rez' from
https://docs.rez-project.io/en/stable/objects.inv ...
The four custom-domain references produced:
WARNING: domain for external cross-reference not found: 'rex'
WARNING: domain for external cross-reference not found: 'rex'
WARNING: domain for external cross-reference not found: 'pkgdef'
WARNING: domain for external cross-reference not found: 'pkgdef'
With warnings treated as errors:
SPHINX_EXIT_STATUS=1
The generated HTML contained no links for those four references. Meanwhile, the Python-domain control reference resolved correctly:
https://rez.readthedocs.io/en/stable/api/rez.resolved_context.html#rez.resolved_context.ResolvedContext
So this clean test confirms:
- The published inventory loads.
- Built-in domains resolve.
- Inventory entries do not register custom domains in the consumer.
- Without a domain extension,
rexandpkgdefreferences do not work.
Your skepticism was reasonable, but the failure is reproducible in a completely clean Sphinx 9.0.4 project. No repository files were changed.
There is an exact upstream discussion
The closest match is the still-open Sphinx discussion:
It describes precisely what we observed:
An
objects.invmay contain(domain name, object type)that do not have a corresponding role name available in your local Sphinx project.
It also says the current workaround effectively requires:
all the same extensions / bespoke
setupas the project you are referencing
That maps directly to Rez’s rex and pkgdef domains.
There is disagreement among the Sphinx maintainers:
- One position is that domains own lookup and rendering semantics, so consumers must install the corresponding extension.
- The alternative proposal is for
externalreferences to fall back to a generic link when the domain or role is unavailable locally.
That fallback has not been implemented.
Earlier issue
This reported the same underlying problem in 2018. A Sphinx maintainer responded:
You can refer it if you'll also define it on your project.
The issue was closed in June 2026 because its specific confval example was solved by moving confval into Sphinx’s built-in standard domain via PR #12536. That did not solve arbitrary third-party domains such as Rez’s rex and pkgdef.
Related open work
- Introducing a v3
objects.invformat — Discussion #12204 — open- Explicitly asks what should happen when an inventory contains a domain unavailable in the local Sphinx environment.
- Add a new
referencesbuilder — PR #12190 — open- Would improve inventory inspection.
- Explicitly states that object types with no locally available matching role are not addressed.
- Implement intersphinx entries web viewer — Issue #8211 — open
- Related tooling and discoverability work, but not a resolution mechanism.
Implication for Rez
This is known upstream behavior rather than a malformed Rez inventory. Unless Sphinx adopts generic fallback resolution, Rez should make its custom domains available as an installable consumer extension if downstream intersphinx references are a supported use case.
Yes—that is the most reliable approach under Sphinx’s current model.
I would provide a small, installable extension whose only responsibility is registering:
rexpkgdef
Consumers could then configure:
extensions = [
"sphinx.ext.intersphinx",
"rez.sphinxext",
]
intersphinx_mapping = {
"rez": ("https://docs.rez-project.io/en/stable/", None),
}
And use:
:external+rez:rex:func:`alias`
:external+rez:pkgdef:attr:`requires`
The extension should be separated from the existing documentation-local rez_sphinxext.py, because that module also generates Rez documentation and registers project-specific directives. Downstream projects only need the domain classes.
A sensible structure would be:
src/rez/sphinxext.py
with optional Sphinx imports so normal Rez users do not acquire Sphinx as a mandatory dependency. We could also add a documentation extra, for example:
pip install "rez[sphinx]"
The Rez documentation itself should then load the packaged extension, ensuring that the producer and consumers always use identical domain definitions. This avoids maintaining a second mock implementation and gives downstream users a supported intersphinx integration path.
Lightweight consumer extension implemented
You were correct: consumers do not need the full directive implementation.
rez.utils.docs now contains only:
- Two
PythonDomainsubclasses with replaced names and labels. - A minimal Sphinx
setup()function. - No copied Python directives or Sphinx internals.
- No Sphinx dependency or version pin in Rez’s package metadata.
Rez’s own documentation still needs its directive workaround to generate the inventory correctly. That remains private in docs/rez_sphinxext.py, layered on top of the lightweight public domain classes to avoid duplicating domain names and definitions.
Usage is documented here.
Verification
External intersphinx builds passed with warnings treated as errors on:
- Sphinx 5.3.0
- Sphinx 7.4.7
- Sphinx 8.2.3
- Sphinx 9.0.4
All produced the expected links for rex:func, rex:attr, pkgdef:func, and pkgdef:attr.
Additional checks:
- Rez documentation build succeeded.
- Generated inventory retained 46
rexand 34pkgdefentries. - Built wheel includes
rez/utils/docs.py. - Ruff and formatting checks passed.
- Rez does not install or pin Sphinx, so consumers remain free to select their own supported Sphinx version.
Reduced to the minimum:
- Restored
docs/rez_sphinxext.pyexactly—zero diff. - Kept only the lightweight new
rez.utils.docsextension. - Kept the short usage documentation in
package_definition.rst.
Verification:
git diff --exit-code -- docs/rez_sphinxext.py
extension_diff_exit=0
Final changed files:
M docs/source/package_definition.rst
?? src/rez/utils/docs.py
Done. The existing extension now reuses the new classes with only these changes:
- Two imports.
RexDomainandPkgDefDomaininherit from their public counterparts.- Duplicate
nameandlabeldeclarations removed.
All existing docstrings, comments, directive classes, and formatting remain unchanged.
Verified both domains retain:
- Correct names and labels.
funcandattrroles.- Rez’s custom producer-side directives.
Options
1. Dedicated Reference page — recommended
Create:
docs/source/sphinx_integration.rst
Add it under the existing Reference toctree, near api:
.. toctree::
:caption: Reference
configuring_rez
commands_index
environment
api
sphinx_integration
changelog.md
Possible title:
===============================
Referencing Rez documentation
===============================
This page could contain:
- Installation/configuration of
rez.utils.docs - The intersphinx mapping
- A table of the
rexandpkgdefdomains - Example references for each domain
- A note that Rez does not install or pin Sphinx
Why it fits: this is reference material for documentation authors consuming Rez’s published documentation. It is neither package-definition documentation nor a general Rez workflow.
2. User guide
Create:
docs/source/guides/linking_to_rez_documentation.rst
Add it to guides/index.rst.
Possible title:
Linking to Rez from Sphinx documentation
Advantages:
- More discoverable as a task-oriented walkthrough.
- Appropriate if we include troubleshooting, inventory inspection, and complete examples.
Disadvantages:
- The current content is configuration reference rather than a substantial guide.
- It would sit beside broader guides such as upgrading Rez and developing plugins.
3. General documentation-integration page
Create:
docs/source/documentation_integration.rst
Place it under Advanced or Reference.
This could eventually cover:
- Sphinx/intersphinx
- Published inventories
- Linking to command references
- Versioned documentation URLs
- Documentation-related Rez utilities
Advantages: leaves room for future documentation tooling.
Disadvantages: currently speculative and broader than the feature being documented.
4. Put it on the Python API page
Add a section to api.rst documenting rez.utils.docs.
Advantages: the extension is technically a Python module.
Disadvantages: not recommended. Users are configuring Sphinx rather than calling a Rez Python API, and the page’s existing compatibility warnings are unrelated.
Recommendation
Use Option 1: a dedicated sphinx_integration.rst page under Reference, titled “Referencing Rez documentation.”
It provides a natural home for both domains because the organizing concept is external documentation integration—not package definitions or Rex commands. It also leaves the two domain-specific pages focused on their actual subject matter.
Created a dedicated user guide: Linking to Rez documentation.
It covers:
- Purpose of the
pkgdefandrexdomains. - Complete
conf.pyconfiguration. - Example references for attributes and functions.
- Mapping-key and role semantics.
- Versioned inventory URL expectations.
- Sphinx version independence.
- Using
-Wto catch unresolved references.
The guide is included in the User Guides toctree, and the misplaced section was removed from package_definition.rst.
The full documentation build succeeded. One pre-existing ambiguous Command cross-reference warning remains, unrelated to these changes.
Compatibility wording
I agree that “Expectations” should primarily describe the compatibility contract, rather than configuration mechanics.
The extension is intentionally loosely coupled:
- Rez does not install or pin Sphinx.
rez.utils.docsonly subclasses Sphinx’s publicPythonDomain.- Consumers choose and manage their own Sphinx version.
- The inventory format allows the documentation producer and consumer to use different Sphinx versions.
However, we should avoid promising universal compatibility:
- Sphinx could change its domain or intersphinx APIs.
- Role-to-object mappings could evolve.
- Future Rez releases could add or change custom-domain objects.
- Installing an extension from one Rez release while referencing another release’s inventory could eventually cause mismatches.
I would rename the section to Compatibility and use wording approximately like:
Rez intentionally keeps this integration small and does not install or pin a Sphinx version. Documentation projects can select and manage the Sphinx version appropriate for their own builds.
We aim to keep
rez.utils.docscompatible across Sphinx and Rez releases, but not every combination is guaranteed. Changes to Sphinx’s domain or intersphinx APIs may require an updated Rez extension. For reproducible documentation builds, projects should pin their documentation dependencies and treat unresolved references as errors.When possible, use the
rez.utils.docsextension from the same Rez release as the documentation inventory being referenced.
I would not publish a specific compatibility matrix unless we add those Sphinx versions to CI. Otherwise, the documented list would quickly become an unsupported promise.
The current operational bullets about mapping keys, versioned URLs, and -W could move into a separate Troubleshooting or How it works section.
Current rendered guide
This is the current page before making those compatibility edits:
The page renders correctly, including navigation, code blocks, and all sections. The documentation build succeeded with one existing unrelated ambiguous Command reference warning.
Updated the guide with:
- Compatibility — documents loose Rez/Sphinx coupling, the lack of universal compatibility guarantees, dependency pinning recommendations, and matching the extension to the inventory’s Rez release.
- Troubleshooting — retains the operational guidance about inventory URLs, mapping keys, domain registration, and unresolved references.
The documentation build succeeded. The only warning is the existing unrelated ambiguous Command reference.
Applied both review comments:
- Removed the entire Troubleshooting section.
- Updated casing so
rezis lowercase except when it begins a sentence.
The documentation build succeeds with only the existing unrelated Command ambiguity warning.
Pull request created: JeanChristopheMorinPerso/rez#3
- Branch:
docs/sphinx-intersphinx-domains - Commit:
18b5822d1d9250a465aa7cac58588d3376c79406 - Base:
main - Commit includes the required
Signed-off-bytrailer. - Working tree is clean.
Done—the local branch is now reset to origin/docs/sphinx-intersphinx-domains at 0dd9b19. I’ll apply the requested import fix on that exact PR head.
The repository’s docs requirement now targets Sphinx 9.1+, but this orb runs Python 3.11 and Sphinx 9.1 requires Python 3.12, so that exact environment cannot be installed here. I’ll run the focused check against the newest compatible Sphinx (9.0.4), which exercises the same import and extension setup path, plus Ruff and byte compilation.