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

CI: Fail doc build on warning #22743

Closed
wants to merge 32 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
1168273
FutureWarning from groupby.
TomAugspurger Sep 18, 2018
41c8297
Purge read_table
TomAugspurger Sep 18, 2018
2e76e84
Removed nested list example
TomAugspurger Sep 18, 2018
a70f86d
Fixed resample __iter__
TomAugspurger Sep 18, 2018
e4a8b06
Old whatsnew
TomAugspurger Sep 18, 2018
693eead
Ecosystem
TomAugspurger Sep 18, 2018
e6b2c09
to_csv
TomAugspurger Sep 18, 2018
a7f0b38
to_json
TomAugspurger Sep 18, 2018
ff3d2dd
Handle subpackages better
TomAugspurger Sep 18, 2018
e544249
Fixed unexpected indent
TomAugspurger Sep 18, 2018
8bdb920
Fixed "inline interpreted text..."
TomAugspurger Sep 18, 2018
ae0f8ff
Fixed "malformed hyperlink target"
TomAugspurger Sep 18, 2018
a275dfb
Add warnings to CLI
TomAugspurger Sep 18, 2018
b190866
Fixed unexpected indentation
TomAugspurger Sep 18, 2018
a46e4c7
newline after directive
TomAugspurger Sep 18, 2018
74af53d
Maybe fix na_value not included in toctree
TomAugspurger Sep 18, 2018
1668c65
Fixed no link to na_value
TomAugspurger Sep 18, 2018
dda2bfc
Fixed II ref
TomAugspurger Sep 18, 2018
a2b31ab
Fixed options ref
TomAugspurger Sep 18, 2018
9f0a948
Fixed link to Resmpaler
TomAugspurger Sep 18, 2018
158c46d
Change warning, error, linting
TomAugspurger Sep 18, 2018
c1a5ab8
Sample warning
TomAugspurger Sep 19, 2018
bbcd7bd
update contributing
TomAugspurger Sep 19, 2018
c8f206c
lint
TomAugspurger Sep 19, 2018
c917101
Merge remote-tracking branch 'upstream/master' into doc-warnings
TomAugspurger Sep 20, 2018
30c9174
Fix call
TomAugspurger Sep 20, 2018
5e0b275
write a parser
TomAugspurger Sep 20, 2018
384ace8
try to exit
TomAugspurger Sep 20, 2018
6a2a060
lint
TomAugspurger Sep 20, 2018
378bd6d
Rework doc build
TomAugspurger Sep 20, 2018
8859f97
executable scripts
TomAugspurger Sep 20, 2018
b9331f1
activate
TomAugspurger Sep 20, 2018
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
9 changes: 6 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -111,17 +111,20 @@ before_script:

script:
- echo "script start"
- ci/run_build_docs.sh
- ci/script_single.sh
- ci/script_multi.sh
- ci/lint.sh
- ci/doctests.sh
- ci/docs/doctests.sh
- ci/docs/build_docs.sh
- ci/docs/lint_docs.sh
- echo "checking imports"
- source activate pandas && python ci/check_imports.py
- echo "script done"

after_success:
- ci/upload_coverage.sh
- source activate pandas
- ci/upload_coverage.sh
- ci/docs/upload_docs.sh

after_script:
- echo "after_script start"
Expand Down
23 changes: 23 additions & 0 deletions ci/docs/build_docs.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/bin/bash
set -e

cd "$TRAVIS_BUILD_DIR"
echo "inside $0"

if [ "$DOC" ]; then

echo "[building docs]"

source activate pandas

mv "$TRAVIS_BUILD_DIR"/doc /tmp
mv "$TRAVIS_BUILD_DIR/LICENSE" /tmp # included in the docs.
cd /tmp/doc

echo './make.py 2>&1 | tee doc-build.log'
./make.py 2>&1 | tee doc-build.log
else
echo "[skipping docs]"
fi

exit 0
File renamed without changes.
15 changes: 15 additions & 0 deletions ci/docs/lint_docs.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/bin/bash
set -e

echo "inside $0"

if [ "$DOC" ]; then
cd /tmp/doc

echo "[linting docs]"

echo './make.py lint_log --log-file=doc-build.log'
./make.py lint_log --log-file=doc-build.log
else
echo "[skipping doc lint]"
fi
26 changes: 4 additions & 22 deletions ci/build_docs.sh → ci/docs/upload_docs.sh
Original file line number Diff line number Diff line change
@@ -1,29 +1,9 @@
#!/bin/bash
set -e

if [ "${TRAVIS_OS_NAME}" != "linux" ]; then
echo "not doing build_docs on non-linux"
exit 0
fi

cd "$TRAVIS_BUILD_DIR"
echo "inside $0"

if [ "$DOC" ]; then

echo "Will build docs"

source activate pandas

