Skip to content

Commit d427c79

Browse files
authored
Merge pull request #206 from basnijholt/pre-commit
Add pre-commit with various linters and static code checkers
2 parents 9c54513 + cac7aaa commit d427c79

File tree

18 files changed

+249
-164
lines changed

18 files changed

+249
-164
lines changed

.github/workflows/pre-commit.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
name: pre-commit
2+
3+
on:
4+
pull_request:
5+
push:
6+
branches: [master]
7+
8+
jobs:
9+
pre-commit:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- uses: actions/checkout@v2
13+
- uses: actions/setup-python@v2
14+
- uses: pre-commit/[email protected]

.github/workflows/tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ jobs:
1313
include:
1414
- os: windows-latest
1515
python-version: 3.7
16-
16+
1717
runs-on: ${{ matrix.os }}
1818

1919
steps:

.pre-commit-config.yaml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
repos:
2+
- repo: "https://github.com/pre-commit/pre-commit-hooks"
3+
rev: v4.3.0
4+
hooks:
5+
- id: trailing-whitespace
6+
- id: end-of-file-fixer
7+
- repo: "https://gitlab.com/pycqa/flake8/"
8+
rev: 3.9.2
9+
hooks:
10+
- id: flake8
11+
- repo: "https://github.com/ambv/black"
12+
rev: 22.3.0
13+
hooks:
14+
- id: black
15+
language_version: python3
16+
- repo: "https://github.com/PyCQA/isort"
17+
rev: 5.10.1
18+
hooks:
19+
- id: isort
20+
- repo: https://github.com/asottile/pyupgrade
21+
rev: v2.34.0
22+
hooks:
23+
- id: pyupgrade
24+
args: ["--py36-plus"]

doc/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,4 @@ html-strict:
2323
@$(SPHINXBUILD) -b html -nW --keep-going "$(SOURCEDIR)" "$(BUILDDIR)/html" $(SPHINXOPTS) $(O)
2424

2525
clean:
26-
rm -r $(BUILDDIR)
26+
rm -r $(BUILDDIR)

doc/source/conf.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
# -*- coding: utf-8 -*-
21
#
32
# Configuration file for the Sphinx documentation builder.
43
#
@@ -11,7 +10,7 @@
1110

1211
sys.path.insert(0, os.path.abspath("../.."))
1312

14-
import jupyter_sphinx
13+
import jupyter_sphinx # noqa: E402
1514

1615
project = "Jupyter Sphinx"
1716
copyright = "2019, Jupyter Development Team"
@@ -35,4 +34,4 @@
3534

3635
jupyter_sphinx_thebelab_config = {"binderOptions": {"repo": "jupyter/jupyter-sphinx"}}
3736

38-
latex_engine = 'xelatex'
37+
latex_engine = "xelatex"

doc/source/index.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,7 @@ When showing code samples that are computationally expensive, access restricted
325325
def slow_print(str):
326326
time.sleep(4000) # Simulate an expensive process
327327
print(str)
328-
328+
329329
slow_print("hello, world!")
330330

331331
.. jupyter-output::
@@ -373,7 +373,7 @@ Downloading the code as a script
373373

374374
Jupyter Sphinx includes 2 roles that can be used to download the code embedded in a document:
375375
``:jupyter-download:script:`` (for a raw script file) and ``:jupyter-download:notebook:`` or ``:jupyter-download:nb:`` (for
376-
a Jupyter notebook).
376+
a Jupyter notebook).
377377

378378
These roles are equivalent to the standard sphinx `download role <https://www.sphinx-doc.org/en/master/usage/restructuredtext/roles.html#role-download>`__, **except** the extension of the file should not be given.
379379
For example, to download all the code from this document as a script we

jupyter_sphinx/__init__.py

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,31 @@
11
"""Simple sphinx extension that executes code in jupyter and inserts output."""
22

3-
from ._version import version_info, __version__
4-
from sphinx.util import logging
3+
from pathlib import Path
4+
55
import docutils
66
import ipywidgets
7-
import os
8-
from sphinx.util.fileutil import copy_asset
7+
from IPython.lib.lexers import IPython3Lexer, IPythonTracebackLexer
98
from sphinx.errors import ExtensionError
10-
from IPython.lib.lexers import IPythonTracebackLexer, IPython3Lexer
11-
from pathlib import Path
9+
from sphinx.util import logging
10+
from sphinx.util.fileutil import copy_asset
1211

