##// END OF EJS Templates
copy nbformat.v3 to v4
MinRK -
Show More
@@ -0,0 +1,74 b''
1 """The main API for the v3 notebook format.
2
3 Authors:
4
5 * Brian Granger
6 """
7
8 #-----------------------------------------------------------------------------
9 # Copyright (C) 2008-2011 The IPython Development Team
10 #
11 # Distributed under the terms of the BSD License. The full license is in
12 # the file COPYING, distributed as part of this software.
13 #-----------------------------------------------------------------------------
14
15 #-----------------------------------------------------------------------------
16 # Imports
17 #-----------------------------------------------------------------------------
18
19 from .nbbase import (
20 NotebookNode,
21 new_code_cell, new_text_cell, new_notebook, new_output, new_worksheet,
22 new_metadata, new_author, new_heading_cell, nbformat, nbformat_minor,
23 nbformat_schema
24 )
25
26 from .nbjson import reads as reads_json, writes as writes_json
27 from .nbjson import reads as read_json, writes as write_json
28 from .nbjson import to_notebook as to_notebook_json
29
30 from .nbpy import reads as reads_py, writes as writes_py
31 from .nbpy import reads as read_py, writes as write_py
32 from .nbpy import to_notebook as to_notebook_py
33
34 from .convert import downgrade, upgrade
35
36 #-----------------------------------------------------------------------------
37 # Code
38 #-----------------------------------------------------------------------------
39
40 def parse_filename(fname):
41 """Parse a notebook filename.
42
43 This function takes a notebook filename and returns the notebook
44 format (json/py) and the notebook name. This logic can be
45 summarized as follows:
46
47 * notebook.ipynb -> (notebook.ipynb, notebook, json)
48 * notebook.json -> (notebook.json, notebook, json)
49 * notebook.py -> (notebook.py, notebook, py)
50 * notebook -> (notebook.ipynb, notebook, json)
51
52 Parameters
53 ----------
54 fname : unicode
55 The notebook filename. The filename can use a specific filename
56 extention (.ipynb, .json, .py) or none, in which case .ipynb will
57 be assumed.
58
59 Returns
60 -------
61 (fname, name, format) : (unicode, unicode, unicode)
62 The filename, notebook name and format.
63 """
64 if fname.endswith(u'.ipynb'):
65 format = u'json'
66 elif fname.endswith(u'.json'):
67 format = u'json'
68 elif fname.endswith(u'.py'):
69 format = u'py'
70 else:
71 fname = fname + u'.ipynb'
72 format = u'json'
73 name = fname.split('.')[0]
74 return fname, name, format
@@ -0,0 +1,90 b''
1 """Code for converting notebooks to and from the v2 format.
2
3 Authors:
4
5 * Brian Granger
6 * Min RK
7 * Jonathan Frederic
8 """
9
10 #-----------------------------------------------------------------------------
11 # Copyright (C) 2008-2011 The IPython Development Team
12 #
13 # Distributed under the terms of the BSD License. The full license is in
14 # the file COPYING, distributed as part of this software.
15 #-----------------------------------------------------------------------------
16
17 #-----------------------------------------------------------------------------
18 # Imports
19 #-----------------------------------------------------------------------------
20
21 from .nbbase import (
22 new_code_cell, new_text_cell, new_worksheet, new_notebook, new_output,
23 nbformat, nbformat_minor
24 )
25
26 from IPython.nbformat import v2
27
28 #-----------------------------------------------------------------------------
29 # Code
30 #-----------------------------------------------------------------------------
31
32 def upgrade(nb, from_version=2, from_minor=0):
33 """Convert a notebook to v3.
34
35 Parameters
36 ----------
37 nb : NotebookNode
38 The Python representation of the notebook to convert.
39 from_version : int
40 The original version of the notebook to convert.
41 from_minor : int
42 The original minor version of the notebook to convert (only relevant for v >= 3).
43 """
44 if from_version == 2:
45 # Mark the original nbformat so consumers know it has been converted.
46 nb.nbformat = nbformat
47 nb.nbformat_minor = nbformat_minor
48
49 nb.orig_nbformat = 2
50 return nb
51 elif from_version == 3:
52 if from_minor != nbformat_minor:
53 nb.orig_nbformat_minor = from_minor
54 nb.nbformat_minor = nbformat_minor
55 return nb
56 else:
57 raise ValueError('Cannot convert a notebook directly from v%s to v3. ' \
58 'Try using the IPython.nbformat.convert module.' % from_version)
59
60
61 def heading_to_md(cell):
62 """turn heading cell into corresponding markdown"""
63 cell.cell_type = "markdown"
64 level = cell.pop('level', 1)
65 cell.source = '#'*level + ' ' + cell.source
66
67
68 def raw_to_md(cell):
69 """let raw passthrough as markdown"""
70 cell.cell_type = "markdown"
71
72
73 def downgrade(nb):
74 """Convert a v3 notebook to v2.
75
76 Parameters
77 ----------
78 nb : NotebookNode
79 The Python representation of the notebook to convert.
80 """
81 if nb.nbformat != 3:
82 return nb
83 nb.nbformat = 2
84 for ws in nb.worksheets:
85 for cell in ws.cells:
86 if cell.cell_type == 'heading':
87 heading_to_md(cell)
88 elif cell.cell_type == 'raw':
89 raw_to_md(cell)
90 return nb No newline at end of file
@@ -0,0 +1,204 b''
1 """The basic dict based notebook format.
2
3 The Python representation of a notebook is a nested structure of
4 dictionary subclasses that support attribute access
5 (IPython.utils.ipstruct.Struct). The functions in this module are merely
6 helpers to build the structs in the right form.
7 """
8
9 # Copyright (c) IPython Development Team.
10 # Distributed under the terms of the Modified BSD License.
11
12 import pprint
13 import uuid
14
15 from IPython.utils.ipstruct import Struct
16 from IPython.utils.py3compat import cast_unicode, unicode_type
17
18 #-----------------------------------------------------------------------------
19 # Code
20 #-----------------------------------------------------------------------------
21
22 # Change this when incrementing the nbformat version
23 nbformat = 3
24 nbformat_minor = 0
25 nbformat_schema = 'v3.withref.json'
26
27 class NotebookNode(Struct):
28 pass
29
30
31 def from_dict(d):
32 if isinstance(d, dict):
33 newd = NotebookNode()
34 for k,v in d.items():
35 newd[k] = from_dict(v)
36 return newd
37 elif isinstance(d, (tuple, list)):
38 return [from_dict(i) for i in d]
39 else:
40 return d
41
42
43 def new_output(output_type, output_text=None, output_png=None,
44 output_html=None, output_svg=None, output_latex=None, output_json=None,
45 output_javascript=None, output_jpeg=None, prompt_number=None,
46 ename=None, evalue=None, traceback=None, stream=None, metadata=None):
47 """Create a new output, to go in the ``cell.outputs`` list of a code cell.
48 """
49 output = NotebookNode()
50 output.output_type = unicode_type(output_type)
51
52 if metadata is None:
53 metadata = {}
54 if not isinstance(metadata, dict):
55 raise TypeError("metadata must be dict")
56 output.metadata = metadata
57
58 if output_type != 'pyerr':
59 if output_text is not None:
60 output.text = cast_unicode(output_text)
61 if output_png is not None:
62 output.png = cast_unicode(output_png)
63 if output_jpeg is not None:
64 output.jpeg = cast_unicode(output_jpeg)
65 if output_html is not None:
66 output.html = cast_unicode(output_html)
67 if output_svg is not None:
68 output.svg = cast_unicode(output_svg)
69 if output_latex is not None:
70 output.latex = cast_unicode(output_latex)
71 if output_json is not None:
72 output.json = cast_unicode(output_json)
73 if output_javascript is not None:
74 output.javascript = cast_unicode(output_javascript)
75
76 if output_type == u'pyout':
77 if prompt_number is not None:
78 output.prompt_number = int(prompt_number)
79
80 if output_type == u'pyerr':
81 if ename is not None:
82 output.ename = cast_unicode(ename)
83 if evalue is not None:
84 output.evalue = cast_unicode(evalue)
85 if traceback is not None:
86 output.traceback = [cast_unicode(frame) for frame in list(traceback)]
87
88 if output_type == u'stream':
89 output.stream = 'stdout' if stream is None else cast_unicode(stream)
90
91 return output
92
93
94 def new_code_cell(input=None, prompt_number=None, outputs=None,
95 language=u'python', collapsed=False, metadata=None):
96 """Create a new code cell with input and output"""
97 cell = NotebookNode()
98 cell.cell_type = u'code'
99 if language is not None:
100 cell.language = cast_unicode(language)
101 if input is not None:
102 cell.input = cast_unicode(input)
103 if prompt_number is not None:
104 cell.prompt_number = int(prompt_number)
105 if outputs is None:
106 cell.outputs = []
107 else:
108 cell.outputs = outputs
109 if collapsed is not None:
110 cell.collapsed = bool(collapsed)
111 cell.metadata = NotebookNode(metadata or {})
112
113 return cell
114
115 def new_text_cell(cell_type, source=None, rendered=None, metadata=None):
116 """Create a new text cell."""
117 cell = NotebookNode()
118 # VERSIONHACK: plaintext -> raw
119 # handle never-released plaintext name for raw cells
120 if cell_type == 'plaintext':
121 cell_type = 'raw'
122 if source is not None:
123 cell.source = cast_unicode(source)
124 if rendered is not None:
125 cell.rendered = cast_unicode(rendered)
126 cell.metadata = NotebookNode(metadata or {})
127 cell.cell_type = cell_type
128 return cell
129
130
131 def new_heading_cell(source=None, rendered=None, level=1, metadata=None):
132 """Create a new section cell with a given integer level."""
133 cell = NotebookNode()
134 cell.cell_type = u'heading'
135 if source is not None:
136 cell.source = cast_unicode(source)
137 if rendered is not None:
138 cell.rendered = cast_unicode(rendered)
139 cell.level = int(level)
140 cell.metadata = NotebookNode(metadata or {})
141 return cell
142
143
144 def new_worksheet(name=None, cells=None, metadata=None):
145 """Create a worksheet by name with with a list of cells."""
146 ws = NotebookNode()
147 if name is not None:
148 ws.name = cast_unicode(name)
149 if cells is None:
150 ws.cells = []
151 else:
152 ws.cells = list(cells)
153 ws.metadata = NotebookNode(metadata or {})
154 return ws
155
156
157 def new_notebook(name=None, metadata=None, worksheets=None):
158 """Create a notebook by name, id and a list of worksheets."""
159 nb = NotebookNode()
160 nb.nbformat = nbformat
161 nb.nbformat_minor = nbformat_minor
162 if worksheets is None:
163 nb.worksheets = []
164 else:
165 nb.worksheets = list(worksheets)
166 if metadata is None:
167 nb.metadata = new_metadata()
168 else:
169 nb.metadata = NotebookNode(metadata)
170 if name is not None:
171 nb.metadata.name = cast_unicode(name)
172 return nb
173
174
175 def new_metadata(name=None, authors=None, license=None, created=None,
176 modified=None, gistid=None):
177 """Create a new metadata node."""
178 metadata = NotebookNode()
179 if name is not None:
180 metadata.name = cast_unicode(name)
181 if authors is not None:
182 metadata.authors = list(authors)
183 if created is not None:
184 metadata.created = cast_unicode(created)
185 if modified is not None:
186 metadata.modified = cast_unicode(modified)
187 if license is not None:
188 metadata.license = cast_unicode(license)
189 if gistid is not None:
190 metadata.gistid = cast_unicode(gistid)
191 return metadata
192
193 def new_author(name=None, email=None, affiliation=None, url=None):
194 """Create a new author."""
195 author = NotebookNode()
196 if name is not None:
197 author.name = cast_unicode(name)
198 if email is not None:
199 author.email = cast_unicode(email)
200 if affiliation is not None:
201 author.affiliation = cast_unicode(affiliation)
202 if url is not None:
203 author.url = cast_unicode(url)
204 return author
@@ -0,0 +1,71 b''
1 """Read and write notebooks in JSON format.
2
3 Authors:
4
5 * Brian Granger
6 """
7
8 #-----------------------------------------------------------------------------
9 # Copyright (C) 2008-2011 The IPython Development Team
10 #
11 # Distributed under the terms of the BSD License. The full license is in
12 # the file COPYING, distributed as part of this software.
13 #-----------------------------------------------------------------------------
14
15 #-----------------------------------------------------------------------------
16 # Imports
17 #-----------------------------------------------------------------------------
18
19 import copy
20 import json
21
22 from .nbbase import from_dict
23 from .rwbase import (
24 NotebookReader, NotebookWriter, restore_bytes, rejoin_lines, split_lines
25 )
26
27 from IPython.utils import py3compat
28
29 #-----------------------------------------------------------------------------
30 # Code
31 #-----------------------------------------------------------------------------
32
33 class BytesEncoder(json.JSONEncoder):
34 """A JSON encoder that accepts b64 (and other *ascii*) bytestrings."""
35 def default(self, obj):
36 if isinstance(obj, bytes):
37 return obj.decode('ascii')
38 return json.JSONEncoder.default(self, obj)
39
40
41 class JSONReader(NotebookReader):
42
43 def reads(self, s, **kwargs):
44 nb = json.loads(s, **kwargs)
45 nb = self.to_notebook(nb, **kwargs)
46 return nb
47
48 def to_notebook(self, d, **kwargs):
49 return rejoin_lines(from_dict(d))
50
51
52 class JSONWriter(NotebookWriter):
53
54 def writes(self, nb, **kwargs):
55 kwargs['cls'] = BytesEncoder
56 kwargs['indent'] = 1
57 kwargs['sort_keys'] = True
58 kwargs['separators'] = (',',': ')
59 if kwargs.pop('split_lines', True):
60 nb = split_lines(copy.deepcopy(nb))
61 return py3compat.str_to_unicode(json.dumps(nb, **kwargs), 'utf-8')
62
63
64 _reader = JSONReader()
65 _writer = JSONWriter()
66
67 reads = _reader.reads
68 read = _reader.read
69 to_notebook = _reader.to_notebook
70 write = _writer.write
71 writes = _writer.writes
@@ -0,0 +1,188 b''
1 """Base classes and utilities for readers and writers.
2
3 Authors:
4
5 * Brian Granger
6 """
7
8 #-----------------------------------------------------------------------------
9 # Copyright (C) 2008-2011 The IPython Development Team
10 #
11 # Distributed under the terms of the BSD License. The full license is in
12 # the file COPYING, distributed as part of this software.
13 #-----------------------------------------------------------------------------
14
15 #-----------------------------------------------------------------------------
16 # Imports
17 #-----------------------------------------------------------------------------
18
19 from base64 import encodestring, decodestring
20 import pprint
21
22 from IPython.utils import py3compat
23 from IPython.utils.py3compat import str_to_bytes, unicode_type, string_types
24
25 #-----------------------------------------------------------------------------
26 # Code
27 #-----------------------------------------------------------------------------
28
29 def restore_bytes(nb):
30 """Restore bytes of image data from unicode-only formats.
31
32 Base64 encoding is handled elsewhere. Bytes objects in the notebook are
33 always b64-encoded. We DO NOT encode/decode around file formats.
34
35 Note: this is never used
36 """
37 for ws in nb.worksheets:
38 for cell in ws.cells:
39 if cell.cell_type == 'code':
40 for output in cell.outputs:
41 if 'png' in output:
42 output.png = str_to_bytes(output.png, 'ascii')
43 if 'jpeg' in output:
44 output.jpeg = str_to_bytes(output.jpeg, 'ascii')
45 return nb
46
47 # output keys that are likely to have multiline values
48 _multiline_outputs = ['text', 'html', 'svg', 'latex', 'javascript', 'json']
49
50
51 # FIXME: workaround for old splitlines()
52 def _join_lines(lines):
53 """join lines that have been written by splitlines()
54
55 Has logic to protect against `splitlines()`, which
56 should have been `splitlines(True)`
57 """
58 if lines and lines[0].endswith(('\n', '\r')):
59 # created by splitlines(True)
60 return u''.join(lines)
61 else:
62 # created by splitlines()
63 return u'\n'.join(lines)
64
65
66 def rejoin_lines(nb):
67 """rejoin multiline text into strings
68
69 For reversing effects of ``split_lines(nb)``.
70
71 This only rejoins lines that have been split, so if text objects were not split
72 they will pass through unchanged.
73
74 Used when reading JSON files that may have been passed through split_lines.
75 """
76 for ws in nb.worksheets:
77 for cell in ws.cells:
78 if cell.cell_type == 'code':
79 if 'input' in cell and isinstance(cell.input, list):
80 cell.input = _join_lines(cell.input)
81 for output in cell.outputs:
82 for key in _multiline_outputs:
83 item = output.get(key, None)
84 if isinstance(item, list):
85 output[key] = _join_lines(item)
86 else: # text, heading cell
87 for key in ['source', 'rendered']:
88 item = cell.get(key, None)
89 if isinstance(item, list):
90 cell[key] = _join_lines(item)
91 return nb
92
93
94 def split_lines(nb):
95 """split likely multiline text into lists of strings
96
97 For file output more friendly to line-based VCS. ``rejoin_lines(nb)`` will
98 reverse the effects of ``split_lines(nb)``.
99
100 Used when writing JSON files.
101 """
102 for ws in nb.worksheets:
103 for cell in ws.cells:
104 if cell.cell_type == 'code':
105 if 'input' in cell and isinstance(cell.input, string_types):
106 cell.input = cell.input.splitlines(True)
107 for output in cell.outputs:
108 for key in _multiline_outputs:
109 item = output.get(key, None)
110 if isinstance(item, string_types):
111 output[key] = item.splitlines(True)
112 else: # text, heading cell
113 for key in ['source', 'rendered']:
114 item = cell.get(key, None)
115 if isinstance(item, string_types):
116 cell[key] = item.splitlines(True)
117 return nb
118
119 # b64 encode/decode are never actually used, because all bytes objects in
120 # the notebook are already b64-encoded, and we don't need/want to double-encode
121
122 def base64_decode(nb):
123 """Restore all bytes objects in the notebook from base64-encoded strings.
124
125 Note: This is never used
126 """
127 for ws in nb.worksheets:
128 for cell in ws.cells:
129 if cell.cell_type == 'code':
130 for output in cell.outputs:
131 if 'png' in output:
132 if isinstance(output.png, unicode_type):
133 output.png = output.png.encode('ascii')
134 output.png = decodestring(output.png)
135 if 'jpeg' in output:
136 if isinstance(output.jpeg, unicode_type):
137 output.jpeg = output.jpeg.encode('ascii')
138 output.jpeg = decodestring(output.jpeg)
139 return nb
140
141
142 def base64_encode(nb):
143 """Base64 encode all bytes objects in the notebook.
144
145 These will be b64-encoded unicode strings
146
147 Note: This is never used
148 """
149 for ws in nb.worksheets:
150 for cell in ws.cells:
151 if cell.cell_type == 'code':
152 for output in cell.outputs:
153 if 'png' in output:
154 output.png = encodestring(output.png).decode('ascii')
155 if 'jpeg' in output:
156 output.jpeg = encodestring(output.jpeg).decode('ascii')
157 return nb
158
159
160 class NotebookReader(object):
161 """A class for reading notebooks."""
162
163 def reads(self, s, **kwargs):
164 """Read a notebook from a string."""
165 raise NotImplementedError("loads must be implemented in a subclass")
166
167 def read(self, fp, **kwargs):
168 """Read a notebook from a file like object"""
169 nbs = fp.read()
170 if not py3compat.PY3 and not isinstance(nbs, unicode_type):
171 nbs = py3compat.str_to_unicode(nbs)
172 return self.reads(nbs, **kwargs)
173
174
175 class NotebookWriter(object):
176 """A class for writing notebooks."""
177
178 def writes(self, nb, **kwargs):
179 """Write a notebook to a string."""
180 raise NotImplementedError("loads must be implemented in a subclass")
181
182 def write(self, nb, fp, **kwargs):
183 """Write a notebook to a file like object"""
184 nbs = self.writes(nb,**kwargs)
185 if not py3compat.PY3 and not isinstance(nbs, unicode_type):
186 # this branch is likely only taken for JSON on Python 2
187 nbs = py3compat.str_to_unicode(nbs)
188 return fp.write(nbs)
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
@@ -0,0 +1,60 b''
1 # -*- coding: utf8 -*-
2 import io
3 import os
4 import shutil
5 import tempfile
6
7 pjoin = os.path.join
8
9 from ..nbbase import (
10 NotebookNode,
11 new_code_cell, new_text_cell, new_worksheet, new_notebook
12 )
13
14 from ..nbpy import reads, writes, read, write
15 from .nbexamples import nb0, nb0_py
16
17
18 def open_utf8(fname, mode):
19 return io.open(fname, mode=mode, encoding='utf-8')
20
21 class NBFormatTest:
22 """Mixin for writing notebook format tests"""
23
24 # override with appropriate values in subclasses
25 nb0_ref = None
26 ext = None
27 mod = None
28
29 def setUp(self):
30 self.wd = tempfile.mkdtemp()
31
32 def tearDown(self):
33 shutil.rmtree(self.wd)
34
35 def assertNBEquals(self, nba, nbb):
36 self.assertEqual(nba, nbb)
37
38 def test_writes(self):
39 s = self.mod.writes(nb0)
40 if self.nb0_ref:
41 self.assertEqual(s, self.nb0_ref)
42
43 def test_reads(self):
44 s = self.mod.writes(nb0)
45 nb = self.mod.reads(s)
46
47 def test_roundtrip(self):
48 s = self.mod.writes(nb0)
49 self.assertNBEquals(self.mod.reads(s),nb0)
50
51 def test_write_file(self):
52 with open_utf8(pjoin(self.wd, "nb0.%s" % self.ext), 'w') as f:
53 self.mod.write(nb0, f)
54
55 def test_read_file(self):
56 with open_utf8(pjoin(self.wd, "nb0.%s" % self.ext), 'w') as f:
57 self.mod.write(nb0, f)
58
59 with open_utf8(pjoin(self.wd, "nb0.%s" % self.ext), 'r') as f:
60 nb = self.mod.read(f)
@@ -0,0 +1,152 b''
1 # -*- coding: utf-8 -*-
2
3 import os
4 from base64 import encodestring
5
6 from ..nbbase import (
7 NotebookNode,
8 new_code_cell, new_text_cell, new_worksheet, new_notebook, new_output,
9 new_metadata, new_author, new_heading_cell, nbformat, nbformat_minor
10 )
11
12 # some random base64-encoded *text*
13 png = encodestring(os.urandom(5)).decode('ascii')
14 jpeg = encodestring(os.urandom(6)).decode('ascii')
15
16 ws = new_worksheet(name='worksheet1')
17
18 ws.cells.append(new_text_cell(
19 u'html',
20 source='Some NumPy Examples',
21 rendered='Some NumPy Examples'
22 ))
23
24
25 ws.cells.append(new_code_cell(
26 input='import numpy',
27 prompt_number=1,
28 collapsed=False
29 ))
30
31 ws.cells.append(new_text_cell(
32 u'markdown',
33 source='A random array',
34 rendered='A random array'
35 ))
36
37 ws.cells.append(new_text_cell(
38 u'raw',
39 source='A random array',
40 ))
41
42 ws.cells.append(new_heading_cell(
43 u'My Heading',
44 level=2
45 ))
46
47 ws.cells.append(new_code_cell(
48 input='a = numpy.random.rand(100)',
49 prompt_number=2,
50 collapsed=True
51 ))
52 ws.cells.append(new_code_cell(
53 input='a = 10\nb = 5\n',
54 prompt_number=3,
55 ))
56 ws.cells.append(new_code_cell(
57 input='a = 10\nb = 5',
58 prompt_number=4,
59 ))
60
61 ws.cells.append(new_code_cell(
62 input=u'print "ünîcødé"',
63 prompt_number=3,
64 collapsed=False,
65 outputs=[new_output(
66 output_type=u'pyout',
67 output_text=u'<array a>',
68 output_html=u'The HTML rep',
69 output_latex=u'$a$',
70 output_png=png,
71 output_jpeg=jpeg,
72 output_svg=u'<svg>',
73 output_json=u'json data',
74 output_javascript=u'var i=0;',
75 prompt_number=3
76 ),new_output(
77 output_type=u'display_data',
78 output_text=u'<array a>',
79 output_html=u'The HTML rep',
80 output_latex=u'$a$',
81 output_png=png,
82 output_jpeg=jpeg,
83 output_svg=u'<svg>',
84 output_json=u'json data',
85 output_javascript=u'var i=0;'
86 ),new_output(
87 output_type=u'pyerr',
88 ename=u'NameError',
89 evalue=u'NameError was here',
90 traceback=[u'frame 0', u'frame 1', u'frame 2']
91 ),new_output(
92 output_type=u'stream',
93 output_text='foo\rbar\r\n'
94 ),new_output(
95 output_type=u'stream',
96 stream='stderr',
97 output_text='\rfoo\rbar\n'
98 )]
99 ))
100
101 authors = [new_author(name='Bart Simpson',email='bsimpson@fox.com',
102 affiliation=u'Fox',url=u'http://www.fox.com')]
103 md = new_metadata(name=u'My Notebook',license=u'BSD',created=u'8601_goes_here',
104 modified=u'8601_goes_here',gistid=u'21341231',authors=authors)
105
106 nb0 = new_notebook(
107 worksheets=[ws, new_worksheet(name='worksheet2')],
108 metadata=md
109 )
110
111 nb0_py = u"""# -*- coding: utf-8 -*-
112 # <nbformat>%i.%i</nbformat>
113
114 # <htmlcell>
115
116 # Some NumPy Examples
117
118 # <codecell>
119
120 import numpy
121
122 # <markdowncell>
123
124 # A random array
125
126 # <rawcell>
127
128 # A random array
129
130 # <headingcell level=2>
131
132 # My Heading
133
134 # <codecell>
135
136 a = numpy.random.rand(100)
137
138 # <codecell>
139
140 a = 10
141 b = 5
142
143 # <codecell>
144
145 a = 10
146 b = 5
147
148 # <codecell>
149
150 print "ünîcødé"
151
152 """ % (nbformat, nbformat_minor)
@@ -0,0 +1,68 b''
1 import pprint
2 from base64 import decodestring
3 from unittest import TestCase
4
5 from IPython.utils.py3compat import unicode_type
6 from ..nbjson import reads, writes
7 from .. import nbjson
8 from .nbexamples import nb0
9
10 from . import formattest
11
12 from .nbexamples import nb0
13
14
15 class TestJSON(formattest.NBFormatTest, TestCase):
16
17 nb0_ref = None
18 ext = 'ipynb'
19 mod = nbjson
20
21 def test_roundtrip_nosplit(self):
22 """Ensure that multiline blobs are still readable"""
23 # ensures that notebooks written prior to splitlines change
24 # are still readable.
25 s = writes(nb0, split_lines=False)
26 self.assertEqual(nbjson.reads(s),nb0)
27
28 def test_roundtrip_split(self):
29 """Ensure that splitting multiline blocks is safe"""
30 # This won't differ from test_roundtrip unless the default changes
31 s = writes(nb0, split_lines=True)
32 self.assertEqual(nbjson.reads(s),nb0)
33
34 def test_read_png(self):
35 """PNG output data is b64 unicode"""
36 s = writes(nb0)
37 nb1 = nbjson.reads(s)
38 found_png = False
39 for cell in nb1.worksheets[0].cells:
40 if not 'outputs' in cell:
41 continue
42 for output in cell.outputs:
43 if 'png' in output:
44 found_png = True
45 pngdata = output['png']
46 self.assertEqual(type(pngdata), unicode_type)
47 # test that it is valid b64 data
48 b64bytes = pngdata.encode('ascii')
49 raw_bytes = decodestring(b64bytes)
50 assert found_png, "never found png output"
51
52 def test_read_jpeg(self):
53 """JPEG output data is b64 unicode"""
54 s = writes(nb0)
55 nb1 = nbjson.reads(s)
56 found_jpeg = False
57 for cell in nb1.worksheets[0].cells:
58 if not 'outputs' in cell:
59 continue
60 for output in cell.outputs:
61 if 'jpeg' in output:
62 found_jpeg = True
63 jpegdata = output['jpeg']
64 self.assertEqual(type(jpegdata), unicode_type)
65 # test that it is valid b64 data
66 b64bytes = jpegdata.encode('ascii')
67 raw_bytes = decodestring(b64bytes)
68 assert found_jpeg, "never found jpeg output"
@@ -0,0 +1,155 b''
1 from unittest import TestCase
2
3 from ..nbbase import (
4 NotebookNode,
5 new_code_cell, new_text_cell, new_worksheet, new_notebook, new_output,
6 new_author, new_metadata, new_heading_cell, nbformat
7 )
8
9 class TestCell(TestCase):
10
11 def test_empty_code_cell(self):
12 cc = new_code_cell()
13 self.assertEqual(cc.cell_type,u'code')
14 self.assertEqual(u'input' not in cc, True)
15 self.assertEqual(u'prompt_number' not in cc, True)
16 self.assertEqual(cc.outputs, [])
17 self.assertEqual(cc.collapsed, False)
18
19 def test_code_cell(self):
20 cc = new_code_cell(input='a=10', prompt_number=0, collapsed=True)
21 cc.outputs = [new_output(output_type=u'pyout',
22 output_svg=u'foo',output_text=u'10',prompt_number=0)]
23 self.assertEqual(cc.input, u'a=10')
24 self.assertEqual(cc.prompt_number, 0)
25 self.assertEqual(cc.language, u'python')
26 self.assertEqual(cc.outputs[0].svg, u'foo')
27 self.assertEqual(cc.outputs[0].text, u'10')
28 self.assertEqual(cc.outputs[0].prompt_number, 0)
29 self.assertEqual(cc.collapsed, True)
30
31 def test_pyerr(self):
32 o = new_output(output_type=u'pyerr', ename=u'NameError',
33 evalue=u'Name not found', traceback=[u'frame 0', u'frame 1', u'frame 2']
34 )
35 self.assertEqual(o.output_type, u'pyerr')
36 self.assertEqual(o.ename, u'NameError')
37 self.assertEqual(o.evalue, u'Name not found')
38 self.assertEqual(o.traceback, [u'frame 0', u'frame 1', u'frame 2'])
39
40 def test_empty_html_cell(self):
41 tc = new_text_cell(u'html')
42 self.assertEqual(tc.cell_type, u'html')
43 self.assertEqual(u'source' not in tc, True)
44 self.assertEqual(u'rendered' not in tc, True)
45
46 def test_html_cell(self):
47 tc = new_text_cell(u'html', 'hi', 'hi')
48 self.assertEqual(tc.source, u'hi')
49 self.assertEqual(tc.rendered, u'hi')
50
51 def test_empty_markdown_cell(self):
52 tc = new_text_cell(u'markdown')
53 self.assertEqual(tc.cell_type, u'markdown')
54 self.assertEqual(u'source' not in tc, True)
55 self.assertEqual(u'rendered' not in tc, True)
56
57 def test_markdown_cell(self):
58 tc = new_text_cell(u'markdown', 'hi', 'hi')
59 self.assertEqual(tc.source, u'hi')
60 self.assertEqual(tc.rendered, u'hi')
61
62 def test_empty_raw_cell(self):
63 tc = new_text_cell(u'raw')
64 self.assertEqual(tc.cell_type, u'raw')
65 self.assertEqual(u'source' not in tc, True)
66 self.assertEqual(u'rendered' not in tc, True)
67
68 def test_raw_cell(self):
69 tc = new_text_cell(u'raw', 'hi', 'hi')
70 self.assertEqual(tc.source, u'hi')
71 self.assertEqual(tc.rendered, u'hi')
72
73 def test_empty_heading_cell(self):
74 tc = new_heading_cell()
75 self.assertEqual(tc.cell_type, u'heading')
76 self.assertEqual(u'source' not in tc, True)
77 self.assertEqual(u'rendered' not in tc, True)
78
79 def test_heading_cell(self):
80 tc = new_heading_cell(u'hi', u'hi', level=2)
81 self.assertEqual(tc.source, u'hi')
82 self.assertEqual(tc.rendered, u'hi')
83 self.assertEqual(tc.level, 2)
84
85
86 class TestWorksheet(TestCase):
87
88 def test_empty_worksheet(self):
89 ws = new_worksheet()
90 self.assertEqual(ws.cells,[])
91 self.assertEqual(u'name' not in ws, True)
92
93 def test_worksheet(self):
94 cells = [new_code_cell(), new_text_cell(u'html')]
95 ws = new_worksheet(cells=cells,name=u'foo')
96 self.assertEqual(ws.cells,cells)
97 self.assertEqual(ws.name,u'foo')
98
99 class TestNotebook(TestCase):
100
101 def test_empty_notebook(self):
102 nb = new_notebook()
103 self.assertEqual(nb.worksheets, [])
104 self.assertEqual(nb.metadata, NotebookNode())
105 self.assertEqual(nb.nbformat,nbformat)
106
107 def test_notebook(self):
108 worksheets = [new_worksheet(),new_worksheet()]
109 metadata = new_metadata(name=u'foo')
110 nb = new_notebook(metadata=metadata,worksheets=worksheets)
111 self.assertEqual(nb.metadata.name,u'foo')
112 self.assertEqual(nb.worksheets,worksheets)
113 self.assertEqual(nb.nbformat,nbformat)
114
115 def test_notebook_name(self):
116 worksheets = [new_worksheet(),new_worksheet()]
117 nb = new_notebook(name='foo',worksheets=worksheets)
118 self.assertEqual(nb.metadata.name,u'foo')
119 self.assertEqual(nb.worksheets,worksheets)
120 self.assertEqual(nb.nbformat,nbformat)
121
122 class TestMetadata(TestCase):
123
124 def test_empty_metadata(self):
125 md = new_metadata()
126 self.assertEqual(u'name' not in md, True)
127 self.assertEqual(u'authors' not in md, True)
128 self.assertEqual(u'license' not in md, True)
129 self.assertEqual(u'saved' not in md, True)
130 self.assertEqual(u'modified' not in md, True)
131 self.assertEqual(u'gistid' not in md, True)
132
133 def test_metadata(self):
134 authors = [new_author(name='Bart Simpson',email='bsimpson@fox.com')]
135 md = new_metadata(name=u'foo',license=u'BSD',created=u'today',
136 modified=u'now',gistid=u'21341231',authors=authors)
137 self.assertEqual(md.name, u'foo')
138 self.assertEqual(md.license, u'BSD')
139 self.assertEqual(md.created, u'today')
140 self.assertEqual(md.modified, u'now')
141 self.assertEqual(md.gistid, u'21341231')
142 self.assertEqual(md.authors, authors)
143
144 class TestOutputs(TestCase):
145 def test_binary_png(self):
146 out = new_output(output_png=b'\x89PNG\r\n\x1a\n', output_type='display_data')
147
148 def test_b64b6tes_png(self):
149 out = new_output(output_png=b'iVBORw0KG', output_type='display_data')
150
151 def test_binary_jpeg(self):
152 out = new_output(output_jpeg=b'\xff\xd8', output_type='display_data')
153
154 def test_b64b6tes_jpeg(self):
155 out = new_output(output_jpeg=b'/9', output_type='display_data')
General Comments 0
You need to be logged in to leave comments. Login now