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]

Reply via email to