12+
from ._version import __version__
1313
from .ast import (
14-
JupyterCell,
15-
JupyterCellNode,
14+
WIDGET_VIEW_MIMETYPE,
1615
CellInput,
1716
CellInputNode,
1817
CellOutput,
1918
CellOutputNode,
20-
MimeBundleNode,
19+
CombineCellInputOutput,
20+
JupyterCell,
21+
JupyterCellNode,
22+
JupyterDownloadRole,
2123
JupyterKernelNode,
22-
JupyterWidgetViewNode,
2324
JupyterWidgetStateNode,
24-
WIDGET_VIEW_MIMETYPE,
25-
JupyterDownloadRole,
26-
CombineCellInputOutput,
25+
JupyterWidgetViewNode,
26+
MimeBundleNode,
2727
)
28-
from .execute import JupyterKernel, ExecuteJupyterCells
28+
from .execute import ExecuteJupyterCells, JupyterKernel
2929
from .thebelab import ThebeButton, ThebeButtonNode, ThebeOutputNode, ThebeSourceNode
3030

3131
REQUIRE_URL_DEFAULT = (
@@ -35,21 +35,20 @@
3535

3636
logger = logging.getLogger(__name__)
3737

38-
##############################################################################
3938
# Constants and functions we'll use later
4039

4140
# Used for nodes that do not need to be rendered
41+
42+
4243
def skip(self, node):
4344
raise docutils.nodes.SkipNode
4445

4546

4647
# Used for nodes that should be gone by rendering time (OutputMimeBundleNode)
4748
def halt(self, node):
4849
raise ExtensionError(
49-
(
50-
"Rendering encountered a node type that should "
51-
"have been removed before rendering: %s" % type(node)
52-
)
50+
"Rendering encountered a node type that should "
51+
"have been removed before rendering: %s" % type(node)
5352
)
5453

5554

@@ -59,6 +58,7 @@ def halt(self, node):
5958
lambda self, node: self.depart_container(node),
6059
)
6160

61+
6262
# Used to render the container and its children as HTML
6363
def visit_container_html(self, node):
6464
self.body.append(node.visit_html())
@@ -89,7 +89,7 @@ def visit_thebe_source(self, node):
8989
lambda self, node: self.depart_container(node),
9090
)
9191

92-
##############################################################################
92+
9393
# Sphinx callback functions
9494
def builder_inited(app):
9595
"""

jupyter_sphinx/_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
_specifier_ = {"alpha": "a", "beta": "b", "candidate": "rc", "final": ""}
44

5-
__version__ = "%s.%s.%s%s" % (
5+
__version__ = "{}.{}.{}{}".format(
66
version_info[0],
77
version_info[1],
88
version_info[2],

jupyter_sphinx/ast.py

Lines changed: 33 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,21 @@
11
"""Manipulating the Sphinx AST with Jupyter objects"""
22

3-
import os
43
import json
5-
import contextlib
64
from pathlib import Path
75

86
import docutils
7+
import ipywidgets.embed
8+
import nbconvert
9+
from docutils.nodes import literal, math_block
910
from docutils.parsers.rst import Directive, directives
10-
from docutils.nodes import math_block, image, literal
11-
from sphinx.util import parselinenos
12-
from sphinx.util.docutils import ReferenceRole
1311
from sphinx.addnodes import download_reference
14-
from sphinx.transforms import SphinxTransform
15-
from sphinx.environment.collectors.asset import ImageCollector
1612
from sphinx.errors import ExtensionError
13+
from sphinx.transforms import SphinxTransform
14+
from sphinx.util import parselinenos
15+
from sphinx.util.docutils import ReferenceRole
1716

18-
import ipywidgets.embed
19-
import nbconvert
20-
21-
from .utils import strip_latex_delimiters, sphinx_abs_dir
22-
from .thebelab import ThebeSourceNode, ThebeOutputNode
17+
from .thebelab import ThebeOutputNode, ThebeSourceNode
18+
from .utils import sphinx_abs_dir, strip_latex_delimiters
2319

2420
WIDGET_VIEW_MIMETYPE = "application/vnd.jupyter.widget-view+json"
2521
WIDGET_STATE_MIMETYPE = "application/vnd.jupyter.widget-state+json"
@@ -45,8 +41,8 @@ def load_content(cell, location, logger):
4541
try:
4642
with Path(filename).open() as f:
4743
content = [line.rstrip() for line in f.readlines()]
48-
except (IOError, OSError):
49-
raise IOError("File {} not found or reading it failed".format(filename))
44+
except OSError:
45+
raise OSError(f"File {filename} not found or reading it failed")
5046
else:
5147
cell.assert_has_content()
5248
content = cell.content
@@ -165,6 +161,7 @@ def run(self):
165161
cell_node += cell_input
166162
return [cell_node]
167163

164+
168165
class CellInput(Directive):
169166
"""Define a code cell to be included verbatim but not executed.
170167
@@ -182,7 +179,7 @@ class CellInput(Directive):
182179
specified line.
183180
emphasize-lines : comma separated list of line numbers
184181
If provided, the specified lines will be highlighted.
185-
182+
186183
Content
187184
-------
188185
code : str
@@ -235,6 +232,7 @@ def run(self):
235232
cell_node += cell_input
236233
return [cell_node]
237234

