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
46 changes: 18 additions & 28 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -1,26 +1,30 @@
version: 2.1

# gen3 resource classes are only valid with the `current` machine image tag -- a
# pinned dated tag is rejected with "is not a valid resource class".
_machine: &machine
machine:
image: ubuntu-2604:current
# large.gen3: 4 vCPUs / 16 GiB, both faster and cheaper per minute than the
# gen1 `large` class. Revert to `large` if gen3 queue times become a problem.
resource_class: large.gen3
# pinned dated tag is rejected with "is not a valid resource class". They are
# both faster and cheaper per minute than their gen1 equivalents; revert to
# `medium` / `large` if gen3 queue times become a problem.
executors:
linux:
parameters:
size:
type: string
default: medium.gen3
machine:
image: ubuntu-2604:current
resource_class: << parameters.size >>

jobs:
build_docs:
docker:
- image: "cimg/python:3.11"
executor: linux
steps:
- checkout
- run:
name: Update apt-get
command: sudo apt-get update
- run:
name: Install TeX
command: sudo apt install dvipng texlive-fonts-recommended texlive-latex-recommended texlive-latex-extra latexmk texlive-xetex
command: sudo apt-get install -yy --no-install-recommends dvipng texlive-fonts-recommended texlive-latex-recommended texlive-latex-extra latexmk texlive-xetex
- restore_cache:
keys:
- pip-cache
Expand Down Expand Up @@ -71,26 +75,12 @@ jobs:
description: Debian packages the project's conf.py needs on PATH.
type: string
default: ""
<<: *machine
# large.gen3: 4 vCPUs / 16 GiB
executor:
name: linux
size: large.gen3
steps:
- checkout
# Pull requests build only when they carry the `integration-tests` label;
# pushes to main always do. CircleCI does not retrigger on label events,
# so a label added later needs a re-run of the workflow. A GitHub API
# hiccup (the CircleCI IP is shared and rate-limited) builds anyway.
- run:
name: Check for the integration-tests label
command: |
[ -n "$CIRCLE_PULL_REQUEST" ] || exit 0
API=$(echo "$CIRCLE_PULL_REQUEST" |
sed -E 's#.*github.com/(.+)/pull/([0-9]+)#https://api.github.com/repos/\1/pulls/\2#')
LABELS=$(curl -fsS "$API" | python3 -c \
'import json,sys; print("\n".join(l["name"] for l in json.load(sys.stdin)["labels"]))' \
2>/dev/null) || {
echo "Could not read labels from $API; building anyway."; exit 0; }
echo "$LABELS" | grep -qx integration-tests || {
echo "Not labelled integration-tests; skipping $CIRCLE_JOB."
circleci-agent step halt; }
- run:
name: Install apt packages
command: |
Expand Down
5 changes: 2 additions & 3 deletions RELEASE.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,8 @@ version string to edit by hand. Example ``__version__`` values:
- 1.9.dev2+gdef # 2 commits after ``v1.8`` (development version)

The CircleCI ``integration`` jobs build numpy, matplotlib, scikit-image and
networkx against this checkout; they run on every push to ``main`` and on a
pull request only once it carries the ``integration-tests`` label (add the
label, then re-run the workflow). ``scipy`` is not in CI -- run
networkx against this checkout on every push, including to pull requests.
``scipy`` is not in CI -- run
``python tools/integration/build_docs.py scipy`` by hand before a release.

Process
Expand Down
11 changes: 10 additions & 1 deletion numpydoc/docscrape.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,9 @@ def _read_sections(self):
else:
yield name, self._strip(data[2:])

# "name: type" or "x1, x2: type", optionally with leading * or **
_missing_colon_space_rgx = re.compile(r"^\*{0,2}\w+(\s*,\s*\*{0,2}\w+)*: ")

def _parse_param_list(self, content, single_element_is_type=False):
content = dedent_lines(content)

Expand All @@ -235,7 +238,13 @@ def _parse_param_list(self, content, single_element_is_type=False):
# much. So, we compact any run of 2+ whitespace.
arg_type = re.sub(r"\s{2,}", " ", arg_type_w_whitespace)
else:
if not single_element_is_type and ": " in header:
# Only warn when what precedes ": " looks like parameter
# name(s), so that prose like ".. note:: ..." or
# "Implementation note: ..." that ended up in a parameter
# section does not trigger a misleading warning.
if not single_element_is_type and self._missing_colon_space_rgx.match(
header
):
self._error_location(
f"Parameter {header!r} has no space before the colon",
error=False,
Expand Down
41 changes: 41 additions & 0 deletions numpydoc/tests/test_docscrape.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,47 @@ def test_parameter_missing_space_before_colon_warns():
assert params == [("val: int", "", ["Input value."])]


@pytest.mark.parametrize(
"header",
[
"x1, x2: array_like",
"*args: tuple",
"**kwargs: dict, optional",
"default: any Python object (default=None)",
],
)
def test_parameter_missing_space_before_colon_warns_variants(header):
doc = f"""
Parameters
----------
{header}
Input value.
"""
with pytest.warns(UserWarning, match="space before the colon"):
NumpyDocString(doc)


@pytest.mark.parametrize(
"header",
[
".. note:: You must specify exactly one of deg or rad.",
"Implementation note: this function creates an intermediate graph",
],
)
def test_parameter_prose_with_colon_does_not_warn(header):
doc = f"""
Parameters
----------
val : int
Input value.

{header}
"""
with warnings.catch_warnings():
warnings.simplefilter("error")
NumpyDocString(doc)


def test_type_continuation():
doc = NumpyDocString("""
Parameters
Expand Down
19 changes: 19 additions & 0 deletions tools/integration/build_docs.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,17 @@ class Project:
exclude_requirements=("pygraphviz",),
# Don't execute the gallery examples or the myst-nb tutorial.
sphinx_defines=("plot_gallery=0", "nb_execution_mode=off"),
# The networkx 3.7 release notes have an unbalanced `*Matcher` that
# docutils warns about (fixed upstream after 3.7); a no-op otherwise.
pre_build_cwd="doc",
pre_build=(
(
"sed",
"-i",
r"s/^- Expose \*Matcher classes/- Expose ``*Matcher`` classes/",
"release/release_3.7.rst",
),
),
),
# Upstream builds with SPHINXOPTS="-W -j auto" and so do we, once the images
# `plot_gallery=0` never renders are suppressed. suppress_warnings repeats
Expand Down Expand Up @@ -129,6 +140,14 @@ class Project:
# them instead would defeat the point.
pre_build_cwd="doc",
pre_build=(("sed", "-i", "-E", _MPL_SED, "missing-references.json"),),
# conf.py turns every warning into an error, and released matplotlib
# has "name: type" parameter headers that numpydoc now warns about
# (fixed upstream after 3.11.x). Keep them visible but non-fatal.
conf_append="""\
warnings.filterwarnings(
"default", message=r".*has no space before the colon", category=UserWarning
)
""",
),
# numpy and scipy get sphinx-build pointed straight at doc/source: their
# Makefiles insist the installed library was built from the checkout.
Expand Down
Loading