Skip to content

Instantly share code, notes, and snippets.

@dschep
Last active September 13, 2022 18:55
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dschep/4358be665537463b9271f782e77ff85f to your computer and use it in GitHub Desktop.
Save dschep/4358be665537463b9271f782e77ff85f to your computer and use it in GitHub Desktop.
Shortcut for commandline python use
#!/usr/bin/env python3
"""
More convinient than `python -c`.
Automatically imports python modules and prints the repr of the last statement.
for example:
`py 'json.load(sys.stdin)'`
instead of
`python -c 'import json,stdin;print(repr(json.load(sys.stdin)))`
Also has aliases for a few things such as np for numpy and dt for datetime.
"""
from argparse import ArgumentParser, RawTextHelpFormatter
from code import InteractiveInterpreter
from collections import defaultdict
from importlib import import_module
from subprocess import call
class RecursiveImportingModule:
def __init__(self, module):
self.module = module
def __getattr__(self, name):
if hasattr(self.module, name):
return getattr(self.module, name)
try:
return RecursiveImportingModule(import_module('.'.join([self.module.__name__, name])))
except ImportError:
exc = AttributeError(
"'module' object has no attribute '{}'".format(name))
exc.__cause__ = None
raise exc
def __repr__(self):
return repr(self.module)
class LocalsImportDict(defaultdict):
"""A dict which automatically imports modules when accessing key names."""
aliases = {
'dt': 'datetime',
'np': 'numpy',
}
def __missing__(self, key):
"""Import the missing key if possible and not a built-in."""
if key in dir(__builtins__):
return getattr(__builtins__, key)
try:
return RecursiveImportingModule(
import_module(self.aliases.get(key, key)))
except ImportError:
exc = NameError("name '{}' is not defined".format(key))
exc.__cause__ = None
raise exc
def main():
"""Run python code with auto imports using code.InteractiveInterpreter."""
parser = ArgumentParser(description=__doc__,
formatter_class=RawTextHelpFormatter)
parser.add_argument('code', help='Python code to execute')
group = parser.add_mutually_exclusive_group()
group.add_argument('-3', action='store_const', dest='python',
const='python3', help='Explicitly use Python 3')
group.add_argument('-2', action='store_const', dest='python',
const='python2', help='Explicitly use Python 2')
group.add_argument('-p', '--python', help='Specify python interpreter')
args = parser.parse_args()
if args.python is not None:
call([args.python, __file__, args.code])
else:
InteractiveInterpreter(LocalsImportDict()).runsource(args.code)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment