Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .readthedocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ formats:
build:
os: ubuntu-24.04
tools:
python: "3.9"
python: "3.11"
jobs:
create_environment:
- asdf plugin add uv
- asdf install uv latest
- asdf global uv latest
- UV_PROJECT_ENVIRONMENT=$READTHEDOCS_VIRTUALENV_PATH uv sync --no-default-groups --extra docs
- UV_PROJECT_ENVIRONMENT=$READTHEDOCS_VIRTUALENV_PATH uv sync --no-default-groups --group docs
install:
- "true"

Expand Down
6 changes: 6 additions & 0 deletions docs/.ruff.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# SPDX-License-Identifier: MIT

extend = "../pyproject.toml"
src = ["../"]

target-version = "py311"
21 changes: 14 additions & 7 deletions docs/_static/scorer.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ function __score(haystack, regex) {
}
let subLength = match[0].length;
let start = match.index;
// longer (and later) submatches get a higher score penalty
return (subLength * 1000 + start) / 1000.0;
}

Expand All @@ -38,23 +39,29 @@ function __setPattern() {

Scorer = {
// Implement the following function to further tweak the score for each result
// The function takes a result array [filename, title, anchor, descr, score]
// The function takes a result array [docname, title, anchor, descr, score, filename, kind]
// and returns the new score.
score: (result) => {
// only inflate the score of things that are actual API reference things
const [, title, , , score,] = result;
const [, title, , , score, , kind] = result;

if (queryBeingDone === undefined) {
__setPattern();
}

// penalize text matches a little bit, sphinx scores pages that have a matching subtitle
// the same as pages that actually have the search term as the title, for some reason
if (kind === "text") return score - 1;

// only inflate the score of things that are actual API reference things
if (pattern !== null && title.startsWith('disnake.')) {
let _score = __score(title, pattern);
if (_score === Number.MAX_VALUE) {
const penalty = __score(title, pattern);
if (penalty === Number.MAX_VALUE) {
return score;
}
let newScore = 100 + queryBeingDone.length - _score;
// console.log(`${title}: ${score} -> ${newScore} (${_score})`);
// calculate new score on top of title score; we want to rank *all* API results
// right below matching pages, and have pages with only a fulltext match appear last
const newScore = Scorer.title - (penalty / 1000);
// console.log(`${title}: ${score} -> ${newScore} (${penalty})`);
return newScore;
}
return score;
Expand Down
11 changes: 6 additions & 5 deletions docs/_static/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -200,13 +200,14 @@ body {
}

/* all URLs only show underline on hover */
a {
/* (also overrides sphinx's :visited highlight) */
a, a:visited {
text-decoration: none;
color: var(--link-text);
transition: color 0.3s;
}

a:hover {
a:hover, a:hover:visited {
text-decoration: underline;
color: var(--link-hover-text);
transition: color 0.05s;
Expand Down Expand Up @@ -236,12 +237,12 @@ header > nav {
line-height: 1em; /* It defaults to 1.2, pushing some icons out of vertical alignment */
}

header > nav a {
header > nav a, header > nav a:visited {
color: var(--nav-link-text);
margin: 0 0.5em;
}

header > nav a:hover {
header > nav a:hover, header > nav a:hover:visited {
color: var(--nav-link-hover-text);
text-decoration: none;
}
Expand Down Expand Up @@ -286,7 +287,7 @@ footer {
z-index: 5;
}

footer a {
footer a, footer a:visited {
text-decoration: underline;
color: var(--footer-link);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ const redirects_map = {{ redirect_data }};

if (!url.pathname.endsWith("/api.html")) return;

// URL_ROOT is relative to `url`, and points to e.g. `<host>/en/latest/`
const root = new URL(DOCUMENTATION_OPTIONS.URL_ROOT, url);
// content_root is relative to `url`, and points to e.g. `<host>/en/latest/`
const root = new URL(document.documentElement.dataset.content_root, url);
if (!root.pathname.endsWith("/")) root.pathname += "/";

const targetPath = redirects_map[url.hash.slice(1)];
Expand Down
3 changes: 1 addition & 2 deletions docs/_templates/layout.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<!-- SPDX-License-Identifier: MIT -->

<!DOCTYPE html>
<html>
<html data-content_root="{{ content_root }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
Expand All @@ -21,7 +21,6 @@
<link rel="stylesheet" href="{{ pathto('_static/style.css', 1)|e }}" type="text/css" />
<link rel="stylesheet" href="{{ pathto('_static/codeblocks.css', 1) }}" type="text/css" />
{%- block scripts %}
<script id="documentation_options" data-url_root="{{ pathto('', 1) }}" src="{{ pathto('_static/documentation_options.js', 1) }}"></script>
{% if ("/" + pagename).endswith("/api") %}
<meta name="robots" content="noindex" />
<script type="text/javascript" src="{{ pathto('_static/api_redirect.js', 1) }}"></script>
Expand Down
27 changes: 24 additions & 3 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,15 @@

import importlib.util
import inspect
import logging
import os
import re
import subprocess # noqa: TID251
import sys
from typing import Any, Dict, Optional
import warnings
from typing import Any

import sphinx.deprecation
from sphinx.application import Sphinx

# If extensions (or modules to document with autodoc) are in another directory,
Expand Down Expand Up @@ -90,7 +93,9 @@
templates_path = ["_templates"]

# The suffix of source filenames.
source_suffix = ".rst"
source_suffix = {
".rst": "restructuredtext",
}

# The encoding of source files.
# source_encoding = 'utf-8-sig'
Expand Down Expand Up @@ -208,7 +213,7 @@ def git(*args: str) -> str:
_disnake_module_path = os.path.dirname(_spec.origin)


def linkcode_resolve(domain: str, info: Dict[str, Any]) -> Optional[str]:
def linkcode_resolve(domain: str, info: dict[str, Any]) -> str | None:
if domain != "py":
return None

Expand Down Expand Up @@ -506,3 +511,19 @@ def setup(app: Sphinx) -> None:
import disnake

del disnake.Embed.Empty # type: ignore

warnings.filterwarnings(
"ignore",
category=sphinx.deprecation.RemovedInSphinx90Warning,
module="hoverxref.extension",
)

# silence somewhat verbose `Writing evaluated template result to ...` log
logging.getLogger("sphinx.sphinx.util.fileutil").addFilter(
lambda r: getattr(r, "subtype", None) != "template_evaluation"
)

# `document is referenced in multiple toctrees:` is fine and expected
logging.getLogger("sphinx.sphinx.environment").addFilter(
lambda r: getattr(r, "subtype", None) != "multiple_toc_parents"
)
20 changes: 10 additions & 10 deletions docs/extensions/attributetable.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import inspect
import re
from collections import defaultdict
from typing import TYPE_CHECKING, ClassVar, DefaultDict, Dict, List, NamedTuple, Optional, Tuple
from typing import TYPE_CHECKING, ClassVar, NamedTuple

from docutils import nodes
from sphinx import addnodes
Expand Down Expand Up @@ -104,7 +104,7 @@ class PyAttributeTable(SphinxDirective):
final_argument_whitespace = False
option_spec: ClassVar[OptionSpec] = {}

def parse_name(self, content: str) -> Tuple[str, Optional[str]]:
def parse_name(self, content: str) -> tuple[str, str | None]:
match = _name_parser_regex.match(content)
path, name = match.groups() if match else (None, None)
if path:
Expand All @@ -119,7 +119,7 @@ def parse_name(self, content: str) -> Tuple[str, Optional[str]]:

return modulename, name

def run(self) -> List[nodes.Node]:
def run(self) -> list[nodes.Node]:
"""If you're curious on the HTML this is meant to generate:

<div class="py-attribute-table">
Expand Down Expand Up @@ -156,10 +156,10 @@ def run(self) -> List[nodes.Node]:
return [node]


def build_lookup_table(env: BuildEnvironment) -> Dict[str, List[str]]:
def build_lookup_table(env: BuildEnvironment) -> dict[str, list[str]]:
# Given an environment, load up a lookup table of
# full-class-name: objects
result: DefaultDict[str, List[str]] = defaultdict(list)
result: defaultdict[str, list[str]] = defaultdict(list)
domain = env.domains["py"]

ignored = {
Expand All @@ -182,7 +182,7 @@ def build_lookup_table(env: BuildEnvironment) -> Dict[str, List[str]]:
class TableElement(NamedTuple):
fullname: str
label: str
badge: Optional[attributetablebadge]
badge: attributetablebadge | None


def process_attributetable(app: Sphinx, doctree: nodes.document, docname: str) -> None:
Expand Down Expand Up @@ -211,12 +211,12 @@ def process_attributetable(app: Sphinx, doctree: nodes.document, docname: str) -


def get_class_results(
lookup: Dict[str, List[str]], modulename: str, name: str, fullname: str
) -> Dict[str, List[TableElement]]:
lookup: dict[str, list[str]], modulename: str, name: str, fullname: str
) -> dict[str, list[TableElement]]:
module = importlib.import_module(modulename)
cls = getattr(module, name)

groups: Dict[str, List[TableElement]] = {
groups: dict[str, list[TableElement]] = {
_("Attributes"): [],
_("Methods"): [],
}
Expand Down Expand Up @@ -265,7 +265,7 @@ def get_class_results(
return groups


def class_results_to_node(key: str, elements: List[TableElement]) -> attributetablecolumn:
def class_results_to_node(key: str, elements: list[TableElement]) -> attributetablecolumn:
title = attributetabletitle(key, key)
ul = nodes.bullet_list("")
ul["classes"].append("py-attribute-table-list")
Expand Down
2 changes: 1 addition & 1 deletion docs/extensions/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

from docutils import nodes
from sphinx.environment.adapters.indexentries import IndexEntries
from sphinxext.opengraph.descriptionparser import DescriptionParser
from sphinxext.opengraph._description_parser import DescriptionParser

if TYPE_CHECKING:
from sphinx.application import Sphinx
Expand Down
4 changes: 2 additions & 2 deletions docs/extensions/collapse.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: MIT
from __future__ import annotations

from typing import TYPE_CHECKING, ClassVar, List
from typing import TYPE_CHECKING, ClassVar

from docutils import nodes
from docutils.parsers.rst import Directive, directives
Expand Down Expand Up @@ -36,7 +36,7 @@ class CollapseDirective(Directive):

option_spec: ClassVar[OptionSpec] = {"open": directives.flag}

def run(self) -> List[collapse]:
def run(self) -> list[collapse]:
self.assert_has_content()
node = collapse(
"\n".join(self.content),
Expand Down
4 changes: 2 additions & 2 deletions docs/extensions/exception_hierarchy.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: MIT
from __future__ import annotations

from typing import TYPE_CHECKING, List
from typing import TYPE_CHECKING

from docutils import nodes
from docutils.parsers.rst import Directive
Expand All @@ -28,7 +28,7 @@ def depart_exception_hierarchy_node(self: HTMLTranslator, node: nodes.Element) -
class ExceptionHierarchyDirective(Directive):
has_content = True

def run(self) -> List[exception_hierarchy]:
def run(self) -> list[exception_hierarchy]:
self.assert_has_content()
node = exception_hierarchy("\n".join(self.content))
self.state.nested_parse(self.content, self.content_offset, node)
Expand Down
4 changes: 2 additions & 2 deletions docs/extensions/fulltoc.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@

from __future__ import annotations

from typing import TYPE_CHECKING, List, cast
from typing import TYPE_CHECKING, cast

from docutils import nodes
from sphinx import addnodes
Expand Down Expand Up @@ -112,7 +112,7 @@ def build_full_toctree(
"""
env: BuildEnvironment = builder.env
doctree = env.get_doctree(index)
toctrees: List[nodes.Element] = []
toctrees: list[nodes.Element] = []
for toctreenode in doctree.traverse(addnodes.toctree):
toctree = env.resolve_toctree(
docname,
Expand Down
11 changes: 6 additions & 5 deletions docs/extensions/redirects.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,21 @@

import json
from pathlib import Path
from typing import TYPE_CHECKING, Dict
from typing import TYPE_CHECKING

from sphinx.application import Sphinx
from sphinx.util.fileutil import copy_asset_file

if TYPE_CHECKING:
from ._types import SphinxExtensionMeta

SCRIPT_PATH = "_templates/api_redirect.js_t"
SCRIPT_PATH = "_templates/api_redirect.js.jinja"


def collect_redirects(app: Sphinx) -> Dict[str, str]:
def collect_redirects(app: Sphinx) -> dict[str, str]:
# mapping of html node id (i.e., thing after "#" in URLs) to the correct page name
# e.g, api.html#disnake.Thread => api/channels.html
mapping: Dict[str, str] = {}
mapping: dict[str, str] = {}

# see https://www.sphinx-doc.org/en/master/extdev/domainapi.html#sphinx.domains.Domain.get_objects
domain = app.env.domains["py"]
Expand All @@ -27,7 +27,7 @@ def collect_redirects(app: Sphinx) -> Dict[str, str]:
return mapping


def copy_redirect_script(app: Sphinx, exception: Exception) -> None:
def copy_redirect_script(app: Sphinx, exception: Exception | None) -> None:
if app.builder.format != "html" or exception:
return

Expand All @@ -41,6 +41,7 @@ def copy_redirect_script(app: Sphinx, exception: Exception) -> None:
SCRIPT_PATH,
str(Path(app.outdir, "_static", "api_redirect.js")),
context=context,
force=True,
)


Expand Down
Loading