Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Register kernelspecs in private directory #9249

Merged
merged 13 commits into from
Mar 7, 2022
Merged

Conversation

DonJayamanne
Copy link
Contributor

Fixes #9141

@codecov-commenter
Copy link

codecov-commenter commented Mar 6, 2022

Codecov Report

Merging #9249 (7a41768) into main (1ee0f7e) will decrease coverage by 0%.
The diff coverage is 97%.

❗ Current head 7a41768 differs from pull request most recent head 29977d3. Consider uploading reports for the commit 29977d3 to get more accurate results

@@          Coverage Diff          @@
##            main   #9249   +/-   ##
=====================================
- Coverage     71%     71%   -1%     
=====================================
  Files        383     383           
  Lines      24803   24833   +30     
  Branches    3986    3989    +3     
=====================================
+ Hits       17753   17754    +1     
- Misses      5456    5476   +20     
- Partials    1594    1603    +9     
Impacted Files Coverage Δ
src/client/datascience/kernel-launcher/types.ts 100% <ø> (ø)
...ience/kernel-launcher/localKernelSpecFinderBase.ts 82% <92%> (+4%) ⬆️
...er/jupyterInterpreterSubCommandExecutionService.ts 92% <100%> (+<1%) ⬆️
...atascience/jupyter/kernels/jupyterKernelService.ts 84% <100%> (+1%) ⬆️
...client/datascience/kernel-launcher/jupyterPaths.ts 71% <100%> (+2%) ⬆️
...t/datascience/kernel-launcher/localKernelFinder.ts 88% <100%> (+<1%) ⬆️
.../kernel-launcher/localKnownPathKernelSpecFinder.ts 89% <100%> (-1%) ⬇️
.../localPythonAndRelatedNonPythonKernelSpecFinder.ts 70% <100%> (-14%) ⬇️
src/client/pythonEnvironments/info/interpreter.ts 79% <0%> (-6%) ⬇️
... and 11 more

jupyterDataPaths.push(path.dirname(await this.jupyterPaths.getKernelSpecTempRegistrationFolder()));
spawnOptions.env = {
...envVars,
JUPYTER_PATH: jupyterDataPaths.join(path.delimiter)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Magic sauce, this ensures Jupyter finds our kernelspecs (registered in a temporary directory)

@@ -234,7 +233,7 @@ export class JupyterKernelService {
cancelToken?: CancellationToken,
forceWrite?: boolean
) {
const kernelSpecRootPath = await this.kernelFinder.getKernelSpecRootPath();
const kernelSpecRootPath = await this.jupyterPaths.getKernelSpecTempRegistrationFolder();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change directory where we register kernelspecs

* (this way we don't register kernels in global path).
*/
public async getKernelSpecTempRegistrationFolder() {
const dir = path.join(this.context.extensionUri.fsPath, 'temp', 'jupyter', 'kernels');
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All kernelspecs are always in extension folder.
This way when ever we update the extension, we always end up creating these.

I kind of like this, if users delete environments or the like, the kernels will not live around unnecessarily.

Note: If you upgrade to a new version of the extension, the exact same kernel (with the same name is created)
I.e. the algorithm for geneating kernel names hasn't changed.

import { loadKernelSpec } from '../../../client/datascience/kernel-launcher/localKernelSpecFinderBase';
import { traceInfoIfCI } from '../../../client/common/logger';

[false, true].forEach((isWindows) => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed all of the old tests
@rchiodo You might recall this is something you asked for (& obviously I agreed with that suggestion).
Basically migrate old tests to the new style.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm confused. Why wouldn't most of these tests still be valid?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They are, they are duplicates and written a different way.
You suggested that I just migrate them to the new way.

Basically I wrote tests in a different way, which I believe was easier, in the test:

  • You can define all global kernle specs, all interpreters & kernlespecs that exist in each interpreter
  • In the previous test this wasn't straightforward, it was slightly complicated.
  • In that PR you suggested I migrate all the old tests to the new style (if the new tests covered the same scenarios)

assert.strictEqual(kernel?.kind, 'startUsingPythonInterpreter');
assert.deepEqual(kernel?.interpreter, activePythonEnv);
});
test('Return active interpreter for interactive window (metadata only has language)', async function () {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added some of the missing tests (as part of deleting old tests)

@DonJayamanne DonJayamanne marked this pull request as ready for review March 7, 2022 06:07
@DonJayamanne DonJayamanne requested a review from a team as a code owner March 7, 2022 06:07
return kernels;
}

// This should return a WRITABLE place that jupyter will look for a kernel as documented
// here: https://jupyter-client.readthedocs.io/en/stable/kernels.html#kernel-specs
public async getKernelSpecRootPath(): Promise<string | undefined> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm kinda surprised we don't need this anymore. We should still be looking for global kernels too?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we're still looking for globals (because juptyerPaths.getKernelSpecRootPath() is still used), so you likely just didn't need this to be public anymore.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we have a list of more paths and the root path was one of them.

if (kernelSpec?.specFile && shouldDeleteKernelSpec) {
// If this kernelSpec was registered by us and is in the global kernels folder,
// then remove it.
this.deleteOldKernelSpec(kernelSpec.specFile).catch(noop);
Copy link
Contributor

@amunger amunger Mar 7, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like unexpected behavior - the result of asking for a kernelSpec that exists is that it possibly gets deleted

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, its a side effect, we need to delete the old kernelspecs & this is a one time task.
I don't want to create a whole new method to iterate through kernels all over again (which is disc io & unnecessary complication).
Also I need a place to filter out these old kernlespecs (hence this is the spot).
In the future this code can be removed.

@DonJayamanne DonJayamanne requested review from amunger and rchiodo March 7, 2022 18:53
@DonJayamanne DonJayamanne merged commit 0d61dc2 into main Mar 7, 2022
@DonJayamanne DonJayamanne deleted the privateKernelSpecDir branch March 7, 2022 19:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

When using Jupyter (instead of raw kernels) create Kernelspecs in a custom directory
4 participants