diff --git a/airflow-core/tests/unit/charts/helm_template_generator.py b/airflow-core/tests/unit/charts/helm_template_generator.py index 954ac98d92e54..04e6828e8778c 100644 --- a/airflow-core/tests/unit/charts/helm_template_generator.py +++ b/airflow-core/tests/unit/charts/helm_template_generator.py @@ -141,7 +141,7 @@ def render_chart( if show_only: for i in show_only: command.extend(["--show-only", i]) - result = subprocess.run(command, capture_output=True, cwd=chart_dir) + result = subprocess.run(command, check=False, capture_output=True, cwd=chart_dir) if result.returncode: raise HelmFailedError(result.returncode, result.args, result.stdout, result.stderr) templates = result.stdout diff --git a/dev/breeze/src/airflow_breeze/utils/publish_docs_to_s3.py b/dev/breeze/src/airflow_breeze/utils/publish_docs_to_s3.py index ef2459ff34266..07e3e760d8156 100644 --- a/dev/breeze/src/airflow_breeze/utils/publish_docs_to_s3.py +++ b/dev/breeze/src/airflow_breeze/utils/publish_docs_to_s3.py @@ -123,7 +123,10 @@ def sync_docs_to_s3(self, source: str, destination: str): return (0, "") get_console().print(f"[info]Syncing {source} to {destination}\n") result = subprocess.run( - ["aws", "s3", "sync", "--delete", source, destination], capture_output=True, text=True + ["aws", "s3", "sync", "--delete", source, destination], + check=False, + capture_output=True, + text=True, ) return (result.returncode, result.stderr) diff --git a/devel-common/src/sphinx_exts/docs_build/docs_builder.py b/devel-common/src/sphinx_exts/docs_build/docs_builder.py index 1f410fdfe7b22..147215a7353b2 100644 --- a/devel-common/src/sphinx_exts/docs_build/docs_builder.py +++ b/devel-common/src/sphinx_exts/docs_build/docs_builder.py @@ -192,6 +192,7 @@ def check_spelling(self, verbose: bool) -> tuple[list[SpellingError], list[DocBu with open(self.log_spelling_filename, "w") as output: completed_proc = run( build_cmd, + check=False, cwd=AIRFLOW_CONTENT_ROOT_PATH, env=env, stdout=output if not verbose else None, @@ -274,6 +275,7 @@ def build_sphinx_docs(self, verbose: bool) -> list[DocBuildError]: with open(self.log_build_filename, "w") as output: completed_proc = run( build_cmd, + check=False, cwd=AIRFLOW_CONTENT_ROOT_PATH, env=env, stdout=output if not verbose else None, diff --git a/helm-tests/tests/chart_utils/helm_template_generator.py b/helm-tests/tests/chart_utils/helm_template_generator.py index 3cd93aea09cfd..0eca0a9f1a20b 100644 --- a/helm-tests/tests/chart_utils/helm_template_generator.py +++ b/helm-tests/tests/chart_utils/helm_template_generator.py @@ -203,7 +203,7 @@ def render_chart( if show_only: for i in show_only: command.extend(["--show-only", i]) - result = subprocess.run(command, capture_output=True, cwd=chart_dir) + result = subprocess.run(command, check=False, capture_output=True, cwd=chart_dir) if result.returncode: raise HelmFailedError(result.returncode, result.args, result.stdout, result.stderr) templates = result.stdout diff --git a/providers/amazon/src/airflow/providers/amazon/aws/executors/aws_lambda/docker/app.py b/providers/amazon/src/airflow/providers/amazon/aws/executors/aws_lambda/docker/app.py index 4f351fba7381f..702e9ee13480f 100644 --- a/providers/amazon/src/airflow/providers/amazon/aws/executors/aws_lambda/docker/app.py +++ b/providers/amazon/src/airflow/providers/amazon/aws/executors/aws_lambda/docker/app.py @@ -66,7 +66,11 @@ def run_and_report(command, task_key): try: log.info("Starting execution for task: %s", task_key) result = subprocess.run( - command, shell=isinstance(command, str), stdout=subprocess.PIPE, stderr=subprocess.STDOUT + command, + check=False, + shell=isinstance(command, str), + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, ) return_code = result.returncode log.info("Execution completed for task %s with return code %s", task_key, return_code) diff --git a/providers/celery/src/airflow/providers/celery/executors/celery_executor_utils.py b/providers/celery/src/airflow/providers/celery/executors/celery_executor_utils.py index fe9323fedbfd9..94bf74f48753e 100644 --- a/providers/celery/src/airflow/providers/celery/executors/celery_executor_utils.py +++ b/providers/celery/src/airflow/providers/celery/executors/celery_executor_utils.py @@ -247,7 +247,14 @@ def _execute_in_subprocess(command_to_exec: CommandType, celery_task_id: str | N if celery_task_id: env["external_executor_id"] = celery_task_id try: - subprocess.run(command_to_exec, stderr=sys.__stderr__, stdout=sys.__stdout__, close_fds=True, env=env) + subprocess.run( + command_to_exec, + check=False, + stderr=sys.__stderr__, + stdout=sys.__stdout__, + close_fds=True, + env=env, + ) except subprocess.CalledProcessError as e: log.exception("[%s] execute_command encountered a CalledProcessError", celery_task_id) log.error(e.output) diff --git a/providers/google/src/airflow/providers/google/cloud/hooks/cloud_sql.py b/providers/google/src/airflow/providers/google/cloud/hooks/cloud_sql.py index 409bb2cce30ba..0313aa6756183 100644 --- a/providers/google/src/airflow/providers/google/cloud/hooks/cloud_sql.py +++ b/providers/google/src/airflow/providers/google/cloud/hooks/cloud_sql.py @@ -1212,7 +1212,7 @@ def _generate_login_token(self, service_account) -> str: cloud_sql_hook = CloudSQLHook(api_version="v1", gcp_conn_id=self.gcp_conn_id) with cloud_sql_hook.provide_authorized_gcloud(): - proc = subprocess.run(cmd, capture_output=True) + proc = subprocess.run(cmd, check=False, capture_output=True) if proc.returncode != 0: stderr_last_20_lines = "\n".join(proc.stderr.decode().strip().splitlines()[-20:]) diff --git a/providers/google/src/airflow/providers/google/cloud/hooks/dataflow.py b/providers/google/src/airflow/providers/google/cloud/hooks/dataflow.py index d52c77ecb8ce6..0b75a4e9b3223 100644 --- a/providers/google/src/airflow/providers/google/cloud/hooks/dataflow.py +++ b/providers/google/src/airflow/providers/google/cloud/hooks/dataflow.py @@ -1005,7 +1005,7 @@ def _create_dataflow_job_with_gcloud(self, cmd: list[str]) -> str: success_code = 0 with self.provide_authorized_gcloud(): - proc = subprocess.run(cmd, capture_output=True) + proc = subprocess.run(cmd, check=False, capture_output=True) if proc.returncode != success_code: stderr_last_20_lines = "\n".join(proc.stderr.decode().strip().splitlines()[-20:]) diff --git a/providers/google/src/airflow/providers/google/cloud/hooks/dataproc.py b/providers/google/src/airflow/providers/google/cloud/hooks/dataproc.py index 872673aae6b12..a3d17db447f00 100644 --- a/providers/google/src/airflow/providers/google/cloud/hooks/dataproc.py +++ b/providers/google/src/airflow/providers/google/cloud/hooks/dataproc.py @@ -298,7 +298,7 @@ def _create_dataproc_cluster_with_gcloud(self, cmd: list[str]) -> str: success_code = 0 with self.provide_authorized_gcloud(): - proc = subprocess.run(cmd, capture_output=True) + proc = subprocess.run(cmd, check=False, capture_output=True) if proc.returncode != success_code: stderr_last_20_lines = "\n".join(proc.stderr.decode().strip().splitlines()[-20:]) diff --git a/pyproject.toml b/pyproject.toml index ab54f43e231b9..4965c934a6548 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -601,6 +601,7 @@ extend-select = [ "PLW1501", # {mode} is not a valid mode for open "PLW1507", # Shallow copy of os.environ via copy.copy(os.environ) "PLW1508", # Invalid type for environment variable default; expected str or None + "PLW1510", # subprocess.run without explicit check argument # Per rule enables "RUF006", # Checks for asyncio dangling task "RUF015", # Checks for unnecessary iterable allocation for first element diff --git a/scripts/in_container/in_container_utils.py b/scripts/in_container/in_container_utils.py index b6f5bd4d95f5a..1368f0817c0bd 100644 --- a/scripts/in_container/in_container_utils.py +++ b/scripts/in_container/in_container_utils.py @@ -57,7 +57,7 @@ def run_command(cmd: list[str], github_actions: bool, **kwargs) -> subprocess.Co with ci_group( f"Running command: {' '.join([shlex.quote(arg) for arg in cmd])}", github_actions=github_actions ): - result = subprocess.run(cmd, **kwargs) + result = subprocess.run(cmd, **kwargs) # noqa: PLW1510 - check is handled below and added by callers if result.returncode != 0 and github_actions and kwargs.get("check", False): console.print(f"[red]Command failed: {' '.join([shlex.quote(entry) for entry in cmd])}[/]") console.print("[red]Please unfold the above group and to investigate the issue[/]") diff --git a/scripts/in_container/run_check_default_configuration.py b/scripts/in_container/run_check_default_configuration.py index 7510da30689f7..b32917f2ec73c 100755 --- a/scripts/in_container/run_check_default_configuration.py +++ b/scripts/in_container/run_check_default_configuration.py @@ -39,7 +39,7 @@ # Write default config cmd output to a temporary file default_config_file = os.path.join(tmp_dir, "airflow.cfg") with open(default_config_file, "w") as f: - result = subprocess.run(list_default_config_cmd, stdout=f) + result = subprocess.run(list_default_config_cmd, check=False, stdout=f) if result.returncode != 0: print(f"\033[0;31mERROR: when running `{' '.join(list_default_config_cmd)}`\033[0m\n") exit(1) @@ -47,7 +47,7 @@ env = os.environ.copy() env["AIRFLOW_HOME"] = tmp_dir env["AIRFLOW_CONFIG"] = default_config_file - result = subprocess.run(lint_config_cmd, capture_output=True, env=env) + result = subprocess.run(lint_config_cmd, check=False, capture_output=True, env=env) output: str = result.stdout.decode().strip() if result.returncode != 0 or expected_output not in output: diff --git a/scripts/in_container/run_prepare_airflow_distributions.py b/scripts/in_container/run_prepare_airflow_distributions.py index 2c9a6ad647991..6dfc64a8d3830 100755 --- a/scripts/in_container/run_prepare_airflow_distributions.py +++ b/scripts/in_container/run_prepare_airflow_distributions.py @@ -93,6 +93,7 @@ def build_airflow_packages(distribution_format: str): console.print(f"[bright_blue]Building apache-airflow-core distributions: {distribution_format}\n") build_process = subprocess.run( airflow_core_build_command, + check=False, capture_output=False, cwd=AIRFLOW_CORE_ROOT_PATH, env=envcopy, @@ -105,6 +106,7 @@ def build_airflow_packages(distribution_format: str): console.print(f"[bright_blue]Building apache-airflow distributions: {distribution_format}\n") build_process = subprocess.run( airflow_build_command, + check=False, capture_output=False, cwd=AIRFLOW_ROOT_PATH, env=envcopy, diff --git a/scripts/tools/initialize_virtualenv.py b/scripts/tools/initialize_virtualenv.py index f78a2dab40bcc..96dd60fd28f58 100755 --- a/scripts/tools/initialize_virtualenv.py +++ b/scripts/tools/initialize_virtualenv.py @@ -93,7 +93,7 @@ def uv_install_requirements() -> int: quoted_command = " ".join([shlex.quote(parameter) for parameter in uv_install_command]) print() print(f"Running command: \n {quoted_command}\n") - e = subprocess.run(uv_install_command) + e = subprocess.run(uv_install_command, check=False) return e.returncode @@ -116,7 +116,7 @@ def main(): if not check_if_in_virtualenv(): version = get_python_version() - e = subprocess.run(["uv", "venv", "--python", version]) + e = subprocess.run(["uv", "venv", "--python", version], check=False) if e.returncode != 0: print(f"There was a problem with 'uv venv'. Error code: {e.returncode}") @@ -168,7 +168,7 @@ def main(): env["AIRFLOW__DATABASE__SQL_ALCHEMY_POOL_ENABLED"] = "False" env["AIRFLOW__CORE__DAGS_FOLDER"] = f"{airflow_sources}/empty" env["AIRFLOW__CORE__PLUGINS_FOLDER"] = f"{airflow_sources}/empty" - subprocess.run(["uv", "run", "airflow", "db", "reset", "--yes"], env=env) + subprocess.run(["uv", "run", "airflow", "db", "reset", "--yes"], check=False, env=env) print("\nResetting AIRFLOW sqlite unit test database...") env = os.environ.copy() @@ -177,7 +177,7 @@ def main(): env["AIRFLOW__DATABASE__SQL_ALCHEMY_POOL_ENABLED"] = "False" env["AIRFLOW__CORE__DAGS_FOLDER"] = f"{airflow_sources}/empty" env["AIRFLOW__CORE__PLUGINS_FOLDER"] = f"{airflow_sources}/empty" - subprocess.run(["uv", "run", "airflow", "db", "reset", "--yes"], env=env) + subprocess.run(["uv", "run", "airflow", "db", "reset", "--yes"], check=False, env=env) print("\nInitialization of environment complete! Go ahead and develop Airflow!")