Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ignore transient errors in windows build CI #1520

Merged
merged 19 commits into from Oct 19, 2023
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
19 changes: 0 additions & 19 deletions docs/examples/pydata.ipynb
Expand Up @@ -37,20 +37,6 @@
"## Matplotlib"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"nbsphinx": "hidden"
},
"outputs": [],
"source": [
"import matplotlib\n",
"\n",
"# avoid warnings upon doc build\n",
"matplotlib.set_loglevel(\"critical\")"
]
},
{
"cell_type": "code",
"execution_count": null,
Expand All @@ -69,11 +55,6 @@
"metadata": {},
"outputs": [],
"source": [
"import matplotlib.pyplot as plt\n",
"import numpy as np\n",
"\n",
"matplotlib.set_loglevel(\"critical\")\n",
"\n",
"rng = np.random.default_rng()\n",
"data = rng.standard_normal((3, 100))\n",
"fig, ax = plt.subplots()\n",
Expand Down
7 changes: 7 additions & 0 deletions src/pydata_sphinx_theme/utils.py
@@ -1,5 +1,6 @@
"""General helpers for the management of config parameters."""

import re
from typing import Any, Dict, Iterator

from docutils.nodes import Node
Expand Down Expand Up @@ -39,3 +40,9 @@ def traverse_or_findall(node: Node, condition: str, **kwargs) -> Iterator[Node]:
if hasattr(node, "findall")
else node.traverse(condition, **kwargs)
)


def escape_ansi(string: str) -> str:
"""Helper function to remove ansi coloring from sphinx warnings."""
ansi_escape = re.compile(r"(\x9B|\x1B\[)[0-?]*[ -\/]*[@-~]")
return ansi_escape.sub("", string)
2 changes: 2 additions & 0 deletions tests/intermittent_warning_list.txt
@@ -0,0 +1,2 @@
WARNING: Cell printed to stderr:
Matplotlib is building the font cache; this may take a moment.
7 changes: 1 addition & 6 deletions tests/test_build.py
Expand Up @@ -5,12 +5,7 @@

import pytest
import sphinx.errors


def escape_ansi(string: str) -> str:
"""Helper function to remove ansi coloring from sphinx warnings."""
ansi_escape = re.compile(r"(\x9B|\x1B\[)[0-?]*[ -\/]*[@-~]")
return ansi_escape.sub("", string)
from pydata_sphinx_theme.utils import escape_ansi


def test_build_html(sphinx_build_factory, file_regression) -> None:
Expand Down
44 changes: 26 additions & 18 deletions tests/utils/check_warnings.py
Expand Up @@ -4,6 +4,7 @@
from pathlib import Path

from colorama import Fore, init
from pydata_sphinx_theme.utils import escape_ansi

# init colors for all plateforms
init()
Expand All @@ -27,30 +28,37 @@ def check_warnings(file: Path) -> bool:

# find the file where all the known warnings are stored
warning_file = Path(__file__).parent.parent / "warning_list.txt"
extra_warning_file = Path(__file__).parent.parent / "intermittent_warning_list.txt"

test_warnings = file.read_text().strip().split("\n")
ref_warnings = warning_file.read_text().strip().split("\n")
received_warnings = escape_ansi(file.read_text()).strip().split("\n")
expected_warnings = warning_file.read_text().strip().split("\n")
intermittent_warnings = extra_warning_file.read_text().strip().split("\n")
# filter out empty warnings (happens on notebooks for some reason)
received_warnings = filter(len, received_warnings)
drammock marked this conversation as resolved.
Show resolved Hide resolved

print(
f'Checking build warnings in file: "{file}" and comparing to expected '
f'warnings defined in "{warning_file}"\n\n'
f'warnings defined in "{warning_file}" and "{extra_warning_file}"\n\n'
)

# find all the missing warnings
missing_warnings = []
for wa in ref_warnings:
index = [i for i, twa in enumerate(test_warnings) if wa in twa]
if len(index) == 0:
missing_warnings += [wa]
print(f"{Fore.YELLOW}Warning was not raised: {Fore.RESET}{wa}\n")
else:
test_warnings.pop(index[0])

# the remaining one are unexpected
for twa in test_warnings:
print(f"{Fore.YELLOW}Unexpected warning: {Fore.RESET}{twa}\n")

return len(missing_warnings) != 0 or len(test_warnings) != 0
for exp_w in expected_warnings[::-1] + intermittent_warnings[::-1]:
found = False
for rec_w in received_warnings:
if exp_w in rec_w:
received_warnings.remove(rec_w)
if exp_w in expected_warnings:
expected_warnings.remove(exp_w)
elif exp_w in intermittent_warnings:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really like this approach of checking presence but discarding absence. nice trick

intermittent_warnings.remove(exp_w)
found = True
break
# alert only if an *always expected* warning wasn't raised (not intermittent)
if not found and exp_w not in intermittent_warnings:
print(f"{Fore.YELLOW}Warning was not raised: {Fore.RESET}{exp_w}\n")
# warn about unexpected warnings
for rec_w in received_warnings[::-1]:
print(f"{Fore.YELLOW}Unexpected warning: {Fore.RESET}{rec_w}\n")
return len(received_warnings) or len(expected_warnings)


if __name__ == "__main__":
Expand Down