diff --git a/CHANGELOG.md b/CHANGELOG.md index c94d03c1..8ab382e3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -256,10 +256,14 @@ therefore be updated in a near future to not take any of the argument related to auto-fixing, and fail instead of silently modifying its parameters on invalid notebooks. -`nbformat` now contain a `normalize` function that will return a -normalized copy of a notebook that is suitable for validation. While -offered as a convenience we discourage its use and suggest library make -sure to generate valid notebooks. +`nbformat` now provides a `normalize` function that returns a normalized +copy of a notebook suitable for validation. This function is intended as +a helper for tools that need to prepare notebooks before calling +`validate()`. + +Most libraries and applications should continue to generate valid +notebooks directly and rely on `validate()` to check correctness, rather +than using `normalize()` as part of normal notebook creation. ### Other changes diff --git a/nbformat/reader.py b/nbformat/reader.py index 6e23b4e8..3bc3066d 100644 --- a/nbformat/reader.py +++ b/nbformat/reader.py @@ -47,7 +47,10 @@ def get_version(nb): def reads(s, **kwargs): - """Read a notebook from a json string and return the + """ + Note: This function reads notebook content from a string and does not perform file I/O. + + Read a notebook from a json string and return the NotebookNode object. This function properly reads notebooks of any version. No version diff --git a/nbformat/validator.py b/nbformat/validator.py index 00e8755f..33b9d4c2 100644 --- a/nbformat/validator.py +++ b/nbformat/validator.py @@ -425,6 +425,8 @@ def validate( """Checks whether the given notebook dict-like object conforms to the relevant notebook format schema. + Note: This function validates notebooks but does not modify them; use `normalize()` if a normalized copy is required before validation. + Parameters ---------- nbdict : dict diff --git a/tests/test_validator.py b/tests/test_validator.py index ba7fd5ef..b7540328 100644 --- a/tests/test_validator.py +++ b/tests/test_validator.py @@ -383,3 +383,22 @@ def test_strip_invalid_metadata(): ): validate(nb, strip_invalid_metadata=True) assert isvalid(nb) + + +def test_validate_does_not_mutate_notebook(): + from nbformat import v4 + from nbformat.validator import validate + + # Create a simple valid notebook + nb = v4.new_notebook(cells=[v4.new_markdown_cell("hello")]) + + # Make a deep copy to compare after validation + import copy + + nb_before = copy.deepcopy(nb) + + # Validate the notebook + validate(nb) + + # Ensure validation did not modify the notebook + assert nb == nb_before