Skip to content

Commit

Permalink
add nbqa_ipynb to temporary files (#870)
Browse files Browse the repository at this point in the history
allows config globs to apply to nbqa-generated files.

e.g.

    default_magicgr4dg5bw_nbqa_ipynb.py

Added to suffix, so e.g. all generated .py files match *nbqa_ipynb.py
  • Loading branch information
minrk authored Oct 30, 2024
1 parent 07400b0 commit aa9e25d
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 2 deletions.
14 changes: 13 additions & 1 deletion docs/known-limitations.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,19 @@ then the following will still not be processed:
- cells with code which ``IPython`` would transform magics into (e.g. ``get_ipython().system('ls')``).

Because ``nbQA`` converts the code cells in Jupyter notebooks to temporary Python files for linting, certain flags like ``flake8``'s
``--per-file-ignores`` don't work. The temporary Python files will not match the specified file patterns and ignored error codes will still
``--per-file-ignores`` don't work perfectly.
The temporary Python files will not match the specified file patterns and ignored error codes will still
surface (`GH issue <https://github.com/nbQA-dev/nbQA/issues/730>`_).
nbqa-generated temporary files will contain the string ``nbqa_ipynb``,
so you can still apply per-file-ignores if you add an additional pattern:

.. sourcecode:: ini

[flake8]
per-file-ignores =
examples/*.ipynb: E402
examples/*nbqa_ipynb.py: E402
The directory and the stem of the filename are preserved, so e.g. ``path/to/mynotebook.ipynb`` will be ``path/to/mynotebook{randomstring}_nbqa_ipynb.py`` when nbqa passes it to the linter.

Any other limitation is likely unintentional - if you run into any, please do report an issue.
2 changes: 1 addition & 1 deletion nbqa/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 +526,7 @@ def _get_nb_to_tmp_mapping(
prefix=remove_suffix(
os.path.basename(notebook), os.path.splitext(notebook)[-1]
),
suffix=SUFFIX[md],
suffix="_nbqa_ipynb" + SUFFIX[md],
)
)
relative_path, _ = get_relative_and_absolute_paths(
Expand Down
47 changes: 47 additions & 0 deletions tests/tools/test_flake8_works.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""Check :code:`flake8` works as intended."""

import os
from pathlib import Path
from textwrap import dedent
from typing import TYPE_CHECKING

Expand Down Expand Up @@ -91,3 +92,49 @@ def test_cell_with_all_magics(capsys: "CaptureFixture") -> None:
out, err = capsys.readouterr()
assert out == ""
assert err == ""


def test_per_file_ignores(
tmp_notebook_for_testing: Path, capsys: "CaptureFixture"
) -> None:
"""
Check flake8 per-file-ignore patterns work.
Parameters
----------
tmp_notebook_for_testing
notebook Path to test
capsys
Pytest fixture to capture stdout and stderr.
"""
# enable per-file ignores with nbqa glob
flake8_ini = Path(".flake8")
flake8_ini.write_text(
dedent(
"""
[flake8]
per-file-ignores =
**/*.ipynb: E402
**/*nbqa_ipynb.py: E402
"""
),
encoding="utf-8",
)

main(["flake8", str(tmp_notebook_for_testing)])
flake8_ini.unlink()

expected_path_0 = os.path.join("tests", "data", "notebook_for_testing.ipynb")

out, err = capsys.readouterr()
expected_out = dedent(
f"""\
{expected_path_0}:cell_1:1:1: F401 'os' imported but unused
{expected_path_0}:cell_1:3:1: F401 'glob' imported but unused
{expected_path_0}:cell_1:5:1: F401 'nbqa' imported but unused
{expected_path_0}:cell_2:19:9: W291 trailing whitespace
{expected_path_0}:cell_4:1:1: F401 'random.randint' imported but unused
"""
)
assert err == ""
assert sorted(out.splitlines()) == sorted(expected_out.splitlines())

0 comments on commit aa9e25d

Please sign in to comment.