Skip to content

Run by line partial implementation #11608

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

Merged
merged 39 commits into from
May 6, 2020
Merged

Run by line partial implementation #11608

merged 39 commits into from
May 6, 2020

Conversation

rchiodo
Copy link

@rchiodo rchiodo commented May 5, 2020

For #11607

Partial implementation of run by line behind a flag. Should be enough for a demo.

List of stuff to be done after this:

  • Debug variable info not complete
  • DataFrame open during debugging if not same cell
  • Step into other cells doesn't work (waiting on debugpy bug)
  • Hover on python files?
  • Tests
  • Run by line on install debugpy
  • Focus/Scroll in cell after step

@@ -406,3 +430,11 @@ export class CellHashProvider implements ICellHashProvider, INotebookExecutionLo
return traceFrame;
}
}

export function getCellHashProvider(notebook: INotebook): ICellHashProvider | undefined {
Copy link
Author

Choose a reason for hiding this comment

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

getCellHashProvider [](start = 16, length = 19)

Figured it made sense to centralize this here.

Copy link
Member

Choose a reason for hiding this comment

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

If you just need the loggers looks like this should just take INotebookExecutionLogger[] instead of the entire notebook. So it doesn't have to expose the whole interface.

Copy link
Author

Choose a reason for hiding this comment

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

Then the caller has to know that it comes from an array of loggers. Two pieces of information isntead of one. They have to have a notebook, why tell them the cell hash provider is on the loggers?


In reply to: 420474295 [](ancestors = 420474295)

Copy link
Author

Choose a reason for hiding this comment

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

As in the CellHashProvider knows it's in the logger list for a notebook, nobody else needs to know this. They just know it's associated with a notebook. We might change how the cell hash provider is associated with a notebook in the future, but we'd likely still have it associated with a notebook itself.


In reply to: 420482187 [](ancestors = 420482187,420474295)

Copy link
Member

Choose a reason for hiding this comment

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

My objection here is more how much is on the INotebook interface. The CellHashProvider could just call notebook.Dispose() here. Or notebook.restartKernel(). I feel like that's something we do a lot, especially with INotebook and IJupyterServer.

Copy link
Author

Choose a reason for hiding this comment

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

But then the caller would have to understand about loggers. I don't think that scopes it down at all. I think it does the opposite. CellHashProvider knows it's a logger on a notebook. Nothing else needs to know that. However other things need some way to get the provider. I suppose other ways we could have done this would be to add a function to the notebook to retrieve it (that seems worse), add some sort of helper class that all you pass in is the notebook identity (that doesn't sound too bad), or this way.


In reply to: 420884909 [](ancestors = 420884909)

Copy link
Author

Choose a reason for hiding this comment

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

Maybe we should split the notebook interface then. Something that's smaller (or readonly).


In reply to: 420881550 [](ancestors = 420881550)

Copy link
Author

Choose a reason for hiding this comment

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

LIke IExecutableNotebook and INotebook where all of the state modifying items are on IExecutableNotebook.


In reply to: 420915749 [](ancestors = 420915749,420881550)

Copy link
Member

Choose a reason for hiding this comment

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

I don't know if we need to do it now, but if you remember the question that I was asking at the end of the SOLID talk about oversized interfaces, INotebook was totally one of the interfaces that I was thinking about. I think part of the advice there was that breaking up the interface might be a good first step to at least make it hard in code to mess with something that should not be messed with. Splitting that might be part of a bigger overall code-health fix, so that might be better to not mess with in this PR.

Choose a reason for hiding this comment

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

With Ian on this, we're passing something that's too broad.

this.getDocument(),
this.getVariableHover(wordAtPosition)
]);
if (!variableHover && languageServer && document) {
Copy link
Author

Choose a reason for hiding this comment

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

If there's a word under the cursor and the debugger (or kernel) knows about it, it takes precedence over normal hover.


// tslint:disable: no-any
@injectable()
export class NativeEditorDebuggerListener
Copy link
Author

Choose a reason for hiding this comment

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

I should put a comment on this saying what this class is for.

glyphMarginClassName: 'codicon codicon-debug-stackframe',
stickiness
};
const TOP_STACK_FRAME_DECORATION: monacoEditor.editor.IModelDecorationOptions = {
Copy link
Author

Choose a reason for hiding this comment

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

Copied these from the VS code decorators they setup when debugging.

@codecov-io
Copy link

codecov-io commented May 5, 2020

Codecov Report

Merging #11608 into master will decrease coverage by 0.11%.
The diff coverage is 39.79%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master   #11608      +/-   ##
==========================================
- Coverage   60.70%   60.58%   -0.12%     
==========================================
  Files         626      627       +1     
  Lines       33767    33865      +98     
  Branches     4748     4763      +15     
==========================================
+ Hits        20498    20517      +19     
- Misses      12289    12359      +70     
- Partials      980      989       +9     
Impacted Files Coverage Δ
.../datascience/interactive-common/interactiveBase.ts 5.55% <0.00%> (-0.04%) ⬇️
...atascience/interactive-window/interactiveWindow.ts 15.62% <0.00%> (ø)
src/client/datascience/jupyter/jupyterVariables.ts 25.00% <0.00%> (ø)
src/datascience-ui/interactive-common/mainState.ts 54.76% <ø> (ø)
...ient/datascience/interactive-ipynb/nativeEditor.ts 11.03% <8.00%> (-0.58%) ⬇️
...active-common/intellisense/intellisenseProvider.ts 37.65% <26.66%> (-0.89%) ⬇️
...datascience/editor-integration/cellhashprovider.ts 75.36% <64.70%> (-2.30%) ⬇️
src/client/common/utils/localize.ts 95.53% <100.00%> (+0.02%) ⬆️
src/client/datascience/constants.ts 99.73% <100.00%> (+<0.01%) ⬆️
...ience/interactive-common/interactiveWindowTypes.ts 100.00% <100.00%> (ø)
... and 11 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update e93fbe4...e93fbe4. Read the comment docs.

hidden={this.isMarkdownCell()}
disabled={this.props.busy}
>
<div className="codicon codicon-button">{'\uead7'}</div>
Copy link
Author

Choose a reason for hiding this comment

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

I should probably make these unicode values constants.

@@ -567,7 +567,7 @@ export abstract class InteractiveBase extends WebViewHost<IInteractiveWindowMapp
line,
id,
originator: this.id,
debug: debug !== undefined ? debug : false
debug: debug !== undefined ? true : false
Copy link
Member

Choose a reason for hiding this comment

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

This almost looked like an error skimming down due the change from a bool to an object. This is just an up to you thing. But if the function took a debugInfo? it might make a bit more sense. Debug just sounds like a bool property to me and we use it as a bool property right here in a different call.

Copy link
Author

Choose a reason for hiding this comment

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

Yeah I'll rename it.


In reply to: 420477853 [](ancestors = 420477853)

if (debug.runByLine && debug.hashFileName) {
await this.jupyterDebugger.startRunByLine(this._notebook, debug.hashFileName);
} else {
await this.jupyterDebugger.startDebugging(this._notebook);
Copy link
Member

Choose a reason for hiding this comment

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

runByLine = true without a debug.hasFileName just goes down the normal debugging path, which seems a bit funny. Is that intended?

Copy link
Author

Choose a reason for hiding this comment

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

No it should probably throw an exception.


In reply to: 420478342 [](ancestors = 420478342)

@@ -352,12 +358,12 @@ export class NativeEditor extends InteractiveBase implements INotebookEditor {
line: number,
id?: string,
data?: nbformat.ICodeCell | nbformat.IRawCell | nbformat.IMarkdownCell,
debug?: boolean,
debugOptions?: { runByLine: boolean; hashFileName?: string },
Copy link
Member

Choose a reason for hiding this comment

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

Didn't even see this when I made my comment on the debug options above. I do like this name better than the debug name for the options object above.

@@ -196,6 +199,18 @@ const images: { [key: string]: { light: string; dark: string } } = {
JupyterServerDisconnected: {
light: require('./images/JupyterServerDisconnected/disconnected-light.svg'),
dark: require('./images/JupyterServerDisconnected/disconnected-dark.svg')
},
RunByLine: {
Copy link
Author

Choose a reason for hiding this comment

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

Actually I don't really need this. I'll delete them.

}
}
}
} catch (exc) {
Copy link
Member

Choose a reason for hiding this comment

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

The try here is around a bunch of code. If hashjs in getCellHashProvider throws an error I'm not sure if we want it showing up as cell output.

Copy link
Member

Choose a reason for hiding this comment

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

Or maybe we do? Guess we have to see it somewhere.

Copy link
Author

Choose a reason for hiding this comment

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

Yeah we do this elsewhere when running cells in a notebook.


In reply to: 420482775 [](ancestors = 420482775)

"DataScience.libraryRequiredToLaunchJupyterKernelNotInstalledInterpreter": "Data Science library {1} is not installed in interpreter {0}. Install?"
"DataScience.libraryRequiredToLaunchJupyterKernelNotInstalledInterpreter": "Data Science library {1} is not installed in interpreter {0}. Install?",
"DataScience.runByLine": "Run by line",
"DataScience.continueRunByLine": "Stop"

Choose a reason for hiding this comment

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

Continue will say stop.

Copy link
Author

Choose a reason for hiding this comment

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

Yep that's on purpose.


In reply to: 420490258 [](ancestors = 420490258)


// Then use that to make a hash value
const hashedCode = stripped.join('');
const hash = hashjs.sha1().update(hashedCode).digest('hex').substr(0, 12);

Choose a reason for hiding this comment

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

Why only first 12 characters?

Copy link
Author

Choose a reason for hiding this comment

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

That's what jupyter uses to generate the file name internally.

@@ -406,3 +430,11 @@ export class CellHashProvider implements ICellHashProvider, INotebookExecutionLo
return traceFrame;
}
}

export function getCellHashProvider(notebook: INotebook): ICellHashProvider | undefined {

Choose a reason for hiding this comment

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

With Ian on this, we're passing something that's too broad.

private async handleRunByLine(runByLine: IRunByLine) {
try {
// If there's any payload, it has the code and the id
if (runByLine.cell.id && runByLine.cell.data.cell_type !== 'messages') {

Choose a reason for hiding this comment

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

What if cell_type=markdown or raw.
Shouldn't we handle other cell types.

Copy link
Author

Choose a reason for hiding this comment

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

This should be impossible so it should just throw an exception unless it's a code cell

@sonarqubecloud
Copy link

sonarqubecloud bot commented May 6, 2020

Kudos, SonarCloud Quality Gate passed!

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities (and Security Hotspot 1 Security Hotspot to review)
Code Smell A 1 Code Smell

No Coverage information No Coverage information
0.0% 0.0% Duplication

@rchiodo rchiodo merged commit c1d8619 into master May 6, 2020
@rchiodo rchiodo deleted the rchiodo/debugger_client branch May 6, 2020 21:22
@lock lock bot locked as resolved and limited conversation to collaborators May 20, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants