Python разница между итерацией стандартного потока и стандартным подпроцессом - PullRequest
0 голосов
/ 23 января 2020

У меня есть Python программа, которая изначально работает, передавая в нее некоторые выходные данные make.

make -d --dry-run | python main.py

Это прекрасно работало с моим кодом, как и предполагалось, однако это было предварительные и у меня есть изменения, чтобы сделать это Я не могу полагаться на передачу вывода с консоли прямой командой, как указано выше.

Поэтому я попытался заменить ее на subprocess.run(), и я получаю некоторое запутанное выполнение. Я сравнил вывод исходной трубы make -d --dry-run, которая была предоставлена ​​(как stdin), и stdout от subprocess.run(), и они точно такие же, после удаления всех разрывов строки (не имеет значения).

С с помощью subprocess.run () я получаю сообщение об ошибке при завершении рекурсии.

Здесь все и начинается, scan_target() - рекурсивная функция, в которой ошибка, по-видимому, возникает.

scan_makefile ()

def scan_makefile(self):
        ...
        # Create nodes based on dry run output (stdin)
        for line in sys.stdin:
            line = line.strip()
            # If line doesn't start with
            if (line.startswith('Considering target file') == False):
                continue

            ...

            if (name.endswith('.d') == False):
                child = self.get_create_target(name)
                root.children.add(child)

                # Call to recursive function
                self.scan_targets(child)

scan_targets ()

def scan_targets(self, target: Target):
        # Create nodes based on Makefile dry-run output (stdin)
        for line in sys.stdin:
            line = line.strip()
            name = self.get_target_name(line)

            # Remove path from name
            source_name = name.split('/')
            split_length = len(source_name)

            if (split_length > 0):
                name = source_name[split_length - 1]
            else:
                name = source_name[0]

            if (('all' in name) or (name.endswith('.c')) or (name.endswith('.h')) or name.endswith('.cc') or name.endswith('.a') or name.endswith('.o')):
                if (line.startswith('Considering target file ')):
                    child = self.get_create_target(name)
                    target.children.add(child)
                    self.scan_targets(child)
                elif (line.startswith('Must remake target ')):
                    self.get_create_target(name).remake = True
                elif (line.startswith('Pruning file ')):
                    child = self.get_create_target(name)
                    target.children.add(child)
                elif (line.startswith('Finished prerequisites of target file ')):
                    if (name != target.name):
                        raise ValueError('Invalid Target value. Expected ' + target.name + ' got ' + line)
                    return

Приведенный выше код работает отлично, и программа выдает ожидаемый результат при передаче из консоли. Ниже, изменения, примененные для попытки использовать subprocess.run(), вместо этого приводят к ошибке рекурсии.

scan_makefile () и scan_targets ()

Методы те же, что и выше кроме строк for line in sys.stdin:, измененных на for line in self.make_result:

make_result - это возвращаемое значение этого

    def make(directory: str) -> list:
        result = subprocess.run(['make', '-d', '--dry-run'], capture_output=True, text=True)
        return result.stdout.split('\n')

Я не уверен, в чем может быть проблема. Вот раздельный вывод diff из консоли ps против subprocess.run(), и они одинаковые.

https://www.diffchecker.com/kwjRkvw4

Помощь оценена, спасибо.

...