Skip to content

Commit 1323459

Browse files
authored
Update the method for determining kernel language (#354)
* Update the method for determining kernel language The previous algorithm for `getNotebookType()` was based on getting the kernel spec out of the current notebook. This is a problem when format is triggered by, for example, `jupyterlab-autosave-on-focus-change`, immediately after notebook creation. In that case, the language is determined to be `null` and errors arise. Now the `onSave()` handler waits for the `sessionContext` to be ready, then `getNotebookType()` gets the same kernel spec info from the session rather than the loaded notebook. * Make metadata access safer at runtime The `!` operator is a type assertion that the attribute is not null, but does nothing at runtime to ensure this is the case. I haven't yet found reproduction steps for this failure, but I encountered a case where accessing `model!.sharedModel` threw an error. This commit adds optional chaining operators, which do provide protection at runtime. * Fall back to session check if metadata is missing `getNotebookType()` has two ways to determine the language. If the metadata check fails, it falls through to the current session check. Previously, if metadata was `null`, the method would return early.
1 parent 9a503ef commit 1323459

File tree

2 files changed

+31
-20
lines changed

2 files changed

+31
-20
lines changed

src/formatter.ts

+30-20
Original file line numberDiff line numberDiff line change
@@ -92,34 +92,44 @@ export class JupyterlabNotebookCodeFormatter extends JupyterlabCodeFormatter {
9292
return codeCells;
9393
}
9494

95-
private getNotebookType() {
95+
private getNotebookType(): string | null {
96+
// If there is no current notebook, there is nothing to do
9697
if (!this.notebookTracker.currentWidget) {
9798
return null;
9899
}
99100

101+
// first, check the notebook's metadata for language info
100102
const metadata =
101-
this.notebookTracker.currentWidget.content.model!.sharedModel.metadata;
102-
103-
if (!metadata) {
104-
return null;
105-
}
103+
this.notebookTracker.currentWidget.content.model?.sharedModel?.metadata;
104+
105+
if (metadata) {
106+
// prefer kernelspec language
107+
if (
108+
metadata.kernelspec &&
109+
metadata.kernelspec.language &&
110+
typeof metadata.kernelspec.language === 'string'
111+
) {
112+
return metadata.kernelspec.language.toLowerCase();
113+
}
106114

107-
// prefer kernelspec language
108-
if (
109-
metadata.kernelspec &&
110-
metadata.kernelspec.language &&
111-
typeof metadata.kernelspec.language === 'string'
112-
) {
113-
return metadata.kernelspec.language.toLowerCase();
115+
// otherwise, check language info code mirror mode
116+
if (metadata.language_info && metadata.language_info.codemirror_mode) {
117+
const mode = metadata.language_info.codemirror_mode;
118+
if (typeof mode === 'string') {
119+
return mode.toLowerCase();
120+
} else if (typeof mode.name === 'string') {
121+
return mode.name.toLowerCase();
122+
}
123+
}
114124
}
115125

116-
// otherwise, check language info code mirror mode
117-
if (metadata.language_info && metadata.language_info.codemirror_mode) {
118-
const mode = metadata.language_info.codemirror_mode;
119-
if (typeof mode === 'string') {
120-
return mode.toLowerCase();
121-
} else if (typeof mode.name === 'string') {
122-
return mode.name.toLowerCase();
126+
// in the absence of metadata, look in the current session's kernel spec
127+
const sessionContext = this.notebookTracker.currentWidget.sessionContext;
128+
const kernelName = sessionContext?.session?.kernel?.name;
129+
if (kernelName) {
130+
const specs = sessionContext.specsManager.specs?.kernelspecs;
131+
if (specs && kernelName in specs) {
132+
return specs[kernelName]!.language;
123133
}
124134
}
125135

src/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ class JupyterLabCodeFormatter
108108
state: DocumentRegistry.SaveState
109109
) {
110110
if (state === 'started' && this.config.formatOnSave) {
111+
await context.sessionContext.ready;
111112
await this.notebookCodeFormatter.formatAllCodeCells(
112113
this.config,
113114
{ saving: true },

0 commit comments

Comments
 (0)