Skip to content

Commit

Permalink
Start working on mutation issues in validate.
Browse files Browse the repository at this point in the history
Step 1 toward jupyter#235
  • Loading branch information
Carreau committed Nov 16, 2021
1 parent f101cd2 commit a08c7f4
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 11 deletions.
2 changes: 2 additions & 0 deletions nbformat/json_compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ def _validator_for_name(validator_name):
for (name, module, validator_cls) in _VALIDATOR_MAP:
if module and validator_name == name:
return validator_cls
# we always return something.
raise ValueError(' missing validator for {validator_name!r}')


def get_current_validator():
Expand Down
72 changes: 61 additions & 11 deletions nbformat/validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@
import pprint
import sys
import warnings
from copy import deepcopy

from ipython_genutils.importstring import import_item
from .json_compat import get_current_validator, ValidationError
from .reader import get_version, reads
from .corpus.words import generate_corpus_id
from .warnings import MissingIDFieldWarning

validators = {}

Expand Down Expand Up @@ -229,15 +231,68 @@ def better_validation_error(error, version, version_minor):
return NotebookValidationError(error, ref)


def validate(nbdict=None, ref=None, version=None, version_minor=None,
relax_add_props=False, nbjson=None):
def normalize(nbdict, version, version_minor):
"""
EXPERIMENTAL
normalise a notebook prior to validation.
This tries to implement a couple of normalisation steps to standardise
notebooks and make validation easier.
You should in general not rely on this function and make sure the notebooks
that reach nbformat are already in a normal form.
Parameters
----------
nbdict : dict
notebook document
version : int
version_minor : int
Returns
-------
changes : int
number of changes in the notebooks
notebook : dict
deep-copy of the original object with relevant changes.
"""
nbdict = deepcopy(nbdict)
return normalize(deepcopy(nbdict))

def _normalize(nbdict, version, version_minor):
changes = 0

if version >= 4 and version_minor >= 5:
# if we support cell ids ensure default ids are provided
for cell in nbdict["cells"]:
if "id" not in cell:
changes +=1
warnings.warn(
"Code cell is missing an id field, this will become"
"an error in future nbformat versions. you may want to use"
"`.normalize()` on your notebooks before validations",
MissingIDFieldWarning,
stacklevel=3,
)
# Generate cell ids if any are missing
cell['id'] = generate_corpus_id()
return changes, nbdict

def validate(nbdict=None, ref:str=None, version=None, version_minor=None,
relax_add_props=False, nbjson=None) -> None:
"""Checks whether the given notebook dict-like object
conforms to the relevant notebook format schema.
Parameters
----------
ref : optional, str
reference to the subset of the schema we want to validate against.
for example ``"markdown_cell"``, `"code_cell"` ....
Raises ValidationError if not valid.
"""

assert isinstance(ref, str) or ref is None
# backwards compatibility for nbjson argument
if nbdict is not None:
pass
Expand All @@ -257,13 +312,8 @@ def validate(nbdict=None, ref=None, version=None, version_minor=None,
# if ref is specified, and we don't have a version number, assume we're validating against 1.0
if version is None:
version, version_minor = 1, 0

if ref is None and version >= 4 and version_minor >= 5:
# if we support cell ids ensure default ids are provided
for cell in nbdict['cells']:
if 'id' not in cell:
# Generate cell ids if any are missing
cell['id'] = generate_corpus_id()
if ref is None:
_normalize(nbdict)

for error in iter_validate(nbdict, ref=ref, version=version,
version_minor=version_minor,
Expand Down
18 changes: 18 additions & 0 deletions nbformat/warnings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
"""
Warnings that can be emitted by nbformat.
"""


class MissingIDFieldWarning(FutureWarning):
"""
This warning is emitted in the validation step of nbformat as we used to
mutate the structure which is cause signature issues.
This will be turned into an error at later point.
We subclass FutureWarning as we will change the behavior in the future.
"""

pass

0 comments on commit a08c7f4

Please sign in to comment.