From ceb883c36c4ba5203f124f39de537adbfd749448 Mon Sep 17 00:00:00 2001 From: Ash Berlin-Taylor Date: Fri, 30 Sep 2022 17:23:33 +0100 Subject: [PATCH] Fix running debuggers inside `airflow tasks test` As part of 2.3.3 we added redaction to output from the tasks test command, but unfortunately that broke using a debugger with this error: ``` File "/usr/lib/python3.10/pdb.py", line 262, in user_line self.interaction(frame, None) File "/home/ash/.virtualenvs/airflow/lib/python3.10/site-packages/pdb.py", line 231, in interaction self._cmdloop() File "/usr/lib/python3.10/pdb.py", line 322, in _cmdloop self.cmdloop() File "/usr/lib/python3.10/cmd.py", line 126, in cmdloop line = input(self.prompt) TypeError: 'NoneType' object cannot be interpreted as an integer ``` (ipdb has a similar but different error) The "fix" is to assign a fileno attribute to the object. `input()` needs this to write the prompt. It feels like a "bug" that it doesn't work without it, but as this class is only used in `tasks test` this is a safe change --- airflow/utils/log/secrets_masker.py | 1 + tests/utils/log/test_secrets_masker.py | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/airflow/utils/log/secrets_masker.py b/airflow/utils/log/secrets_masker.py index 4200056abc5b2..17234bf4082ea 100644 --- a/airflow/utils/log/secrets_masker.py +++ b/airflow/utils/log/secrets_masker.py @@ -271,6 +271,7 @@ class RedactedIO(TextIO): def __init__(self): self.target = sys.stdout + self.fileno = sys.stdout.fileno def write(self, s: str) -> int: s = redact(s) diff --git a/tests/utils/log/test_secrets_masker.py b/tests/utils/log/test_secrets_masker.py index c07be27bb7ae0..6de30eb574787 100644 --- a/tests/utils/log/test_secrets_masker.py +++ b/tests/utils/log/test_secrets_masker.py @@ -18,9 +18,11 @@ import contextlib import inspect +import io import logging import logging.config import os +import sys import textwrap import pytest @@ -363,3 +365,13 @@ def test_write(self, capsys): RedactedIO().write(p) stdout = capsys.readouterr().out assert stdout == "***" + + def test_input_builtin(self, monkeypatch): + """ + Test that when redirect is inplace the `input()` builtin works. + + This is used by debuggers! + """ + monkeypatch.setattr(sys, 'stdin', io.StringIO("a\n")) + with contextlib.redirect_stdout(RedactedIO()): + assert input() == "a"