示例#1
0
def FormatFiles(filenames,
                lines,
                style_config=None,
                no_local_style=False,
                in_place=False,
                print_diff=False,
                verify=True):
    """Format a list of files.

  Arguments:
    filenames: (list of unicode) A list of files to reformat.
    lines: (list of tuples of integers) A list of tuples of lines, [start, end],
      that we want to format. The lines are 1-based indexed. This argument
      overrides the 'args.lines'. It can be used by third-party code (e.g.,
      IDEs) when reformatting a snippet of code.
    style_config: (string) Style name or file path.
    no_local_style: (string) If style_config is None don't search for
      directory-local style configuration.
    in_place: (bool) Modify the files in place.
    print_diff: (bool) Instead of returning the reformatted source, return a
      diff that turns the formatted source into reformatter source.
    verify: (bool) True if reformatted code should be verified for syntax.

  Returns:
    True if the source code changed in any of the files being formatted.
  """
    changed = False
    for filename in filenames:
        logging.info('Reformatting %s', filename)
        if style_config is None and not no_local_style:
            style_config = (file_resources.GetDefaultStyleForDir(
                os.path.dirname(filename)))
        try:
            reformatted_code, encoding, has_change = yapf_api.FormatFile(
                filename,
                in_place=in_place,
                style_config=style_config,
                lines=lines,
                print_diff=print_diff,
                verify=verify,
                logger=logging.warning)
            if has_change and reformatted_code is not None:
                file_resources.WriteReformattedCode(filename, reformatted_code,
                                                    in_place, encoding)
            changed |= has_change
        except SyntaxError as e:
            e.filename = filename
            raise
    return changed
示例#2
0
文件: __init__.py 项目: wwade/yapf
def print_help(args):
    """Prints the help menu."""

    if args.style is None and not args.no_local_style:
        args.style = file_resources.GetDefaultStyleForDir(os.getcwd())
    style.SetGlobalStyle(style.CreateStyleFromConfig(args.style))
    print('[style]')
    for option, docstring in sorted(style.Help().items()):
        for line in docstring.splitlines():
            print('#', line and ' ' or '', line, sep='')
        option_value = style.Get(option)
        if isinstance(option_value, set) or isinstance(option_value, list):
            option_value = ', '.join(map(str, option_value))
        print(option.lower(), '=', option_value, sep='')
        print()
示例#3
0
def fix_code(code):
    """Formats Python code to conform to the PEP 8 style guide.

    """
    if not yapf_api:
        raise Fault('yapf not installed', code=400)
    style_config = file_resources.GetDefaultStyleForDir(os.getcwd())
    try:
        reformatted_source, _ = yapf_api.FormatCode(code,
                                                    filename='<stdin>',
                                                    style_config=style_config,
                                                    verify=False)
        return reformatted_source
    except Exception as e:
            raise Fault("Error during formatting: {}".format(e),
                        code=400)
示例#4
0
def _format(document, lines=None):
    new_source, changed = FormatCode(
        document.source,
        lines=lines,
        filename=document.filename,
        style_config=file_resources.GetDefaultStyleForDir(
            os.path.dirname(document.path)
        )
    )

    if not changed:
        return []

    # I'm too lazy at the moment to parse diffs into TextEdit items
    # So let's just return the entire file...
    return [{
        'range': {
            'start': {'line': 0, 'character': 0},
            # End char 0 of the line after our document
            'end': {'line': len(document.lines), 'character': 0}
        },
        'newText': new_source
    }]
示例#5
0
文件: __init__.py 项目: wwade/yapf
def _FormatFile(filename,
                lines,
                style_config=None,
                no_local_style=False,
                in_place=False,
                print_diff=False,
                verify=False,
                quiet=False,
                verbose=False):
    """Format an individual file."""
    if verbose and not quiet:
        print('Reformatting %s' % filename)

    if style_config is None and not no_local_style:
        style_config = file_resources.GetDefaultStyleForDir(
            os.path.dirname(filename))

    try:
        reformatted_code, encoding, has_change = yapf_api.FormatFile(
            filename,
            in_place=in_place,
            style_config=style_config,
            lines=lines,
            print_diff=print_diff,
            verify=verify,
            logger=logging.warning)
    except tokenize.TokenError as e:
        raise errors.YapfError('%s:%s:%s' %
                               (filename, e.args[1][0], e.args[0]))
    except SyntaxError as e:
        e.filename = filename
        raise

    if not in_place and not quiet and reformatted_code:
        file_resources.WriteReformattedCode(filename, reformatted_code,
                                            encoding, in_place)
    return has_change
