Repository: executablebooks/jupyter-book
File: jupyter_book/config.py (Python)

Code before:
    """Update the dict `config` with `update` recursively.
    This *updates* nested dicts / lists instead of replacing them.
    """
    for key, val in update.items():
        if isinstance(config.get(key), dict):
            # if a dict value update is set to None,
            # then the entire dict will be "wiped",
            # otherwise it is recursively updated.
            if isinstance(val, dict):
                _recursive_update(config[key], val, list_extend)
            else:
                config[key] = val
        elif isinstance(config.get(key), list):
            if isinstance(val, list) and list_extend:
                config[key].extend(val)
            else:
                config[key] = val
        else:
            config[key] = val


def _get_files_outside_toc(
    toc: Path, sourcedir: Path, excluded_patterns: Collection[str]
):
    source_root = sourcedir or Path()
    source_files = {f for f in glob(str(source_root / "**/*"), recursive=True)}

    excluded_file_sets = [set(glob(p, recursive=True)) for p in excluded_patterns]
    included_files: Set[str] = {
        Path(relpath(f, source_root)).as_posix()
        for f in source_files.difference(*excluded_file_sets)
        if not isdir(f)
    }

    toc_yaml = yaml.safe_load(toc.read_text(encoding="utf8"))

    from nested_lookup import nested_lookup

    toc_files = {f for f in nested_lookup("file", toc_yaml)}

    verified_toc_files: Set[str] = {
        Path(f).as_posix()
        for f in included_files
        if os.path.splitext(f)[0] in toc_files
    }
    return included_files.difference(verified_toc_files)


Review comment (suggestion):
```suggestion
    source_files = {ff for ff in glob(str(source_root / "**/*"), recursive=True)}
```


Code after:
def _recursive_update(config, update, list_extend=False):
    """Update the dict `config` with `update` recursively.
    This *updates* nested dicts / lists instead of replacing them.
    """
    for key, val in update.items():
        if isinstance(config.get(key), dict):
            # if a dict value update is set to None,
            # then the entire dict will be "wiped",
            # otherwise it is recursively updated.
            if isinstance(val, dict):
                _recursive_update(config[key], val, list_extend)
            else:
                config[key] = val
        elif isinstance(config.get(key), list):
            if isinstance(val, list) and list_extend:
                config[key].extend(val)
            else:
                config[key] = val
        else:
            config[key] = val


def _get_files_outside_toc(
    toc: Path, sourcedir: Path, excluded_patterns: Collection[str]
) -> Set[str]:
    """Returns a set of files that are outside of the toc for exclusion from sphinx.

    Hidden files are NOT processed here as it may result in thousands of individual
     exclusions.
    """
    source_root = sourcedir or Path()
    source_files = {ff for ff in glob(str(source_root / "**/*"), recursive=True)}

    excluded_file_sets = [set(glob(pp, recursive=True)) for pp in excluded_patterns]
    included_files: Set[str] = {
        Path(relpath(ff, source_root)).as_posix()
        for ff in source_files.difference(*excluded_file_sets)
        if not isdir(ff)
    }

    toc_yaml = yaml.safe_load(toc.read_text(encoding="utf8"))
    toc_files = {ff for ff in nested_lookup("file", toc_yaml)}

    verified_toc_files: Set[str] = {
        Path(ff).as_posix()
        for ff in included_files
        if os.path.splitext(ff)[0] in toc_files
    }
    return included_files.difference(verified_toc_files)