Open twavv opened 5 years ago
The offending code is this function. It is called whenever there is an await
statement at the top level.
https://github.com/ipython/ipython/blob/f0f6cd8b8c9f74ea8b2c5e37b6132212ce661c28/IPython/core/async_helpers.py#L77-L91
It wraps a block in an async function and naively indents it by eight. I'm not super familiar with AST parsing (especially using the builtin ast
module), but there isn't (or at the very least I don't see) a way to check if a given string is a triple-quote string via the ast
module.
It'd be a shame if this were just silently broken. At the very least, we could warn if we detect the use of triple-quotes together with await (even a simple heuristic along the lines of if '"""' in code: ...
, as well as only warning once to avoid spamming the user).
(tag @Carreau since they seem to be the one most involved with asyncio in the REPL)
Thanks for the ping.
I'm hopping to get some of this natively handled by CPython at some point. I'll see if I can do something when I have some time.
Great! If there's anything I (or anyone else) can do, feel free to suggest next steps.
Well if you figure out even a prototype of how we can do this... that would help. Or even just how to access or detect the strings that would need fixing. I'm going to assume we want to wrap those in some kind of texwrap.dedent()
that only affect multiple lines strings? And do not touch the first line?
I'm not sure if it would be reproducible using ipython from the CLI
Since I haven't seen anyone confirming that it's reproducible on IPython from the cli, I'm confirming :P It works fine for Python 3.8+ because different logic is used then, but it doesn't work for pre-3.8 (tested on Python 3.7):
In [1]: import asyncio
...: text = '''
...: text
...: '''
...: print(repr(text))
...: await asyncio.sleep(0)
'\n text\n '
In [2]: import asyncio
...: text = '''
...: text
...: '''
...: print(repr(text))
'\ntext\n'
Yeah, Ithink it's reasonable to tell users that using 3.8+ for this to work is reasonable. 3.7 is best effort.
yields
with indentation (8 indents to be exact), whereas dropping the
await
doesn't.I figured this belonged here rather than in Jupyter notebook, but I'm using the notebook to run this example (I'm not sure if it would be reproducible using
ipython
from the CLI since I imagine thecode = ...
andawait ...
get run in different execution requests).For now, I can just
textwrap.dedent
, but thought I'd file the issue nonetheless.