Open krassowski opened 4 years ago
Are there languages other than Python that have cell magics? This almost feels like an implementation detail of the LSP that it should be supporting 'Notebook Python' but the underlying implementation only supports Python.
Could cell magics be implemented via an extension to the existing Python LSP engines?
will kernel developers in Jupyter community be willing to go this route, or would they prefer that a LSP server is implemented for each kernel / existing language servers are amended for each kernel?
I'm of the (possibly unpopular) opinion that magics introduce significant unexpected tooling overhead. This includes lsp, syntax highlighting, lint, format and graduating code to files). Languages should think very hard before adding them.
Thank you for chiming in @blois. I respect your point of view, and agree that if there were no magics, the overhead in maintaining the tooling would not be as high.
However, as a happy user of IPython I could not see it without magics; I use them heavily everyday and I believe they are a huge contributor to the IPython success as compared to some other kernels that explicitly decided not to support magics (excluding kernels of languages which do not need magics as the syntax of the language is very flexible in itself).
Could cell magics be implemented via an extension to the existing Python LSP engines?
No, I believe that implementing magics in LSP servers would not be realistically possible. In addition to the reasons listed in Why should it be declared by the kernel? Should not the LSP servers work harder to adopt to the language variation? (above):
n:m
problem (n
editors need to adapt to support m
languages)Are there languages other than Python that have cell magics
Kernels that support magics in general:
#%
and %%
syntax)
- Basic set of line and cell magics for all kernels.
- Python magic for accessing python interpreter.
- Run kernels in parallel.
- Shell magics.
- Classroom management magics.
- Tab completion for magics and file paths.
- Help for magics using ? or Shift+Tab.
- Plot magic for setting default plot behavior.
- this includes: matlab_kernel, octave_kernel, calysto_processing kernel and dozens more.
%%timeit
) available to all xeus-based kernels (https://github.com/jupyter-xeus/xeus-python/issues/63#issuecomment-556023719)Kernels that do not support magics:
_
variables.I did not look specifically for cell magics - why are you focusing on cell magics only?
I agree on the usefulness of magics, really trying to figure out a way to break the problem down some.
For moving support into the LSP- I wonder if it could be done with one LSP wrapping another and doing the translation at that level. Some of the implementation would be tricky but I'm not sure it's much different than what needs to be done at the editor level. It sounds like VSCode may be trying something along these lines for their notebook support? I see no mention of supporting magics there though.
What are you trying to do?
Add token based code overrides. The code overrides make the existing language servers work with non-standard syntax which is added by the kernels on top of the underlying language. For example:
%ls
(variable names cannot start with%
in Python, and prefixing magic names with%
so IPython uses it to mark some of its magics). The IPython interpreter modifies the Abstract Syntax Tree, executing a special action when such a symbol is found: it callsipython.run_line_magic('ls', '')
whereipython
represents the global IPython instance. This call returns a value and can have side-effects. It is possible to replace this magic with valid Python via the proposed code override mechanism, as the valid pure Python equivalent would be:The reverse code replacement translates the above back to
%ls
. This is needed to make the LSP functions which modify the document work (e.g. rename/reformat/quick fix).Some magics take variables as arguments. For example,
%store data
would save the value ofdata
variable. A customised code replacement for this IPython magic would call a function using this variable, e.g.:This has several advantages:
How is it done today?
We only support regular expression-based code overrides. This was initially a "band-aid" to make LSP work with IPython, but we are hitting the limitations of regular expressions.
What are the limitations of using regular expressions?
x['a = !ls'] = !ls
(possibly more apparent on:x['\'a = !ls\''] = !ls
)'
and"
asx['a'] = !ls
is a valid expression with magic=
as!
and%
magics have to start from new line or assignment; for examplex == !ls
is not a valid magic;The proposal
%store
magic; for examples see rpy2 magics or ipython-sql magics).Why should it be declared by the kernel? Should not the LSP servers work harder to adopt to the language variation?
Now, I believe that magics are fun. Magics are what makes the IPython and others kernels easier to work with in the interactive setting. I would like to enable kernel developers, especially developers of kernels for languages which are not so well established (I do not expect to see huge changes in IPython magics) to add, change and refine magics without the fear that the cool language features will stop working for them.
Design notes
Before reading further, you may want to have a quick look at the current regular-expression-based implementation:
Design considerations:
find_matches
,replace
,reverse_replace
DocumentStart
andDocumentEnd
tokens, so that we can prepend the document with necessary code. Regular expressions cannot do that as ^ is either beginning of the document OR of the line. This would allow, for example:get_ipython()
functionint main() {
and appendreturn 0; }
-o
and--output
arguments will lead to the same result and will be always reversed to-o
).%Rpull
would conflict with the aboveint?
and?int
are evaluated to the same code, so cannot be distinguished during reverse substitutionDraft of the interface (to be converted to JSON schema once finished):
Example IPython magic for
%store
:Questions to consider
How to make this work for kernel developers?
Testing overrides would need to be made easy for the kernel developers.
ITokenCodeOverride
and overrides are presented.ITestCase
interface and accept thatITestCase[]
on the static website to give developers a hint on how it all should work likeITokenCodeOverride
andITestCase[]
Will this work?