Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
As previewed in slack, this PR introduces a new feature, called
live show if
. It works likejs show if
, but it lets users write python expressions as they would in a code block instead. It uses a simple1 JavaScript to python transpiler to convert python operations and expressions to JavaScript, and by monkey-patching that library by wrapping python variable references inval("...")
.Use
In a YAML file, it's use looks something like this:
Technical Implementation
On the backend, when the
parse.py
module is loaded, it loads themetapensiero.pj.__main__.transform_string
, overriding a few functions that convert the python AST to JavaScript's:da_obj.attribute
), subscripts (da_list[1]
orda_dict["key"]
), and simple variable names get wrapped inval("...")
in JavaScript.yesnomaybe
return the string"None"
for python's None, instead of JavaScript'snull
. We override to preserve this behavior. Someone could certainly write a python expression that usesNone
that shouldn't be the string"None"
, but it seems unlikely since you are restricted to variables on the page, whereNone
is only used for those select cases.The only substantial modification to existing code is that we can't transpile python to JS if that python still has Mako present, and we need to transpile the expressions before finding what variables are present in it. So I moved the search for variables later in the process. I think this adds a bit of runtime per screen as opposed to per interview load, but it's necessary, and in my testing didn't slow down things extensively.
On the frontend, it uses all of the same JavaScript as the
js show if
does, so no changes there.Other considerations
The biggest consideration is the addition and monkey patching of the
javascripthon
ormetapensiero.pj
library as a dependency. From the TODO section of it's README, there aren't any major refactors or upcoming changes mentioned for the few places that we override, so IMO it's not too extensive of a change for our uses. It definitely a choice to be made though, so I'll leave it to you. I've added a demo here, and if this gets accepted, I'll make another PR documenting this further.Footnotes
Simple as compared to heavier ways to run python in the browser, such as
brython
orpyodide
, which require a lot of extra javascript to be delivered to the user and make different assumptions about where the python variables referenced actually are. ↩