-
Notifications
You must be signed in to change notification settings - Fork 106
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
Variables view feature #297
Conversation
922f348
to
b2400c7
Compare
jupyter-lib/api/src/main/kotlin/org/jetbrains/kotlinx/jupyter/api/Notebook.kt
Outdated
Show resolved
Hide resolved
jupyter-lib/api/src/main/kotlin/org/jetbrains/kotlinx/jupyter/api/Notebook.kt
Outdated
Show resolved
Hide resolved
jupyter-lib/api/src/main/kotlin/org/jetbrains/kotlinx/jupyter/api/VariableState.kt
Outdated
Show resolved
Hide resolved
data class VariableState( | ||
val propertyKlass: KProperty1<Any, *>, | ||
val scriptInstance: Any, | ||
var stringValue: String |
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.
It should be val
, at least here, in API class. You may make an interface with val stringValue
and then implement it in this class.
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.
So we basically would like to consider that VariableState is an immutable thing, hence, from the semantic perspective, changing stringValue gives us a new VariableState? Sure thing, I can have another var field in a implementation
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.
Basically, property class and script instance hold the exhaustive information about variable state. Other things may be obtained from these two. So I suggest something like this:
data class VariableState(
private val propertyClass: KProperty1<Any, *>,
private val scriptInstance: Any,
) {
// caching, methods to get pure and stringified values go here
}
What do you think?
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.
Cool, I did this way :
interface VarState {
val propertyKlass: KProperty<*>
val scriptInstance: Any?
val stringValue: String?
}
data class VariableState(
override val propertyKlass: KProperty1<Any, *>,
override val scriptInstance: Any,
var mutableStringValue: String?
) : VarState {
override val stringValue: String?
get() = mutableStringValue
}
But I like your approach more
...iler/src/main/kotlin/org/jetbrains/kotlinx/jupyter/compiler/util/serializedCompiledScript.kt
Outdated
Show resolved
Hide resolved
src/main/kotlin/org/jetbrains/kotlinx/jupyter/repl/impl/InternalEvaluatorImpl.kt
Outdated
Show resolved
Hide resolved
src/main/kotlin/org/jetbrains/kotlinx/jupyter/repl/impl/InternalEvaluatorImpl.kt
Outdated
Show resolved
Hide resolved
/** | ||
* Current state of visible variables | ||
*/ | ||
val variablesMap: Map<String, VariableState> |
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.
Let's call it variablesState
jupyter-lib/api/src/main/kotlin/org/jetbrains/kotlinx/jupyter/api/Notebook.kt
Outdated
Show resolved
Hide resolved
jupyter-lib/api/src/main/kotlin/org/jetbrains/kotlinx/jupyter/api/Notebook.kt
Outdated
Show resolved
Hide resolved
jupyter-lib/api/src/main/kotlin/org/jetbrains/kotlinx/jupyter/api/VariableState.kt
Outdated
Show resolved
Hide resolved
jupyter-lib/api/src/main/kotlin/org/jetbrains/kotlinx/jupyter/api/VariableState.kt
Outdated
Show resolved
Hide resolved
src/main/kotlin/org/jetbrains/kotlinx/jupyter/repl/impl/InternalEvaluatorImpl.kt
Outdated
Show resolved
Hide resolved
src/main/kotlin/org/jetbrains/kotlinx/jupyter/repl/impl/InternalEvaluatorImpl.kt
Outdated
Show resolved
Hide resolved
src/test/kotlin/org/jetbrains/kotlinx/jupyter/test/repl/CustomLibraryResolverTests.kt
Outdated
Show resolved
Hide resolved
src/test/kotlin/org/jetbrains/kotlinx/jupyter/test/repl/IntegrationApiTests.kt
Outdated
Show resolved
Hide resolved
8ab2741
to
76f1d75
Compare
b203e86
to
58d0a74
Compare
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.
Almost all is OK. The latest serious thing which I don't like is that stringified values are exposed as a part of Notebook API. They may be exposed, but at least with the corresponding raw values.
@@ -0,0 +1,29 @@ | |||
package org.jetbrains.kotlinx.jupyter.api |
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.
Let's rename this class to VariableState.kt
jupyter-lib/api/src/main/kotlin/org/jetbrains/kotlinx/jupyter/api/VariableStateImpl.kt
Outdated
Show resolved
Hide resolved
import kotlin.reflect.jvm.isAccessible | ||
|
||
interface VariableState { | ||
val propertyKlass: KProperty<*> |
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.
What about renaming it to property
or kProperty
? I don't see a reason for a word class
return buildString { | ||
append( | ||
""" | ||
<table class="$varsTableStyleClass" style="width:80%;margin-left:auto;margin-right:auto;" align="center"> |
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.
Something happened with indentation here, I think that additional tab will make things better
if (isHtmlFormat) notebook.variablesReportAsHTML() else notebook.variablesReport() | ||
) | ||
|
||
// TODO: causes some tests to fail. perhaps, due to exhausting log calling |
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.
What tests are failing? Let's do something with them
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.
Fixed
@@ -395,7 +415,14 @@ class ReplForJupyterImpl( | |||
updateClasspath() | |||
} ?: emptyList() | |||
|
|||
EvalResult(rendered, EvaluatedSnippetMetadata(newClasspath, compiledData, newImports)) | |||
notebook.updateVariablesState(variablesState) | |||
notebook.cellVariables = cellVariables |
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.
Let's create a Notebook method that will be called like notebook.updateVariablesState(internalEvaluator)
. It seems that we can make cellVariables
a val property
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.
It seems like we cant make it val since we need to reasign it once it changed
assertEquals(res.metadata.evaluatedVariablesState, varsUpdate) | ||
assertFalse(repl.notebook.variablesState.isEmpty()) | ||
val varsState = repl.notebook.variablesState | ||
assertEquals("1", varsState["x"]!!.stringValue) |
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.
Let's add extension method that will allow us to write varsState.getStringValue("x")
. And also, varsState.getValue("x")
for getting raw value
cell = notebook.addCell(internalId, codeToExecute, EvalData(jupyterId, code)) | ||
} | ||
} finally { | ||
compiledData = internalEvaluator.popAddedCompiledScripts() | ||
newImports = importsCollector.popAddedImports() | ||
} | ||
val variablesState = internalEvaluator.variablesHolder | ||
val cellVariables = internalEvaluator.cellVariables |
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.
Is this variable needed?
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.
Nah)
cell = notebook.addCell(internalId, codeToExecute, EvalData(jupyterId, code)) | ||
} | ||
} finally { | ||
compiledData = internalEvaluator.popAddedCompiledScripts() | ||
newImports = importsCollector.popAddedImports() | ||
} | ||
val variablesState = internalEvaluator.variablesHolder |
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 variable may be inlined
* Value: set of variable names. | ||
* Useful <==> declarations + modifying references | ||
*/ | ||
var cellVariables: Map<Int, Set<String>> |
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.
Do we still need it to be a var
?
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.
We might create another field and make val in api. I think it might make sense since we do not want to allow change notebook.varsState from notebook
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.
Let's do so then
if (property is KMutableProperty1) { | ||
variablesHolder.remove(property.name) | ||
} | ||
|
||
if (property !is KMutableProperty1) { | ||
variablesHolder[property.name] = state |
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.
if
-else
?
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.
Could you expand a bit more?
protected fun Map<String, VariableState>.getStringValue(variableName: String): String? { | ||
return get(variableName)?.stringValue | ||
} | ||
|
||
protected fun Map<String, VariableState>.getValue(variableName: String): Any? { | ||
return get(variableName)?.value | ||
} | ||
|
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.
Let's replace these declarations to testUtil.kt
, they may be useful in other tests as well
b7fbc83
to
6ec1281
Compare
Thank you @nikolay-egorov! Merged manually as c6b1390 |
No description provided.