示例#6
0
文件: cells.py 项目: NikZak/celltest
    def apply_callbacks(self, output_string, callbacks):
        """Apply callbacks."""
        for callback in callbacks:
            if callback not in [x[0] for x in self.accepted["callbacks"]]:
                logger.error("Uknonwn callback %s", callback)
                continue
            if callback == "isort":
                import isort  # pylint: disable=import-outside-toplevel
                output_string = isort.code(output_string)  # pylint: disable=import-outside-toplevel
            if callback == "black":
                from black import format_str, FileMode  # pylint: disable=import-outside-toplevel
                output_string = format_str(output_string, mode=FileMode())
            if callback == "yapf":
                from yapf.yapflib.yapf_api import FormatCode  # pylint: disable=import-outside-toplevel
                from yapf.yapflib import file_resources  # pylint: disable=import-outside-toplevel
                style_config = file_resources.GetDefaultStyleForDir(
                    os.getcwd())

                output_string = FormatCode(output_string,
                                           style_config=style_config)
                # yapf<0.3 returns diff as str, >=0.3 returns a tuple of (diff, changed)
                output_string = output_string[0] if isinstance(
                    output_string, tuple) else output_string
        return output_string
示例#7
0
def main(argv):
  """Main program.

  Arguments:
    argv: command-line arguments, such as sys.argv (including the program name
      in argv[0]).

  Returns:
    0 if there were no changes, non-zero otherwise.

  Raises:
    YapfError: if none of the supplied files were Python files.
  """
  parser = argparse.ArgumentParser(description='Formatter for Python code.')
  parser.add_argument(
      '-v',
      '--version',
      action='store_true',
      help='show version number and exit')

  diff_inplace_group = parser.add_mutually_exclusive_group()
  diff_inplace_group.add_argument(
      '-d',
      '--diff',
      action='store_true',
      help='print the diff for the fixed source')
  diff_inplace_group.add_argument(
      '-i',
      '--in-place',
      action='store_true',
      help='make changes to files in place')

  lines_recursive_group = parser.add_mutually_exclusive_group()
  lines_recursive_group.add_argument(
      '-r',
      '--recursive',
      action='store_true',
      help='run recursively over directories')
  lines_recursive_group.add_argument(
      '-l',
      '--lines',
      metavar='START-END',
      action='append',
      default=None,
      help='range of lines to reformat, one-based')

  parser.add_argument(
      '-e',
      '--exclude',
      metavar='PATTERN',
      action='append',
      default=None,
      help='patterns for files to exclude from formatting')
  parser.add_argument(
      '--style',
      action='store',
      help=('specify formatting style: either a style name (for example "pep8" '
            'or "google"), or the name of a file with style settings. The '
            'default is pep8 unless a %s or %s file located in one of the '
            'parent directories of the source file (or current directory for '
            'stdin)' % (style.LOCAL_STYLE, style.SETUP_CONFIG)))
  parser.add_argument(
      '--style-help',
      action='store_true',
      help=('show style settings and exit; this output can be '
            'saved to .style.yapf to make your settings '
            'permanent'))
  parser.add_argument(
      '--no-local-style',
      action='store_true',
      help="don't search for local style definition")
  parser.add_argument('--verify', action='store_true', help=argparse.SUPPRESS)
  parser.add_argument(
      '-p',
      '--parallel',
      action='store_true',
      help=('Run yapf in parallel when formatting multiple files. Requires '
            'concurrent.futures in Python 2.X'))

  parser.add_argument('files', nargs='*')
  args = parser.parse_args(argv[1:])

  if args.version:
    print('yapf {}'.format(__version__))
    return 0

  if args.style_help:
    style.SetGlobalStyle(style.CreateStyleFromConfig(args.style))
    print('[style]')
    for option, docstring in sorted(style.Help().items()):
      for line in docstring.splitlines():
        print('#', line and ' ' or '', line, sep='')
      print(option.lower(), '=', style.Get(option), sep='')
      print()
    return 0

  if args.lines and len(args.files) > 1:
    parser.error('cannot use -l/--lines with more than one file')

  lines = _GetLines(args.lines) if args.lines is not None else None
  if not args.files:
    # No arguments specified. Read code from stdin.
    if args.in_place or args.diff:
      parser.error('cannot use --in-place or --diff flags when reading '
                   'from stdin')

    original_source = []
    while True:
      try:
        # Use 'raw_input' instead of 'sys.stdin.read', because otherwise the
        # user will need to hit 'Ctrl-D' more than once if they're inputting
        # the program by hand. 'raw_input' throws an EOFError exception if
        # 'Ctrl-D' is pressed, which makes it easy to bail out of this loop.
        original_source.append(py3compat.raw_input())
      except EOFError:
        break

    style_config = args.style
    if style_config is None and not args.no_local_style:
      style_config = file_resources.GetDefaultStyleForDir(os.getcwd())

    source = [line.rstrip() for line in original_source]
    reformatted_source, _ = yapf_api.FormatCode(
        py3compat.unicode('\n'.join(source) + '\n'),
        filename='<stdin>',
        style_config=style_config,
        lines=lines,
        verify=args.verify)
    file_resources.WriteReformattedCode('<stdout>', reformatted_source)
    return 0

  files = file_resources.GetCommandLineFiles(args.files, args.recursive,
                                             args.exclude)
  if not files:
    raise errors.YapfError('Input filenames did not match any python files')

  FormatFiles(
      files,
      lines,
      style_config=args.style,
      no_local_style=args.no_local_style,
      in_place=args.in_place,
      print_diff=args.diff,
      verify=args.verify,
      parallel=args.parallel)
  return 0
