def import_main(path, *args, **pconf): """ An utility to import the main function of a plac tool. It also works with command container factories. """ if ":" in path: # importing a factory path, factory_name = path.split(":") else: # importing the main function factory_name = None if not os.path.isabs(path): # relative path, look at PLACDIRS for placdir in PLACDIRS: fullpath = os.path.join(placdir, path) if os.path.exists(fullpath): break else: # no break raise ImportError(_("Cannot find %s" % path)) else: fullpath = path name, ext = os.path.splitext(os.path.basename(fullpath)) module = imp.load_module(name, open(fullpath), fullpath, (ext, "U", 1)) if factory_name: tool = partial_call(getattr(module, factory_name), args) else: tool = module.main # set the parser configuration plac_core.parser_from(tool, **pconf) return tool
def partial_call(factory, arglist): "Call a container factory with the arglist and return a plac object" a = plac_core.parser_from(factory).argspec if a.defaults or a.varargs or a.varkw: raise TypeError('Interpreter.call must be invoked on ' 'factories with required arguments only') required_args = ', '.join(a.args) if required_args: required_args += ',' # trailing comma code = '''def makeobj(interact, %s *args): obj = factory(%s) obj._interact_ = interact obj._args_ = args return obj\n''' % (required_args, required_args) dic = dict(factory=factory) exec_(code, dic) makeobj = dic['makeobj'] makeobj.add_help = False if inspect.isclass(factory): makeobj.__annotations__ = getattr(factory.__init__, '__annotations__', {}) else: makeobj.__annotations__ = getattr(factory, '__annotations__', {}) makeobj.__annotations__['interact'] = ('start interactive interpreter', 'flag', 'i') return plac_core.call(makeobj, arglist)
def default_help(obj, cmd=None): "The default help functionality in plac interpreters" parser = plac_core.parser_from(obj) if cmd is None: yield parser.format_help() return subp = parser.subparsers._name_parser_map.get(cmd) if subp is None: yield _('Unknown command %s' % cmd) elif getattr(obj, '_interact_', False): # in interactive mode formatter = subp._get_formatter() formatter._prog = cmd # remove the program name from the usage formatter.add_usage(subp.usage, [a for a in subp._actions if a.dest != 'help'], subp._mutually_exclusive_groups) formatter.add_text(subp.description) for action_group in subp._action_groups: formatter.start_section(action_group.title) formatter.add_text(action_group.description) formatter.add_arguments(a for a in action_group._group_actions if a.dest != 'help') formatter.end_section() yield formatter.format_help() else: # regular argparse help yield subp.format_help()
def partial_call(factory, arglist): "Call a container factory with the arglist and return a plac object" a = plac_core.parser_from(factory).argspec if a.defaults or a.varargs or a.varkw: raise TypeError("Interpreter.call must be invoked on " "factories with required arguments only") required_args = ", ".join(a.args) if required_args: required_args += "," # trailing comma code = """def makeobj(interact, %s *args): obj = factory(%s) obj._interact_ = interact obj._args_ = args return obj\n""" % ( required_args, required_args, ) dic = dict(factory=factory) exec code in dic makeobj = dic["makeobj"] if inspect.isclass(factory): makeobj.__annotations__ = getattr(factory.__init__, "__annotations__", {}) else: makeobj.__annotations__ = getattr(factory, "__annotations__", {}) makeobj.__annotations__["interact"] = ("start interactive interpreter", "flag", "i") return plac_core.call(makeobj, arglist)
def add(cls, obj, specialcommands): p = plac_core.parser_from(obj) c = cmd.Cmd(stdout=cls()) c.stdout.write('\n') c.print_topics('special commands', sorted(specialcommands), 15, 80) c.print_topics('custom commands', sorted(obj.commands), 15, 80) c.print_topics('commands run in external processes', sorted(obj.mpcommands), 15, 80) c.print_topics('threaded commands', sorted(obj.thcommands), 15, 80) p.helpsummary = str(c.stdout)
def __init__(self, obj): self.obj = obj self.registry = {} # {taskno : task} if obj.mpcommands or obj.thcommands: self.specialcommands.update(['.kill', '.list', '.output']) interact = getattr(obj, '_interact_', False) self.parser = plac_core.parser_from( obj, prog='' if interact else None, formatter_class=PlacFormatter) HelpSummary.add(obj, self.specialcommands) self.man = Manager() if obj.mpcommands else None signal.signal(signal.SIGTERM, terminatedProcess)
def __init__(self, obj, commentchar="#", split=shlex.split): self.obj = obj try: self.name = obj.__module__ except AttributeError: self.name = "plac" self.commentchar = commentchar self.split = split self._set_commands(obj) self.tm = TaskManager(obj) self.parser = plac_core.parser_from(obj, prog="", add_help=False) if self.commands: self.commands.update(self.tm.specialcommands) self.parser.addsubcommands(self.tm.specialcommands, self.tm, title="special commands") if obj.mpcommands: self.parser.addsubcommands(obj.mpcommands, obj, title="commands run in external processes") if obj.thcommands: self.parser.addsubcommands(obj.thcommands, obj, title="threaded commands") self.parser.error = lambda msg: sys.exit(msg) # patch the parser self._interpreter = None
def help(self, cmd=None): "show help about a given command" if cmd is None: yield str(self.helpsummary) else: yield plac_core.parser_from(self.obj).help_cmd(cmd)