diff --git a/IPython/nbconvert/exporters/export.py b/IPython/nbconvert/exporters/export.py index e6df098..f342eb4 100644 --- a/IPython/nbconvert/exporters/export.py +++ b/IPython/nbconvert/exporters/export.py @@ -5,7 +5,7 @@ from functools import wraps -from IPython.nbformat.v4 import NotebookNode +from IPython.nbformat import NotebookNode from IPython.utils.decorators import undoc from IPython.utils.py3compat import string_types @@ -29,7 +29,7 @@ def DocDecorator(f): #Set docstring of function f.__doc__ = f.__doc__ + """ - nb : :class:`~{nbnode_mod}.NotebookNode` + nb : :class:`~IPython.nbformat.NotebookNode` The notebook to export. config : config (optional, keyword arg) User configuration instance. @@ -52,7 +52,7 @@ def DocDecorator(f): Notes ----- WARNING: API WILL CHANGE IN FUTURE RELEASES OF NBCONVERT - """.format(nbnode_mod=NotebookNode.__module__) + """ @wraps(f) def decorator(*args, **kwargs): diff --git a/IPython/nbconvert/exporters/exporter.py b/IPython/nbconvert/exporters/exporter.py index 77973ba..a6c00fd 100644 --- a/IPython/nbconvert/exporters/exporter.py +++ b/IPython/nbconvert/exporters/exporter.py @@ -89,7 +89,7 @@ class Exporter(LoggingConfigurable): Parameters ---------- - nb : :class:`~IPython.nbformat.current.NotebookNode` + nb : :class:`~IPython.nbformat.NotebookNode` Notebook node (dict-like with attr-access) resources : dict Additional resources that can be accessed read/write by diff --git a/IPython/nbconvert/exporters/templateexporter.py b/IPython/nbconvert/exporters/templateexporter.py index 53bf36e..8472c93 100644 --- a/IPython/nbconvert/exporters/templateexporter.py +++ b/IPython/nbconvert/exporters/templateexporter.py @@ -199,7 +199,7 @@ class TemplateExporter(Exporter): Parameters ---------- - nb : :class:`~IPython.nbformat.current.NotebookNode` + nb : :class:`~IPython.nbformat.NotebookNode` Notebook node resources : dict Additional resources that can be accessed read/write by diff --git a/IPython/nbformat/__init__.py b/IPython/nbformat/__init__.py index e6b1309..14ce638 100644 --- a/IPython/nbformat/__init__.py +++ b/IPython/nbformat/__init__.py @@ -23,6 +23,7 @@ versions = { from .validator import validate, ValidationError from .converter import convert from . import reader +from .notebooknode import from_dict, NotebookNode from .v4 import ( nbformat as current_nbformat, diff --git a/IPython/nbformat/notebooknode.py b/IPython/nbformat/notebooknode.py new file mode 100644 index 0000000..76e7141 --- /dev/null +++ b/IPython/nbformat/notebooknode.py @@ -0,0 +1,21 @@ +"""NotebookNode - adding attribute access to dicts""" + +from IPython.utils.ipstruct import Struct + +class NotebookNode(Struct): + """A dict-like node with attribute-access""" + pass + +def from_dict(d): + """Convert dict to dict-like NotebookNode + + Recursively converts any dict in the container to a NotebookNode + """ + if isinstance(d, dict): + return NotebookNode({k:from_dict(v) for k,v in d.items()}) + elif isinstance(d, (tuple, list)): + return [from_dict(i) for i in d] + else: + return d + + diff --git a/IPython/nbformat/v4/__init__.py b/IPython/nbformat/v4/__init__.py index 73b53a3..873134f 100644 --- a/IPython/nbformat/v4/__init__.py +++ b/IPython/nbformat/v4/__init__.py @@ -4,15 +4,15 @@ # Distributed under the terms of the Modified BSD License. from .nbbase import ( - NotebookNode, from_dict, nbformat, nbformat_minor, nbformat_schema, new_code_cell, new_markdown_cell, new_notebook, new_output, output_from_msg, ) -from .nbjson import reads as reads_json, writes as writes_json -from .nbjson import reads as read_json, writes as write_json -from .nbjson import to_notebook as to_notebook_json +from .nbjson import reads, writes, to_notebook +reads_json = reads +writes_json = writes +to_notebook_json = to_notebook from .convert import downgrade, upgrade diff --git a/IPython/nbformat/v4/nbbase.py b/IPython/nbformat/v4/nbbase.py index 586f399..1827bf7 100644 --- a/IPython/nbformat/v4/nbbase.py +++ b/IPython/nbformat/v4/nbbase.py @@ -9,7 +9,7 @@ helpers to build the structs in the right form. # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. -from IPython.utils.ipstruct import Struct +from ..notebooknode import from_dict, NotebookNode # Change this when incrementing the nbformat version nbformat = 4 @@ -23,18 +23,6 @@ def validate(node, ref=None): return validate(node, ref=ref, version=nbformat) -class NotebookNode(Struct): - pass - -def from_dict(d): - if isinstance(d, dict): - return NotebookNode({k:from_dict(v) for k,v in d.items()}) - elif isinstance(d, (tuple, list)): - return [from_dict(i) for i in d] - else: - return d - - def new_output(output_type, data=None, **kwargs): """Create a new output, to go in the ``cell.outputs`` list of a code cell.""" output = NotebookNode(output_type=output_type) diff --git a/IPython/nbformat/v4/nbjson.py b/IPython/nbformat/v4/nbjson.py index fdc8a7a..753d49a 100644 --- a/IPython/nbformat/v4/nbjson.py +++ b/IPython/nbformat/v4/nbjson.py @@ -25,12 +25,18 @@ class BytesEncoder(json.JSONEncoder): class JSONReader(NotebookReader): def reads(self, s, **kwargs): + """Read a JSON string into a Notebook object""" nb = json.loads(s, **kwargs) nb = self.to_notebook(nb, **kwargs) return nb def to_notebook(self, d, **kwargs): - nb = rejoin_lines(from_dict(d)) + """Convert a disk-format notebook dict to in-memory NotebookNode + + handles multi-line values as strings, scrubbing of transient values, etc. + """ + nb = from_dict(d) + nb = rejoin_lines(nb) nb = strip_transient(nb) return nb @@ -38,6 +44,7 @@ class JSONReader(NotebookReader): class JSONWriter(NotebookWriter): def writes(self, nb, **kwargs): + """Serialize a NotebookNode object as a JSON string""" kwargs['cls'] = BytesEncoder kwargs['indent'] = 1 kwargs['sort_keys'] = True