-
Notifications
You must be signed in to change notification settings - Fork 290
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
Use breakpiont() in the new IW Jupyter Debugger #10114
Conversation
await cellDebugSetup(this.kernel, this.debugAdapter); | ||
|
||
const realPath = this.debugAdapter.getSourcePath(metadata.interactive.uristring); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No more adding of breakpoints, we use the technique of injecting breakpoint()
, that works much better.
@@ -64,15 +64,6 @@ export class KernelDebugAdapter extends KernelDebugAdapterBase { | |||
return super.handleMessage(message); | |||
} | |||
|
|||
public override async dumpAllCells() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressing previous PR comments
lineOffset: metadata.interactive.line + 1 // Add an extra 1 for the cell marker. | ||
lineOffset: | ||
metadata.interactive.lineIndex + | ||
(metadata.generatedCode?.lineOffsetRelativeToIndexOfFirstLineInCell || 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is more desecriptive way.
Also I changed the line property to be lineIndex as its the index, where as the line property in the generated code is actually the line number, was very confusing and found this was because i assumed both were line numbers.
? metadata.interactive.line + lineList[0] | ||
: metadata.interactive.line; | ||
return { stripped, trueStartLine, firstExecutableLineIndex }; | ||
return { stripped, trueStartLine }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Simpler now
// Compute the code that will really be sent to jupyter | ||
const stripped = this.extractExecutableLines(metadata.interactive.originalSource); | ||
// Compute the code that will really be sent to jupyter (including the cell marker) | ||
const { lines: stripped } = this.extractExecutableLines(metadata.interactive.originalSource); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: I've simplified the code by sending the cell marker as well to the Jupyter kernel.
This way we don't have to strip white space and don't have to take into account any leading white space having been stripped off by Jupyter (as we'll have a cell marker - except in the case where user uses shift enter
when there's no cell marker - and tha'ts handled as well and we have tests for that too)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good, I was about to ask about the shift-enter case. Sounds like it's covered.
@@ -101,7 +102,7 @@ export type InteractiveCellMetadata = { | |||
interactiveWindowCellMarker?: string; | |||
interactive: { | |||
uristring: string; | |||
line: number; | |||
lineIndex: number; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See above, in IGeneratedCode
the line
property is ` based, and this is 0 based, hence renamed to avoid confusions.
return traceback.map((traceFrame) => { | ||
// Check IPython8. We handle that one special | ||
if (/^[Input|File].*?\n.*/.test(traceFrame)) { | ||
if (useIPython8Format) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was incorrect, we need to test the regex on the entire output, not just one line.
const newLine = match!.firstNonBlankLineIndex + n - 1; | ||
return `${prefix}<a href='${matchUri?.toString()}?line=${newLine}'>${newLine + 1}</a>${suffix}`; | ||
const lineNumberOfFirstLineInCell = match!.hasCellMarker ? match!.line - 1 : match!.line; | ||
const lineIndexOfFirstLineInCell = lineNumberOfFirstLineInCell - 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Split this up into few more lines to make it more obvious what we were doing.
@@ -222,9 +222,17 @@ export abstract class KernelDebugAdapterBase implements DebugAdapter, IKernelDeb | |||
return this.session.customRequest('setBreakpoints', args); | |||
} | |||
|
|||
public abstract dumpAllCells(): Promise<void>; | |||
public async dumpAllCells() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressing previous code review comment
@@ -140,7 +140,7 @@ export class NotebookServerProvider implements IJupyterServerProvider { | |||
} catch (e) { | |||
disposeAllDisposables(disposables); | |||
// If user cancelled, then do nothing. | |||
if (options.token?.isCancellationRequested && e instanceof CancellationError) { | |||
if (options.token?.isCancellationRequested && isCancellationError(e)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Found in the PRs that when you run tests locally, we have a lot of unhandled exceptions, that's because some of the cancellation errors were not handled.
We have our own cancellation error as well, removed ours and used the VS Code cancellation error and added a utility function.
Now,
- When we run tests locally we don't have the same number of unhandled errors
- The output log is cleaner (previously we'd see 1000s of entries after the test output and its impossible to see the test results as the console output is too large, too large even to scroll - as we've exceeded vscodes buffer limit)
info.push(`EnvType: ${this.kernelConnectionMetadata.interpreter.envType}`); | ||
info.push(`EnvName: '${this.kernelConnectionMetadata.interpreter.envName}'`); | ||
info.push(`Version: ${this.kernelConnectionMetadata.interpreter.version?.raw}`); | ||
pythonInfo = ` (${info.join(', ')})`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've always wanted to see the version and the type of the python environment used, figured i'd add this now
@@ -604,7 +612,7 @@ export abstract class BaseKernel implements IKernel { | |||
// Have our debug cell script run first for safety | |||
if ( | |||
isLocalConnection(this.kernelConnectionMetadata) && | |||
!this.configService.getSettings(undefined).useJupyterDebugger | |||
!this.configService.getSettings(undefined).forceIPyKernelDebugger |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Address comment from previous PR
error | ||
); | ||
if (!isCancellationError(error)) { | ||
traceWarning( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No point adding logs when its a cancellation error, we just end up with lots of Errors logged in the output along with stack trace when these are not real errors (basically filling the error logs when running simple tests) - thus leading to false positives - i.e. it looks as though there are errors, when infact there aren't any.
); | ||
if (token.isCancellationRequested) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Found that this code was running even after tests completed, adding cancellation to fix that.
/** | ||
* Error type thrown when canceling. | ||
*/ | ||
export class CancellationError extends BaseError { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed our CancellationError, we weren't testing for this everywhere, hence we had a few weird behaviours when it came to handling of cancellation errors (basically we weren't handling it correctly as we weren't account for VSC and our cancellation error)
Now there's only one.
|
||
type DebuggerType = 'VSCodePythonDebugger' | 'JupyterProtocolDebugger'; | ||
const debuggerTypes: DebuggerType[] = ['JupyterProtocolDebugger', 'VSCodePythonDebugger']; | ||
debuggerTypes.forEach((debuggerType) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Running the IW debugger tests against both old and new jupyter protocol debugger.
Codecov Report
@@ Coverage Diff @@
## main #10114 +/- ##
======================================
- Coverage 64% 58% -6%
======================================
Files 203 203
Lines 9241 9247 +6
Branches 1488 1493 +5
======================================
- Hits 5927 5402 -525
- Misses 2853 3422 +569
+ Partials 461 423 -38
|
Fixes #10037
Fixes issues identified in #10106 (just for IW)
Adds tests for the new Debugger (sharing the same tests as the existing IW debugger)