From 726ce5e19dc141a5d3a7b45f89299d57218b5709 Mon Sep 17 00:00:00 2001 From: Jason Grout Date: Wed, 29 May 2019 08:47:14 -0700 Subject: [PATCH] Make kernel message typing follow the spec more closely. All kernel message replies have a status field. This ensures that reply messages reflect this and handle the abort and error status appropriately. We also simplify typings since we can refer to most content typings using the field accessor. --- packages/completer/src/kernelconnector.ts | 2 +- packages/console/src/history.ts | 12 +- packages/console/src/widget.ts | 8 +- packages/help-extension/src/index.tsx | 5 +- packages/inspector/src/kernelconnector.ts | 2 +- packages/notebook/src/actions.tsx | 4 +- packages/outputarea/src/widget.ts | 8 +- packages/services/src/kernel/default.ts | 17 +- packages/services/src/kernel/future.ts | 2 +- packages/services/src/kernel/kernel.ts | 16 +- packages/services/src/kernel/messages.ts | 540 +++++++++--------- packages/tooltip-extension/src/index.ts | 2 +- .../test-services/src/kernel/ikernel.spec.ts | 2 +- tests/test-services/src/utils.ts | 2 +- 14 files changed, 307 insertions(+), 315 deletions(-) diff --git a/packages/completer/src/kernelconnector.ts b/packages/completer/src/kernelconnector.ts index b406a99a3629..e940cf6b0ad4 100644 --- a/packages/completer/src/kernelconnector.ts +++ b/packages/completer/src/kernelconnector.ts @@ -41,7 +41,7 @@ export class KernelConnector extends DataConnector< return Promise.reject(new Error('No kernel for completion request.')); } - const contents: KernelMessage.ICompleteRequest = { + const contents: KernelMessage.ICompleteRequestMsg['content'] = { code: request.text, cursor_pos: request.offset }; diff --git a/packages/console/src/history.ts b/packages/console/src/history.ts index 28f991a90594..390010270267 100644 --- a/packages/console/src/history.ts +++ b/packages/console/src/history.ts @@ -224,10 +224,12 @@ export class ConsoleHistory implements IConsoleHistory { this._history.length = 0; let last = ''; let current = ''; - for (let i = 0; i < value.content.history.length; i++) { - current = (value.content.history[i] as string[])[2]; - if (current !== last) { - this._history.push((last = current)); + if (value.content.status === 'ok') { + for (let i = 0; i < value.content.history.length; i++) { + current = (value.content.history[i] as string[])[2]; + if (current !== last) { + this._history.push((last = current)); + } } } // Reset the history navigation cursor back to the bottom. @@ -360,7 +362,7 @@ export namespace ConsoleHistory { * A namespace for private data. */ namespace Private { - export const initialRequest: KernelMessage.IHistoryRequest = { + export const initialRequest: KernelMessage.IHistoryRequestMsg['content'] = { output: false, raw: true, hist_access_type: 'tail', diff --git a/packages/console/src/widget.ts b/packages/console/src/widget.ts index 65c07b07101a..f3d610711074 100644 --- a/packages/console/src/widget.ts +++ b/packages/console/src/widget.ts @@ -646,7 +646,7 @@ export class CodeConsole extends Widget { return; } if (value && value.content.status === 'ok') { - let content = value.content as KernelMessage.IExecuteOkReply; + let content = value.content; // Use deprecated payloads for backwards compatibility. if (content.payload && content.payload.length) { let setNextInput = content.payload.filter(i => { @@ -682,7 +682,11 @@ export class CodeConsole extends Widget { /** * Update the console based on the kernel info. */ - private _handleInfo(info: KernelMessage.IInfoReply): void { + private _handleInfo(info: KernelMessage.IInfoReplyMsg['content']): void { + if (info.status !== 'ok') { + this._banner.model.value.text = 'Error in getting kernel banner'; + return; + } this._banner.model.value.text = info.banner; let lang = info.language_info as nbformat.ILanguageInfoMetadata; this._mimetype = this._mimeTypeService.getMimeTypeByLanguage(lang); diff --git a/packages/help-extension/src/index.tsx b/packages/help-extension/src/index.tsx index d406b3f53d4a..5fb5e30f34f1 100644 --- a/packages/help-extension/src/index.tsx +++ b/packages/help-extension/src/index.tsx @@ -164,7 +164,10 @@ function activate( helpMenu.addGroup(resourcesGroup, 10); // Generate a cache of the kernel help links. - const kernelInfoCache = new Map(); + const kernelInfoCache = new Map< + string, + KernelMessage.IInfoReplyMsg['content'] + >(); serviceManager.sessions.runningChanged.connect((m, sessions) => { // If a new session has been added, it is at the back // of the session list. If one has changed or stopped, diff --git a/packages/inspector/src/kernelconnector.ts b/packages/inspector/src/kernelconnector.ts index 0547cd422756..6d5ec681b977 100644 --- a/packages/inspector/src/kernelconnector.ts +++ b/packages/inspector/src/kernelconnector.ts @@ -41,7 +41,7 @@ export class KernelConnector extends DataConnector< return Promise.reject(new Error('Inspection fetch requires a kernel.')); } - const contents: KernelMessage.IInspectRequest = { + const contents: KernelMessage.IInspectRequestMsg['content'] = { code: request.text, cursor_pos: request.offset, detail_level: 0 diff --git a/packages/notebook/src/actions.tsx b/packages/notebook/src/actions.tsx index 41e3c48da52e..3c1733ab633e 100644 --- a/packages/notebook/src/actions.tsx +++ b/packages/notebook/src/actions.tsx @@ -1488,7 +1488,7 @@ namespace Private { } if (reply.content.status === 'ok') { - const content = reply.content as KernelMessage.IExecuteOkReply; + const content = reply.content; if (content.payload && content.payload.length) { handlePayload(content, notebook, cell); @@ -1532,7 +1532,7 @@ namespace Private { * See [Payloads (DEPRECATED)](https://jupyter-client.readthedocs.io/en/latest/messaging.html#payloads-deprecated). */ function handlePayload( - content: KernelMessage.IExecuteOkReply, + content: KernelMessage.IExecuteReply, notebook: Notebook, cell: Cell ) { diff --git a/packages/outputarea/src/widget.ts b/packages/outputarea/src/widget.ts index 624ea5bf616a..933b004f0e25 100644 --- a/packages/outputarea/src/widget.ts +++ b/packages/outputarea/src/widget.ts @@ -468,7 +468,10 @@ export class OutputArea extends Widget { // is overridden from 'execute_reply' to 'display_data' in order to // render output. let model = this.model; - let content = msg.content as KernelMessage.IExecuteOkReply; + let content = msg.content; + if (content.status !== 'ok') { + return; + } let payload = content && content.payload; if (!payload || !payload.length) { return; @@ -557,7 +560,7 @@ export namespace OutputArea { ) { stopOnError = false; } - let content: KernelMessage.IExecuteRequest = { + let content: KernelMessage.IExecuteRequestMsg['content'] = { code, stop_on_error: stopOnError }; @@ -712,6 +715,7 @@ export class Stdin extends Widget implements IStdin { if ((event as KeyboardEvent).keyCode === 13) { // Enter this._future.sendInputReply({ + status: 'ok', value: input.value }); if (input.type === 'password') { diff --git a/packages/services/src/kernel/default.ts b/packages/services/src/kernel/default.ts index 6c74023de227..cf795fdc3440 100644 --- a/packages/services/src/kernel/default.ts +++ b/packages/services/src/kernel/default.ts @@ -415,6 +415,9 @@ export class DefaultKernel implements Kernel.IKernel { if (this.isDisposed) { throw new Error('Disposed kernel'); } + if (reply.content.status !== 'ok') { + throw new Error('Kernel info reply errored'); + } this._info = reply.content; return reply; } @@ -429,7 +432,7 @@ export class DefaultKernel implements Kernel.IKernel { * received and validated. */ requestComplete( - content: KernelMessage.ICompleteRequest + content: KernelMessage.ICompleteRequestMsg['content'] ): Promise { let msg = KernelMessage.createMessage({ msgType: 'complete_request', @@ -453,7 +456,7 @@ export class DefaultKernel implements Kernel.IKernel { * received and validated. */ requestInspect( - content: KernelMessage.IInspectRequest + content: KernelMessage.IInspectRequestMsg['content'] ): Promise { let msg = KernelMessage.createMessage({ msgType: 'inspect_request', @@ -477,7 +480,7 @@ export class DefaultKernel implements Kernel.IKernel { * received and validated. */ requestHistory( - content: KernelMessage.IHistoryRequest + content: KernelMessage.IHistoryRequestMsg['content'] ): Promise { let msg = KernelMessage.createMessage({ msgType: 'history_request', @@ -507,7 +510,7 @@ export class DefaultKernel implements Kernel.IKernel { * **See also:** [[IExecuteReply]] */ requestExecute( - content: KernelMessage.IExecuteRequest, + content: KernelMessage.IExecuteRequestMsg['content'], disposeOnDone: boolean = true, metadata?: JSONObject ): Kernel.IFuture< @@ -544,7 +547,7 @@ export class DefaultKernel implements Kernel.IKernel { * received and validated. */ requestIsComplete( - content: KernelMessage.IIsCompleteRequest + content: KernelMessage.IIsCompleteRequestMsg['content'] ): Promise { let msg = KernelMessage.createMessage({ msgType: 'is_complete_request', @@ -566,7 +569,7 @@ export class DefaultKernel implements Kernel.IKernel { * received and validated. */ requestCommInfo( - content: KernelMessage.ICommInfoRequest + content: KernelMessage.ICommInfoRequestMsg['content'] ): Promise { let msg = KernelMessage.createMessage({ msgType: 'comm_info_request', @@ -586,7 +589,7 @@ export class DefaultKernel implements Kernel.IKernel { * #### Notes * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#messages-on-the-stdin-router-dealer-sockets). */ - sendInputReply(content: KernelMessage.IInputReply): void { + sendInputReply(content: KernelMessage.IInputReplyMsg['content']): void { if (this.status === 'dead') { throw new Error('Kernel is dead'); } diff --git a/packages/services/src/kernel/future.ts b/packages/services/src/kernel/future.ts index 8c35471c1d6d..f26e0024bf7f 100644 --- a/packages/services/src/kernel/future.ts +++ b/packages/services/src/kernel/future.ts @@ -154,7 +154,7 @@ export class KernelFutureHandler< /** * Send an `input_reply` message. */ - sendInputReply(content: KernelMessage.IInputReply): void { + sendInputReply(content: KernelMessage.IInputReplyMsg['content']): void { this._kernel.sendInputReply(content); } diff --git a/packages/services/src/kernel/kernel.ts b/packages/services/src/kernel/kernel.ts index 9766bc4d1b7c..268ebcf3ded1 100644 --- a/packages/services/src/kernel/kernel.ts +++ b/packages/services/src/kernel/kernel.ts @@ -206,7 +206,7 @@ export namespace Kernel { * received and validated. */ requestComplete( - content: KernelMessage.ICompleteRequest + content: KernelMessage.ICompleteRequestMsg['content'] ): Promise; /** @@ -223,7 +223,7 @@ export namespace Kernel { * received and validated. */ requestInspect( - content: KernelMessage.IInspectRequest + content: KernelMessage.IInspectRequestMsg['content'] ): Promise; /** @@ -240,7 +240,7 @@ export namespace Kernel { * received and validated. */ requestHistory( - content: KernelMessage.IHistoryRequest + content: KernelMessage.IHistoryRequestMsg['content'] ): Promise; /** @@ -265,7 +265,7 @@ export namespace Kernel { * **See also:** [[IExecuteReply]] */ requestExecute( - content: KernelMessage.IExecuteRequest, + content: KernelMessage.IExecuteRequestMsg['content'], disposeOnDone?: boolean, metadata?: JSONObject ): Kernel.IFuture< @@ -287,7 +287,7 @@ export namespace Kernel { * received and validated. */ requestIsComplete( - content: KernelMessage.IIsCompleteRequest + content: KernelMessage.IIsCompleteRequestMsg['content'] ): Promise; /** @@ -304,7 +304,7 @@ export namespace Kernel { * received and validated. */ requestCommInfo( - content: KernelMessage.ICommInfoRequest + content: KernelMessage.ICommInfoRequestMsg['content'] ): Promise; /** @@ -315,7 +315,7 @@ export namespace Kernel { * #### Notes * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#messages-on-the-stdin-router-dealer-sockets). */ - sendInputReply(content: KernelMessage.IInputReply): void; + sendInputReply(content: KernelMessage.IInputReplyMsg['content']): void; /** * Connect to a comm, or create a new one. @@ -830,7 +830,7 @@ export namespace Kernel { /** * Send an `input_reply` message. */ - sendInputReply(content: KernelMessage.IInputReply): void; + sendInputReply(content: KernelMessage.IInputReplyMsg['content']): void; } /** diff --git a/packages/services/src/kernel/messages.ts b/packages/services/src/kernel/messages.ts index 823aaf575797..549ffac16c02 100644 --- a/packages/services/src/kernel/messages.ts +++ b/packages/services/src/kernel/messages.ts @@ -233,34 +233,34 @@ export namespace KernelMessage { */ export interface IMessage { /** - * The message header. + * An optional list of binary buffers. */ - header: IHeader; + buffers?: (ArrayBuffer | ArrayBufferView)[]; /** - * The parent message + * The channel on which the message is transmitted. */ - parent_header: IHeader | {}; + channel: Channel; /** - * Metadata associated with the message. + * The content of the message. */ - metadata: JSONObject; + content: Message['content']; /** - * The content of the message. + * The message header. */ - content: MessageContent; + header: IHeader; /** - * The channel on which the message is transmitted. + * Metadata associated with the message. */ - channel: Channel; + metadata: JSONObject; /** - * An optional list of binary buffers. + * The parent message */ - buffers?: (ArrayBuffer | ArrayBufferView)[]; + parent_header: IHeader | {}; } /** @@ -319,7 +319,9 @@ export namespace KernelMessage { | IStreamMsg | IUpdateDisplayDataMsg; - export type MessageContent = T['content']; + ////////////////////////////////////////////////// + // IOPub Messages + ///////////////////////////////////////////////// /** * A `'stream'` message on the `'iopub'` channel. @@ -478,6 +480,10 @@ export namespace KernelMessage { return msg.header.msg_type === 'clear_output'; } + ////////////////////////////////////////////////// + // Comm Messages + ///////////////////////////////////////////////// + /** * A `'comm_open'` message on the `'iopub'` channel. * @@ -487,53 +493,21 @@ export namespace KernelMessage { T extends 'shell' | 'iopub' = 'iopub' | 'shell' > extends IMessage<'comm_open'> { channel: T; - content: ICommOpen; - } - - /** - * A `'comm_open'` message on the `'iopub'` channel. - * - * See [Comm open](https://jupyter-client.readthedocs.io/en/latest/messaging.html#opening-a-comm). - */ - export interface ICommOpenIOPubMsg extends IIOPubMessage<'comm_open'> { - channel: 'iopub'; - content: ICommOpen; - } - - /** - * A `'comm_open'` message on the `'shell'` channel. - * - * See [Comm open](https://jupyter-client.readthedocs.io/en/latest/messaging.html#opening-a-comm). - */ - export interface ICommOpenShellMsg extends IShellMessage<'comm_open'> { - channel: 'shell'; - content: ICommOpen; - } - - /** - * The content of a `'comm_open'` message. The message can - * be received on the `'iopub'` channel or send on the `'shell'` channel. - * - * See [Comm open](https://jupyter-client.readthedocs.io/en/latest/messaging.html#opening-a-comm). - */ - export interface ICommOpen { - comm_id: string; - target_name: string; - data: JSONObject; - target_module?: string; + content: { + comm_id: string; + target_name: string; + data: JSONObject; + target_module?: string; + }; } /** * Test whether a kernel message is a `'comm_open'` message. */ - export function isCommOpenMsg( - msg: IMessage - ): msg is ICommOpenIOPubMsg | ICommOpenShellMsg { + export function isCommOpenMsg(msg: IMessage): msg is ICommOpenMsg { return msg.header.msg_type === 'comm_open'; } - export type iopubshell = 'iopub' | 'shell'; - /** * A `'comm_close'` message on the `'iopub'` channel. * @@ -543,18 +517,10 @@ export namespace KernelMessage { T extends 'iopub' | 'shell' = 'iopub' | 'shell' > extends IMessage<'comm_close'> { channel: T; - content: ICommClose; - } - - /** - * The content of a `'comm_close'` method. The message can - * be received on the `'iopub'` channel or send on the `'shell'` channel. - * - * See [Comm close](https://jupyter-client.readthedocs.io/en/latest/messaging.html#opening-a-comm). - */ - export interface ICommClose { - comm_id: string; - data: JSONObject; + content: { + comm_id: string; + data: JSONObject; + }; } /** @@ -574,29 +540,72 @@ export namespace KernelMessage { export interface ICommMsgMsg extends IMessage<'comm_msg'> { channel: T; - content: ICommMsg; + content: { + comm_id: string; + data: JSONObject; + }; } /** - * The content of a `'comm_msg'` message. The message can - * be received on the `'iopub'` channel or send on the `'shell'` channel. + * Test whether a kernel message is a `'comm_msg'` message. + */ + export function isCommMsgMsg(msg: IMessage): msg is ICommMsgMsg { + return msg.header.msg_type === 'comm_msg'; + } + + ////////////////////////////////////////////////// + // Shell Messages + ///////////////////////////////////////////////// + + /** + * Reply content indicating a sucessful request. + */ + export interface IReplyOkContent { + status: 'ok'; + } + + /** + * Reply content indicating an error. * - * See [Comm msg](https://jupyter-client.readthedocs.io/en/latest/messaging.html#opening-a-comm). + * See the [Message spec](https://jupyter-client.readthedocs.io/en/latest/messaging.html#request-reply) for details. */ - export interface ICommMsg { - comm_id: string; - data: JSONObject; + export interface IReplyErrorContent { + status: 'error'; + + /** + * Exception name + */ + ename: string; + + /** + * Exception value + */ + evalue: string; + + /** + * Traceback + */ + traceback: string[]; } /** - * Test whether a kernel message is a `'comm_msg'` message. + * Reply content indicating an aborted request. + * + * This is [deprecated](https://jupyter-client.readthedocs.io/en/latest/messaging.html#request-reply) + * in message spec 5.1. Kernels should send an 'error' reply instead. */ - export function isCommMsgMsg( - msg: IMessage - ): msg is ICommMsgMsg<'iopub' | 'shell'> { - return msg.header.msg_type === 'comm_msg'; + export interface IReplyAbortContent { + status: 'abort'; } + /** + * A convenience type for reply content. + * + * This automatically unions the necessary error and abort replies required in + * the [message spec](https://jupyter-client.readthedocs.io/en/latest/messaging.html#request-reply). + */ + type ReplyContent = T | IReplyErrorContent | IReplyAbortContent; + /** * A `'kernel_info_request'` message on the `'shell'` channel. * @@ -615,21 +624,11 @@ export namespace KernelMessage { } /** - * A `'kernel_info_reply'` message on the `'shell'` channel. - * - * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#kernel-info). - */ - export interface IInfoReplyMsg extends IShellMessage<'kernel_info_reply'> { - parent_header: IHeader<'kernel_info_request'>; - content: IInfoReply; - } - - /** - * The kernel info content. + * A `'kernel_info_reply'` message content. * * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#kernel-info). */ - export interface IInfoReply { + export interface IInfoReply extends IReplyOkContent { protocol_version: string; implementation: string; implementation_version: string; @@ -648,6 +647,16 @@ export namespace KernelMessage { nbconverter_exporter?: string; } + /** + * A `'kernel_info_reply'` message on the `'shell'` channel. + * + * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#kernel-info). + */ + export interface IInfoReplyMsg extends IShellMessage<'kernel_info_reply'> { + parent_header: IHeader<'kernel_info_request'>; + content: ReplyContent; + } + /** * A `'complete_request'` message. * @@ -657,23 +666,28 @@ export namespace KernelMessage { */ export interface ICompleteRequestMsg extends IShellMessage<'complete_request'> { - content: ICompleteRequest; + content: { + code: string; + cursor_pos: number; + }; } /** - * The content of a `'complete_request'` message. + * A `'complete_reply'` message content. * * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#completion). * - * **See also:** [[ICompleteReply]], [[IKernel.complete]] + * **See also:** [[ICompleteRequest]], [[IKernel.complete]] */ - export interface ICompleteRequest { - code: string; - cursor_pos: number; + interface ICompleteReply extends IReplyOkContent { + matches: string[]; + cursor_start: number; + cursor_end: number; + metadata: JSONObject; } /** - * A `'complete_reply'` message on the `'stream'` channel. + * A `'complete_reply'` message on the `'shell'` channel. * * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#completion). * @@ -681,13 +695,7 @@ export namespace KernelMessage { */ export interface ICompleteReplyMsg extends IShellMessage<'complete_reply'> { parent_header: IHeader<'complete_request'>; - content: { - matches: string[]; - cursor_start: number; - cursor_end: number; - metadata: JSONObject; - status: 'ok' | 'error'; - }; + content: ReplyContent; } /** @@ -698,24 +706,29 @@ export namespace KernelMessage { * **See also:** [[IInspectReplyMsg]], [[[IKernel.inspect]]] */ export interface IInspectRequestMsg extends IShellMessage<'inspect_request'> { - content: IInspectRequest; + content: { + code: string; + cursor_pos: number; + detail_level: 0 | 1; + }; } /** - * The content of an `'inspect_request'` message. + * A `'inspect_reply'` message content. * * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#introspection). * - * **See also:** [[IInspectReply]], [[[IKernel.inspect]]] + * **See also:** [[IInspectRequest]], [[IKernel.inspect]] */ - export interface IInspectRequest { - code: string; - cursor_pos: number; - detail_level: 0 | 1; + + export interface IInspectReply extends IReplyOkContent { + found: boolean; + data: JSONObject; + metadata: JSONObject; } /** - * A `'inspect_reply'` message on the `'stream'` channel. + * A `'inspect_reply'` message on the `'shell'` channel. * * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#introspection). * @@ -723,12 +736,7 @@ export namespace KernelMessage { */ export interface IInspectReplyMsg extends IShellMessage<'inspect_reply'> { parent_header: IHeader<'inspect_request'>; - content: { - status: 'ok' | 'error'; - found: boolean; - data: JSONObject; - metadata: JSONObject; - }; + content: ReplyContent; } /** @@ -739,14 +747,9 @@ export namespace KernelMessage { * **See also:** [[IHistoryReplyMsg]], [[[IKernel.history]]] */ export interface IHistoryRequestMsg extends IShellMessage<'history_request'> { - content: IHistoryRequest; + content: IHistoryRequestRange | IHistoryRequestSearch | IHistoryRequestTail; } - /** - * The history access settings. - */ - export type HistAccess = 'range' | 'tail' | 'search'; - /** * The content of a `'history_request'` range message. * @@ -764,49 +767,48 @@ export namespace KernelMessage { } /** - * The content of a `'history_request'` tail message. + * The content of a `'history_request'` search message. * * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#history). * * **See also:** [[IHistoryReply]], [[[IKernel.history]]] */ - export interface IHistoryRequestTail { + export interface IHistoryRequestSearch { output: boolean; raw: boolean; - hist_access_type: 'tail'; + hist_access_type: 'search'; n: number; + pattern: string; + unique: boolean; } /** - * The content of a `'history_request'` search message. + * The content of a `'history_request'` tail message. * * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#history). * * **See also:** [[IHistoryReply]], [[[IKernel.history]]] */ - export interface IHistoryRequestSearch { + export interface IHistoryRequestTail { output: boolean; raw: boolean; - hist_access_type: 'search'; + hist_access_type: 'tail'; n: number; - pattern: string; - unique: boolean; } /** - * The content of a `'history_request'` message. + * A `'history_reply'` message content. * * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#history). * - * **See also:** [[IHistoryReply]], [[[IKernel.history]]] + * **See also:** [[IHistoryRequest]], [[IKernel.history]] */ - export type IHistoryRequest = - | IHistoryRequestRange - | IHistoryRequestTail - | IHistoryRequestSearch; + export interface IHistoryReply extends IReplyOkContent { + history: [number, number, string][] | [number, number, [string, string]][]; + } /** - * A `'history_reply'` message on the `'stream'` channel. + * A `'history_reply'` message on the `'shell'` channel. * * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#history). * @@ -814,11 +816,7 @@ export namespace KernelMessage { */ export interface IHistoryReplyMsg extends IShellMessage<'history_reply'> { parent_header: IHeader<'history_request'>; - content: { - history: - | [number, number, string][] - | [number, number, [string, string]][]; - }; + content: ReplyContent; } /** @@ -830,18 +828,9 @@ export namespace KernelMessage { */ export interface IIsCompleteRequestMsg extends IShellMessage<'is_complete_request'> { - content: IIsCompleteRequest; - } - - /** - * The content of an `'is_complete_request'` message. - * - * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#code-completeness). - * - * **See also:** [[IIsCompleteReply]], [[IKernel.isComplete]] - */ - export interface IIsCompleteRequest { - code: string; + content: { + code: string; + }; } /** @@ -854,78 +843,65 @@ export namespace KernelMessage { export interface IIsCompleteReplyMsg extends IShellMessage<'is_complete_reply'> { parent_header: IHeader<'is_complete_request'>; - content: { - status: string; - indent: string; - }; + content: ReplyContent; } /** - * An `execute_request` message on the ` + * An 'incomplete' completion reply */ - export interface IExecuteRequestMsg extends IShellMessage<'execute_request'> { - content: IExecuteRequest; + export interface IIsCompleteReplyIncomplete { + status: 'incomplete'; + indent: string; } /** - * The content of an `'execute_request'` message. - * - * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#execute). - * - * **See also:** [[IExecuteReply]], [[IKernel.execute]] + * A completion reply for completion or invalid states. */ - export interface IExecuteRequest extends IExecuteOptions { - code: string; + export interface IIsCompleteReplyOther { + status: 'complete' | 'invalid' | 'unknown'; } /** - * The options used to configure an execute request. - * - * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#execute). + * An `execute_request` message on the ` */ - export interface IExecuteOptions { - /** - * Whether to execute the code as quietly as possible. - * The default is `false`. - */ - silent?: boolean; + export interface IExecuteRequestMsg extends IShellMessage<'execute_request'> { + content: { + /** + * The code to execute. + */ + code: string; - /** - * Whether to store history of the execution. - * The default `true` if silent is False. - * It is forced to `false ` if silent is `true`. - */ - store_history?: boolean; + /** + * Whether to execute the code as quietly as possible. + * The default is `false`. + */ + silent?: boolean; - /** - * A mapping of names to expressions to be evaluated in the - * kernel's interactive namespace. - */ - user_expressions?: JSONObject; + /** + * Whether to store history of the execution. + * The default `true` if silent is False. + * It is forced to `false ` if silent is `true`. + */ + store_history?: boolean; - /** - * Whether to allow stdin requests. - * The default is `true`. - */ - allow_stdin?: boolean; + /** + * A mapping of names to expressions to be evaluated in the + * kernel's interactive namespace. + */ + user_expressions?: JSONObject; - /** - * Whether to the abort execution queue on an error. - * The default is `false`. - */ - stop_on_error?: boolean; - } + /** + * Whether to allow stdin requests. + * The default is `true`. + */ + allow_stdin?: boolean; - /** - * An `'execute_reply'` message on the `'stream'` channel. - * - * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#execution-results). - * - * **See also:** [[IExecuteRequest]], [[IKernel.execute]] - */ - export interface IExecuteReplyMsg extends IShellMessage<'execute_reply'> { - parent_header: IHeader<'execute_request'>; - content: IExecuteReply; + /** + * Whether to the abort execution queue on an error. + * The default is `false`. + */ + stop_on_error?: boolean; + }; } /** @@ -933,17 +909,21 @@ export namespace KernelMessage { * * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#execution-results). */ - export interface IExecuteReply { - status: 'ok' | 'error' | 'abort'; + export interface IExecuteCount { execution_count: nbformat.ExecutionCount; } + /** + * A convenience type for a base for an execute reply content. + */ + type IExecuteReplyBase = IExecuteCount & IReplyOkContent; + /** * The `'execute_reply'` contents for an `'ok'` status. * * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#execution-results). */ - export interface IExecuteOkReply extends IExecuteReply { + export interface IExecuteReply extends IExecuteReplyBase { /** * A list of payload objects. * Payloads are considered deprecated. @@ -959,25 +939,15 @@ export namespace KernelMessage { } /** - * The `'execute_reply'` contents for an `'error'` status. + * An `'execute_reply'` message on the `'stream'` channel. * * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#execution-results). + * + * **See also:** [[IExecuteRequest]], [[IKernel.execute]] */ - export interface IExecuteErrorReply extends IExecuteReply { - /** - * The exception name. - */ - ename: string; - - /** - * The Exception value. - */ - evalue: string; - - /** - * A list of traceback frames. - */ - traceback: string[]; + export interface IExecuteReplyMsg extends IShellMessage<'execute_reply'> { + parent_header: IHeader<'execute_request'>; + content: ReplyContent & IExecuteCount; } /** @@ -988,95 +958,101 @@ export namespace KernelMessage { } /** - * An `'input_request'` message on the `'stdin'` channel. + * A `'comm_info_request'` message on the `'shell'` channel. * - * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#messages-on-the-stdin-router-dealer-sockets). + * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#comm-info). + * + * **See also:** [[ICommInfoReplyMsg]], [[IKernel.commInfo]] */ - export interface IInputRequestMsg extends IStdinMessage<'input_request'> { - content: IInputRequest; + + export interface ICommInfoRequestMsg + extends IShellMessage<'comm_info_request'> { + content: { + target?: string; + }; } /** - * The content of an `'input_request'` message. + * A `'comm_info_reply'` message content. + * + * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#comm-info). + * + * **See also:** [[ICommInfoRequest]], [[IKernel.commInfo]] */ - export interface IInputRequest { - /** - * The text to show at the prompt. - */ - prompt: string; + export interface ICommInfoReply extends IReplyOkContent { /** - * Whether the request is for a password. - * If so, the frontend shouldn't echo input. + * Mapping of comm ids to target names. */ - password: boolean; + comms: { [commId: string]: { target_name: string } }; } /** - * Test whether a kernel message is an `'input_request'` message. + * A `'comm_info_reply'` message on the `'shell'` channel. + * + * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#comm-info). + * + * **See also:** [[ICommInfoRequestMsg]], [[IKernel.commInfo]] */ - export function isInputRequestMsg(msg: IMessage): msg is IInputRequestMsg { - return msg.header.msg_type === 'input_request'; + export interface ICommInfoReplyMsg extends IShellMessage<'comm_info_reply'> { + parent_header: IHeader<'comm_info_request'>; + content: ReplyContent; } + ////////////////////////////////////////////////// + // Stdin Messages + ///////////////////////////////////////////////// + /** - * An `'input_reply'` message on the `'stdin'` channel. + * An `'input_request'` message on the `'stdin'` channel. * * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#messages-on-the-stdin-router-dealer-sockets). */ - export interface IInputReplyMsg extends IStdinMessage<'input_reply'> { - parent_header: IHeader<'input_request'>; - content: IInputReply; + export interface IInputRequestMsg extends IStdinMessage<'input_request'> { + content: { + /** + * The text to show at the prompt. + */ + prompt: string; + + /** + * Whether the request is for a password. + * If so, the frontend shouldn't echo input. + */ + password: boolean; + }; } /** - * The content of an `'input_reply'` message. - * - * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#messages-on-the-stdin-router-dealer-sockets). - * - * **See also:** [[IKernel.input_reply]] + * Test whether a kernel message is an `'input_request'` message. */ - export interface IInputReply { - value: string; + export function isInputRequestMsg(msg: IMessage): msg is IInputRequestMsg { + return msg.header.msg_type === 'input_request'; } /** - * Test whether a kernel message is an `'input_reply'` message. + * An `'input_reply'` message content. + * + * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#messages-on-the-stdin-router-dealer-sockets). */ - export function isInputReplyMsg(msg: IMessage): msg is IInputReplyMsg { - return msg.header.msg_type === 'input_reply'; - } - - export interface ICommInfoRequestMsg - extends IShellMessage<'comm_info_request'> { - content: ICommInfoRequest; + export interface IInputReply extends IReplyOkContent { + value: string; } /** - * The content of a `'comm_info_request'` message. - * - * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#comm-info). + * An `'input_reply'` message on the `'stdin'` channel. * - * **See also:** [[ICommInfoReply]], [[IKernel.commInfo]] + * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#messages-on-the-stdin-router-dealer-sockets). */ - export interface ICommInfoRequest { - target?: string; + export interface IInputReplyMsg extends IStdinMessage<'input_reply'> { + parent_header: IHeader<'input_request'>; + content: ReplyContent; } /** - * A `'comm_info_reply'` message on the `'stream'` channel. - * - * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#comm-info). - * - * **See also:** [[ICommInfoRequest]], [[IKernel.commInfo]] + * Test whether a kernel message is an `'input_reply'` message. */ - export interface ICommInfoReplyMsg extends IShellMessage<'comm_info_reply'> { - parent_header: IHeader<'comm_info_request'>; - content: { - /** - * Mapping of comm ids to target names. - */ - comms: { [commId: string]: { target_name: string } }; - }; + export function isInputReplyMsg(msg: IMessage): msg is IInputReplyMsg { + return msg.header.msg_type === 'input_reply'; } } diff --git a/packages/tooltip-extension/src/index.ts b/packages/tooltip-extension/src/index.ts index 8d214b27dc1d..c229e3ba0579 100644 --- a/packages/tooltip-extension/src/index.ts +++ b/packages/tooltip-extension/src/index.ts @@ -301,7 +301,7 @@ namespace Private { return Promise.reject(void 0); } - let contents: KernelMessage.IInspectRequest = { + let contents: KernelMessage.IInspectRequestMsg['content'] = { code, cursor_pos: offset, detail_level: detail || 0 diff --git a/tests/test-services/src/kernel/ikernel.spec.ts b/tests/test-services/src/kernel/ikernel.spec.ts index f28a9896fa7a..a2a65e2d9fe7 100644 --- a/tests/test-services/src/kernel/ikernel.spec.ts +++ b/tests/test-services/src/kernel/ikernel.spec.ts @@ -791,7 +791,7 @@ describe('Kernel.IKernel', () => { describe('#requestIsComplete()', () => { it('should resolve the promise', async () => { - const options: KernelMessage.IIsCompleteRequest = { + const options: KernelMessage.IIsCompleteRequestMsg['content'] = { code: 'hello' }; await defaultKernel.requestIsComplete(options); diff --git a/tests/test-services/src/utils.ts b/tests/test-services/src/utils.ts index ef4cbc05b1ee..0d5cae0aae78 100644 --- a/tests/test-services/src/utils.ts +++ b/tests/test-services/src/utils.ts @@ -58,7 +58,7 @@ export function makeSettings( return ServerConnection.makeSettings(settings); } -const EXAMPLE_KERNEL_INFO: KernelMessage.IInfoReply = { +const EXAMPLE_KERNEL_INFO: KernelMessage.IInfoReplyMsg['content'] = { protocol_version: '1', implementation: 'a', implementation_version: '1',