potiuk commented on PR #44086:
URL: https://github.com/apache/airflow/pull/44086#issuecomment-2480398502
IMHO I think those lazy imports (below) are evil.
I think we should not try to repeat the same mistake we did with "airflow.".
In theory it's **nice** to have objects like that at the top package, but it
only creates confusion to have the same classes importable from multiple places
and it precisely causes circular imports, because instead of distributing
imports and only importing what's needed, we are effectively importing the
whole sub-tree - even if those imports are "lazified".
In Airflow 2 it caused us to have a special pre-commit that forbid to import
from top-level when we used it in "core" airflow codebase because it caused
exactly the same circular imports problem.
I would very much prefer if we ALWAYS explicitly import from `definitions`.
Other than being a little longer, it does not have any other bad effects, and
it's actually even better for IDEs because it will automatically import it from
the right place. And it's more explicit (i.e. follows Python Zen).
I think we are trying to be too smart with those lazy imports - for no good
reason. IMHO in most cases __init__ should contain absolutely nothing, unless
it's really necessary, that improves startup time - and avoids the circular
imports problems like that.
```
__all__ = [
"BaseOperator",
"DAG",
"EdgeModifier",
"Label",
"TaskGroup",
"dag",
"__version__",
]
__version__ = "1.0.0.dev1"
if TYPE_CHECKING:
from airflow.sdk.definitions.baseoperator import BaseOperator
from airflow.sdk.definitions.dag import DAG, dag
from airflow.sdk.definitions.edges import EdgeModifier, Label
from airflow.sdk.definitions.taskgroup import TaskGroup
__lazy_imports: dict[str, str] = {
"DAG": ".definitions.dag",
"dag": ".definitions.dag",
"BaseOperator": ".definitions.baseoperator",
"TaskGroup": ".definitions.taskgroup",
"EdgeModifier": ".definitions.edges",
"Label": ".definitions.edges",
}
def __getattr__(name: str):
if module_path := __lazy_imports.get(name):
import importlib
mod = importlib.import_module(module_path, __name__)
val = getattr(mod, name)
# Store for next time
globals()[name] = val
return val
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]