summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/extdev/deprecated.rst5
-rw-r--r--sphinx/search/__init__.py24
-rw-r--r--sphinx/util/jsdump.py20
-rw-r--r--tests/test_search.py33
4 files changed, 58 insertions, 24 deletions
diff --git a/doc/extdev/deprecated.rst b/doc/extdev/deprecated.rst
index 9fc1110fc..114c927dc 100644
--- a/doc/extdev/deprecated.rst
+++ b/doc/extdev/deprecated.rst
@@ -22,6 +22,11 @@ The following is a list of deprecated interfaces.
- (will be) Removed
- Alternatives
+ * - ``sphinx.util.jsdump``
+ - 5.0
+ - 7.0
+ - The standard library ``json`` module.
+
* - :doc:`Setuptools integration </usage/advanced/setuptools>`
- 5.0
- 7.0
diff --git a/sphinx/search/__init__.py b/sphinx/search/__init__.py
index c3e46ce22..f8fc294d6 100644
--- a/sphinx/search/__init__.py
+++ b/sphinx/search/__init__.py
@@ -1,7 +1,9 @@
"""Create a full-text search index for offline search."""
import html
+import json
import pickle
import re
+import warnings
from importlib import import_module
from os import path
from typing import IO, Any, Dict, Iterable, List, Optional, Set, Tuple, Type
@@ -10,8 +12,8 @@ from docutils import nodes
from docutils.nodes import Element, Node
from sphinx import addnodes, package_dir
+from sphinx.deprecation import RemovedInSphinx70Warning
from sphinx.environment import BuildEnvironment
-from sphinx.util import jsdump
class SearchLanguage:
@@ -154,14 +156,14 @@ class _JavaScriptIndex:
SUFFIX = ')'
def dumps(self, data: Any) -> str:
- return self.PREFIX + jsdump.dumps(data) + self.SUFFIX
+ return self.PREFIX + json.dumps(data) + self.SUFFIX
def loads(self, s: str) -> Any:
data = s[len(self.PREFIX):-len(self.SUFFIX)]
if not data or not s.startswith(self.PREFIX) or not \
s.endswith(self.SUFFIX):
raise ValueError('invalid data')
- return jsdump.loads(data)
+ return json.loads(data)
def dump(self, data: Any, f: IO) -> None:
f.write(self.dumps(data))
@@ -224,7 +226,7 @@ class IndexBuilder:
passed to the `feed` method.
"""
formats = {
- 'jsdump': jsdump,
+ 'json': json,
'pickle': pickle
}
@@ -265,7 +267,11 @@ class IndexBuilder:
def load(self, stream: IO, format: Any) -> None:
"""Reconstruct from frozen data."""
- if isinstance(format, str):
+ if format == "jsdump":
+ warnings.warn("format=jsdump is deprecated, use json instead",
+ RemovedInSphinx70Warning, stacklevel=2)
+ format = self.formats["json"]
+ elif isinstance(format, str):
format = self.formats[format]
frozen = format.load(stream)
# if an old index is present, we treat it as not existing.
@@ -291,7 +297,11 @@ class IndexBuilder:
def dump(self, stream: IO, format: Any) -> None:
"""Dump the frozen index to a stream."""
- if isinstance(format, str):
+ if format == "jsdump":
+ warnings.warn("format=jsdump is deprecated, use json instead",
+ RemovedInSphinx70Warning, stacklevel=2)
+ format = self.formats["json"]
+ elif isinstance(format, str):
format = self.formats[format]
format.dump(self.freeze(), stream)
@@ -417,7 +427,7 @@ class IndexBuilder:
return {
'search_language_stemming_code': self.get_js_stemmer_code(),
- 'search_language_stop_words': jsdump.dumps(sorted(self.lang.stopwords)),
+ 'search_language_stop_words': json.dumps(sorted(self.lang.stopwords)),
'search_scorer_tool': self.js_scorer_code,
'search_word_splitter_code': js_splitter_code,
}
diff --git a/sphinx/util/jsdump.py b/sphinx/util/jsdump.py
index ed5aea4ba..77acef9d2 100644
--- a/sphinx/util/jsdump.py
+++ b/sphinx/util/jsdump.py
@@ -6,6 +6,8 @@ Uses the basestring encode function from simplejson by Bob Ippolito.
import re
from typing import IO, Any, Dict, List, Match, Union
+from sphinx.deprecation import RemovedInSphinx70Warning, deprecated_alias
+
_str_re = re.compile(r'"(\\\\|\\"|[^"])*"')
_int_re = re.compile(r'\d+')
_name_re = re.compile(r'[a-zA-Z_]\w*')
@@ -192,3 +194,21 @@ def loads(x: str) -> Any:
def load(f: IO) -> Any:
return loads(f.read())
+
+
+deprecated_alias(
+ 'sphinx.util.jsdump',
+ {
+ 'dumps': dumps,
+ 'dump': dump,
+ 'loads': loads,
+ 'load': load,
+ },
+ RemovedInSphinx70Warning,
+ {
+ 'dumps': 'json.dumps',
+ 'dump': 'json.dump',
+ 'loads': 'json.loads',
+ 'load': 'json.load',
+ }
+)
diff --git a/tests/test_search.py b/tests/test_search.py
index 024e6941c..540793544 100644
--- a/tests/test_search.py
+++ b/tests/test_search.py
@@ -1,5 +1,6 @@
"""Test the search index builder."""
+import json
from collections import namedtuple
from io import BytesIO
@@ -8,7 +9,6 @@ from docutils import frontend, utils
from docutils.parsers import rst
from sphinx.search import IndexBuilder
-from sphinx.util import jsdump
DummyEnvironment = namedtuple('DummyEnvironment', ['version', 'domains'])
@@ -32,12 +32,12 @@ def setup_module():
parser = rst.Parser()
-def jsload(path):
+def load_searchindex(path):
searchindex = path.read_text()
assert searchindex.startswith('Search.setIndex(')
assert searchindex.endswith(')')
- return jsdump.loads(searchindex[16:-1])
+ return json.loads(searchindex[16:-1])
def is_registered_term(index, keyword):
@@ -57,7 +57,7 @@ test that non-comments are indexed: fermion
@pytest.mark.sphinx(testroot='ext-viewcode')
def test_objects_are_escaped(app, status, warning):
app.builder.build_all()
- index = jsload(app.outdir / 'searchindex.js')
+ index = load_searchindex(app.outdir / 'searchindex.js')
for item in index.get('objects').get(''):
if item[-1] == 'n::Array&lt;T, d&gt;': # n::Array<T,d> is escaped
break
@@ -68,7 +68,7 @@ def test_objects_are_escaped(app, status, warning):
@pytest.mark.sphinx(testroot='search')
def test_meta_keys_are_handled_for_language_en(app, status, warning):
app.builder.build_all()
- searchindex = jsload(app.outdir / 'searchindex.js')
+ searchindex = load_searchindex(app.outdir / 'searchindex.js')
assert not is_registered_term(searchindex, 'thisnoteith')
assert is_registered_term(searchindex, 'thisonetoo')
assert is_registered_term(searchindex, 'findthiskei')
@@ -81,7 +81,7 @@ def test_meta_keys_are_handled_for_language_en(app, status, warning):
@pytest.mark.sphinx(testroot='search', confoverrides={'html_search_language': 'de'})
def test_meta_keys_are_handled_for_language_de(app, status, warning):
app.builder.build_all()
- searchindex = jsload(app.outdir / 'searchindex.js')
+ searchindex = load_searchindex(app.outdir / 'searchindex.js')
assert not is_registered_term(searchindex, 'thisnoteith')
assert is_registered_term(searchindex, 'thisonetoo')
assert not is_registered_term(searchindex, 'findthiskei')
@@ -100,7 +100,7 @@ def test_stemmer_does_not_remove_short_words(app, status, warning):
@pytest.mark.sphinx(testroot='search')
def test_stemmer(app, status, warning):
- searchindex = jsload(app.outdir / 'searchindex.js')
+ searchindex = load_searchindex(app.outdir / 'searchindex.js')
print(searchindex)
assert is_registered_term(searchindex, 'findthisstemmedkei')
assert is_registered_term(searchindex, 'intern')
@@ -112,13 +112,13 @@ def test_term_in_heading_and_section(app, status, warning):
# if search term is in the title of one doc and in the text of another
# both documents should be a hit in the search index as a title,
# respectively text hit
- assert 'textinhead:2' in searchindex
- assert 'textinhead:0' in searchindex
+ assert '"textinhead": 2' in searchindex
+ assert '"textinhead": 0' in searchindex
@pytest.mark.sphinx(testroot='search')
def test_term_in_raw_directive(app, status, warning):
- searchindex = jsload(app.outdir / 'searchindex.js')
+ searchindex = load_searchindex(app.outdir / 'searchindex.js')
assert not is_registered_term(searchindex, 'raw')
assert is_registered_term(searchindex, 'rawword')
assert not is_registered_term(searchindex, 'latex_keyword')
@@ -255,18 +255,17 @@ def test_IndexBuilder_lookup():
)
def test_search_index_gen_zh(app, status, warning):
app.builder.build_all()
- # jsdump fails if search language is 'zh'; hence we just get the text:
- searchindex = (app.outdir / 'searchindex.js').read_text()
- assert 'chinesetest ' not in searchindex
- assert 'chinesetest' in searchindex
- assert 'chinesetesttwo' in searchindex
- assert 'cas' in searchindex
+ index = load_searchindex(app.outdir / 'searchindex.js')
+ assert 'chinesetest ' not in index['terms']
+ assert 'chinesetest' in index['terms']
+ assert 'chinesetesttwo' in index['terms']
+ assert 'cas' in index['terms']
@pytest.mark.sphinx(testroot='search')
def test_nosearch(app):
app.build()
- index = jsload(app.outdir / 'searchindex.js')
+ index = load_searchindex(app.outdir / 'searchindex.js')
assert index['docnames'] == ['index', 'nosearch', 'tocitem']
assert 'latex' not in index['terms']
assert 'zfs' in index['terms']