mv "$TRAVIS_BUILD_DIR"/doc /tmp
mv "$TRAVIS_BUILD_DIR/LICENSE" /tmp # included in the docs.
cd /tmp/doc

echo ###############################
echo # Log file for the doc build #
echo ###############################

echo ./make.py
./make.py
if [ "${DOC}" ] && [ "${TRAVIS_PULL_REQUEST}" = "false" ]; then

echo ########################
echo # Create and send docs #
Expand Down Expand Up @@ -51,6 +31,8 @@ if [ "$DOC" ]; then
git remote -v

git push origin gh-pages -f
else
echo "[skipping doc upload]"
fi

exit 0
10 changes: 0 additions & 10 deletions ci/run_build_docs.sh

This file was deleted.

1 change: 1 addition & 0 deletions doc/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
doc-build.log
80 changes: 77 additions & 3 deletions doc/make.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,12 @@
import importlib
import sys
import os
import re
import textwrap
import shutil
# import subprocess
import argparse
from collections import namedtuple
from contextlib import contextmanager
import webbrowser
import jinja2
Expand Down Expand Up @@ -78,7 +81,7 @@ class DocBuilder:
script.
"""
def __init__(self, num_jobs=1, include_api=True, single_doc=None,
verbosity=0):
verbosity=0, warnings_are_errors=False, log_file=None):
self.num_jobs = num_jobs
self.include_api = include_api
self.verbosity = verbosity
Expand All @@ -87,6 +90,8 @@ def __init__(self, num_jobs=1, include_api=True, single_doc=None,
if single_doc is not None:
self._process_single_doc(single_doc)
self.exclude_patterns = self._exclude_patterns
self.warnings_are_errors = warnings_are_errors
self.log_file = log_file

self._generate_index()
if self.single_doc_type == 'docstring':
Expand Down Expand Up @@ -135,6 +140,12 @@ def _process_single_doc(self, single_doc):
try:
obj = pandas # noqa: F821
for name in single_doc.split('.'):
try:
Copy link
Contributor Author

Choose a reason for hiding this comment

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

cc @datapythonista single-page pandas.io.formats.style.Styler wasn't working earlier, since it's not available from the top-level namespace. Do we have tests for this?

# for names not in the top-level namespace by default,
# e.g. pandas.io.formats.style.Styler
importlib.import_module('.'.join([obj.__name__, name]))
except ImportError:
pass
obj = getattr(obj, name)
except AttributeError:
raise ValueError('Single document not understood, it should '
Expand Down Expand Up @@ -227,10 +238,10 @@ def _sphinx_build(self, kind):
if kind not in ('html', 'latex', 'spelling'):
raise ValueError('kind must be html, latex or '
'spelling, not {}'.format(kind))

self._run_os('sphinx-build',
'-j{}'.format(self.num_jobs),
'-b{}'.format(kind),
'{}'.format("W" if self.warnings_are_errors else ""),
'-{}'.format(
'v' * self.verbosity) if self.verbosity else '',
'-d{}'.format(os.path.join(BUILD_PATH, 'doctrees')),
Expand Down Expand Up @@ -317,6 +328,61 @@ def spellcheck(self):
' Check pandas/doc/build/spelling/output.txt'
' for more details.')

def lint_log(self):
with open(self.log_file) as f:
log = f.read()

tokens = tokenize_log(log)
failed = [tok for tok in tokens if tok.kind != 'OK']
if failed:
report_failures(failed)
sys.exit(1)


# ------
# Linter
# ------

LinterToken = namedtuple("Token", ['kind', 'value'])
IPY_ERROR = r'(?P<IPY_ERROR>>>>-*\n.*?<<<-*\n)'
SPHINX_WARNING = r'(?P<SPHINX_WARNING>^[^\n]*?: WARNING:.*?$\n?)'
OK = r'(?P<OK>^.*?\n)'


def tokenize_log(log):
master_pat = re.compile("|".join([IPY_ERROR, SPHINX_WARNING, OK]),
flags=re.MULTILINE | re.DOTALL)

def generate_tokens(pat, text):
scanner = pat.scanner(text)
for m in iter(scanner.match, None):
yield LinterToken(m.lastgroup, m.group(m.lastgroup))

tok = list(generate_tokens(master_pat, log))
return tok


def report_failures(failed):
tpl = textwrap.dedent("""\
{n} failure{s}

