Skip to content

Commit a08c7f4

Browse files
committed
Start working on mutation issues in validate.
Step 1 toward #235
1 parent f101cd2 commit a08c7f4

File tree

3 files changed

+81
-11
lines changed

3 files changed

+81
-11
lines changed

nbformat/json_compat.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ def _validator_for_name(validator_name):
7676
for (name, module, validator_cls) in _VALIDATOR_MAP:
7777
if module and validator_name == name:
7878
return validator_cls
79+
# we always return something.
80+
raise ValueError(' missing validator for {validator_name!r}')
7981

8082

8183
def get_current_validator():

nbformat/validator.py

Lines changed: 61 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@
77
import pprint
88
import sys
99
import warnings
10+
from copy import deepcopy
1011

1112
from ipython_genutils.importstring import import_item
1213
from .json_compat import get_current_validator, ValidationError
1314
from .reader import get_version, reads
1415
from .corpus.words import generate_corpus_id
16+
from .warnings import MissingIDFieldWarning
1517

1618
validators = {}
1719

@@ -229,15 +231,68 @@ def better_validation_error(error, version, version_minor):
229231
return NotebookValidationError(error, ref)
230232

231233

232-
def validate(nbdict=None, ref=None, version=None, version_minor=None,
233-
relax_add_props=False, nbjson=None):
234+
def normalize(nbdict, version, version_minor):
235+
"""
236+
EXPERIMENTAL
237+
238+
normalise a notebook prior to validation.
239+
240+
This tries to implement a couple of normalisation steps to standardise
241+
notebooks and make validation easier.
242+
243+
You should in general not rely on this function and make sure the notebooks
244+
that reach nbformat are already in a normal form.
245+
246+
Parameters
247+
----------
248+
nbdict : dict
249+
notebook document
250+
version : int
251+
version_minor : int
252+
253+
Returns
254+
-------
255+
changes : int
256+
number of changes in the notebooks
257+
notebook : dict
258+
deep-copy of the original object with relevant changes.
259+
260+
"""
261+
nbdict = deepcopy(nbdict)
262+
return normalize(deepcopy(nbdict))
263+
264+
def _normalize(nbdict, version, version_minor):
265+
changes = 0
266+
267+
if version >= 4 and version_minor >= 5:
268+
# if we support cell ids ensure default ids are provided
269+
for cell in nbdict["cells"]:
270+
if "id" not in cell:
271+
changes +=1
272+
warnings.warn(
273+
"Code cell is missing an id field, this will become"
274+
"an error in future nbformat versions. you may want to use"
275+
"`.normalize()` on your notebooks before validations",
276+
MissingIDFieldWarning,
277+
stacklevel=3,
278+
)
279+
# Generate cell ids if any are missing
280+
cell['id'] = generate_corpus_id()
281+
return changes, nbdict
282+
283+
def validate(nbdict=None, ref:str=None, version=None, version_minor=None,
284+
relax_add_props=False, nbjson=None) -> None:
234285
"""Checks whether the given notebook dict-like object
235286
conforms to the relevant notebook format schema.
236287
237-
288+
Parameters
289+
----------
290+
ref : optional, str
291+
reference to the subset of the schema we want to validate against.
292+
for example ``"markdown_cell"``, `"code_cell"` ....
238293
Raises ValidationError if not valid.
239294
"""
240-
295+
assert isinstance(ref, str) or ref is None
241296
# backwards compatibility for nbjson argument
242297
if nbdict is not None:
243298
pass
@@ -257,13 +312,8 @@ def validate(nbdict=None, ref=None, version=None, version_minor=None,
257312
# if ref is specified, and we don't have a version number, assume we're validating against 1.0
258313
if version is None:
259314
version, version_minor = 1, 0
260-
261-
if ref is None and version >= 4 and version_minor >= 5:
262-
# if we support cell ids ensure default ids are provided
263-
for cell in nbdict['cells']:
264-
if 'id' not in cell:
265-
# Generate cell ids if any are missing
266-
cell['id'] = generate_corpus_id()
315+
if ref is None:
316+
_normalize(nbdict)
267317

268318
for error in iter_validate(nbdict, ref=ref, version=version,
269319
version_minor=version_minor,

nbformat/warnings.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
"""
2+
Warnings that can be emitted by nbformat.
3+
"""
4+
5+
6+
class MissingIDFieldWarning(FutureWarning):
7+
"""
8+
9+
This warning is emitted in the validation step of nbformat as we used to
10+
mutate the structure which is cause signature issues.
11+
12+
This will be turned into an error at later point.
13+
14+
We subclass FutureWarning as we will change the behavior in the future.
15+
16+
"""
17+
18+
pass

0 commit comments

Comments
 (0)