-
-
Save dschep/4358be665537463b9271f782e77ff85f to your computer and use it in GitHub Desktop.
Shortcut for commandline python use
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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