Source code for pimlico.cli.pyshell

# This file is part of Pimlico
# Copyright (C) 2020 Mark Granroth-Wilding
# Licensed under the GNU LGPL v3.0 - https://www.gnu.org/licenses/lgpl-3.0.en.html

from __future__ import print_function
from past.builtins import execfile
from builtins import object

from pimlico.cli.subcommands import PimlicoCLISubcommand


[docs]class PimlicoPythonShellContext(object): """ A class used as a static global data structure to provide access to the loaded pipeline when running the Pimlico Python shell command. This should never be used in any other context to pass around loaded pipelines or other global data. We don't do that sort of thing. """ def __init__(self): self.pipeline = None
# Make the pipeline available in (effectively) a global variable when we run the shell # The attribute's non-None value indicates that we're running through the shell and have a pipeline loaded # In other contexts, this will be None, indicating that we're not running the shell and the pipeline shouldn't be # accessed in this way _shell_context = PimlicoPythonShellContext()
[docs]class PythonShellCmd(PimlicoCLISubcommand): command_name = "python" command_help = "Load the pipeline config and enter a Python interpreter with access to it in the environment"
[docs] def add_arguments(self, parser): parser.add_argument("script", nargs="?", help="Script file to execute. Omit to enter interpreter") parser.add_argument("-i", action="store_true", help="Enter interactive shell after running script")
[docs] def run_command(self, pipeline, opts): _shell_context.pipeline = pipeline if opts.script: # Script given on the command line, execute it # Use the __main__ context, so that if the script uses the standard if __name__ == "__main__" way # to define a main script, this will be executed import __main__ execfile(opts.script, __main__.__dict__) if not opts.script or opts.i: # Enter the interpreter from code import interact print("Loaded pipeline config") print("PipelineConfig object is available as variable 'pipeline' (or 'p')") local = {"pipeline": pipeline, "p": pipeline} interact(local=local)
[docs]def get_pipeline(): """ This function may be used in scripts that are expected to be run exclusively from the Pimlico Python shell command (``python``) to get hold of the pipeline that was specified on the command line and loaded when the shell was started. """ if _shell_context.pipeline is None: raise ShellContextError("tried to access the pipeline loaded by the Pimlico Python shell, but not is " "available. This probably means that this has been called from a context other " "than the Pimlico Python shell and should not be used") return _shell_context.pipeline
[docs]class ShellContextError(Exception): pass