I have set IPYTHONDIR=.ipython, and created a startup file at .ipython/profile_default/startup/01_hello.py. Now, when I run ipython, it executes the contents of that file as if they had been entered into the IPython shell.
I can run sync code this way:
# contents of 01_hello.py
print( "hello!" )
$ ipython
Python 3.12.0 (main, Nov 12 2023, 10:40:37) [GCC 11.4.0]
Type 'copyright', 'credits' or 'license' for more information
IPython 8.31.0 -- An enhanced Interactive Python. Type '?' for help.
hello
In [1]:
I can also run async code directly in the shell:
# contents of 01_hello.py
print( "hello!" )
async def foo():
print( "foo" )
$ ipython
Python 3.12.0 (main, Nov 12 2023, 10:40:37) [GCC 11.4.0]
Type 'copyright', 'credits' or 'license' for more information
IPython 8.31.0 -- An enhanced Interactive Python. Type '?' for help.
hello
In [1]: await foo()
foo
In [2]:
However, I cannot run async code in the startup file, even though it's supposed to be as if that code was entered into the shell:
# contents of 01_hello.py
print( "hello!" )
async def foo():
print( "foo" )
await foo()
$ ipython
Python 3.12.0 (main, Nov 12 2023, 10:40:37) [GCC 11.4.0]
Type 'copyright', 'credits' or 'license' for more information
IPython 8.31.0 -- An enhanced Interactive Python. Type '?' for help.
[TerminalIPythonApp] WARNING | Unknown error in handling startup files:
File ~/proj/.ipython/profile_default/startup/01_imports.py:5
await foo()
^
SyntaxError: 'await' outside function
Question: Why doesn't this work, and is there a way to run async code in the startup file without explicitly starting a new event loop just for that? (asyncio.run())
Doing that wouldn't make sense, since that event loop would have to close by the end of the file, which makes it impossible to do any initialization work that involves context vars (which is where Tortoise-ORM stores its connections), which defeats the purpose.
Or stated differently: How can I access the event loop that IPython starts for the benefit of the interactive shell?