示例#8
0
文件: __init__.py 项目: wwade/yapf
def main(argv):
    """Main program.

  Arguments:
    argv: command-line arguments, such as sys.argv (including the program name
      in argv[0]).

  Returns:
    Zero on successful program termination, non-zero otherwise.
    With --diff: zero if there were no changes, non-zero otherwise.

  Raises:
    YapfError: if none of the supplied files were Python files.
  """
    args = _ParseArguments(argv)
    if args.version:
        print('yapf {}'.format(__version__))
        return 0

    style_config = args.style

    if args.style_help:
        print_help(args)
        return 0

    if args.lines and len(args.files) > 1:
        parser.error('cannot use -l/--lines with more than one file')

    lines = _GetLines(args.lines) if args.lines is not None else None
    if not args.files:
        # No arguments specified. Read code from stdin.
        if args.in_place or args.diff:
            parser.error('cannot use --in-place or --diff flags when reading '
                         'from stdin')

        original_source = []
        while True:
            if sys.stdin.closed:
                break
            try:
                # Use 'raw_input' instead of 'sys.stdin.read', because otherwise the
                # user will need to hit 'Ctrl-D' more than once if they're inputting
                # the program by hand. 'raw_input' throws an EOFError exception if
                # 'Ctrl-D' is pressed, which makes it easy to bail out of this loop.
                original_source.append(py3compat.raw_input())
            except EOFError:
                break
            except KeyboardInterrupt:
                return 1

        if style_config is None and not args.no_local_style:
            style_config = file_resources.GetDefaultStyleForDir(os.getcwd())

        source = [line.rstrip() for line in original_source]
        source[0] = py3compat.removeBOM(source[0])

        try:
            reformatted_source, _ = yapf_api.FormatCode(
                py3compat.unicode('\n'.join(source) + '\n'),
                filename='<stdin>',
                style_config=style_config,
                lines=lines,
                verify=args.verify)
        except tokenize.TokenError as e:
            raise errors.YapfError('%s:%s' % (e.args[1][0], e.args[0]))

        file_resources.WriteReformattedCode('<stdout>', reformatted_source)
        return 0

    # Get additional exclude patterns from ignorefile
    exclude_patterns_from_ignore_file = file_resources.GetExcludePatternsForDir(
        os.getcwd())

    files = file_resources.GetCommandLineFiles(
        args.files, args.recursive,
        (args.exclude or []) + exclude_patterns_from_ignore_file)
    if not files:
        raise errors.YapfError(
            'Input filenames did not match any python files')

    changed = FormatFiles(files,
                          lines,
                          style_config=args.style,
                          no_local_style=args.no_local_style,
                          in_place=args.in_place,
                          print_diff=args.diff,
                          verify=args.verify,
                          parallel=args.parallel,
                          quiet=args.quiet,
                          verbose=args.verbose)
    return 1 if changed and (args.diff or args.quiet) else 0
示例#9
0
 def test_no_local_style_custom_default(self):
   test_file = os.path.join(self.test_tmpdir, 'file.py')
   style_name = file_resources.GetDefaultStyleForDir(
       test_file, default_style='custom-default')
   self.assertEqual(style_name, 'custom-default')
示例#10
0
 def test_no_local_style(self):
   test_file = os.path.join(self.test_tmpdir, 'file.py')
   style_name = file_resources.GetDefaultStyleForDir(test_file)
   self.assertEqual(style_name, 'pep8')
