gpt4 book ai didi

python - PyCharm:在区域上运行 `black -S`

转载 作者:行者123 更新时间:2023-12-04 11:26:14 27 4
gpt4 key购买 nike

我们还没有准备好用 black 自动格式化整个源代码.
但有时我想执行black -S通过 PyCharm 在一个区域上。
有一个hint in the docs如何运行 black (或 black -S(我喜欢的))在整个文件中。但 ...
如何仅在 上运行黑色选定区域 ?

最佳答案

使用 Python Black PyCharm IDE 中的代码区域可以通过将其实现为 external tool 来完成。 .目前 Black 有两个主要选项来选择要格式化的代码

  • 在整个模块上运行 Black,在 CLI 上将其指定为 [SRC]...
  • 使用 -c, --code TEXT 在 CLI 上将代码区域作为字符串传递选项。

  • 下面的实现展示了如何使用第二个选项来做到这一点。原因是将黑色应用于整个模块可能会改变行数,从而使通过选择开始和结束行号来选择代码区域的工作更加复杂。
    可以实现第一个选项,但需要在 Black 格式化整个模块后将初始代码区域映射到最终代码区域。
    让我们以以下代码为例,其中有许多明显的 PEP-8 违规(缺少空格和空行):
    """
    long multi-line
    comment
    """
    def foo(token:int=None)->None:
    a=token+1

    class bar:
    foo:int=None

    def the_simple_test():
    """the_simple_test"""
    pass
    第1步。
    使用黑色 as an external tool in the IDE可以通过去 File进行配置 > Tools > External Tools并单击 AddEdit图标。
    感兴趣的是通过右边 Macros - (see point 3 "Parameter with macros")从 PyCharm IDE 到调用 Black 并执行必要处理的自定义脚本。即你需要宏
  • FilePath - File Path
  • SelectionStartLine - Selected text start line number
  • SelectionEndLine - Select text end line number
  • PyInterpreterDirectory - The directory containing the Python interpreter selected for the project

  • But from time to time I would like to execute black -S on a region via PyCharm.


    任何额外的 Black CLI options你想传递的参数最好放在参数列表的末尾。
    由于您可能在特定的 venv 上安装了 Black,该示例还使用了 PyInterpreterDirectory宏。
    屏幕截图说明了上述内容:
    enter image description here
    第2步。
    您需要实现一个脚本来调用 Black 并与 IDE 交互。下面是一个工作示例。需要注意的是:
  • 四行是特定于 OS/shell 的注释(根据您的环境调整它们应该是微不足道的)。
  • 一些细节可以进一步调整,例如,实现做出了简单的选择。

  • import os
    import pathlib
    import tempfile
    import subprocess
    import sys

    def region_to_str(file_path: pathlib.Path, start_line: int, end_line: int) -> str:

    file = open(file_path)
    str_build = list()

    for line_number, line in enumerate(file, start=1):
    if line_number > end_line:
    break
    elif line_number < start_line:
    continue
    else:
    str_build.append(line)

    return "".join(str_build)

    def black_to_clipboard(py_interpeter, black_cli_options, code_region_str):

    py_interpreter_path = pathlib.Path(py_interpeter) / "python.exe" # OS specific, .exe for Windows.

    proc = subprocess.Popen([py_interpreter_path, "-m", "black", *black_cli_options,
    "-c", code_region_str], stdout=subprocess.PIPE)

    try:
    outs, errs = proc.communicate(timeout=15)
    except TimeoutExpired:
    proc.kill()
    outs, errs = proc.communicate()

    # By default Black outputs binary, decodes to default Python module utf-8 encoding.
    result = outs.decode('utf-8').replace('\r','') # OS specific, remove \r from \n\r Windows new-line.

    tmp_dir_name = tempfile.gettempdir()
    tmp_file = tempfile.gettempdir() + "\\__run_black_tmp.txt" # OS specific, escaped path separator.

    with open(tmp_file, mode='w+', encoding='utf-8', errors='strict') as out_file:
    out_file.write(result + '\n')

    command = 'clip < ' + str(tmp_file) # OS specific, send result to clipboard for copy-paste.
    os.system(command)

    def main(argv: list[str] = sys.argv[1:]) -> int:
    """External tool script to run black on a code region.

    Args:
    argv[0] (str): Path to module containing code region.
    argv[1] (str): Code region start line.
    argv[2] (str): Code region end line.
    argv[3] (str): Path to venv /Scripts directory.
    argv[4:] (str): Black CLI options.
    """
    # print(argv)
    lines_as_str = region_to_str(argv[0], int(argv[1]), int(argv[2]))
    black_to_clipboard(argv[3], argv[4:], lines_as_str)

    if __name__ == "__main__":
    main(sys.argv[1:])
    第 3 步。
    困难的部分已经完成。让我们使用新功能。
    通常选择您想要的行作为编辑器中的代码区域。这个必须要强调,因为之前的 SelectionStartLineSelectionEndLine宏需要选择才能工作。 (请参阅下一个屏幕截图)。
    第四步。
    运行之前实现的外部工具。这可以通过在编辑器中右键单击并选择 External Tools 来完成。 > the_name_of_your_external_tool .
    enter image description here
    第 5 步。
    只需粘贴(屏幕截图显示了运行外部工具并按 Ctrl + v 后的结果)。 中的实现步骤 2 将 Black 的输出复制到您的操作系统的剪贴板,这似乎是更可取的解决方案,因为您可以通过这种方式更改编辑器内的文件 Undo Ctrl + z 也可以使用。通过在编辑器外以编程方式覆盖文件来更改文件会不太无缝,并且可能需要在编辑器内刷新它。
    enter image description here
    第 6 步。
    您可以 record a macro前面的步骤和 associate it with a keyboard shortcut一次按键即可获得上述功能(类似于复制粘贴 Ctrl + c + Ctrl + v)。
    enter image description here
    结束注释。
  • 如果您需要调试 中的功能步骤 2 Run Configuration也可以使用与外部工具配置相同的宏进行配置。
  • 使用剪贴板时要注意字符编码可以跨层更改,这一点很重要。我决定使用 clip 并直接从临时文件中读入,这是为了避免在命令行上将代码字符串传递给 Black,因为 CMD Windows 编码默认不是 UTF-8。 (对于 Linux 用户,这应该更简单,但可能取决于您的系统设置。)
  • 一个重要的注意事项是,您可以选择一个没有缩进级别更广泛上下文的代码区域。这意味着,例如,如果您只在一个类中选择 2 个方法,它们将被传递给 Black 并使用模块级函数的缩进级别进行格式化。如果您小心地选择具有适当范围的代码区域,这应该不是问题。这也可以通过传递额外的宏 SelectionStartColumn - Select text start column number 轻松解决。来自 步骤 1 并在 中的每一行前面加上该数量的空格步骤 2 脚本。 (理想情况下,此类功能将由 Black 作为 CLI 选项实现。)在任何情况下,如果需要,使用 Tab 将区域置于其适当的缩进级别非常容易。
  • 问题的主要主题是如何将 Black 与 PyCharm IDE 集成到代码区域,因此演示第二个选项应该足以解决问题,因为在大多数情况下,第一个选项只会增加实现特定的复杂性。 (答案已经足够长了。实现第一个选项的细节将为 Black 项目提供一个很好的功能/拉取请求。)
  • 关于python - PyCharm:在区域上运行 `black -S`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65951208/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com