diff --git a/pgidocgen/mergeindex.py b/pgidocgen/mergeindex.py index 3c3c9454..ab3829b1 100755 --- a/pgidocgen/mergeindex.py +++ b/pgidocgen/mergeindex.py @@ -19,32 +19,60 @@ from .util import unescape_parameter +from typing import TypedDict + + +class IndexObject(TypedDict): + objnames: dict[str, list[str]] + objtypes: dict[str, str] + docnames: list[str] + filenames: list[str] + titles: list[str] + objects: dict[str, list[list[int | str]]] + + +class PartialIndexObject(IndexObject, total=False): + objnames: dict[str, list[str]] + objtypes: dict[str, str] + docnames: list[str] + filenames: list[str] + titles: list[str] + objects: dict[str, list[list[int | str]]] + + +class DoneIndexObject(PartialIndexObject, total=False): + namespaces: dict[str, PartialIndexObject] + class SearchIndexMerger(object): def __init__(self): - self._indices = {} + self._indices: dict[str, IndexObject] = {} - def add_index(self, namespace, index): + def add_index(self, namespace: str, index: IndexObject): if index is not None: assert namespace not in self._indices self._indices[namespace] = index - def load_index(self, namespace, index_path): + def load_index(self, namespace: str, index_path: str): with io.open(index_path, "r", encoding="utf-8") as h: data = h.read() mod = js_index.loads(data) self.add_index(namespace, mod) - def merge(self): + def merge(self) -> DoneIndexObject: if not self._indices: raise ValueError - done = {} - namespaces = {} + done: DoneIndexObject = { + # Initialise empty vars to satisfy type checker + "objtypes": {}, + "namespaces": {} + } + namespaces: dict[str, PartialIndexObject] = {} - pairs = [] + pairs: list[tuple[str, list[str]]] = [] for ns, index in self._indices.items(): for k, v in index["objnames"].items(): pair = (index["objtypes"][k], v) @@ -62,31 +90,34 @@ def merge(self): new_objnames = {} new_objtypes = {} - objtype_indizes = {} + objtype_indices = { + "gobject:property": 0 + } for i, (type_, name) in enumerate(pairs): new_objnames[str(i)] = name new_objtypes[str(i)] = type_ - objtype_indizes[type_] = i + objtype_indices[type_] = i done["objnames"] = new_objnames done["objtypes"] = new_objtypes - def get_obj_index(ns, old_index): - old_index = str(old_index) + def get_obj_index(ns: str, old_index: int | str) -> int: + inner_old_index = str(old_index) index = self._indices[ns] - value = index["objtypes"][old_index] + value = index["objtypes"][inner_old_index] for k, v in done["objtypes"].items(): if value == v: return int(k) assert 0 + return 0 # OBJECTS for ns, index in self._indices.items(): namespaces[ns] = {} - new_titles = [] - new_filenames = [] - new_docnames = [] + new_titles: list[str] = [] + new_filenames: list[str] = [] + new_docnames: list[str] = [] for docname, fn, title in zip(index["docnames"], index["filenames"], index["titles"]): new_filenames.append(fn) @@ -99,7 +130,7 @@ def get_obj_index(ns, old_index): namespaces[ns]["filenames"] = new_filenames namespaces[ns]["docnames"] = new_docnames - new_objects = {} + new_objects: dict[str, list[list[int | str]]] = {} for k, attributes in index["objects"].items(): if "." in k: k = k.split(".", 1)[-1] @@ -117,33 +148,34 @@ def get_obj_index(ns, old_index): is_signals = True if k not in new_objects: - new_objects[k] = {} + new_objects[k] = [] new_attributes = new_objects[k] - for attr, v in attributes.items(): - fn_index, objtype_index, prio, shortanchor = v + for v in attributes: + fn_index, objtype_index, prio, _, shortanchor = v + attr: str = str(shortanchor) objtype_index = get_obj_index(ns, objtype_index) new_v = [fn_index, objtype_index, prio, shortanchor] # Move things around so that signals and properties # better match devhelp output. if is_props: - new_v[1] = objtype_indizes["gobject:property"] + new_v[1] = objtype_indices["gobject:property"] new_v[3] = orig_k + "." + attr attr = "%s:%s" % ( orig_k.rsplit(".", 1)[0], unescape_parameter(attr)) elif is_signals: - new_v[1] = objtype_indizes["gobject:signal"] + new_v[1] = objtype_indices["gobject:signal"] new_v[3] = orig_k + "." + attr attr = "%s::%s" % ( orig_k.rsplit(".", 1)[0], unescape_parameter(attr)) elif attr.startswith("do_"): # change vfunc object type # XXX: there could be methods called "do_XXX".. - new_v[1] = objtype_indizes["gobject:vfunc"] + new_v[1] = objtype_indices["gobject:vfunc"] assert attr not in new_attributes - new_attributes[attr] = new_v + new_attributes.append([]) namespaces[ns]["objects"] = new_objects @@ -152,7 +184,7 @@ def get_obj_index(ns, old_index): return done -def mergeindex(path): +def mergeindex(path: str): """Merge searchindex files in subdirectories of `path` and create a searchindex files under `path` """