def test_description(self, capsys): _, rc = Sample.run(["sample", "--help"], exit=False) assert rc == 0 stdout, stderr = capsys.readouterr() cols, _ = get_terminal_size() if cols < 9: # Terminal is too narrow to test pass else: # Paragraph indentation should be preserved assert " ABC" in stdout assert " DEF" in stdout assert " - Item" in stdout # List items should not be combined into paragraphs assert " * Star 2" # Lines of the same list item should be combined. (The right-hand expression of the 'or' operator # below is for when the terminal is too narrow, causing "GHI" to be wrapped to the next line.) assert " GHI" not in stdout or " GHI" in stdout # List item with invisible bullet should be indented without the bullet assert " XYZ" in stdout
def test_description(self, capsys): _, rc = Sample.run(["sample", "--help"], exit = False) assert rc == 0 stdout, stderr = capsys.readouterr() cols, _ = get_terminal_size() if cols < 9: # Terminal is too narrow to test pass else: # Paragraph indentation should be preserved assert " ABC" in stdout assert " DEF" in stdout assert " - Item" in stdout # List items should not be combined into paragraphs assert " * Star 2" # Lines of the same list item should be combined. (The right-hand expression of the 'or' operator # below is for when the terminal is too narrow, causing "GHI" to be wrapped to the next line.) assert " GHI" not in stdout or " GHI" in stdout # List item with invisible bullet should be indented without the bullet assert " XYZ" in stdout
def help(self): # @ReservedAssignment """Prints this help message and quits""" if self._get_prog_version(): self.version() print("") if self.DESCRIPTION: print(self.DESCRIPTION.strip()) m_args, m_varargs, _, m_defaults = inspect.getargspec(self.main) tailargs = m_args[1:] # skip self if m_defaults: for i, d in enumerate(reversed(m_defaults)): tailargs[-i - 1] = "[%s=%r]" % (tailargs[-i - 1], d) if m_varargs: tailargs.append("%s..." % (m_varargs,)) tailargs = " ".join(tailargs) print("Usage:") if not self.USAGE: if self._subcommands: self.USAGE = " %(progname)s [SWITCHES] [SUBCOMMAND [SWITCHES]] %(tailargs)s\n" else: self.USAGE = " %(progname)s [SWITCHES] %(tailargs)s\n" print(self.USAGE % {"progname": self.PROGNAME, "tailargs": tailargs}) by_groups = {} for si in self._switches_by_func.values(): if si.group not in by_groups: by_groups[si.group] = [] by_groups[si.group].append(si) def switchs(by_groups, show_groups): for grp, swinfos in sorted(by_groups.items(), key = lambda item: item[0]): if show_groups: print("%s:" % (grp,)) for si in sorted(swinfos, key = lambda si: si.names): swnames = ", ".join(("-" if len(n) == 1 else "--") + n for n in si.names if n in self._switches_by_name and self._switches_by_name[n] == si) if si.argtype: if isinstance(si.argtype, type): typename = si.argtype.__name__ else: typename = str(si.argtype) argtype = " %s:%s" % (si.argname.upper(), typename) else: argtype = "" prefix = swnames + argtype yield si, prefix if show_groups: print("") sw_width = max(len(prefix) for si, prefix in switchs(by_groups, False)) + 4 cols, _ = get_terminal_size() description_indent = " %s%s%s" wrapper = TextWrapper(width = max(cols - min(sw_width, 60), 50) - 6) indentation = "\n" + " " * (cols - wrapper.width) for si, prefix in switchs(by_groups, True): help = si.help # @ReservedAssignment if si.list: help += "; may be given multiple times" if si.mandatory: help += "; required" if si.requires: help += "; requires %s" % (", ".join((("-" if len(s) == 1 else "--") + s) for s in si.requires)) if si.excludes: help += "; excludes %s" % (", ".join((("-" if len(s) == 1 else "--") + s) for s in si.excludes)) msg = indentation.join(wrapper.wrap(" ".join(l.strip() for l in help.splitlines()))) if len(prefix) + wrapper.width >= cols: padding = indentation else: padding = " " * max(cols - wrapper.width - len(prefix) - 4, 1) print(description_indent % (prefix, padding, msg)) if self._subcommands: print("Subcommands:") for name, subcls in sorted(self._subcommands.items()): subapp = subcls.get() doc = subapp.DESCRIPTION if subapp.DESCRIPTION else inspect.getdoc(subapp) help = doc + "; " if doc else "" # @ReservedAssignment help += "see '%s %s --help' for more info" % (self.PROGNAME, name) msg = indentation.join(wrapper.wrap(" ".join(l.strip() for l in help.splitlines()))) if len(name) + wrapper.width >= cols: padding = indentation else: padding = " " * max(cols - wrapper.width - len(name) - 4, 1) print(description_indent % (name, padding, msg))
def help(self): # @ReservedAssignment """Prints this help message and quits""" if self._get_prog_version(): self.version() print("") if self.DESCRIPTION: print(self.COLOR_DISCRIPTION[self.DESCRIPTION.strip() + '\n']) m_args, m_varargs, _, m_defaults = inspect.getargspec(self.main) tailargs = m_args[1:] # skip self if m_defaults: for i, d in enumerate(reversed(m_defaults)): tailargs[-i - 1] = "[%s=%r]" % (tailargs[-i - 1], d) if m_varargs: tailargs.append("%s..." % (m_varargs, )) tailargs = " ".join(tailargs) with self.COLOR_USAGE: print(self.COLOR_HEADING["Usage:"]) if not self.USAGE: if self._subcommands: self.USAGE = " %(progname)s [SWITCHES] [SUBCOMMAND [SWITCHES]] %(tailargs)s\n" else: self.USAGE = " %(progname)s [SWITCHES] %(tailargs)s\n" print(self.USAGE % { "progname": self.PROGNAME, "tailargs": tailargs }) by_groups = {} for si in self._switches_by_func.values(): if si.group not in by_groups: by_groups[si.group] = [] by_groups[si.group].append(si) def switchs(by_groups, show_groups): for grp, swinfos in sorted(by_groups.items(), key=lambda item: item[0]): if show_groups: with (self.COLOR_HEADING + self.COLOR_GROUPS[grp]): print("%s:" % grp) # Print in body color unless empty, otherwise group color, otherwise nothing with self.COLOR_GROUPS_BODY.get(grp, self.COLOR_GROUPS[grp]): for si in sorted(swinfos, key=lambda si: si.names): swnames = ", ".join( ("-" if len(n) == 1 else "--") + n for n in si.names if n in self._switches_by_name and self._switches_by_name[n] == si) if si.argtype: if isinstance(si.argtype, type): typename = si.argtype.__name__ else: typename = str(si.argtype) argtype = " %s:%s" % (si.argname.upper(), typename) else: argtype = "" prefix = swnames + argtype yield si, prefix if show_groups: print("") sw_width = max( len(prefix) for si, prefix in switchs(by_groups, False)) + 4 cols, _ = get_terminal_size() description_indent = " %s%s%s" wrapper = TextWrapper(width=max(cols - min(sw_width, 60), 50) - 6) indentation = "\n" + " " * (cols - wrapper.width) for si, prefix in switchs(by_groups, True): help = si.help # @ReservedAssignment if si.list: help += "; may be given multiple times" if si.mandatory: help += "; required" if si.requires: help += "; requires %s" % (", ".join( (("-" if len(s) == 1 else "--") + s) for s in si.requires)) if si.excludes: help += "; excludes %s" % (", ".join( (("-" if len(s) == 1 else "--") + s) for s in si.excludes)) msg = indentation.join( wrapper.wrap(" ".join(l.strip() for l in help.splitlines()))) if len(prefix) + wrapper.width >= cols: padding = indentation else: padding = " " * max(cols - wrapper.width - len(prefix) - 4, 1) print(description_indent % (prefix, padding, msg)) if self._subcommands: with (self.COLOR_HEADING + self.COLOR_SUBCOMMANDS): print("Subcommands:") for name, subcls in sorted(self._subcommands.items()): with self.COLOR_SUBCOMMANDS: subapp = subcls.get() doc = subapp.DESCRIPTION if subapp.DESCRIPTION else inspect.getdoc( subapp) help = doc + "; " if doc else "" # @ReservedAssignment help += "see '%s %s --help' for more info" % ( self.PROGNAME, name) msg = indentation.join( wrapper.wrap(" ".join(l.strip() for l in help.splitlines()))) if len(name) + wrapper.width >= cols: padding = indentation else: padding = " " * max( cols - wrapper.width - len(name) - 4, 1) print(description_indent % (name, padding, msg))
def help(self): # @ReservedAssignment """Prints this help message and quits""" if self._get_prog_version(): self.version() print("") if self.DESCRIPTION: print(self.DESCRIPTION.strip() + '\n') m = six.getfullargspec(self.main) tailargs = m.args[1:] # skip self if m.defaults: for i, d in enumerate(reversed(m.defaults)): tailargs[-i - 1] = "[%s=%r]" % (tailargs[-i - 1], d) if m.varargs: tailargs.append("%s..." % (m.varargs,)) tailargs = " ".join(tailargs) with self.COLOR_USAGE: print("Usage:") if not self.USAGE: if self._subcommands: self.USAGE = " %(progname)s [SWITCHES] [SUBCOMMAND [SWITCHES]] %(tailargs)s\n" else: self.USAGE = " %(progname)s [SWITCHES] %(tailargs)s\n" print(self.USAGE % {"progname": colors.filter(self.PROGNAME), "tailargs": tailargs}) by_groups = {} for si in self._switches_by_func.values(): if si.group not in by_groups: by_groups[si.group] = [] by_groups[si.group].append(si) def switchs(by_groups, show_groups): for grp, swinfos in sorted(by_groups.items(), key = lambda item: item[0]): if show_groups: print(self.COLOR_GROUPS[grp] | grp) for si in sorted(swinfos, key = lambda si: si.names): swnames = ", ".join(("-" if len(n) == 1 else "--") + n for n in si.names if n in self._switches_by_name and self._switches_by_name[n] == si) if si.argtype: if hasattr(si.argtype, '__name__'): typename = si.argtype.__name__ else: typename = str(si.argtype) argtype = " %s:%s" % (si.argname.upper(), typename) else: argtype = "" prefix = swnames + argtype yield si, prefix, self.COLOR_GROUPS[grp] if show_groups: print("") sw_width = max(len(prefix) for si, prefix, color in switchs(by_groups, False)) + 4 cols, _ = get_terminal_size() description_indent = " %s%s%s" wrapper = TextWrapper(width = max(cols - min(sw_width, 60), 50) - 6) indentation = "\n" + " " * (cols - wrapper.width) for si, prefix, color in switchs(by_groups, True): help = si.help # @ReservedAssignment if si.list: help += "; may be given multiple times" if si.mandatory: help += "; required" if si.requires: help += "; requires %s" % (", ".join((("-" if len(s) == 1 else "--") + s) for s in si.requires)) if si.excludes: help += "; excludes %s" % (", ".join((("-" if len(s) == 1 else "--") + s) for s in si.excludes)) msg = indentation.join(wrapper.wrap(" ".join(l.strip() for l in help.splitlines()))) if len(prefix) + wrapper.width >= cols: padding = indentation else: padding = " " * max(cols - wrapper.width - len(prefix) - 4, 1) print(description_indent % (color | prefix, padding, color | msg)) if self._subcommands: gc = self.COLOR_GROUPS["Subcommands"] print(gc | "Subcommands:") for name, subcls in sorted(self._subcommands.items()): with gc: subapp = subcls.get() doc = subapp.DESCRIPTION if subapp.DESCRIPTION else getdoc(subapp) if self.SUBCOMMAND_HELPMSG: help = doc + "; " if doc else "" # @ReservedAssignment help += self.SUBCOMMAND_HELPMSG.format(parent=self.PROGNAME, sub=name) else: help = doc if doc else "" # @ReservedAssignment msg = indentation.join(wrapper.wrap(" ".join(l.strip() for l in help.splitlines()))) if len(name) + wrapper.width >= cols: padding = indentation else: padding = " " * max(cols - wrapper.width - len(name) - 4, 1) if colors.contains_colors(subcls.name): bodycolor = colors.extract(subcls.name) else: bodycolor = gc print(description_indent % (subcls.name, padding, bodycolor | colors.filter(msg)))
def hline(): width, height = get_terminal_size(default=(80, 25)) print(width * u'\u2500')