示例#11
0
def main(argv):
  """Main program.

  Arguments:
    argv: command-line arguments, such as sys.argv (including the program name
      in argv[0]).

  Returns:
    Zero on successful program termination, non-zero otherwise.
    With --diff: zero if there were no changes, non-zero otherwise.

  Raises:
    YapfError: if none of the supplied files were Python files.
  """
  parser = argparse.ArgumentParser(description='Formatter for Python code.')
  parser.add_argument(
      '-v',
      '--version',
      action='store_true',
      help='show version number and exit')

  diff_inplace_quiet_group = parser.add_mutually_exclusive_group()
  diff_inplace_quiet_group.add_argument(
      '-d',
      '--diff',
      action='store_true',
      help='print the diff for the fixed source')
  diff_inplace_quiet_group.add_argument(
      '-i',
      '--in-place',
      action='store_true',
      help='make changes to files in place')
  diff_inplace_quiet_group.add_argument(
      '-q',
      '--quiet',
      action='store_true',
      help='output nothing and set return value')

  lines_recursive_group = parser.add_mutually_exclusive_group()
  lines_recursive_group.add_argument(
      '-r',
      '--recursive',
      action='store_true',
      help='run recursively over directories')
  lines_recursive_group.add_argument(
      '-l',
      '--lines',
      metavar='START-END',
      action='append',
      default=None,
      help='range of lines to reformat, one-based')

  parser.add_argument(
      '-e',
      '--exclude',
      metavar='PATTERN',
      action='append',
      default=None,
      help='patterns for files to exclude from formatting')
  parser.add_argument(
      '--style',
      action='store',
      help=('specify formatting style: either a style name (for example "pep8" '
            'or "google"), or the name of a file with style settings. The '
            'default is pep8 unless a %s or %s file located in the same '
            'directory as the source or one of its parent directories '
            '(for stdin, the current directory is used).' %
            (style.LOCAL_STYLE, style.SETUP_CONFIG)))
  parser.add_argument(
      '--style-help',
      action='store_true',
      help=('show style settings and exit; this output can be '
            'saved to .style.yapf to make your settings '
            'permanent'))
  parser.add_argument(
      '--no-local-style',
      action='store_true',
      help="don't search for local style definition")
  parser.add_argument('--verify', action='store_true', help=argparse.SUPPRESS)
  parser.add_argument(
      '-p',
      '--parallel',
      action='store_true',
      help=('run yapf in parallel when formatting multiple files. Requires '
            'concurrent.futures in Python 2.X'))
  parser.add_argument(
      '-vv',
      '--verbose',
      action='store_true',
      help='print out file names while processing')

  parser.add_argument(
      'files', nargs='*', help='reads from stdin when no files are specified.')
  args = parser.parse_args(argv[1:])

  if args.version:
    print('yapf {}'.format(__version__))
    return 0

  style_config = args.style

  if args.style_help:
    print_help(args)
    return 0

  if args.lines and len(args.files) > 1:
    parser.error('cannot use -l/--lines with more than one file')

  lines = _GetLines(args.lines) if args.lines is not None else None
  if not args.files:
    # No arguments specified. Read code from stdin.
    if args.in_place or args.diff:
      parser.error('cannot use --in-place or --diff flags when reading '
                   'from stdin')

    original_source = []
    while True:
      if sys.stdin.closed:
        break
      try:
        # Use 'raw_input' instead of 'sys.stdin.read', because otherwise the
        # user will need to hit 'Ctrl-D' more than once if they're inputting
        # the program by hand. 'raw_input' throws an EOFError exception if
        # 'Ctrl-D' is pressed, which makes it easy to bail out of this loop.
        original_source.append(py3compat.raw_input())
      except EOFError:
        break
      except KeyboardInterrupt:
        return 1

    if style_config is None and not args.no_local_style:
      style_config = file_resources.GetDefaultStyleForDir(os.getcwd())

    source = [line.rstrip() for line in original_source]
    source[0] = py3compat.removeBOM(source[0])

    try:
      reformatted_source, _ = yapf_api.FormatCode(
          py3compat.unicode('\n'.join(source) + '\n'),
          filename='<stdin>',
          style_config=style_config,
          lines=lines,
          verify=args.verify)
    except tokenize.TokenError as e:
      raise errors.YapfError('%s:%s' % (e.args[1][0], e.args[0]))

    file_resources.WriteReformattedCode('<stdout>', reformatted_source)
    return 0

  # Get additional exclude patterns from ignorefile
  exclude_patterns_from_ignore_file = file_resources.GetExcludePatternsForDir(
      os.getcwd())

  files = file_resources.GetCommandLineFiles(args.files, args.recursive,
                                             (args.exclude or []) +
                                             exclude_patterns_from_ignore_file)
  if not files:
    raise errors.YapfError('Input filenames did not match any python files')

  changed = FormatFiles(
      files,
      lines,
      style_config=args.style,
      no_local_style=args.no_local_style,
      in_place=args.in_place,
      print_diff=args.diff,
      verify=args.verify,
      parallel=args.parallel,
      quiet=args.quiet,
      verbose=args.verbose)
  return 1 if changed and (args.diff or args.quiet) else 0