235+
238236
class CellOutput(Directive):
239237
"""Define an output cell to be included verbatim.
240238
@@ -328,14 +326,14 @@ def render_as(self, visitor):
328326
try:
329327
# Or should we go to config via the node?
330328
priority = visitor.builder.env.app.config[
331-
'render_priority_' + visitor.builder.format
329+
"render_priority_" + visitor.builder.format
332330
]
333331
except (AttributeError, KeyError):
334332
# Not sure what do to, act as a container and show everything just in case.
335333
return super()
336334
for mimetype in priority:
337335
try:
338-
return self.children[self.attributes['mimetypes'].index(mimetype)]
336+
return self.children[self.attributes["mimetypes"].index(mimetype)]
339337
except ValueError:
340338
pass
341339
# Same
@@ -388,19 +386,19 @@ def __init__(self, rawsource="", *children, **attributes):
388386
super().__init__("", state=attributes["state"])
389387

390388
def html(self):
391-
392-
# escape </script> to avoid early closing of the tag in the html page
389+
390+
# escape </script> to avoid early closing of the tag in the html page
393391
json_data = json.dumps(self["state"]).replace("</script>", r"<\/script>")
394-
392+
395393
# TODO: render into a separate file if 'html-manager' starts fully
396394
# parsing script tags, and not just grabbing their innerHTML
397395
# https://github.com/jupyter-widgets/ipywidgets/blob/master/packages/html-manager/src/libembed.ts#L36
398396
return ipywidgets.embed.snippet_template.format(
399397
load="", widget_views="", json_data=json_data
400398
)
401399

402-
def cell_output_to_nodes(outputs, write_stderr, out_dir,
403-
thebe_config, inline=False):
400+
401+
def cell_output_to_nodes(outputs, write_stderr, out_dir, thebe_config, inline=False):
404402
"""Convert a jupyter cell with outputs and filenames to doctree nodes.
405403
406404
Parameters
@@ -476,11 +474,8 @@ def cell_output_to_nodes(outputs, write_stderr, out_dir,
476474
)
477475
elif output_type in ("display_data", "execute_result"):
478476
children_by_mimetype = {
479-
mime_type: output2sphinx(
480-
data, mime_type, output["metadata"], out_dir
481-
)
477+
mime_type: output2sphinx(data, mime_type, output["metadata"], out_dir)
482478
for mime_type, data in output["data"].items()
483-
484479
}
485480
# Filter out unknown mimetypes
486481
# TODO: rewrite this using walrus once we depend on Python 3.8
@@ -489,11 +484,13 @@ def cell_output_to_nodes(outputs, write_stderr, out_dir,
489484
for mime_type, node in children_by_mimetype.items()
490485
if node is not None
491486
}
492-
to_add.append(MimeBundleNode(
493-
"",
494-
*list(children_by_mimetype.values()),
495-
mimetypes=list(children_by_mimetype.keys())
496-
))
487+
to_add.append(
488+
MimeBundleNode(
489+
"",
490+
*list(children_by_mimetype.values()),
491+
mimetypes=list(children_by_mimetype.keys()),
492+
)
493+
)
497494

498495
return to_add
499496

@@ -552,7 +549,7 @@ def output2sphinx(data, mime_type, metadata, out_dir, inline=False):
552549
uri = (out_dir / filename).as_posix()
553550
return docutils.nodes.image(uri=uri)
554551
else:
555-
logger.debug(f'Unknown mime type in cell output: {mime_type}')
552+
logger.debug(f"Unknown mime type in cell output: {mime_type}")
556553

557554

558555
def apply_styling(node, thebe_config):
@@ -621,14 +618,14 @@ def apply(self):
621618
moved_outputs = set()
622619

623620
for cell_node in self.document.traverse(JupyterCellNode):
624-
if cell_node.attributes["execute"] == False:
625-
if cell_node.attributes["hide_code"] == False:
621+
if not cell_node.attributes["execute"]:
622+
if not cell_node.attributes["hide_code"]:
626623
# Cell came from jupyter-input
627624
sibling = cell_node.next_node(descend=False, siblings=True)
628625
if (
629626
isinstance(sibling, JupyterCellNode)
630-
and sibling.attributes["execute"] == False
631-
and sibling.attributes["hide_code"] == True
627+
and not sibling.attributes["execute"]
628+
and sibling.attributes["hide_code"]
632629
):
633630
# Sibling came from jupyter-output, so we merge
634631
cell_node += sibling.children[1]

0 commit comments

Comments
 (0)