{individual}
""")
joined = []
for i, tok in enumerate(failed):
line = "Failure [{}]: {}".format(i, tok.value.strip())
joined.append(line)
joined = '\n'.join(joined)

print(tpl.format(n=len(failed),
s="s" if len(failed) != 1 else "",
individual=joined))


# ---
# CLI
# ---


def main():
cmds = [method for method in dir(DocBuilder) if not method.startswith('_')]
Expand Down Expand Up @@ -349,6 +415,13 @@ def main():
argparser.add_argument('-v', action='count', dest='verbosity', default=0,
help=('increase verbosity (can be repeated), '
'passed to the sphinx build command'))
argparser.add_argument("--warnings-are-errors",
default=False,
action="store_true",
help="Whether to fail the build on warnings.")
argparser.add_argument("--log-file",
default="doc-build.log",
help="Log file of the build to lint for warnings.")
args = argparser.parse_args()

if args.command not in cmds:
Expand All @@ -368,7 +441,8 @@ def main():
os.environ['MPLBACKEND'] = 'module://matplotlib.backends.backend_agg'

builder = DocBuilder(args.num_jobs, not args.no_api, args.single,
args.verbosity)
args.verbosity, args.warnings_are_errors,
args.log_file)
getattr(builder, args.command)()


Expand Down
9 changes: 9 additions & 0 deletions doc/source/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2603,3 +2603,12 @@ objects.
generated/pandas.Series.ix
generated/pandas.Series.imag
generated/pandas.Series.real


.. Can't convince sphinx to generate toctree for this class attribute.
.. So we do it manually to avoid a warning
.. toctree::
:hidden:

generated/pandas.api.extensions.ExtensionDtype.na_value
Copy link
Contributor Author

Choose a reason for hiding this comment

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

No idea on this one. Something with numpydoc / sphinx autodoc. I think autodoc detects that na_value has a "docstring" (comments), but numpydoc doesn't. Not super important.

2 changes: 1 addition & 1 deletion doc/source/basics.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1935,7 +1935,7 @@ NumPy's type-system for a few cases.
* :ref:`Categorical <categorical>`
* :ref:`Datetime with Timezone <timeseries.timezone_series>`
* :ref:`Period <timeseries.periods>`
* :ref:`Interval <advanced.indexing.intervallindex>`
* :ref:`Interval <indexing.intervallindex>`

Pandas uses the ``object`` dtype for storing strings.

Expand Down
5 changes: 5 additions & 0 deletions doc/source/contributing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,11 @@ Some other important things to know about the docs:
Every method should be included in a ``toctree`` in ``api.rst``, else Sphinx
will emit a warning.

* The pandas CI system does not allow warnings in the documentation build.
If you cannot discover the cause of the warning from the build output, you can
try elevating warnings to errors with ``python make.py --warnings-are-errors``,
which will immediately halt the build when a warning is encountered.

.. note::

The ``.rst`` files are used to automatically generate Markdown and HTML versions
Expand Down
6 changes: 2 additions & 4 deletions doc/source/cookbook.rst
Original file line number Diff line number Diff line change
Expand Up @@ -505,13 +505,11 @@ Unlike agg, apply's callable is passed a sub-DataFrame which gives you access to
.. ipython:: python

df = pd.DataFrame({'A' : [1, 1, 2, 2], 'B' : [1, -1, 1, 2]})

gb = df.groupby('A')

def replace(g):
mask = g < 0
g.loc[mask] = g[~mask].mean()
return g
mask = g < 0
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Apparently the argument passed to func in transform can be either a Series or DataFrame? This implementation should be robust to either.

return g.where(mask, g[~mask].mean())

gb.transform(replace)

Expand Down
8 changes: 4 additions & 4 deletions doc/source/ecosystem.rst
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ large data to thin clients.
`seaborn <https://seaborn.pydata.org>`__
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Seaborn is a Python visualization library based on `matplotlib
<http://matplotlib.org>`__. It provides a high-level, dataset-oriented
Seaborn is a Python visualization library based on
`matplotlib <http://matplotlib.org>`__. It provides a high-level, dataset-oriented
interface for creating attractive statistical graphics. The plotting functions
in seaborn understand pandas objects and leverage pandas grouping operations
internally to support concise specification of complex visualizations. Seaborn
Expand Down Expand Up @@ -140,7 +140,7 @@ which are utilized by Jupyter Notebook for displaying
(Note: HTML tables may or may not be
compatible with non-HTML Jupyter output formats.)

See :ref:`Options and Settings <options>` and :ref:`<options.available>`
See :ref:`Options and Settings <options>` and :ref:`options.available`
for pandas ``display.`` settings.

`quantopian/qgrid <https://github.com/quantopian/qgrid>`__
Expand Down Expand Up @@ -169,7 +169,7 @@ or the clipboard into a new pandas DataFrame via a sophisticated import wizard.
Most pandas classes, methods and data attributes can be autocompleted in
Spyder's `Editor <https://docs.spyder-ide.org/editor.html>`__ and
`IPython Console <https://docs.spyder-ide.org/ipythonconsole.html>`__,
and Spyder's `Help pane<https://docs.spyder-ide.org/help.html>`__ can retrieve
and Spyder's `Help pane <https://docs.spyder-ide.org/help.html>`__ can retrieve
and render Numpydoc documentation on pandas objects in rich text with Sphinx
both automatically and on-demand.

Expand Down
Loading