* test/jupyter-test.el: Move all zmq related tests (and code) to
`test/jupyter-zmq-test.el`, add a `zmq` tag to the tests.
* test/test-helper.el (zmq, jupyter-zmq-channel-ioloop)
(jupyter-zmq-channel-ioloop-comm): Remove requires.
(jupyter-test-ioloop-eval-event, jupyter-test-channel-ioloop)
(initialize-instance) [jupyter-echo-client]: Remove uses of ZMQ by using
a `jupyter-mock-comm-layer` for the `kcomm` slot.
(jupyter-test-zmq-sockets): Move to `test/jupyter-zmq-test.el` along with all
related code.
* test/jupyter-zmq-test.el: Add tests moved from `test/jupyter-test.el` and all
related code.
* test/jupyter-server-test.el (jupyter-server): Replace test with one that
takes into account a `jupyter-server`s changed implementation. Before, in
addition to talking to a kernel via the REST API, it managed a set of websocket
connections in a separate process. Now, those websocket connections live in
the current Emacs process.
Ensure that `jupyter-test-with-notebook` uses a `jupyter-server` object by
let binding `jupyter-server-use-zmq` around its call.
(jupyter-server-ioloop-comm): New test with the same body as `jupyter-server`
had before this commit. Skip the test unless `jupyter-server-use-zmq` is
non-nil. Rename `jupyter-server-kernel-comm` to
`jupyter-server-ioloop-kernel-comm`.
The following changes are made:
`jupyter-initialize-connection` -> `jupyter-comm-initialize`
`jupyter-connect-client` -> `jupyter-comm-add-handler`
`jupyter-disconnect-client` -> `jupyter-comm-remove-handler`
`jupyter-comm-client-loop` -> `jupyter-comm-handler-loop`
* README.org: Do it.
* jupyter-channel-ioloop-comm: Do it.
* jupyter-client.el: Do it.
* jupyter-comm-layer.el: Do it.
(jupyter-comm-layer): Rename `clients` slot to `handlers`. Update all uses.
* jupyter-kernel-process-manager.el: Do it.
* jupyter-repl.el: Do it.
* jupyter-server.el: Do it.
* jupyter-zmq-channel-comm.el: Do it.
* test/jupyter-server-test.el: Do it.
* test/jupyter-test.el: Do it.
* README.org: Add notes on behavior when a kernel's language name has spaces
and uppercase characters.
* jupyter-base.el (jupyter-canonicalize-language-string): New function.
* jupyter-client.el (jupyter-kernel-info): Use it.
* jupyter-kernelspec.el (jupyter-available-kernelspecs): Use it.
* ob-jupyter.el (org-babel-jupyter-aliases-from-kernelspecs): Use it.
* test/jupyter-test.el (jupyter-canonicalize-language-string): New test.
Since we are using keyword to represent channels on the client level, use a
plist of channels on the comm layer level instead of channel slots. This allows
us to remove `jupyter-comm-channel` and simplify the relevant code somewhat.
So as to further generalize and separate out the abstract kernel manager class
from its various implementations.
* jupyter-kernel-manager.el (jupyter-meta-kernel): Fix documentation.
(jupyter-kernel-process, jupyter-command-kernel, jupyter-spec-kernel):
Move related functions and methods to `jupyter-kernel-process-manager.el`
(jupyter-kernel-manager-base): Remove class.
(jupyter-kernel-manager): Re-purpose class as the base class of all kernel
managers. The class corresponding to the old functionality is now named
`jupyter-kernel-process-manager`. Move all related functions and methods for
`jupyter-kernel-process-manager` to `jupyter-kernel-process-manager.el`.
* jupyter-kernel-process-manager.el: New file.
* jupyter-repl.el: Require `jupyter-kernel-process-manager` instead of
`jupyter-kernel-manager`.
* jupyter-server.el (jupyter-server-kernel-manager): Inherit from
`jupyter-kernel-manager` instead of `jupyter-kernel-manager-base`.
* test/jupyter-test.el (jupyter-kernel-lifetime)
(jupyter-command-kernel): Use `jupyter-kernel-process-manager` instead of
`jupyter-kernel-manager`.
* test/test-helper.el: Require `jupyter-kernel-process-manager` instead of
`jupyter-kernel-manager`.
See #161
* jupyter-rest-api.el (jupyter-api--delete-cookie):
(jupyter-api-delete-cookies): New functions.
* jupyter-server.el (jupyter-gc-servers): Do it.
* test/jupyter-server-test.el (jupyter-api-delete-cookies): New test.
* jupyter-rest-api.el: Ensure strings are encoded before making HTTP request.
(jupyter-api-http-request): Encode JSON as utf-8.
(jupyter-api-xsrf-header-from-cookies): Ensure header isn't multibyte.
(jupyter-api-authenticate): For the token method, ensure token isn't multibyte.
(jupyter-api-copy-file): Encode string before encoding to base64 for binary content.
(jupyter-api-read-file-content): Decode content as utf-8 when necessary.
* jupyter-tramp.el
(jupyter-tramp-write-region): Ensure only `utf-8` or `binary` coding systems
are used since Jupyter only supports those.
* test/jupyter-tramp-test.el: Update for above changes.
* jupyter-rest-api.el (jupyter-api-content-buffer): New function.
(jupyter-api-insert-model-content): Use it.
* jupyter-tramp.el (jupyter-tramp-file-local-copy): Use it.
* Start notebook on-demand during tests
* Do cleanup of sockets/processes when killing Emacs
* This should work around intermittent core dumps on Travis due to epoll
reconnect attempts.
* Simplify tests by creating and using setup/teardown macros
* jupyter-rest-api.el (jupyter-api-url): Remove.
(jupyter-api--request): Remove. Work moved into `jupyter-api-request`.
(jupyter-api--url-request): Rename to `jupyter-api-url-request`.
Update all callers.
(jupyter-api-add-websocket-headers)
(jupyter-api-construct-endpoint): New functions.
(jupyter-api-request): Use them.
Don't assume "api" prefixes endpoint, update all callers.
(jupyter-api-get-file-model)
(jupyter-api-get-kernel-ws):
Update to account for how query parameters are
passed in `jupyter-api-request`.
* jupyter-server-test: Update tests for changes to `jupyter-api-request`.
(jupyter-api-add-websocket-headers)
(jupyter-api-construct-endpoint): New tests.
squash! jupyter-api-request: Refactor
* jupyter-org-client.el (jupyter-org-request-at-point): Do it.
(org-babel-jupyter-src-block-session): New declare.
* ob-jupyter.el (org-babel-jupyter-session-clients): Add doc about keys.
* test/jupyter-test.el (jupyter-org-request-at-point): New test.
* jupyter-env.el (jupyter-runtime-directory): Remove custom status.
New function definition.
* jupyter-kernel-manager.el (jupyter-write-connection-file):
Use new function.
* ob-jupyter.el (org-babel-jupyter--run-repl):
Remove setting of `jupyter-runtime-directory`.
* test/jupyter-test.el (jupyter-runtime-directory): New test.
This change localizes all `zmq` related functionality to `jupyter-ioloop` and
`jupyter-zmq-*` files.
* jupyter-channel-ioloop-comm.el: Add better commentary.
(jupyter-base): Require.
(jupyter-channel-ioloop-comm): Add `ioloop-class` slot
(initialize-instance [jupyter-channel-ioloop-comm]): Use it.
* jupyter-channel-ioloop.el (jupyter-base, jupyter-zmq-channel): Un-require.
(jupyter-ioloop-session, jupyter-ioloop-channels):
Rename to `jupyter-channel-ioloop-session` `jupyter-channel-ioloop-channels` and
update all callers.
(jupyter-channel-ioloop): Make into an abstract class.
(initialize-instance [jupyter-channel-ioloop]): Re-add
`jupyter-channel-ioloop-add-send-event`. Don't add to
`jupyter-ioloop-post-hook`.
(jupyter-channel-ioloop-recv-messages): Remove.
(jupyter-channel-ioloop--set-session, jupyter-ioloop-start)
(jupyter-channel-ioloop-add-send-event): Doc changes.
(jupyter-channel-ioloop-add-start-channel-event)
(jupyter-channel-ioloop-add-stop-channel-event):
Don't add/remove from the `jupyter-ioloop-poller`.
Now expected to be handled in the `jupyter-channel` subclass.
Update documentation. In addition, for the start-channel event,
do not attempt to add a channel if one doesn't already exist.
* jupyter-ioloop.el
(jupyter-ioloop-add-teardown):
Remove mention of `jupyter-channel-ioloop` behavior.
(jupyter-ioloop-add-arg-type): Update example variable.
(jupyter-ioloop-environment-p): New function.
* jupyter-kernel-manager.el (jupyter-channel): Require.
(jupyter-make-client): Require and use `jupyter-zmq-channel-ioloop`.
(jupyter-start-channels): Use `make-instance`.
(jupyter-interrupt-kernel): Remove `condition-case`. Not needed since
preventing socket blocking is now handled by `jupyter-recv`.
* jupyter-repl.el
(jupyter-connect-repl): Require and use `jupyter-zmq-channel-ioloop`.
* jupyter-zmq-channel-ioloop.el: New file.
* jupyter-zmq-channel.el (jupyter-ioloop-poller-remove)
(jupyter-ioloop-poller-add): New declares.
(jupyter-start-channel):
Add to `jupyter-ioloop-poller` when in `jupyter-ioloop-environment-p`.
(jupyter-stop-channel):
Only disconnect the socket from its endpoint instead of closing it, leave that
up to garbage collection.
Remove from `jupyter-ioloop-poller` when in `jupyter-ioloop-environment-p`.
(jupyter-recv): Handle non-blocking.
* test/jupyter-test.el
(jupyter-zmq-channel): Use non-blocking `zmq-send` since socket is no longer
closed when calling `jupyter-stop-channel`.
(jupyter-ioloop-test-eval-ioloop): Rename to `jupyter-test-ioloop-eval-event`,
update all callers, and move to `test/test-helper.el`.
(jupyter-channel-ioloop-send-event, jupyter-channel-ioloop-stop-channel-event)
(jupyter-channel-ioloop-start-channel-event): Fix tests for variable name
changes. Use `jupyter-test-channel-ioloop`. Update `jupyter-ioloop-poller`,
addition/removal from poller is now done in the `jupyter-channel` subclass by
checking `jupyter-ioloop-environment-p`.
* test/test-helper.el (jupyter-zmq-channel-ioloop): Require.
(initialize-instance [jupyter-echo-client]): Use it.
(jupyter-test-channel-ioloop): New macro.
(jupyter-test-ioloop-eval-event): New function.
* jupyter-channel-ioloop.el (jupyter-zmq-channel): Require.
(jupyter-channel-ioloop-add-start-channel-event): `sync` -> `zmq`
* jupyter-comm-layer (jupyter-comm--channel): Moved from `jupyter-channels.el`.
* jupyter-kernel-manager.el: `sync` -> `zmq`
* jupyter-zmq-channel-comm.el: New file.
* jupyter-channels.el: Mostly renamed to jupyter-zmq-channel.el. The
`jupyter-channel` class was moved to `jupyter-channel.el`. All that remains are
those classes dependent on `zmq`.
* test/jupyter-test.el: `sync` -> `zmq` where appropriate.
Extract `jupyter-channel` class from `jupyter-zmq-channel.el` into its own file
Having the `jupyter-comm-layer` abstraction means we do not need to do so.
* jupyter-base.el (zmq): Un-require.
(jupyter-socket-types): Move to `jupyter-channels.el`.
(jupyter-session): Don't mention zmq in doc string.
(jupyter-available-local-ports, jupyter-make-ssh-tunnel): New functions.
(jupyter-tunnel-connection): Use them.
* jupyter-channel-ioloop-comm.el: New file.
* jupyter-channels.el (jupyter-messages): Un-require.
(jupyter-comm-layer, zmq): New requires.
(jupyter-socket-types): Moved from `jupyter-base.el`.
(jupyter-send, jupyter-recv):
Implementations for `jupyter-session` moved from `jupyter-messages.el`.
(jupyter-sync-channel-comm): `jupyter-comm-layer` implementation for
`jupyter-sync-channel` objects moved from `jupyter-comm-layer.el`.
* jupyter-comm-layer.el (jupyter-channel-ioloop): Un-require.
(jupyter-sync-channel-comm): Move implementation to `jupyter-channels.el`.
(jupyter-ioloop-comm): Move implementation to new file `jupyter-ioloop-comm.el`.
(jupyter-channel-ioloop-comm):
Move implementation to new file `jupyter-channel-ioloop-comm.el`.
* jupyter-ioloop-comm.el: New file.
* jupyter-ioloop.el (zmq): Require.
* jupyter-kernel-manager.el
(jupyter-make-client): Ensure `jupyter-channel-ioloop-comm` is required.
* jupyter-messages.el (jupyter-send)
(jupyter-recv): Moved to `jupyter-channels.el`
* jupyter-repl.el
(jupyter-connect-repl): Ensure `jupyter-channel-ioloop-comm` is required.
* test/jupyter-test.el (jupyter-available-local-ports): New test.
* test/test-helper.el (jupyter-channel-ioloop-comm): New require.