Skip to content

Commit

Permalink
intersphinx: Handle the case where intersphinx_cache_limit is negative
Browse files Browse the repository at this point in the history
The documentation said:

  Set this (intersphinx_cache_limit) to a negative value to cache inventories
  for unlimited time.

In the current implementation, a negative intersphinx_cache_limit causes
inventories always expire, this patch ensures that it behaves as documented.
  • Loading branch information
SilverRainZ committed Jul 10, 2024
1 parent c67ef51 commit cd7aa0a
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 2 deletions.
3 changes: 3 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,9 @@ Bugs fixed
* #11961: Omit anchor references from document title entries in the search index,
removing duplication of search results.
Patch by James Addison.
* #12514: intersphinx: fix the meaning of a negative value for
:confval:`intersphinx_cache_limit`.
Patch by Shengyu Zhang.

Testing
-------
Expand Down
10 changes: 8 additions & 2 deletions sphinx/ext/intersphinx/_load.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,15 +107,21 @@ def fetch_inventory_group(
app: Sphinx,
now: int,
) -> bool:
cache_time = now - app.config.intersphinx_cache_limit * 86400
if app.config.intersphinx_cache_limit < 0:
cache_time = now - app.config.intersphinx_cache_limit * 86400
else:
cache_time = None
failures = []
try:
for inv in invs:
if not inv:
inv = posixpath.join(uri, INVENTORY_FILENAME)
# decide whether the inventory must be read: always read local
# files; remote ones only if the cache time is expired
if '://' not in inv or uri not in cache or cache[uri][1] < cache_time:
if (
'://' not in inv or uri not in cache or
(cache_time and cache[uri][1] < cache_time)
):
safe_inv_url = _get_safe_url(inv)
inv_descriptor = name or 'main_inventory'
LOGGER.info(__("loading intersphinx inventory '%s' from %s..."),
Expand Down
25 changes: 25 additions & 0 deletions tests/test_extensions/test_ext_intersphinx.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
"""Test the intersphinx extension."""

import http.server
import time
from typing import TYPE_CHECKING
from unittest import mock

import pytest
Expand All @@ -10,6 +12,7 @@
from sphinx.builders.html import INVENTORY_FILENAME
from sphinx.ext.intersphinx import (
fetch_inventory,
fetch_inventory_group,
inspect_main,
load_mappings,
missing_reference,
Expand All @@ -26,6 +29,9 @@
)
from tests.utils import http_server

if TYPE_CHECKING:
from sphinx.ext.intersphinx._shared import InventoryCacheEntry


def fake_node(domain, type, target, content, **attrs):
contnode = nodes.emphasis(content, content)
Expand Down Expand Up @@ -603,3 +609,22 @@ def test_intersphinx_role(app, warning):

# explicit title
assert html.format('index.html#foons') in content


@pytest.mark.sphinx()
def test_intersphinx_cache_limit(app):
url = 'https://example.org/'
app.config.intersphinx_mapping = {
'inv': (url, None),
}
# load the inventory and check if it's done correctly
normalize_intersphinx_mapping(app, app.config)
intersphinx_cache: dict[str, InventoryCacheEntry] = {
url: (None, 0, {}), # 0 is a timestamp, make sure the entry is expired
}
now = int(time.time())

app.config.intersphinx_cache_limit = -1
for name, (uri, invs) in app.config.intersphinx_mapping.values():
# no need to read from remote
assert not fetch_inventory_group(name, uri, invs, intersphinx_cache, app, now)

0 comments on commit cd7aa0a

Please sign in to comment.