Skip to content

Commit ef44180

Browse files
authored
New Autograde Preprocessor: IgnorePattern (#1904)
* Create IgnorePattern Preprocessor * Disable and add to the list by default
1 parent 338ec4d commit ef44180

File tree

5 files changed

+157
-1
lines changed

5 files changed

+157
-1
lines changed

nbgrader/converters/autograde.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from .base import BaseConverter, NbGraderException
1010
from ..preprocessors import (
1111
AssignLatePenalties, ClearOutput, DeduplicateIds, OverwriteCells, SaveAutoGrades,
12-
Execute, LimitOutput, OverwriteKernelspec, CheckCellMetadata)
12+
Execute, LimitOutput, OverwriteKernelspec, CheckCellMetadata, IgnorePattern)
1313
from ..api import Gradebook, MissingEntry
1414
from .. import utils
1515

@@ -61,6 +61,7 @@ def _output_directory(self) -> str:
6161
]).tag(config=True)
6262
autograde_preprocessors = List([
6363
Execute,
64+
IgnorePattern,
6465
ClearMetadataPreprocessor,
6566
LimitOutput,
6667
SaveAutoGrades,

nbgrader/preprocessors/__init__.py

+2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
from .clearhiddentests import ClearHiddenTests
1818
from .clearmarkingscheme import ClearMarkScheme
1919
from .overwritekernelspec import OverwriteKernelspec
20+
from .ignorepattern import IgnorePattern
2021

2122
__all__ = [
2223
"AssignLatePenalties",
@@ -37,4 +38,5 @@
3738
"ClearHiddenTests",
3839
"ClearMarkScheme",
3940
"OverwriteKernelspec",
41+
"IgnorePattern",
4042
]
+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
from . import NbGraderPreprocessor
2+
3+
from traitlets import Unicode, Bool
4+
from nbformat.notebooknode import NotebookNode
5+
from nbconvert.exporters.exporter import ResourcesDict
6+
from typing import Tuple
7+
import re
8+
9+
10+
class IgnorePattern(NbGraderPreprocessor):
11+
"""Preprocessor for removing cell outputs that match a particular pattern"""
12+
13+
pattern = Unicode("", help="The regular expression to remove from stderr").tag(config=True)
14+
enabled = Bool(False, help="Whether to use this preprocessor when running nbgrader").tag(config=True)
15+
16+
def preprocess_cell(self,
17+
cell: NotebookNode,
18+
resources: ResourcesDict,
19+
cell_index: int
20+
) -> Tuple[NotebookNode, ResourcesDict]:
21+
22+
if self.pattern and cell.cell_type == "code":
23+
new_outputs = []
24+
for output in cell.outputs:
25+
if output.output_type == "stream" and output.name == "stderr" \
26+
and re.search(self.pattern, output.text):
27+
continue
28+
new_outputs.append(output)
29+
cell.outputs = new_outputs
30+
31+
return cell, resources
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "code",
5+
"execution_count": 2,
6+
"id": "efd8b463-ea80-4620-b01b-1382a56e7836",
7+
"metadata": {
8+
"tags": []
9+
},
10+
"outputs": [
11+
{
12+
"name": "stderr",
13+
"output_type": "stream",
14+
"text": [
15+
"[W NNPACK.cpp:64] Could not initialize NNPACK! Reason: Unsupported hardware.\n"
16+
]
17+
},
18+
{
19+
"data": {
20+
"text/plain": [
21+
"5"
22+
]
23+
},
24+
"execution_count": 2,
25+
"metadata": {},
26+
"output_type": "execute_result"
27+
}
28+
],
29+
"source": [
30+
"import torch\n",
31+
"layer = torch.nn.Conv2d(1, 32, 3, stride=1, padding=1)\n",
32+
"x = torch.randn(1, 1, 28, 28)\n",
33+
"y = layer(x)\n",
34+
"5"
35+
]
36+
},
37+
{
38+
"cell_type": "code",
39+
"execution_count": 2,
40+
"id": "2a2b6474-f64b-4c28-ac83-5d1c7bbfd92f",
41+
"metadata": {
42+
"tags": []
43+
},
44+
"outputs": [
45+
{
46+
"name": "stderr",
47+
"output_type": "stream",
48+
"text": [
49+
"/tmp/ipykernel_522/3731920106.py:3: UserWarning: This is a warning message\n",
50+
" warnings.warn(\"This is a warning message\")\n"
51+
]
52+
}
53+
],
54+
"source": [
55+
"import warnings\n",
56+
"\n",
57+
"warnings.warn(\"This is a warning message\")"
58+
]
59+
}
60+
],
61+
"metadata": {
62+
"kernelspec": {
63+
"display_name": "Python 3",
64+
"language": "python",
65+
"name": "python3"
66+
},
67+
"language_info": {
68+
"codemirror_mode": {
69+
"name": "ipython",
70+
"version": 3
71+
},
72+
"file_extension": ".py",
73+
"mimetype": "text/x-python",
74+
"name": "python",
75+
"nbconvert_exporter": "python",
76+
"pygments_lexer": "ipython3",
77+
"version": "3.10.12"
78+
}
79+
},
80+
"nbformat": 4,
81+
"nbformat_minor": 5
82+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import pytest
2+
import os
3+
4+
from ...preprocessors import IgnorePattern
5+
from .base import BaseTestPreprocessor
6+
7+
8+
@pytest.fixture
9+
def preprocessor():
10+
pp = IgnorePattern()
11+
pp.pattern = r"\[.*\.cpp.*\] Could not initialize NNPACK! Reason: Unsupported hardware."
12+
return pp
13+
14+
15+
class TestIgnorePattern(BaseTestPreprocessor):
16+
17+
def test_remove_matching_output(self, preprocessor):
18+
nb = self._read_nb(os.path.join("files", "warning-pattern.ipynb"))
19+
cell = nb.cells[0]
20+
21+
outputs = cell.outputs
22+
assert len(outputs) == 2
23+
24+
cell, _ = preprocessor.preprocess_cell(cell, {}, 0)
25+
26+
assert len(cell.outputs) == 1
27+
28+
29+
def test_skip_nonmatching_output(self, preprocessor):
30+
nb = self._read_nb(os.path.join("files", "warning-pattern.ipynb"))
31+
cell = nb.cells[1]
32+
33+
outputs = cell.outputs
34+
assert len(outputs) == 1
35+
36+
cell, _ = preprocessor.preprocess_cell(cell, {}, 1)
37+
38+
assert len(cell.outputs) == 1
39+
assert cell.outputs[0].name == "stderr"
40+

0 commit comments

Comments
 (0)