From 0251893c243203bee3d0d49e24e4b3c87b5ae595 2011-07-29 22:15:33 From: Brian E. Granger Date: 2011-07-29 22:15:33 Subject: [PATCH] Full versioning added to nbformat. --- diff --git a/IPython/nbformat/current.py b/IPython/nbformat/current.py new file mode 100644 index 0000000..f857124 --- /dev/null +++ b/IPython/nbformat/current.py @@ -0,0 +1,190 @@ +import json +from xml.etree import ElementTree as ET +import re + +from IPython.nbformat import v2 +from IPython.nbformat import v1 + + +current_nbformat = 2 + + +class NBFormatError(Exception): + pass + + +def parse_json(s, **kwargs): + """Parse a string into a (nbformat, dict) tuple.""" + d = json.loads(s, **kwargs) + nbformat = d.get('nbformat',1) + return nbformat, d + + +def parse_xml(s, **kwargs): + """Parse a string into a (nbformat, etree) tuple.""" + root = ET.fromstring(s) + nbformat_e = root.find('nbformat') + if nbformat_e is not None: + nbformat = int(nbformat_e.text) + else: + raise NBFormatError('No nbformat version found') + return nbformat, root + + +def parse_py(s, **kwargs): + """Parse a string into a (nbformat, string) tuple.""" + pattern = r'# (?P\d+)' + m = re.search(pattern,s) + if m is not None: + nbformat = int(m.group('nbformat')) + else: + raise NBFormatError('No nbformat version found') + return nbformat, s + + +def reads_json(s, **kwargs): + """Read a JSON notebook from a string and return the NotebookNode object.""" + nbformat, d = parse_json(s, **kwargs) + if nbformat == 1: + nb = v1.to_notebook_json(d, **kwargs) + nb = v2.convert_to_this_nbformat(nb, orig_version=1) + elif nbformat == 2: + nb = v2.to_notebook_json(d, **kwargs) + else: + raise NBFormatError('Unsupported JSON nbformat version: %i' % nbformat) + return nb + + +def writes_json(nb, **kwargs): + return v2.writes_json(nb, **kwargs) + + +def reads_xml(s, **kwargs): + """Read an XML notebook from a string and return the NotebookNode object.""" + nbformat, root = parse_xml(s, **kwargs) + if nbformat == 2: + nb = v2.to_notebook_xml(root, **kwargs) + else: + raise NBFormatError('Unsupported XML nbformat version: %i' % nbformat) + return nb + + +def writes_xml(nb, **kwargs): + return v2.writes_xml(nb, **kwargs) + + +def reads_py(s, **kwargs): + """Read a .py notebook from a string and return the NotebookNode object.""" + nbformat, s = parse_py(s, **kwargs) + if nbformat == 2: + nb = v2.to_notebook_py(s, **kwargs) + else: + raise NBFormatError('Unsupported PY nbformat version: %i' % nbformat) + return nb + + +def writes_py(nb, **kwargs): + return v2.writes_py(nb, **kwargs) + + +# High level API + + +def reads(s, format, **kwargs): + """Read a notebook from a string and return the NotebookNode object. + + This function properly handles notebooks of any version. The notebook + returned will always be in the current version's format. + + Parameters + ---------- + s : str + The raw string to read the notebook from. + format : ('xml','json','py') + The format that the string is in. + + Returns + ------- + nb : NotebookNode + The notebook that was read. + """ + if format == 'xml': + return reads_xml(s, **kwargs) + elif format == 'json': + return reads_json(s, **kwargs) + elif format == 'py': + return reads_py(s, **kwargs) + else: + raise NBFormatError('Unsupported format: %s' % format) + + +def writes(nb, format, **kwargs): + """Write a notebook to a string in a given format in the current nbformat version. + + This function always writes the notebook in the current nbformat version. + + Parameters + ---------- + nb : NotebookNode + The notebook to write. + format : ('xml','json','py') + The format to write the notebook in. + + Returns + ------- + s : str + The notebook string. + """ + if format == 'xml': + return writes_xml(nb, **kwargs) + elif format == 'json': + return writes_json(nb, **kwargs) + elif format == 'py': + return writes_py(nb, **kwargs) + else: + raise NBFormatError('Unsupported format: %s' % format) + + +def read(fp, format, **kwargs): + """Read a notebook from a file and return the NotebookNode object. + + This function properly handles notebooks of any version. The notebook + returned will always be in the current version's format. + + Parameters + ---------- + fp : file + Any file-like object with a read method. + format : ('xml','json','py') + The format that the string is in. + + Returns + ------- + nb : NotebookNode + The notebook that was read. + """ + return reads(fp.read(), format, **kwargs) + + +def write(nb, fp, format, **kwargs): + """Write a notebook to a file in a given format in the current nbformat version. + + This function always writes the notebook in the current nbformat version. + + Parameters + ---------- + nb : NotebookNode + The notebook to write. + fp : file + Any file-like object with a write method. + format : ('xml','json','py') + The format to write the notebook in. + + Returns + ------- + s : str + The notebook string. + """ + return fp.write(writes(nb, format, **kwargs)) + + diff --git a/IPython/nbformat/v1/__init__.py b/IPython/nbformat/v1/__init__.py new file mode 100644 index 0000000..767e848 --- /dev/null +++ b/IPython/nbformat/v1/__init__.py @@ -0,0 +1,12 @@ + +from .nbbase import ( + NotebookNode, + new_code_cell, new_text_cell, new_notebook +) + +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 .convert import convert_to_this_nbformat + diff --git a/IPython/nbformat/v1/convert.py b/IPython/nbformat/v1/convert.py new file mode 100644 index 0000000..ac9bc81 --- /dev/null +++ b/IPython/nbformat/v1/convert.py @@ -0,0 +1,5 @@ + + +def convert_to_this_nbformat(nb, orig_version=None): + raise ValueError('Cannot convert to v1 notebook format') + diff --git a/IPython/nbformat/v1/nbbase.py b/IPython/nbformat/v1/nbbase.py new file mode 100644 index 0000000..609619b --- /dev/null +++ b/IPython/nbformat/v1/nbbase.py @@ -0,0 +1,53 @@ +"""The basic dict based notebook format.""" + +import pprint +import uuid + +from IPython.utils.ipstruct import Struct + + +class NotebookNode(Struct): + pass + + +def from_dict(d): + if isinstance(d, dict): + newd = NotebookNode() + for k,v in d.items(): + newd[k] = from_dict(v) + return newd + elif isinstance(d, (tuple, list)): + return [from_dict(i) for i in d] + else: + return d + + +def new_code_cell(code=None, prompt_number=None): + """Create a new code cell with input and output""" + cell = NotebookNode() + cell.cell_type = u'code' + if code is not None: + cell.code = unicode(code) + if prompt_number is not None: + cell.prompt_number = int(prompt_number) + return cell + + +def new_text_cell(text=None): + """Create a new text cell.""" + cell = NotebookNode() + if text is not None: + cell.text = unicode(text) + cell.cell_type = u'text' + return cell + + +def new_notebook(cells=None): + """Create a notebook by name, id and a list of worksheets.""" + nb = NotebookNode() + if cells is not None: + nb.cells = cells + else: + nb.cells = [] + return nb + diff --git a/IPython/nbformat/v1/nbjson.py b/IPython/nbformat/v1/nbjson.py new file mode 100644 index 0000000..d2c6013 --- /dev/null +++ b/IPython/nbformat/v1/nbjson.py @@ -0,0 +1,35 @@ +"""Read and write notebooks in JSON format.""" + +from base64 import encodestring +from .rwbase import NotebookReader, NotebookWriter +from .nbbase import from_dict +import json + + +class JSONReader(NotebookReader): + + def reads(self, s, **kwargs): + nb = json.loads(s, **kwargs) + return self.to_notebook(nb, **kwargs) + + def to_notebook(self, d, **kwargs): + """Convert from a raw JSON dict to a nested NotebookNode structure.""" + return from_dict(d) + + +class JSONWriter(NotebookWriter): + + def writes(self, nb, **kwargs): + kwargs['indent'] = 4 + return json.dumps(nb, **kwargs) + + +_reader = JSONReader() +_writer = JSONWriter() + +reads = _reader.reads +read = _reader.read +to_notebook = _reader.to_notebook +write = _writer.write +writes = _writer.writes + diff --git a/IPython/nbformat/v1/rwbase.py b/IPython/nbformat/v1/rwbase.py new file mode 100644 index 0000000..d0a1b1b --- /dev/null +++ b/IPython/nbformat/v1/rwbase.py @@ -0,0 +1,26 @@ +from base64 import encodestring, decodestring + + +class NotebookReader(object): + + def reads(self, s, **kwargs): + """Read a notebook from a string.""" + raise NotImplementedError("loads must be implemented in a subclass") + + def read(self, fp, **kwargs): + """Read a notebook from a file like object""" + return self.reads(fp.read(), **kwargs) + + +class NotebookWriter(object): + + def writes(self, nb, **kwargs): + """Write a notebook to a string.""" + raise NotImplementedError("loads must be implemented in a subclass") + + def write(self, nb, fp, **kwargs): + """Write a notebook to a file like object""" + return fp.write(self.writes(nb,**kwargs)) + + + diff --git a/IPython/nbformat/tests/__init__.py b/IPython/nbformat/v1/tests/__init__.py similarity index 100% rename from IPython/nbformat/tests/__init__.py rename to IPython/nbformat/v1/tests/__init__.py diff --git a/IPython/nbformat/v1/tests/nbexamples.py b/IPython/nbformat/v1/tests/nbexamples.py new file mode 100644 index 0000000..e07ac48 --- /dev/null +++ b/IPython/nbformat/v1/tests/nbexamples.py @@ -0,0 +1,29 @@ +from ..nbbase import ( + NotebookNode, + new_code_cell, new_text_cell, new_notebook +) + + + +nb0 = new_notebook() + +nb0.cells.append(new_text_cell( + text='Some NumPy Examples' +)) + + +nb0.cells.append(new_code_cell( + code='import numpy', + prompt_number=1 +)) + +nb0.cells.append(new_code_cell( + code='a = numpy.random.rand(100)', + prompt_number=2 +)) + +nb0.cells.append(new_code_cell( + code='print a', + prompt_number=3 +)) + diff --git a/IPython/nbformat/tests/test_json.py b/IPython/nbformat/v1/tests/test_json.py similarity index 71% rename from IPython/nbformat/tests/test_json.py rename to IPython/nbformat/v1/tests/test_json.py index 7b7430e..09d1c4e 100644 --- a/IPython/nbformat/tests/test_json.py +++ b/IPython/nbformat/v1/tests/test_json.py @@ -1,7 +1,7 @@ from unittest import TestCase -from IPython.nbformat.nbjson import reads, writes -from IPython.nbformat.tests.nbexamples import nb0 +from ..nbjson import reads, writes +from .nbexamples import nb0 class TestJSON(TestCase): diff --git a/IPython/nbformat/v1/tests/test_nbbase.py b/IPython/nbformat/v1/tests/test_nbbase.py new file mode 100644 index 0000000..19fe6d1 --- /dev/null +++ b/IPython/nbformat/v1/tests/test_nbbase.py @@ -0,0 +1,41 @@ +from unittest import TestCase + +from ..nbbase import ( + NotebookNode, + new_code_cell, new_text_cell, new_notebook +) + +class TestCell(TestCase): + + def test_empty_code_cell(self): + cc = new_code_cell() + self.assertEquals(cc.cell_type,'code') + self.assertEquals('code' not in cc, True) + self.assertEquals('prompt_number' not in cc, True) + + def test_code_cell(self): + cc = new_code_cell(code='a=10', prompt_number=0) + self.assertEquals(cc.code, u'a=10') + self.assertEquals(cc.prompt_number, 0) + + def test_empty_text_cell(self): + tc = new_text_cell() + self.assertEquals(tc.cell_type, 'text') + self.assertEquals('text' not in tc, True) + + def test_text_cell(self): + tc = new_text_cell('hi') + self.assertEquals(tc.text, u'hi') + + +class TestNotebook(TestCase): + + def test_empty_notebook(self): + nb = new_notebook() + self.assertEquals(nb.cells, []) + + def test_notebooke(self): + cells = [new_code_cell(),new_text_cell()] + nb = new_notebook(cells=cells) + self.assertEquals(nb.cells,cells) + diff --git a/IPython/nbformat/v2/__init__.py b/IPython/nbformat/v2/__init__.py new file mode 100644 index 0000000..4f71ce5 --- /dev/null +++ b/IPython/nbformat/v2/__init__.py @@ -0,0 +1,21 @@ + +from .nbbase import ( + NotebookNode, + new_code_cell, new_text_cell, new_notebook, new_output, new_worksheet +) + +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 .nbxml import reads as reads_xml, writes as writes_xml +from .nbxml import reads as read_xml, writes as write_xml +from .nbxml import to_notebook as to_notebook_xml + +from .nbpy import reads as reads_py, writes as writes_py +from .nbpy import reads as read_py, writes as write_py +from .nbpy import to_notebook as to_notebook_py + +from .convert import convert_to_this_nbformat + + diff --git a/IPython/nbformat/v2/convert.py b/IPython/nbformat/v2/convert.py new file mode 100644 index 0000000..7ab5908 --- /dev/null +++ b/IPython/nbformat/v2/convert.py @@ -0,0 +1,20 @@ +from .nbbase import ( + new_code_cell, new_text_cell, new_worksheet, new_notebook, new_output +) + +def convert_to_this_nbformat(nb, orig_version=1): + if orig_version == 1: + newnb = new_notebook() + ws = new_worksheet() + for cell in nb.cells: + if cell.cell_type == 'code': + newcell = new_code_cell(input=cell.get('code'),prompt_number=cell.get('prompt_number')) + elif cell.cell_type == 'text': + newcell = new_text_cell(text=cell.get('text')) + ws.cells.append(newcell) + newnb.worksheets.append(ws) + return newnb + else: + raise ValueError('Cannot convert a notebook from v%s to v2' % orig_version) + + diff --git a/IPython/nbformat/nbbase.py b/IPython/nbformat/v2/nbbase.py similarity index 93% rename from IPython/nbformat/nbbase.py rename to IPython/nbformat/v2/nbbase.py index 3696dc5..df61687 100644 --- a/IPython/nbformat/nbbase.py +++ b/IPython/nbformat/v2/nbbase.py @@ -10,6 +10,18 @@ class NotebookNode(Struct): pass +def from_dict(d): + if isinstance(d, dict): + newd = NotebookNode() + for k,v in d.items(): + newd[k] = from_dict(v) + return newd + elif isinstance(d, (tuple, list)): + return [from_dict(i) for i in d] + else: + return d + + def new_output(output_type=None, output_text=None, output_png=None, output_html=None, output_svg=None, output_latex=None, output_json=None, output_javascript=None): @@ -76,6 +88,7 @@ def new_worksheet(name=None, cells=None): def new_notebook(name=None, id=None, worksheets=None): """Create a notebook by name, id and a list of worksheets.""" nb = NotebookNode() + nb.nbformat = 2 if name is not None: nb.name = unicode(name) if id is None: diff --git a/IPython/nbformat/nbjson.py b/IPython/nbformat/v2/nbjson.py similarity index 88% rename from IPython/nbformat/nbjson.py rename to IPython/nbformat/v2/nbjson.py index e98578d..14e8c92 100644 --- a/IPython/nbformat/nbjson.py +++ b/IPython/nbformat/v2/nbjson.py @@ -1,6 +1,7 @@ """Read and write notebooks in JSON format.""" from base64 import encodestring +from .nbbase import from_dict from .rwbase import NotebookReader, NotebookWriter, base64_decode import json @@ -16,9 +17,12 @@ class JSONReader(NotebookReader): def reads(self, s, **kwargs): nb = json.loads(s, **kwargs) - nb = base64_decode(nb) + nb = self.to_notebook(nb, **kwargs) return nb + def to_notebook(self, d, **kwargs): + return base64_decode(from_dict(d)) + class JSONWriter(NotebookWriter): @@ -33,6 +37,7 @@ _writer = JSONWriter() reads = _reader.reads read = _reader.read +to_notebook = _reader.to_notebook write = _writer.write writes = _writer.writes diff --git a/IPython/nbformat/nbpy.py b/IPython/nbformat/v2/nbpy.py similarity index 90% rename from IPython/nbformat/nbpy.py rename to IPython/nbformat/v2/nbpy.py index bd07820..1c51cf0 100644 --- a/IPython/nbformat/nbpy.py +++ b/IPython/nbformat/v2/nbpy.py @@ -7,16 +7,20 @@ from .nbbase import new_code_cell, new_worksheet, new_notebook class PyReader(NotebookReader): def reads(self, s, **kwargs): + return self.to_notebook(s,**kwargs) + + def to_notebook(self, s, **kwargs): lines = s.splitlines() cells = [] cell_lines = [] for line in lines: if line.startswith(u'# '): + cell_lines = [] + if line.startswith(u'# '): code = u'\n'.join(cell_lines) code = code.strip(u'\n') if code: cells.append(new_code_cell(input=code)) - cell_lines = [] else: cell_lines.append(line) ws = new_worksheet(cells=cells) @@ -28,13 +32,15 @@ class PyWriter(NotebookWriter): def writes(self, nb, **kwargs): lines = [] + lines.extend(['# 2','']) for ws in nb.worksheets: for cell in ws.cells: if cell.cell_type == 'code': input = cell.input lines.extend([u'# ',u'']) lines.extend(input.splitlines()) - lines.append(u'') + lines.extend([u'',u'# ']) + lines.append('') return unicode('\n'.join(lines)) @@ -43,5 +49,7 @@ _writer = PyWriter() reads = _reader.reads read = _reader.read +to_notebook = _reader.to_notebook write = _writer.write writes = _writer.writes + diff --git a/IPython/nbformat/nbxml.py b/IPython/nbformat/v2/nbxml.py similarity index 90% rename from IPython/nbformat/nbxml.py rename to IPython/nbformat/v2/nbxml.py index 2d97864..2d7d7b4 100644 --- a/IPython/nbformat/nbxml.py +++ b/IPython/nbformat/v2/nbxml.py @@ -1,5 +1,6 @@ """Read and write notebook files as XML.""" +from base64 import encodestring, decodestring from xml.etree import ElementTree as ET from .rwbase import NotebookReader, NotebookWriter @@ -51,11 +52,27 @@ def _set_int(nbnode, attr, parent, tag): e.text = unicode(nbnode[attr]) +def _get_binary(e, tag): + sub_e = e.find(tag) + if sub_e is None: + return None + else: + return decodestring(sub_e.text) + + +def _set_binary(nbnode, attr, parent, tag): + if attr in nbnode: + e = ET.SubElement(parent, tag) + e.text = encodestring(nbnode[attr]) + + class XMLReader(NotebookReader): def reads(self, s, **kwargs): root = ET.fromstring(s) + return self.to_notebook(root, **kwargs) + def to_notebook(self, root, **kwargs): nbname = _get_text(root,'name') nbid = _get_text(root,'id') @@ -72,7 +89,7 @@ class XMLReader(NotebookReader): for output_e in cell_e.find('outputs').getiterator('output'): output_type = _get_text(output_e,'output_type') output_text = _get_text(output_e,'text') - output_png = _get_text(output_e,'png') + output_png = _get_binary(output_e,'png') output_svg = _get_text(output_e,'svg') output_html = _get_text(output_e,'html') output_latex = _get_text(output_e,'latex') @@ -103,6 +120,7 @@ class XMLWriter(NotebookWriter): nb_e = ET.Element('notebook') _set_text(nb,'name',nb_e,'name') _set_text(nb,'id',nb_e,'id') + _set_int(nb,'nbformat',nb_e,'nbformat') wss_e = ET.SubElement(nb_e,'worksheets') for ws in nb.worksheets: ws_e = ET.SubElement(wss_e, 'worksheet') @@ -120,7 +138,7 @@ class XMLWriter(NotebookWriter): output_e = ET.SubElement(outputs_e, 'output') _set_text(output,'output_type',output_e,'output_type') _set_text(output,'text',output_e,'text') - _set_text(output,'png',output_e,'png') + _set_binary(output,'png',output_e,'png') _set_text(output,'html',output_e,'html') _set_text(output,'svg',output_e,'svg') _set_text(output,'latex',output_e,'latex') @@ -141,5 +159,7 @@ _writer = XMLWriter() reads = _reader.reads read = _reader.read +to_notebook = _reader.to_notebook write = _writer.write writes = _writer.writes + diff --git a/IPython/nbformat/rwbase.py b/IPython/nbformat/v2/rwbase.py similarity index 60% rename from IPython/nbformat/rwbase.py rename to IPython/nbformat/v2/rwbase.py index 17747c9..0c5432e 100644 --- a/IPython/nbformat/rwbase.py +++ b/IPython/nbformat/v2/rwbase.py @@ -1,23 +1,23 @@ from base64 import encodestring, decodestring - +import pprint def base64_decode(nb): """Base64 encode all bytes objects in the notebook.""" - for ws in nb['worksheets']: - for cell in ws['cells']: - if cell['cell_type'] == 'code': - if cell.get('image/png',''): - cell['image/png'] = bytes(decodestring(cell['image/png'])) + for ws in nb.worksheets: + for cell in ws.cells: + if cell.cell_type == 'code': + if 'png' in cell: + cell.png = bytes(decodestring(cell.png)) return nb def base64_encode(nb): """Base64 decode all binary objects in the notebook.""" - for ws in nb['worksheets']: - for cell in ws['cells']: - if cell['cell_type'] == 'code': - if cell.get('image/png',''): - cell['image/png'] = unicode(encodestring(cell['image/png'])) + for ws in nb.worksheets: + for cell in ws.cells: + if cell.cell_type == 'code': + if 'png' in cell: + cell.png = unicode(encodestring(cell.png)) return nb @@ -29,7 +29,7 @@ class NotebookReader(object): def read(self, fp, **kwargs): """Read a notebook from a file like object""" - return self.loads(fp.read(), **kwargs) + return self.read(fp.read(), **kwargs) class NotebookWriter(object): @@ -40,7 +40,7 @@ class NotebookWriter(object): def write(self, nb, fp, **kwargs): """Write a notebook to a file like object""" - return fp.write(self.dumps(nb,**kwargs)) + return fp.write(self.writes(nb,**kwargs)) diff --git a/IPython/nbformat/v2/tests/__init__.py b/IPython/nbformat/v2/tests/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/IPython/nbformat/v2/tests/__init__.py diff --git a/IPython/nbformat/tests/nbexamples.py b/IPython/nbformat/v2/tests/nbexamples.py similarity index 92% rename from IPython/nbformat/tests/nbexamples.py rename to IPython/nbformat/v2/tests/nbexamples.py index bd6206e..57a3cbb 100644 --- a/IPython/nbformat/tests/nbexamples.py +++ b/IPython/nbformat/v2/tests/nbexamples.py @@ -1,4 +1,4 @@ -from IPython.nbformat.nbbase import ( +from ..nbbase import ( NotebookNode, new_code_cell, new_text_cell, new_worksheet, new_notebook, new_output ) @@ -51,17 +51,23 @@ nb0 = new_notebook( worksheets=[ws, new_worksheet(name='worksheet2')] ) -nb0_py = """# +nb0_py = """# 2 + +# import numpy +# # a = numpy.random.rand(100) +# # print a + +# """ diff --git a/IPython/nbformat/v2/tests/test_json.py b/IPython/nbformat/v2/tests/test_json.py new file mode 100644 index 0000000..d9a582a --- /dev/null +++ b/IPython/nbformat/v2/tests/test_json.py @@ -0,0 +1,15 @@ + +from unittest import TestCase + +from ..nbjson import reads, writes +from .nbexamples import nb0 + + +class TestJSON(TestCase): + + def test_roundtrip(self): + s = writes(nb0) + self.assertEquals(reads(s),nb0) + + + diff --git a/IPython/nbformat/tests/test_nbbase.py b/IPython/nbformat/v2/tests/test_nbbase.py similarity index 93% rename from IPython/nbformat/tests/test_nbbase.py rename to IPython/nbformat/v2/tests/test_nbbase.py index 875f0d2..06607f8 100644 --- a/IPython/nbformat/tests/test_nbbase.py +++ b/IPython/nbformat/v2/tests/test_nbbase.py @@ -1,6 +1,6 @@ from unittest import TestCase -from IPython.nbformat.nbbase import ( +from ..nbbase import ( NotebookNode, new_code_cell, new_text_cell, new_worksheet, new_notebook, new_output ) @@ -53,10 +53,12 @@ class TestNotebook(TestCase): self.assertEquals('id' in nb, True) self.assertEquals(nb.worksheets, []) self.assertEquals('name' not in nb, True) + self.assertEquals(nb.nbformat,2) - def test_notebooke(self): + def test_notebook(self): worksheets = [new_worksheet(),new_worksheet()] nb = new_notebook(name='foo',worksheets=worksheets) self.assertEquals(nb.name,u'foo') self.assertEquals(nb.worksheets,worksheets) + self.assertEquals(nb.nbformat,2) diff --git a/IPython/nbformat/tests/test_nbpy.py b/IPython/nbformat/v2/tests/test_nbpy.py similarity index 72% rename from IPython/nbformat/tests/test_nbpy.py rename to IPython/nbformat/v2/tests/test_nbpy.py index 9fa685b..a51ac42 100644 --- a/IPython/nbformat/tests/test_nbpy.py +++ b/IPython/nbformat/v2/tests/test_nbpy.py @@ -1,12 +1,12 @@ from unittest import TestCase -from IPython.nbformat.nbbase import ( +from ..nbbase import ( NotebookNode, new_code_cell, new_text_cell, new_worksheet, new_notebook ) -from IPython.nbformat.nbpy import reads, writes -from IPython.nbformat.tests.nbexamples import nb0, nb0_py +from ..nbpy import reads, writes +from .nbexamples import nb0, nb0_py class TestPy(TestCase): diff --git a/IPython/nbformat/tests/test_xml.py b/IPython/nbformat/v2/tests/test_xml.py similarity index 85% rename from IPython/nbformat/tests/test_xml.py rename to IPython/nbformat/v2/tests/test_xml.py index 0a1a660..45cc2e1 100644 --- a/IPython/nbformat/tests/test_xml.py +++ b/IPython/nbformat/v2/tests/test_xml.py @@ -1,7 +1,7 @@ from unittest import TestCase -from IPython.nbformat.nbxml import reads, writes -from IPython.nbformat.tests.nbexamples import nb0 +from ..nbxml import reads, writes +from .nbexamples import nb0 import pprint class TestXML(TestCase):