diff --git a/airflow/configuration.py b/airflow/configuration.py index 41dc8d718e0d9..7f04c6926b24c 100644 --- a/airflow/configuration.py +++ b/airflow/configuration.py @@ -35,22 +35,25 @@ from contextlib import contextmanager from copy import deepcopy from json.decoder import JSONDecodeError -from typing import IO, Any, Dict, Generator, Iterable, Pattern, Set, Tuple, Union +from typing import IO, TYPE_CHECKING, Any, Dict, Generator, Iterable, Pattern, Set, Tuple, Union from urllib.parse import urlsplit import re2 from packaging.version import parse as parse_version from typing_extensions import overload -from airflow.auth.managers.base_auth_manager import BaseAuthManager from airflow.exceptions import AirflowConfigException -from airflow.secrets import DEFAULT_SECRETS_SEARCH_PATH, BaseSecretsBackend +from airflow.secrets import DEFAULT_SECRETS_SEARCH_PATH from airflow.utils import yaml from airflow.utils.empty_set import _get_empty_set_for_configuration from airflow.utils.module_loading import import_string from airflow.utils.providers_configuration_loader import providers_configuration_loaded from airflow.utils.weight_rule import WeightRule +if TYPE_CHECKING: + from airflow.auth.managers.base_auth_manager import BaseAuthManager + from airflow.secrets import BaseSecretsBackend + log = logging.getLogger(__name__) # show Airflow's deprecation warnings diff --git a/airflow/exceptions.py b/airflow/exceptions.py index b471297cd9593..0840e801a1a85 100644 --- a/airflow/exceptions.py +++ b/airflow/exceptions.py @@ -20,7 +20,6 @@ """Exceptions used by Airflow.""" from __future__ import annotations -import datetime import warnings from http import HTTPStatus from typing import TYPE_CHECKING, Any, NamedTuple, Sized @@ -28,6 +27,8 @@ from airflow.utils.trigger_rule import TriggerRule if TYPE_CHECKING: + import datetime + from airflow.models import DAG, DagRun diff --git a/airflow/executors/base_executor.py b/airflow/executors/base_executor.py index 909a955cbf536..2791c938a4f87 100644 --- a/airflow/executors/base_executor.py +++ b/airflow/executors/base_executor.py @@ -17,18 +17,16 @@ """Base executor - this is the base class for all the implemented executors.""" from __future__ import annotations -import argparse import logging import sys import warnings from collections import defaultdict from dataclasses import dataclass, field -from datetime import datetime from typing import TYPE_CHECKING, Any, List, Optional, Sequence, Tuple import pendulum -from airflow.cli.cli_config import DefaultHelpParser, GroupCommand +from airflow.cli.cli_config import DefaultHelpParser from airflow.configuration import conf from airflow.exceptions import RemovedInAirflow3Warning from airflow.stats import Stats @@ -38,8 +36,12 @@ PARALLELISM: int = conf.getint("core", "PARALLELISM") if TYPE_CHECKING: + import argparse + from datetime import datetime + from airflow.callbacks.base_callback_sink import BaseCallbackSink from airflow.callbacks.callback_requests import CallbackRequest + from airflow.cli.cli_config import GroupCommand from airflow.models.taskinstance import TaskInstance from airflow.models.taskinstancekey import TaskInstanceKey diff --git a/airflow/executors/local_executor.py b/airflow/executors/local_executor.py index 9dcfdb629faed..fd3cc6a62938f 100644 --- a/airflow/executors/local_executor.py +++ b/airflow/executors/local_executor.py @@ -29,8 +29,7 @@ import subprocess from abc import abstractmethod from multiprocessing import Manager, Process -from multiprocessing.managers import SyncManager -from queue import Empty, Queue +from queue import Empty from typing import TYPE_CHECKING, Any, Optional, Tuple from setproctitle import getproctitle, setproctitle @@ -42,6 +41,9 @@ from airflow.utils.state import TaskInstanceState if TYPE_CHECKING: + from multiprocessing.managers import SyncManager + from queue import Queue + from airflow.executors.base_executor import CommandType from airflow.models.taskinstance import TaskInstanceStateType from airflow.models.taskinstancekey import TaskInstanceKey diff --git a/airflow/kubernetes/pre_7_4_0_compatibility/k8s_model.py b/airflow/kubernetes/pre_7_4_0_compatibility/k8s_model.py index 8280a3265f09d..cff12d057bcad 100644 --- a/airflow/kubernetes/pre_7_4_0_compatibility/k8s_model.py +++ b/airflow/kubernetes/pre_7_4_0_compatibility/k8s_model.py @@ -19,8 +19,10 @@ from abc import ABC, abstractmethod from functools import reduce +from typing import TYPE_CHECKING -from kubernetes.client import models as k8s +if TYPE_CHECKING: + from kubernetes.client import models as k8s class K8SModel(ABC): diff --git a/airflow/kubernetes/pre_7_4_0_compatibility/pod_generator.py b/airflow/kubernetes/pre_7_4_0_compatibility/pod_generator.py index 1fe8d50d76c43..45761978638c8 100644 --- a/airflow/kubernetes/pre_7_4_0_compatibility/pod_generator.py +++ b/airflow/kubernetes/pre_7_4_0_compatibility/pod_generator.py @@ -27,13 +27,13 @@ from __future__ import annotations import copy -import datetime import logging import os import secrets import string import warnings from functools import reduce +from typing import TYPE_CHECKING import re2 from dateutil import parser @@ -54,6 +54,9 @@ from airflow.utils.hashlib_wrapper import md5 from airflow.version import version as airflow_version +if TYPE_CHECKING: + import datetime + log = logging.getLogger(__name__) MAX_LABEL_LEN = 63 diff --git a/airflow/plugins_manager.py b/airflow/plugins_manager.py index 1b117101d7f65..0970e2ca3c10d 100644 --- a/airflow/plugins_manager.py +++ b/airflow/plugins_manager.py @@ -28,19 +28,18 @@ import types from typing import TYPE_CHECKING, Any, Iterable -try: - import importlib_metadata -except ImportError: - from importlib import metadata as importlib_metadata # type: ignore[no-redef] - -from types import ModuleType - from airflow import settings from airflow.utils.entry_points import entry_points_with_dist from airflow.utils.file import find_path_from_directory from airflow.utils.module_loading import import_string, qualname if TYPE_CHECKING: + try: + import importlib_metadata + except ImportError: + from importlib import metadata as importlib_metadata # type: ignore[no-redef] + from types import ModuleType + from airflow.hooks.base import BaseHook from airflow.listeners.listener import ListenerManager from airflow.timetables.base import Timetable diff --git a/airflow/providers_manager.py b/airflow/providers_manager.py index 002747c33255d..3623be284306b 100644 --- a/airflow/providers_manager.py +++ b/airflow/providers_manager.py @@ -33,7 +33,6 @@ from typing import TYPE_CHECKING, Any, Callable, MutableMapping, NamedTuple, TypeVar, cast from packaging.utils import canonicalize_name -from typing_extensions import Literal from airflow.exceptions import AirflowOptionalProviderFeatureException from airflow.hooks.filesystem import FSHook @@ -85,6 +84,8 @@ def ensure_prefix(field): if TYPE_CHECKING: + from typing_extensions import Literal + from airflow.decorators.base import TaskDecorator from airflow.hooks.base import BaseHook diff --git a/airflow/settings.py b/airflow/settings.py index 4ba9e80bd760f..79523bb989fe1 100644 --- a/airflow/settings.py +++ b/airflow/settings.py @@ -30,8 +30,7 @@ import pluggy import sqlalchemy from sqlalchemy import create_engine, exc, text -from sqlalchemy.engine import Engine -from sqlalchemy.orm import Session as SASession, scoped_session, sessionmaker +from sqlalchemy.orm import scoped_session, sessionmaker from sqlalchemy.pool import NullPool from airflow import policies @@ -43,6 +42,9 @@ from airflow.utils.state import State if TYPE_CHECKING: + from sqlalchemy.engine import Engine + from sqlalchemy.orm import Session as SASession + from airflow.www.utils import UIAlert log = logging.getLogger(__name__) diff --git a/airflow/stats.py b/airflow/stats.py index 5b84def6db76a..f6a6e97c54359 100644 --- a/airflow/stats.py +++ b/airflow/stats.py @@ -22,7 +22,10 @@ from typing import TYPE_CHECKING, Callable from airflow.configuration import conf -from airflow.metrics.base_stats_logger import NoStatsLogger, StatsLogger +from airflow.metrics.base_stats_logger import NoStatsLogger + +if TYPE_CHECKING: + from airflow.metrics.base_stats_logger import StatsLogger log = logging.getLogger(__name__) diff --git a/airflow/templates.py b/airflow/templates.py index 8cd113054dbf0..95851253a7d22 100644 --- a/airflow/templates.py +++ b/airflow/templates.py @@ -17,11 +17,14 @@ # under the License. from __future__ import annotations -import datetime +from typing import TYPE_CHECKING import jinja2.nativetypes import jinja2.sandbox +if TYPE_CHECKING: + import datetime + class _AirflowEnvironmentMixin: def __init__(self, **kwargs): diff --git a/airflow/timetables/_cron.py b/airflow/timetables/_cron.py index 89cae4bdcbede..678762888823b 100644 --- a/airflow/timetables/_cron.py +++ b/airflow/timetables/_cron.py @@ -18,17 +18,19 @@ import datetime from functools import cached_property -from typing import Any +from typing import TYPE_CHECKING, Any from cron_descriptor import CasingTypeEnum, ExpressionDescriptor, FormatException, MissingFieldException from croniter import CroniterBadCronError, CroniterBadDateError, croniter -from pendulum import DateTime from pendulum.tz.timezone import Timezone from airflow.exceptions import AirflowTimetableInvalid from airflow.utils.dates import cron_presets from airflow.utils.timezone import convert_to_utc, make_aware, make_naive +if TYPE_CHECKING: + from pendulum import DateTime + def _is_schedule_fixed(expression: str) -> bool: """Figures out if the schedule has a fixed time (e.g. 3 AM every day). diff --git a/airflow/timetables/base.py b/airflow/timetables/base.py index c02f700233782..b5e95ef5f4662 100644 --- a/airflow/timetables/base.py +++ b/airflow/timetables/base.py @@ -19,11 +19,11 @@ from typing import TYPE_CHECKING, Any, NamedTuple, Sequence from warnings import warn -from pendulum import DateTime - from airflow.typing_compat import Protocol, runtime_checkable if TYPE_CHECKING: + from pendulum import DateTime + from airflow.utils.types import DagRunType diff --git a/airflow/timetables/events.py b/airflow/timetables/events.py index ce8fa9527f787..62cf3dce4e4bb 100644 --- a/airflow/timetables/events.py +++ b/airflow/timetables/events.py @@ -17,12 +17,16 @@ from __future__ import annotations import itertools -from typing import Iterable +from typing import TYPE_CHECKING, Iterable import pendulum -from pendulum import DateTime -from airflow.timetables.base import DagRunInfo, DataInterval, TimeRestriction, Timetable +from airflow.timetables.base import DagRunInfo, DataInterval, Timetable + +if TYPE_CHECKING: + from pendulum import DateTime + + from airflow.timetables.base import TimeRestriction class EventsTimetable(Timetable): diff --git a/airflow/timetables/interval.py b/airflow/timetables/interval.py index 27e128ff52802..077c4195a7ae0 100644 --- a/airflow/timetables/interval.py +++ b/airflow/timetables/interval.py @@ -17,16 +17,19 @@ from __future__ import annotations import datetime -from typing import Any, Union +from typing import TYPE_CHECKING, Any, Union from dateutil.relativedelta import relativedelta from pendulum import DateTime from airflow.exceptions import AirflowTimetableInvalid from airflow.timetables._cron import CronMixin -from airflow.timetables.base import DagRunInfo, DataInterval, TimeRestriction, Timetable +from airflow.timetables.base import DagRunInfo, DataInterval, Timetable from airflow.utils.timezone import convert_to_utc +if TYPE_CHECKING: + from airflow.timetables.base import TimeRestriction + Delta = Union[datetime.timedelta, relativedelta] diff --git a/airflow/timetables/simple.py b/airflow/timetables/simple.py index 53ddf6a7a85ea..0dd73627d6a6f 100644 --- a/airflow/timetables/simple.py +++ b/airflow/timetables/simple.py @@ -21,12 +21,13 @@ from pendulum import DateTime -from airflow.timetables.base import DagRunInfo, DataInterval, TimeRestriction, Timetable +from airflow.timetables.base import DagRunInfo, DataInterval, Timetable if TYPE_CHECKING: from sqlalchemy import Session from airflow.models.dataset import DatasetEvent + from airflow.timetables.base import TimeRestriction from airflow.utils.types import DagRunType diff --git a/airflow/timetables/trigger.py b/airflow/timetables/trigger.py index e5c5b7c15304a..95d29238037c4 100644 --- a/airflow/timetables/trigger.py +++ b/airflow/timetables/trigger.py @@ -17,14 +17,18 @@ from __future__ import annotations import datetime -from typing import Any +from typing import TYPE_CHECKING, Any -from dateutil.relativedelta import relativedelta from pendulum import DateTime -from pendulum.tz.timezone import Timezone from airflow.timetables._cron import CronMixin -from airflow.timetables.base import DagRunInfo, DataInterval, TimeRestriction, Timetable +from airflow.timetables.base import DagRunInfo, DataInterval, Timetable + +if TYPE_CHECKING: + from dateutil.relativedelta import relativedelta + from pendulum.tz.timezone import Timezone + + from airflow.timetables.base import TimeRestriction class CronTriggerTimetable(CronMixin, Timetable): diff --git a/airflow/triggers/external_task.py b/airflow/triggers/external_task.py index 431d91a15e025..00c7c52284435 100644 --- a/airflow/triggers/external_task.py +++ b/airflow/triggers/external_task.py @@ -18,18 +18,23 @@ import asyncio import typing -from datetime import datetime from asgiref.sync import sync_to_async from sqlalchemy import func -from sqlalchemy.orm import Session from airflow.models import DagRun, TaskInstance from airflow.triggers.base import BaseTrigger, TriggerEvent from airflow.utils.session import NEW_SESSION, provide_session -from airflow.utils.state import DagRunState, TaskInstanceState +from airflow.utils.state import TaskInstanceState from airflow.utils.timezone import utcnow +if typing.TYPE_CHECKING: + from datetime import datetime + + from sqlalchemy.orm import Session + + from airflow.utils.state import DagRunState + class TaskStateTrigger(BaseTrigger): """