Skip to content

Commit 7ad87f3

Browse files
Improves the initialization (#124)
* Improves the initialization * Update jupyter_ydoc/ydoc.py * Review * Fixes tests * Fix nbformat * Fix tests * Improve tests * Lint Co-authored-by: David Brochart <[email protected]>
1 parent 36bfd0a commit 7ad87f3

File tree

4 files changed

+94
-11
lines changed

4 files changed

+94
-11
lines changed

javascript/src/api.ts

+5
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,11 @@ export namespace ISharedNotebook {
345345
* considered on the full document across all cells.
346346
*/
347347
disableDocumentWideUndoRedo?: boolean;
348+
349+
/**
350+
* The language preference for the model.
351+
*/
352+
languagePreference?: string;
348353
}
349354
}
350355

javascript/src/ynotebook.ts

+18-3
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,14 @@ export class YNotebook
7575
const ynotebook = new YNotebook({
7676
disableDocumentWideUndoRedo: options.disableDocumentWideUndoRedo ?? false
7777
});
78-
ynotebook.ymeta.set('metadata', new Y.Map());
78+
const ymetadata = new Y.Map();
79+
ymetadata.set('language_info', { name: options.languagePreference ?? '' });
80+
ymetadata.set('kernelspec', {
81+
name: '',
82+
display_name: ''
83+
});
84+
ynotebook.ymeta.set('metadata', ymetadata);
85+
7986
return ynotebook;
8087
}
8188

@@ -404,7 +411,16 @@ export class YNotebook
404411
if (metadata['orig_nbformat'] !== undefined) {
405412
delete metadata['orig_nbformat'];
406413
}
407-
this.metadata = metadata;
414+
415+
if (!this.metadata) {
416+
const ymetadata = new Y.Map();
417+
for (const [key, value] of Object.entries(metadata)) {
418+
ymetadata.set(key, value);
419+
}
420+
this.ymeta.set('metadata', ymetadata);
421+
} else {
422+
this.metadata = metadata;
423+
}
408424

409425
const useId = value.nbformat === 4 && value.nbformat_minor >= 5;
410426
const ycells = value.cells.map(cell => {
@@ -449,7 +465,6 @@ export class YNotebook
449465

450466
if (metadataEvents) {
451467
const metadataChange = metadataEvents.changes.keys;
452-
453468
const ymetadata = this.ymeta.get('metadata') as Y.Map<any>;
454469
metadataEvents.changes.keys.forEach((change, key) => {
455470
switch (change.action) {

javascript/test/ymodels.spec.ts

+58-5
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ describe('@jupyter/ydoc', () => {
139139

140140
test('should emit all metadata changes', () => {
141141
const notebook = YNotebook.create();
142+
142143
const metadata = {
143144
orig_nbformat: 1,
144145
kernelspec: {
@@ -153,19 +154,58 @@ describe('@jupyter/ydoc', () => {
153154
});
154155
notebook.metadata = metadata;
155156

157+
expect(changes).toHaveLength(3);
158+
expect(changes).toEqual([
159+
{
160+
type: 'remove',
161+
key: 'language_info',
162+
oldValue: { name: '' }
163+
},
164+
{
165+
type: 'change',
166+
key: 'kernelspec',
167+
newValue: metadata.kernelspec,
168+
oldValue: { display_name: '', name: '' }
169+
},
170+
{
171+
type: 'add',
172+
key: 'orig_nbformat',
173+
newValue: metadata.orig_nbformat
174+
}
175+
]);
176+
177+
notebook.dispose();
178+
});
179+
180+
test('should emit all metadata changes on update', () => {
181+
const notebook = YNotebook.create();
182+
183+
const metadata = {
184+
orig_nbformat: 1,
185+
kernelspec: {
186+
display_name: 'python',
187+
name: 'python'
188+
}
189+
};
190+
191+
const changes: IMapChange[] = [];
192+
notebook.metadataChanged.connect((_, c) => {
193+
changes.push(c);
194+
});
195+
notebook.updateMetadata(metadata);
196+
156197
expect(changes).toHaveLength(2);
157198
expect(changes).toEqual([
158199
{
159200
type: 'add',
160201
key: 'orig_nbformat',
161-
newValue: metadata.orig_nbformat,
162-
oldValue: undefined
202+
newValue: metadata.orig_nbformat
163203
},
164204
{
165-
type: 'add',
205+
type: 'change',
166206
key: 'kernelspec',
167207
newValue: metadata.kernelspec,
168-
oldValue: undefined
208+
oldValue: { display_name: '', name: '' }
169209
}
170210
]);
171211

@@ -502,6 +542,7 @@ describe('@jupyter/ydoc', () => {
502542

503543
test('should emit all metadata changes', () => {
504544
const notebook = YNotebook.create();
545+
505546
const metadata = {
506547
collapsed: true,
507548
editable: false,
@@ -514,8 +555,20 @@ describe('@jupyter/ydoc', () => {
514555
});
515556
notebook.metadata = metadata;
516557

517-
expect(changes).toHaveLength(3);
558+
expect(changes).toHaveLength(5);
518559
expect(changes).toEqual([
560+
{
561+
type: 'remove',
562+
key: 'language_info',
563+
newValue: undefined,
564+
oldValue: { name: '' }
565+
},
566+
{
567+
type: 'remove',
568+
key: 'kernelspec',
569+
newValue: undefined,
570+
oldValue: { display_name: '', name: '' }
571+
},
519572
{
520573
type: 'add',
521574
key: 'collapsed',

jupyter_ydoc/ydoc.py

+13-3
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@
1010

1111
from .utils import cast_all
1212

13+
# The default major version of the notebook format.
14+
NBFORMAT_MAJOR_VERSION = 4
15+
# The default minor version of the notebook format.
16+
NBFORMAT_MINOR_VERSION = 5
17+
1318

1419
class YBaseDoc(ABC):
1520
"""
@@ -424,9 +429,14 @@ def set(self, value: Dict) -> None:
424429

425430
# initialize document
426431
self._ycells.extend(t, [self.create_ycell(cell) for cell in cells])
427-
self._ymeta.set(t, "nbformat", nb["nbformat"])
428-
self._ymeta.set(t, "nbformat_minor", nb["nbformat_minor"])
429-
self._ymeta.set(t, "metadata", Y.YMap(nb.get("metadata", {})))
432+
self._ymeta.set(t, "nbformat", nb.get("nbformat", NBFORMAT_MAJOR_VERSION))
433+
self._ymeta.set(t, "nbformat_minor", nb.get("nbformat_minor", NBFORMAT_MINOR_VERSION))
434+
435+
metadata = nb.get("metadata", {})
436+
metadata.setdefault("language_info", {"name": ""})
437+
metadata.setdefault("kernelspec", {"name": "", "display_name": ""})
438+
439+
self._ymeta.set(t, "metadata", Y.YMap(metadata))
430440

431441
def observe(self, callback: Callable[[Any], None]) -> None:
432442
"""

0 commit comments

Comments
 (0)