Python `invoke` не печатает с помощью многострочных команд в Windows - PullRequest
0 голосов
/ 21 февраля 2019

При использовании библиотеки invoke из Windows создается впечатление, что вывод не выводится на терминал, если команда занимает несколько строк.Вот пример для воспроизведения;положить это в tasks.py.

import invoke

@invoke.task
def test_oneline(ctx):
    ctx.run("pip install nonexistant-package1234")

@invoke.task
def test_multiline(ctx):
    ctx.run(
    """
    pip install nonexistant-package1234
    """
    )

Затем из командной строки в том же каталоге, что и tasks.py, я получаю следующее:

>invoke test-oneline
Collecting nonexistant-package1234
  Could not find a version that satisfies the requirement nonexistant-package1234 (from versions: )
No matching distribution found for nonexistant-package1234
>
>invoke test-multiline

>

ВыполнениеТо же самое в Linux (ну, по крайней мере, Windows Subsystem for Linux) работает как положено:

$ invoke test-multiline
Collecting nonexistant-package1234
  Could not find a version that satisfies the requirement nonexistant-package1234 (from versions: )
No matching distribution found for nonexistant-package1234
$

Есть ли способ напечатать вывод в Windows для многострочных команд?

1 Ответ

0 голосов
/ 21 февраля 2019

Вот хак, который я сейчас использую на тот случай, если другим нужно обойти это в краткосрочной перспективе.Я отправлю ответ, если у меня возникнут проблемы с ним;пока только минимально проверено.В основном, если вы работаете в Windows, я просто записываю команду в файл .bat, затем запускаю файл .bat (как однострочную команду).

import invoke
import platform
from pathlib import Path
from tempfile import TemporaryDirectory


def _fixed_run(ctx, cmd: str, *args, **kwargs):
    if platform.system() != "Windows":
        return ctx._old_run(cmd, *args, **kwargs)

    with TemporaryDirectory() as tmp_dir:
        tmp_file = Path(tmp_dir) / "tmp.bat"
        tmp_file.write_text("@echo off\r\n" + cmd)
        return ctx._old_run(str(tmp_file), *args, **kwargs)

invoke.Context._old_run = invoke.Context.run
invoke.Context.run = _fixed_run

Чтобы использовать этолегко, сохраните его в файл (например, fix_invoke.py, а затем просто сделайте import fix_invoke всякий раз, когда вам нужно это исправление).

Я был бы рад услышать о реальном решении, хотя, если у кого-то есть такое решение!

...