Skip to content

Commit

Permalink
Add ability to ignore .OTTER_LOG to Notebook.export and Otter Assign (#…
Browse files Browse the repository at this point in the history
…863)

* add ability to ignore .OTTER_LOG to Notebook.export and Otter Assign

* typo
  • Loading branch information
chrispyles authored Oct 15, 2024
1 parent 7fbb47f commit 8900368
Show file tree
Hide file tree
Showing 8 changed files with 36 additions and 3 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
* Added ability to monitor grading progress to Otter Grade per [#827](https://github.com/ucbds-infra/otter-grader/issues/827)
* Added handling of student-created files with the `student_files` configuration in Otter Assign per [#737](https://github.com/ucbds-infra/otter-grader/issues/737)
* Updated Otter Assign to add a cell to install Otter at the top of Colab notebooks per [#861](https://github.com/ucbds-infra/otter-grader/issues/861)
* Added the ability to ignore the `.OTTER_LOG` file to `Notebook.export` and Otter Assign per [#857](https://github.com/ucbds-infra/otter-grader/issues/857)

**v5.7.1:**

Expand Down
6 changes: 6 additions & 0 deletions otter/assign/assignment.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,12 @@ class RequireNoPDFAckValue(fica.Config):
subkey_container=RequireNoPDFAckValue,
)

ignore_log: bool = fica.Key(
description="whether to exclude the .OTTER_LOG file from the submission zip file",
default=False,
type_=bool,
)

export_cell: ExportCellValue = fica.Key(
description="whether to include an Otter export cell in the output notebooks",
subkey_container=ExportCellValue,
Expand Down
2 changes: 2 additions & 0 deletions otter/assign/cell_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,8 @@ def create_export_cells(self) -> list[nbformat.NotebookNode]:
args += ["force_save=True"]
if self.assignment.export_cell.run_tests:
args += ["run_tests=True"]
if self.assignment.export_cell.ignore_log:
args += ["ignore_log=True"]
if self.assignment.export_cell.files or self.assignment.student_files:
l = [*self.assignment.export_cell.files, *self.assignment.student_files]
args += [f"files={l}"]
Expand Down
4 changes: 3 additions & 1 deletion otter/check/notebook.py
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,7 @@ def export(
display_link: bool = True,
force_save: bool = False,
run_tests: bool = False,
ignore_log: bool = False,
):
"""
Export a submission zip file.
Expand All @@ -430,6 +431,7 @@ def export(
notebook (only works in Jupyter Notebook classic, not JupyterLab)
run_tests (``bool``): whether to validating the resulting submission zip against local
test cases
ignore_log (``bool``): whether to exclude the .OTTER_LOG file from the submission zip
"""
self._log_event(EventType.BEGIN_EXPORT)

Expand Down Expand Up @@ -485,7 +487,7 @@ def export(
warnings.warn("Could not locate a PDF to include")

def continue_export():
if os.path.isfile(OTTER_LOG_FILENAME):
if not ignore_log and os.path.isfile(OTTER_LOG_FILENAME):
zf.write(OTTER_LOG_FILENAME)
self._logger.debug("Added Otter log to zip file")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -515,7 +515,7 @@
},
"outputs": [],
"source": [
"grader.export(force_save=True, run_tests=True, files=['student_file.py'])"
"grader.export(force_save=True, run_tests=True, ignore_log=True, files=['student_file.py'])"
]
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@
},
"outputs": [],
"source": [
"grader.export(force_save=True, run_tests=True, files=['student_file.py'])"
"grader.export(force_save=True, run_tests=True, ignore_log=True, files=['student_file.py'])"
]
},
{
Expand Down
1 change: 1 addition & 0 deletions test/test_assign/files/example.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"show_question_points: true\n",
"export_cell:\n",
" force_save: true\n",
" ignore_log: true\n",
"python_version: 3.8\n",
"exclude_conda_defaults: true\n",
"files:\n",
Expand Down
21 changes: 21 additions & 0 deletions test/test_check/test_notebook.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,27 @@ def test_export(mocked_export, mocked_zf, mocked_dt, write_notebook):
)


@mock.patch("otter.check.notebook.zipfile.ZipFile")
@mock.patch("otter.check.notebook.export_notebook")
def test_export_ignore_log(mocked_export, mocked_zf, write_notebook):
"""
Checks the ``ignore_log`` argument of ``Notebook.export``
"""
write_notebook(nbf.v4.new_notebook())

grader = Notebook(tests_dir=TESTS_DIR)

with mock.patch.object(grader, "_resolve_nb_path") as mocked_resolve:
mocked_resolve.return_value = NB_PATH

grader.export(ignore_log=True)

# There is no assert_not_called_with method on the MagicMock class, so check that asserting
# the undesired call raises an AssertionError instead.
with pytest.raises(AssertionError):
mocked_zf.return_value.write.assert_any_call(OTTER_LOG_FILENAME)


@mock.patch("otter.check.notebook.zipfile.ZipFile")
def test_export_with_directory_in_files(mocked_zf, write_notebook):
"""
Expand Down

0 comments on commit 8900368

Please sign in to comment.