From b291c6751a186074faff28b1416f769e481a344b Mon Sep 17 00:00:00 2001 From: Aditya kumar singh <143548997+Adityakk9031@users.noreply.github.com> Date: Sun, 2 Aug 2026 23:20:56 +0530 Subject: [PATCH] Fix Windows compatibility in prek scripts and POSIX-only test skip guards --- scripts/ci/prek/common_prek_utils.py | 10 +++++----- .../src/airflow_shared/observability/metrics/stats.py | 3 ++- .../tests/task_sdk/execution_time/test_supervisor.py | 4 ++++ .../tests/task_sdk/execution_time/test_task_runner.py | 5 +++++ 4 files changed, 16 insertions(+), 6 deletions(-) diff --git a/scripts/ci/prek/common_prek_utils.py b/scripts/ci/prek/common_prek_utils.py index e316eb154aea6..ce9af9d5b70ec 100644 --- a/scripts/ci/prek/common_prek_utils.py +++ b/scripts/ci/prek/common_prek_utils.py @@ -118,7 +118,7 @@ def run_command(*args, **kwargs) -> None: def read_airflow_version() -> str: - ast_obj = ast.parse((AIRFLOW_CORE_SOURCES_PATH / "airflow" / "__init__.py").read_text()) + ast_obj = ast.parse((AIRFLOW_CORE_SOURCES_PATH / "airflow" / "__init__.py").read_text(encoding="utf-8")) for node in ast_obj.body: if isinstance(node, ast.Assign): if node.targets[0].id == "__version__": # type: ignore[attr-defined] @@ -139,7 +139,7 @@ def _read_global_constants_assignment(name: str) -> Any: (``NAME: type = ...``). The value must be a literal so it can be safely evaluated with ``ast.literal_eval``. """ - tree = ast.parse(GLOBAL_CONSTANTS_PATH.read_text()) + tree = ast.parse(GLOBAL_CONSTANTS_PATH.read_text(encoding="utf-8")) for node in tree.body: if isinstance(node, ast.Assign): for target in node.targets: @@ -226,7 +226,7 @@ def insert_documentation( extra_information: str | None = None, ) -> bool: found = False - old_content = file_path.read_text() + old_content = file_path.read_text(encoding="utf-8") lines = old_content.splitlines(keepends=True) replacing = False result: list[str] = [] @@ -274,7 +274,7 @@ def read_uv_required_min_version() -> tuple[str, tuple[int, ...]]: Parses ``[tool.uv] required-version = ">=X.Y.Z"`` and returns ``(raw, tuple)``. We parse by regex to avoid pulling a TOML dep into every prek script. """ - pyproject = (AIRFLOW_ROOT_PATH / "pyproject.toml").read_text() + pyproject = (AIRFLOW_ROOT_PATH / "pyproject.toml").read_text(encoding="utf-8") # Narrow to the [tool.uv] section so we don't match a different required-version. match = re.search(r"^\[tool\.uv\]\s*$(?P.*?)(?=^\[|\Z)", pyproject, re.MULTILINE | re.DOTALL) if not match: @@ -789,7 +789,7 @@ def inner(): When only_top_level = False then returns ['os', 'collections.defaultdict', 'numpy', 'pandas.DataFrame', 'json', 'pathlib.Path', 'pathlib.PurePath'] """ - root = ast.parse(file_path.read_text(), file_path.name) + root = ast.parse(file_path.read_text(encoding="utf-8"), file_path.name) imports: list[str] = [] nodes = ast.iter_child_nodes(root) if only_top_level else ast.walk(root) diff --git a/shared/observability/src/airflow_shared/observability/metrics/stats.py b/shared/observability/src/airflow_shared/observability/metrics/stats.py index 7b51e580cd036..0775c41288664 100644 --- a/shared/observability/src/airflow_shared/observability/metrics/stats.py +++ b/shared/observability/src/airflow_shared/observability/metrics/stats.py @@ -65,7 +65,8 @@ def _reset_backend_after_fork() -> None: _backend = None -os.register_at_fork(after_in_child=_reset_backend_after_fork) +if hasattr(os, "register_at_fork"): + os.register_at_fork(after_in_child=_reset_backend_after_fork) def normalize_name_for_stats(name: str, log_warning: bool = True) -> str: diff --git a/task-sdk/tests/task_sdk/execution_time/test_supervisor.py b/task-sdk/tests/task_sdk/execution_time/test_supervisor.py index f777b2d5a8a90..0a2c21a091a68 100644 --- a/task-sdk/tests/task_sdk/execution_time/test_supervisor.py +++ b/task-sdk/tests/task_sdk/execution_time/test_supervisor.py @@ -181,6 +181,10 @@ from airflow.sdk.definitions.context import Context +pytestmark = pytest.mark.skipif( + sys.platform == "win32", reason="Supervisor uses POSIX-only process primitives" +) + log = logging.getLogger(__name__) TI_ID = uuid7() diff --git a/task-sdk/tests/task_sdk/execution_time/test_task_runner.py b/task-sdk/tests/task_sdk/execution_time/test_task_runner.py index cbd194e35ebf2..3e2d898a122f4 100644 --- a/task-sdk/tests/task_sdk/execution_time/test_task_runner.py +++ b/task-sdk/tests/task_sdk/execution_time/test_task_runner.py @@ -22,6 +22,7 @@ import functools import json import os +import sys import textwrap import time from collections.abc import Iterable @@ -192,6 +193,10 @@ from kgb import SpyAgency import time_machine +pytestmark = pytest.mark.skipif( + sys.platform == "win32", reason="Task runner uses POSIX-only process primitives" +) + def get_inline_dag(dag_id: str, task: BaseOperator) -> DAG: """Creates an inline dag and returns it based on dag_id and task."""