From 105031a353d009320f232f1812abb04da5a9fc84 Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+aa-turner@users.noreply.github.com> Date: Mon, 24 Apr 2023 08:16:38 +0100 Subject: [PATCH 1/2] Remove jsdump --- sphinx/search/__init__.py | 14 +-- sphinx/util/jsdump.py | 201 -------------------------------------- 2 files changed, 2 insertions(+), 213 deletions(-) delete mode 100644 sphinx/util/jsdump.py diff --git a/sphinx/search/__init__.py b/sphinx/search/__init__.py index 04f33a60cf0..d662ba80cee 100644 --- a/sphinx/search/__init__.py +++ b/sphinx/search/__init__.py @@ -7,7 +7,6 @@ import json import pickle import re -import warnings from importlib import import_module from os import path from typing import ( @@ -31,7 +30,6 @@ 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 split_into @@ -308,11 +306,7 @@ def __init__(self, env: BuildEnvironment, lang: str, options: dict, scoring: str def load(self, stream: IO, format: Any) -> None: """Reconstruct from frozen data.""" - if format == "jsdump": - warnings.warn("format=jsdump is deprecated, use json instead", - RemovedInSphinx70Warning, stacklevel=2) - format = self.formats["json"] - elif isinstance(format, str): + if isinstance(format, str): format = self.formats[format] frozen = format.load(stream) # if an old index is present, we treat it as not existing. @@ -345,11 +339,7 @@ def load_terms(mapping: dict[str, Any]) -> dict[str, set[str]]: def dump(self, stream: IO, format: Any) -> None: """Dump the frozen index to a stream.""" - if format == "jsdump": - warnings.warn("format=jsdump is deprecated, use json instead", - RemovedInSphinx70Warning, stacklevel=2) - format = self.formats["json"] - elif isinstance(format, str): + if isinstance(format, str): format = self.formats[format] format.dump(self.freeze(), stream) diff --git a/sphinx/util/jsdump.py b/sphinx/util/jsdump.py deleted file mode 100644 index 4a14fbf6ca3..00000000000 --- a/sphinx/util/jsdump.py +++ /dev/null @@ -1,201 +0,0 @@ -"""This module implements a simple JavaScript serializer. - -Uses the basestring encode function from simplejson by Bob Ippolito. -""" - -from __future__ import annotations - -import re -import warnings -from typing import IO, Any - -from sphinx.deprecation import RemovedInSphinx70Warning - -warnings.warn('"sphinx.util.jsdump" has been deprecated. Please use "json" instead.', - RemovedInSphinx70Warning) - -_str_re = re.compile(r'"(\\\\|\\"|[^"])*"') -_int_re = re.compile(r'\d+') -_name_re = re.compile(r'[a-zA-Z_]\w*') -_nameonly_re = re.compile(r'[a-zA-Z_][a-zA-Z0-9_]*$') - -# escape \, ", control characters and everything outside ASCII -ESCAPE_ASCII = re.compile(r'([\\"]|[^\ -~])') -ESCAPE_DICT = { - '\\': '\\\\', - '"': '\\"', - '\b': '\\b', - '\f': '\\f', - '\n': '\\n', - '\r': '\\r', - '\t': '\\t', -} - -ESCAPED = re.compile(r'\\u.{4}|\\.') - - -def encode_string(s: str) -> str: - def replace(match: re.Match) -> str: - s = match.group(0) - try: - return ESCAPE_DICT[s] - except KeyError: - n = ord(s) - if n < 0x10000: - return f'\\u{n:04x}' - else: - # surrogate pair - n -= 0x10000 - s1 = 0xd800 | ((n >> 10) & 0x3ff) - s2 = 0xdc00 | (n & 0x3ff) - return f'\\u{s1:04x}\\u{s2:04x}' - return '"' + str(ESCAPE_ASCII.sub(replace, s)) + '"' - - -def decode_string(s: str) -> str: - return ESCAPED.sub(lambda m: eval('"' + m.group() + '"'), s) # NoQA: PGH001 - - -reswords = set("""\ -abstract else instanceof switch -boolean enum int synchronized -break export interface this -byte extends long throw -case false native throws -catch final new transient -char finally null true -class float package try -const for private typeof -continue function protected var -debugger goto public void -default if return volatile -delete implements short while -do import static with -double in super""".split()) - - -def dumps(obj: Any, key: bool = False) -> str: - if key: - if not isinstance(obj, str): - obj = str(obj) - if _nameonly_re.match(obj) and obj not in reswords: - return obj # return it as a bare word - else: - return encode_string(obj) - if obj is None: - return 'null' - elif obj is True or obj is False: - return 'true' if obj else 'false' - elif isinstance(obj, (int, float)): - return str(obj) - elif isinstance(obj, dict): - return '{%s}' % ','.join( - sorted(f'{dumps(key, True)}:{dumps(value)}' for key, value in obj.items()), - ) - elif isinstance(obj, set): - return '[%s]' % ','.join(sorted(dumps(x) for x in obj)) - elif isinstance(obj, (tuple, list)): - return '[%s]' % ','.join(dumps(x) for x in obj) - elif isinstance(obj, str): - return encode_string(obj) - raise TypeError(type(obj)) - - -def dump(obj: Any, f: IO) -> None: - f.write(dumps(obj)) - - -def loads(x: str) -> Any: - """Loader that can read the JS subset the indexer produces.""" - nothing = object() - i = 0 - n = len(x) - stack: list[list | dict] = [] - obj: Any = nothing - key = False - keys = [] - while i < n: - c = x[i] - if c == '{': - obj = {} - stack.append(obj) - key = True - keys.append(nothing) - i += 1 - elif c == '[': - obj = [] - stack.append(obj) - key = False - keys.append(nothing) - i += 1 - elif c in '}]': - if key: - if keys[-1] is not nothing: - raise ValueError("unfinished dict") - # empty dict - key = False - oldobj = stack.pop() - keys.pop() - if stack: - obj = stack[-1] - if isinstance(obj, dict): - if keys[-1] is nothing: - raise ValueError("invalid key object", oldobj) - obj[keys[-1]] = oldobj - else: - obj.append(oldobj) - else: - break - i += 1 - elif c == ',': - if key: - raise ValueError("multiple keys") - if isinstance(obj, dict): - key = True - i += 1 - elif c == ':': - if not isinstance(obj, dict): - raise ValueError("colon in list") - i += 1 - if not key: - raise ValueError("multiple values") - key = False - else: - y: Any = None - m = _str_re.match(x, i) - if m: - y = decode_string(m.group()[1:-1]) - else: - m = _int_re.match(x, i) - if m: - y = int(m.group()) - else: - m = _name_re.match(x, i) - if m: - y = m.group() - if y == 'true': - y = True - elif y == 'false': - y = False - elif y == 'null': - y = None - elif not key: - raise ValueError("bareword as value") - else: - raise ValueError("read error at pos %d" % i) - i = m.end() - if isinstance(obj, dict): - if key: - keys[-1] = y - else: - obj[keys[-1]] = y - key = False - else: - obj.append(y) - if obj is nothing: - raise ValueError("nothing loaded from string") - return obj - - -def load(f: IO) -> Any: - return loads(f.read()) From 20f9a7543eb7afc9bb026c892c64d05c891c73b1 Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+aa-turner@users.noreply.github.com> Date: Thu, 27 Apr 2023 00:39:35 +0100 Subject: [PATCH 2/2] CHANGES --- CHANGES | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGES b/CHANGES index 359c02d64c9..13ce3e24d5d 100644 --- a/CHANGES +++ b/CHANGES @@ -7,6 +7,8 @@ Dependencies Incompatible changes -------------------- +* #11365: Remove support for the ``jsdump`` format in ``sphinx.search``. + Deprecated ----------