示例#12
0
def _get_file_style():
    path = vim.current.buffer.name or os.getcwd()
    project_style = file_resources.GetDefaultStyleForDir(path)
    if project_style == style.DEFAULT_STYLE:
        return None
    return project_style
示例#13
0
 def __init__(self, path, parent):
     super(YapfItem, self).__init__(path, parent)
     self.path = str(path)
     self.show_diff = self.parent.config.option.yapfdiff is True
     self.style = self.parent.config.getoption(
         'yapfstyle') or file_resources.GetDefaultStyleForDir(self.path)
示例#14
0
    def rpc_lsp_formatter_yapf(self, args: List[Any]) -> Any:
        buf_path: Optional[str]
        buf_root_dir: str
        default_config_path: str
        fmt_ranges: Optional[List[List[int]]]
        buf_lines: List[str]
        buf_path, buf_root_dir, default_config_path, fmt_ranges, buf_lines = args

        try:
            from yapf.yapflib.yapf_api import FormatCode
            from yapf.yapflib import file_resources
            from yapf.yapflib.errors import YapfError
            from lib2to3.pgen2.parse import ParseError as ParseError2to3
        except ModuleNotFoundError as err:
            raise pynvim.ErrorResponse('yapf is not installed: {}'.format(err))

        # The following code is essentially a reimplementation of
        # <https://github.com/google/yapf/blob/v0.31.0/yapf/__init__.py#L82-L114>.
        try:
            buf_dir = os.path.dirname(
                buf_path) if buf_path is not None else buf_root_dir
            config_path = default_config_path
            if buf_dir is not None:
                # This thing is actually not possible to pull off just through shelling
                # out to Yapf because it only has an option to override the config
                # globally and without any regard for project-local settings.
                config_path = file_resources.GetDefaultStyleForDir(
                    buf_dir, default_config_path)

            if buf_root_dir is not None and buf_path is not None:
                # It should be mentioned that this function doesn't look for files in
                # parent directories, which is a shame.
                excluded_patterns = file_resources.GetExcludePatternsForDir(
                    buf_root_dir)
                if buf_path.startswith(buf_root_dir):
                    buf_path = buf_path[len(buf_root_dir):]
                if file_resources.IsIgnored(buf_path, excluded_patterns):
                    return None

            # TODO: comment here about normalization of newlines by yapf and how a
            # string takes up less space than an array of them when encoded also how
            # Vim handles BOM
            buf_text = '\n'.join(buf_lines) + '\n'

            try:
                fmt_text, changed = FormatCode(
                    buf_text,
                    filename=buf_path if buf_path is not None else '<unknown>',
                    style_config=config_path,
                    lines=fmt_ranges,
                    verify=False)
            except ParseError2to3 as err:
                # lineno, offset = err.context[1]
                # raise pynvim.ErrorResponse(
                #   'yapf: syntax error on {}:{}: {}'.format(lineno, offset, err.msg)
                # )
                return None
            except SyntaxError as err:
                # raise pynvim.ErrorResponse(
                #   'yapf: syntax error on {}:{}: {}'.format(err.lineno, err.offset, err.msg)
                # )
                return None
            if not changed:
                return None

            # TODO: write a continuation of that comment here as well
            fmt_lines = (fmt_text[:-1]
                         if fmt_text.endswith('\n') else fmt_text).split('\n')
            changed, common_lines_from_start, common_lines_from_end = (
                dotfiles.utils.simple_line_diff(buf_lines, fmt_lines))
            if not changed:
                return None
            if common_lines_from_start > 0:
                fmt_lines = fmt_lines[common_lines_from_start:]
            if common_lines_from_end > 0:
                fmt_lines = fmt_lines[:-common_lines_from_end]
            return (common_lines_from_start, common_lines_from_end, fmt_lines)

        except YapfError as err:
            # <https://github.com/google/yapf/blob/5fda04e1cdf50f548e121173337e07cc5304b752/yapf/__init__.py#L363-L365>
            # raise pynvim.ErrorResponse('yapf: {}'.format(err))
            return None