How can we start ipython REPL and instruct it to pass some command-line arguments to the underlying python interpreter?
For example, we can open a python REPL with increased verbosity by using
python -v
But I could not see how to pass that flag through when opening IPython.
I'd say the best way to do that would be to explicitly launch ipython with python:
python /usr/bin/ipython
as the ipython executable is just a python script ; or you can launch ipython by telling python to load the ipython library:
python -m IPython.frontend.terminal.ipapp
and then you can add all the native python arguments:
python -v /usr/bin/ipython
python -v -m IPython.frontend.terminal.ipapp
HTH
You could write your own ipython shebang script.
Here I copied my ipython script and added the -v
#!/usr/local/bin/python3.5 -v
# -*- coding: utf-8 -*-
import re
import sys
from IPython import start_ipython
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
sys.exit(start_ipython())
Now when I execute ./vipython I get many pages of import information upon startup and shutdown.
I gather from other SO questions that I might not be able to add multiple options to such a shebang line.
How to use multiple arguments with a shebang (i.e. #!)?
So for example
#!/usr/local/bin/python3.5 -vv
works, but
#!/usr/local/bin/python3.5 -v -v
doesn't - it gives me
1008:~/mypy$ ./vipython
Unknown option: -
usage: /usr/local/bin/python3.5 [option] ... [-c cmd | -m mod | file | -] [arg] ...
Try `python -h' for more information.
That -v option affects the behavior of the interpreter itself, not just the REPL. You get the extra import information regardless of whether you add the -i option.
Here's the default script that launches ipython (or at least one version of that)
1522:~/mypy$ cat /usr/local/bin/ipython3.5
#!/usr/local/bin/python3.5
# -*- coding: utf-8 -*-
import re
import sys
from IPython import start_ipython
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
sys.exit(start_ipython())
and from within an ipython session:
In [1153]: from IPython import start_ipython
In [1154]: start_ipython??
String form: <function start_ipython at 0xb697edac>
File: /usr/lib/python3/dist-packages/IPython/__init__.py
Definition: start_ipython(argv=None, **kwargs)
Source:
def start_ipython(argv=None, **kwargs):
"..."
from IPython.terminal.ipapp import launch_new_instance
return launch_new_instance(argv=argv, **kwargs)
Eventually the argv are passed to an argparse parser. Ipython populates that parser with arguments derived from its config files. So you have several options for setting parameters - default config, profile config, and commandline. But all of this is after the interpreter has been launched. Some things are acted on in the same was a with an interpreter REPL, but not all (-m, but not -v).
When -v is used as zmo suggests, we see all the imports of ipython code - which are quite a few. Are you interested in those, or are you more interested in imports related to your own script?
I use ipython a lot to test answers, especially for numpy. In fact my default ipython call has the --pylab flag. But to test stand alone scripts I use plain python (often called from a terminal window in my editor). Sometimes though I'll %run a script from within ipython. That loads the module into the main workspace, making it easy to perform %timeit tests on functions.
Other ipython scripts use
#!/usr/bin/python
import sys
from pkg_resources import load_entry_point
if __name__ == '__main__':
sys.exit(
load_entry_point(...)
I don't write much code using this style, but I don't see how that kind initiation can pass argv on through to the interpreter. By the time the module has been loaded and start running, the interpreter is already running.
In general it looks like ipython handles options like -i, -m, -c in basically the same way as the regular python. It may doing so with its own code, rather than delegating to the interpreter. But things like -v, -O, -t apply to the interpreter, not the REPL, and aren't handled by ipython code.
Related
When you run python manage.py shell, (or shell_plus if you have the extension), the script will import some stuff for you and then open a regular python shell for you to try commands out, as opposed to running the script and immediately closing.
I know that you can use the -i switch when calling a script to keep the command prompt open, for example python -i foo.py will run the contents of foo.py yet keep the shell open instead of immediately closing.
I would guess that when you call django's manage.py shell it somehow uses the same feature to get the command prompt to stay open and not immediately close out.
How does it work? Can I add something to any script file to make it behave the same way (without using the -i switch) ?
As of 2.2.3, the shell management command has three programs it can start -- ipython, bpython, and python. For the first two, you can start the shells using python:
def ipython(self, options):
from IPython import start_ipython
start_ipython(argv=[])
def bpython(self, options):
import bpython
bpython.embed()
For python, django sets up readline and then uses code.interact to start the python interpreter:
def python(self, options):
import code
# Set up a dictionary to serve as the environment for the shell, so
# that tab completion works on objects that are imported at runtime.
imported_objects = {}
try: # Try activating rlcompleter, because it's handy.
import readline
except ImportError:
pass
else:
# We don't have to wrap the following import in a 'try', because
# we already know 'readline' was imported successfully.
import rlcompleter
readline.set_completer(rlcompleter.Completer(imported_objects).complete)
# Enable tab completion on systems using libedit (e.g. macOS).
# These lines are copied from Python's Lib/site.py.
readline_doc = getattr(readline, '__doc__', '')
if readline_doc is not None and 'libedit' in readline_doc:
readline.parse_and_bind("bind ^I rl_complete")
else:
readline.parse_and_bind("tab:complete")
# We want to honor both $PYTHONSTARTUP and .pythonrc.py, so follow system
# conventions and get $PYTHONSTARTUP first then .pythonrc.py.
if not options['no_startup']:
for pythonrc in OrderedSet([os.environ.get("PYTHONSTARTUP"), os.path.expanduser('~/.pythonrc.py')]):
if not pythonrc:
continue
if not os.path.isfile(pythonrc):
continue
with open(pythonrc) as handle:
pythonrc_code = handle.read()
# Match the behavior of the cpython shell where an error in
# PYTHONSTARTUP prints an exception and continues.
try:
exec(compile(pythonrc_code, pythonrc, 'exec'), imported_objects)
except Exception:
traceback.print_exc()
code.interact(local=imported_objects)
I would like to use a python module from shell (to be exact: indirect from gnuplot). I do not want to write for every call an extra script or implement some I/O logic.
Let's say as a minimal working example, I have a python module module_foo.py with
#!/usr/bin/python
def bar():
print(1,2,3)
My question is:
Why isn't it possible to use a python module combining module loading and command execution like here?:
$ python -m module_foo -c 'bar()'
When executed, nothing happens. But what does work, is using only a command call like this
$ python -c 'import module_foo; module_foo.bar()'
1 2 3
or this
$ python -c 'from module_foo import *; bar()'
1 2 3
As soon as I load a module before, even a syntactically errorneous command is “accepted” – not executed, I suppose (the bracked of the call to bar isn't closed):
$ python -m module_foo -c 'bar('
$
It is, however, possible to use the -m module option using a python unit test (from the python docs):
python -m unittest test_module1 test_module2
The python manpage says for both options:
-c command
Specify the command to execute (see next section). This terminates the option
list (following options are passed as arguments to the command).
-m module-name
Searches sys.path for the named module and runs the corresponding .py file as
a script.
So I'd expect to be able to use path options in this -m ... -c ..., but not in reverse order -c ... -m ...'. Am I missing something obvious?
If you want your Python module to be executable and to call function bar(), you should add this to the end of the python file:
if __name__ == "__main__": # this checks that the file is "executed", rather than "imported"
bar() # call the function you want to call
Then call:
python module_foo.py
If you want more control, you can pass arguments to the script and access them from sys.argv.
For even more flexibility in arguments passed to the script, see argparse module.
I have a python project where I execute the app as a module using the -m flag. So something like:
python -m apps.validate -i input.mp4
Now, I want to profile it using the command line. So the inline examples suggest invoking cProfile itself a module. However, I cannot do something like:
python -m cProfile apps.validate -i input.mp4
However, this results in the error "No such file or directory". I cannot just go to the apps directory and launch validate.py due to relative imports.
Is there a way to profile a module on the command line?
Instead of running cProfile in shell, maybe you can use cProfile in your python script by adding some code in apps.validate or creating a new script and import apps.validate like this. Maybe some typo below :)
import cProfile
import sys
def run_validate(args):
# run your apps.validate code with shell arguments args here
pass
if __name__ == '__main__':
pr = cProfile.Profile()
pr.enable()
run_validate(*sys.argv)
pr.disable()
pr.print_stats()
then just run the original script: python -m apps.validate -i input.mp4
I am trying to get tab completion to work while running pdb on OS X 10.10.5. I have installed the homebrew version of python 2.7.13 because it appears (also see this) that Apple does not ship with a functional readline. If I have a trivial script, trivial.py
var1 = "this"
var2 = "is annoying"
and I run /usr/local/bin/python -m pdb trivial.py and on the first entry I enter import readline, rlcompleter; I subsequently can get tab completion. However, if I put in my .pdbrc
import readline
import rlcompleter
tab completion does not work. How is this not the exact same thing? Shouldn't tab completion work when put in my .pdbrc?
I get the same behavior on linux.
ie. with no .pdbrc
$ python3 -m pdb foo.py
(Pdb) in<tab> gives interact
(Pdb) interact
(Pdb) import rlcompleter
(Pdb) in<tab>
(Pdb) in input( int(
If I have import rlcompleter in my .pdbrc I only get interact when I type in. I get this same result even after I import rlcompleter.
$ python3 -m pdb -c 'import rlcompleter' foo.py
Also prevents tab completion.
Comparing the output of
$ python3 -vv -m pdb -c 'import rlcompleter' foo.py
and
$ python3 -vv -m pdb foo.py
resulted in a segfault so I would consider this a bug. I suggest you file a bug. Mention something about the import rlcompleter could be missing the Pdb completeionkey=setting being overwritten or the cmd module could be misinitialized. FWIW here is the source I was looking at to gleam some additional info. Pdb source
I found this
Using this method I was able to get the tab completion to work. His code uses a .pdbrc in the source dir and a hidden python script in the home dir. The file has comments where to split the file into two parts.
I am trying to set up a shell-launch script like this:
./practice.py
I intend to debug commands using various modules which can be tedious to import, set up oauth settings, etc.
How do I set example practice.py to launch with this sort of preset:
import module_x
import module_y
from module_z import something
a = something.settings(var_1='123', var_1='456')
>> #start doing stuff
You can use the PYTHONSTARTUP environmental variable. Quoting the documentation:
PYTHONSTARTUP
If this is the name of a readable file, the Python commands in
that file are executed before the first prompt is displayed in
interactive mode. The file is executed in the same namespace where
interactive commands are executed so that objects defined or imported
in it can be used without qualification in the interactive session.
You can also change the prompts sys.ps1 and sys.ps2 and the hook
sys.__interactivehook__ in this file.
How you set environmental variables depends on the OS.
Put a shebang at first line with interactive mode switch:
#!/usr/bin/env python -i
import module_x
import module_y
from module_z import something
a = something.settings(var_1='123', var_1='456')
Then make sure it is executable:
chmod +x practice.py
Then you can run it like this:
./practice.py
python (and the more comfortable ipython) support -i somefile.py as option to execute the contents of a file before opening the interactive prompt.
on Linux/Unix/OS X you could simply set that as the interpreter of your script like this
#! /usr/bin/python -i
import module_x
# other preloaded settings
On Windows you need to create a batch file or similar to wrap it.