diff --git a/flow360/__init__.py b/flow360/__init__.py index cc5c63346..ea1dee1b7 100644 --- a/flow360/__init__.py +++ b/flow360/__init__.py @@ -1,404 +1,74 @@ """ -This module is flow360 for simulation based models +This module is flow360 for simulation based models. """ +from __future__ import annotations + +import ast from importlib import import_module +from pathlib import Path +from types import ModuleType + +_PUBLIC_NAMESPACE_MODULE: ModuleType | None = None + + +def _load_public_namespace_module() -> ModuleType: + global _PUBLIC_NAMESPACE_MODULE # pylint: disable=global-statement + if _PUBLIC_NAMESPACE_MODULE is None: + _PUBLIC_NAMESPACE_MODULE = import_module("flow360._public_namespace") + return _PUBLIC_NAMESPACE_MODULE + + +def _is_all_target(target: ast.expr) -> bool: + return isinstance(target, ast.Name) and target.id == "__all__" + -from flow360_schema.framework.expression import ( - UserVariable, - get_user_variable, - remove_user_variable, - show_user_variables, -) -from flow360_schema.models.functions import math -from flow360_schema.models.variables import solution +def _literal_exported_names(value: ast.expr | None) -> list[str]: + if value is None: + raise RuntimeError("flow360._public_namespace must assign __all__") + names = ast.literal_eval(value) + if not isinstance(names, list) or not all(isinstance(name, str) for name in names): + raise RuntimeError("flow360._public_namespace __all__ must be a list of strings") + return names -from flow360.accounts_utils import Accounts -from flow360.cli.api_set_func import configure_caller as configure -from flow360.component.case import Case -from flow360.component.cloud_examples import show_available_examples -from flow360.component.geometry import Geometry -from flow360.component.project import Project, create_draft -from flow360.component.simulation import migration, services -from flow360.component.simulation import units as u -from flow360.component.simulation.draft_context.mirror import MirrorPlane -from flow360.component.simulation.entity_operation import CoordinateSystem -from flow360.component.simulation.folder import Folder -from flow360.component.simulation.framework.entity_selector import ( - BodyGroupSelector, - EdgeSelector, - VolumeSelector, -) -from flow360.component.simulation.meshing_param import snappy -from flow360.component.simulation.meshing_param.edge_params import ( - AngleBasedRefinement, - AspectRatioBasedRefinement, - HeightBasedRefinement, - ProjectAnisoSpacing, - SurfaceEdgeRefinement, -) -from flow360.component.simulation.meshing_param.face_params import ( - BoundaryLayer, - GeometryRefinement, - PassiveSpacing, - SurfaceRefinement, -) -from flow360.component.simulation.meshing_param.meshing_specs import ( - MeshingDefaults, - OctreeSpacing, - VolumeMeshingDefaults, -) -from flow360.component.simulation.meshing_param.params import ( - MeshingParams, - ModularMeshingWorkflow, - VolumeMeshingParams, -) -from flow360.component.simulation.meshing_param.volume_params import ( - AutomatedFarfield, - AxisymmetricRefinement, - CentralBelt, - CustomZones, - FullyMovingFloor, - MeshSliceOutput, - RotationCylinder, - RotationSphere, - RotationVolume, - StaticFloor, - StructuredBoxRefinement, - UniformRefinement, - UserDefinedFarfield, - WheelBelts, - WindTunnelFarfield, -) -from flow360.component.simulation.models.material import ( - Air, - FrozenSpecies, - NASA9Coefficients, - NASA9CoefficientSet, - SolidMaterial, - Sutherland, - ThermallyPerfectGas, - Water, -) -from flow360.component.simulation.models.solver_numerics import ( - DetachedEddySimulation, - HeatEquationSolver, - KOmegaSST, - KOmegaSSTModelConstants, - KrylovLinearSolver, - LinearSolver, - LineSearch, - NavierStokesSolver, - NoneSolver, - SpalartAllmaras, - SpalartAllmarasModelConstants, - TransitionModelSolver, - TurbulenceModelControls, -) -from flow360.component.simulation.models.surface_models import ( - Freestream, - HeatFlux, - Inflow, - Mach, - MassFlowRate, - Outflow, - Periodic, - PorousJump, - Pressure, - Rotational, - SlaterPorousBleed, - SlipWall, - Supersonic, - SymmetryPlane, - Temperature, - TotalPressure, - Translational, - Wall, - WallFunction, - WallRotation, -) -from flow360.component.simulation.models.turbulence_quantities import ( - TurbulenceQuantities, -) -from flow360.component.simulation.models.volume_models import ( - ActuatorDisk, - AngleExpression, - AngularVelocity, - BETDisk, - BETDiskChord, - BETDiskSectionalPolar, - BETDiskTwist, - C81File, - DFDCFile, - Fluid, - ForcePerArea, - FromUserDefinedDynamics, - Gravity, - HeatEquationInitialCondition, - NavierStokesInitialCondition, - NavierStokesModifiedRestartSolution, - PorousMedium, - Rotation, - Solid, - XFOILFile, - XROTORFile, -) -from flow360.component.simulation.operating_condition.operating_condition import ( - AerospaceCondition, - GenericReferenceCondition, - LiquidOperatingCondition, - ThermalState, -) -from flow360.component.simulation.outputs import render_config -from flow360.component.simulation.outputs.output_entities import ( - Isosurface, - Point, - PointArray, - PointArray2D, - Slice, -) -from flow360.component.simulation.outputs.outputs import ( - AeroAcousticOutput, - ForceDistributionOutput, - ForceOutput, - IsosurfaceOutput, - MovingStatistic, - Observer, - ProbeOutput, - RenderOutput, - RenderOutputGroup, - SliceOutput, - StreamlineOutput, - SurfaceIntegralOutput, - SurfaceOutput, - SurfaceProbeOutput, - SurfaceSliceOutput, - TimeAverageForceDistributionOutput, - TimeAverageIsosurfaceOutput, - TimeAverageProbeOutput, - TimeAverageSliceOutput, - TimeAverageStreamlineOutput, - TimeAverageSurfaceOutput, - TimeAverageSurfaceProbeOutput, - TimeAverageVolumeOutput, - UserDefinedField, - VolumeOutput, -) -from flow360.component.simulation.primitives import ( - AxisymmetricBody, - Box, - CustomVolume, - Cylinder, - ReferenceGeometry, - SeedpointVolume, - Sphere, -) -from flow360.component.simulation.run_control.run_control import RunControl -from flow360.component.simulation.run_control.stopping_criterion import ( - StoppingCriterion, -) -from flow360.component.simulation.simulation_params import SimulationParams -from flow360.component.simulation.time_stepping.time_stepping import ( - AdaptiveCFL, - RampCFL, - Steady, - Unsteady, -) -from flow360.component.simulation.unit_system import ( - CGS_unit_system, - SI_unit_system, - imperial_unit_system, -) -from flow360.component.simulation.user_defined_dynamics.user_defined_dynamics import ( - UserDefinedDynamic, -) -from flow360.component.surface_mesh_v2 import SurfaceMeshV2 as SurfaceMesh -from flow360.component.volume_mesh import VolumeMeshV2 as VolumeMesh -from flow360.environment import Env -from flow360.plugins import report -from flow360.version_utils import warn_if_prerelease_version as _warn_prerelease -__all__ = [ - "GeometryRefinement", - "Env", - "Case", - "create_draft", - "CoordinateSystem", - "MirrorPlane", - "EdgeSelector", - "VolumeSelector", - "BodyGroupSelector", - "AngleBasedRefinement", - "AspectRatioBasedRefinement", - "ProjectAnisoSpacing", - "BoundaryLayer", - "PassiveSpacing", - "Accounts", - "Project", - "u", - "MeshSliceOutput", - "SimulationParams", - "SI_unit_system", - "imperial_unit_system", - "CGS_unit_system", - "services", - "MeshingParams", - "MeshingDefaults", - "SurfaceRefinement", - "AutomatedFarfield", - "AxisymmetricRefinement", - "CustomZones", - "StructuredBoxRefinement", - "RotationCylinder", - "RotationSphere", - "RotationVolume", - "UniformRefinement", - "SurfaceEdgeRefinement", - "HeightBasedRefinement", - "ReferenceGeometry", - "CustomVolume", - "Cylinder", - "Sphere", - "AxisymmetricBody", - "AerospaceCondition", - "ThermalState", - "LiquidOperatingCondition", - "Steady", - "Unsteady", - "RampCFL", - "AdaptiveCFL", - "Wall", - "WallFunction", - "Freestream", - "SlipWall", - "Outflow", - "Inflow", - "Periodic", - "PorousJump", - "SymmetryPlane", - "Fluid", - "Solid", - "ActuatorDisk", - "AngularVelocity", - "BETDisk", - "BETDiskChord", - "BETDiskSectionalPolar", - "BETDiskTwist", - "Rotation", - "PorousMedium", - "SurfaceOutput", - "TimeAverageSurfaceOutput", - "VolumeOutput", - "TimeAverageVolumeOutput", - "ForceDistributionOutput", - "TimeAverageForceDistributionOutput", - "SliceOutput", - "TimeAverageSliceOutput", - "IsosurfaceOutput", - "TimeAverageIsosurfaceOutput", - "SurfaceIntegralOutput", - "ProbeOutput", - "SurfaceProbeOutput", - "AeroAcousticOutput", - "StreamlineOutput", - "TimeAverageStreamlineOutput", - "Observer", - "HeatEquationSolver", - "NavierStokesSolver", - "NoneSolver", - "SpalartAllmaras", - "KOmegaSST", - "SpalartAllmarasModelConstants", - "DetachedEddySimulation", - "KOmegaSSTModelConstants", - "KrylovLinearSolver", - "LineSearch", - "LinearSolver", - "Folder", - "ForcePerArea", - "Air", - "NASA9CoefficientSet", - "NASA9Coefficients", - "FrozenSpecies", - "Sutherland", - "ThermallyPerfectGas", - "SolidMaterial", - "Slice", - "Isosurface", - "TurbulenceQuantities", - "UserDefinedDynamic", - "Translational", - "NavierStokesInitialCondition", - "NavierStokesModifiedRestartSolution", - "FromUserDefinedDynamics", - "Gravity", - "HeatEquationInitialCondition", - "Temperature", - "HeatFlux", - "Point", - "PointArray", - "AngleExpression", - "Box", - "GenericReferenceCondition", - "TransitionModelSolver", - "TurbulenceModelControls", - "Pressure", - "TotalPressure", - "Supersonic", - "Rotational", - "Mach", - "MassFlowRate", - "UserDefinedField", - "VolumeMesh", - "SurfaceMesh", - "UserDefinedFarfield", - "Geometry", - "XROTORFile", - "DFDCFile", - "C81File", - "XFOILFile", - "TimeAverageProbeOutput", - "TimeAverageSurfaceProbeOutput", - "SurfaceSliceOutput", - "SlaterPorousBleed", - "migration", - "Water", - "PointArray2D", - "WallRotation", - "UserVariable", - "math", - "solution", - "report", - "snappy", - "ModularMeshingWorkflow", - "SeedpointVolume", - "VolumeMeshingParams", - "VolumeMeshingDefaults", - "get_user_variable", - "show_user_variables", - "remove_user_variable", - "StoppingCriterion", - "MovingStatistic", - "OctreeSpacing", - "RunControl", - "WindTunnelFarfield", - "StaticFloor", - "FullyMovingFloor", - "CentralBelt", - "WheelBelts", - "show_available_examples", - "ForceOutput", - "RenderOutput", - "RenderOutputGroup", - "render_config", -] +def _extract_exported_names(module_ast: ast.Module) -> list[str]: + for node in module_ast.body: + if isinstance(node, ast.Assign): + for target in node.targets: + if _is_all_target(target): + return _literal_exported_names(node.value) + if isinstance(node, ast.AnnAssign) and _is_all_target(node.target): + return _literal_exported_names(node.value) + raise RuntimeError("flow360._public_namespace must define __all__") -_warn_prerelease() +def _load_exported_names() -> list[str]: + namespace_source = Path(__file__).with_name("_public_namespace.py").read_text(encoding="utf-8") + module_ast = ast.parse(namespace_source) + return _extract_exported_names(module_ast) -def __getattr__(name): + +__all__ = _load_exported_names() + + +def __getattr__(name: str): if name == "version_check": module = import_module("flow360.version_check") globals()[name] = module return module + + if name in __all__: + namespace_module = _load_public_namespace_module() + try: + value = getattr(namespace_module, name) + except AttributeError as error: + raise AttributeError(f"module {__name__!r} has no attribute {name!r}") from error + globals()[name] = value + return value + raise AttributeError(f"module {__name__!r} has no attribute {name!r}") + + +def __dir__(): + return sorted(set(globals()) | set(__all__)) diff --git a/flow360/__init__.pyi b/flow360/__init__.pyi new file mode 100644 index 000000000..3d090b978 --- /dev/null +++ b/flow360/__init__.pyi @@ -0,0 +1,192 @@ +"""Static exports for the lazy Flow360 package facade.""" + +from . import version_check as version_check +from ._public_namespace import Accounts as Accounts +from ._public_namespace import ActuatorDisk as ActuatorDisk +from ._public_namespace import AdaptiveCFL as AdaptiveCFL +from ._public_namespace import AeroAcousticOutput as AeroAcousticOutput +from ._public_namespace import AerospaceCondition as AerospaceCondition +from ._public_namespace import Air as Air +from ._public_namespace import AngleBasedRefinement as AngleBasedRefinement +from ._public_namespace import AngleExpression as AngleExpression +from ._public_namespace import AngularVelocity as AngularVelocity +from ._public_namespace import AspectRatioBasedRefinement as AspectRatioBasedRefinement +from ._public_namespace import AutomatedFarfield as AutomatedFarfield +from ._public_namespace import AxisymmetricBody as AxisymmetricBody +from ._public_namespace import AxisymmetricRefinement as AxisymmetricRefinement +from ._public_namespace import BETDisk as BETDisk +from ._public_namespace import BETDiskChord as BETDiskChord +from ._public_namespace import BETDiskSectionalPolar as BETDiskSectionalPolar +from ._public_namespace import BETDiskTwist as BETDiskTwist +from ._public_namespace import BodyGroupSelector as BodyGroupSelector +from ._public_namespace import BoundaryLayer as BoundaryLayer +from ._public_namespace import Box as Box +from ._public_namespace import C81File as C81File +from ._public_namespace import Case as Case +from ._public_namespace import CentralBelt as CentralBelt +from ._public_namespace import CGS_unit_system as CGS_unit_system +from ._public_namespace import CoordinateSystem as CoordinateSystem +from ._public_namespace import CustomVolume as CustomVolume +from ._public_namespace import CustomZones as CustomZones +from ._public_namespace import Cylinder as Cylinder +from ._public_namespace import DetachedEddySimulation as DetachedEddySimulation +from ._public_namespace import DFDCFile as DFDCFile +from ._public_namespace import EdgeSelector as EdgeSelector +from ._public_namespace import Env as Env +from ._public_namespace import Fluid as Fluid +from ._public_namespace import Folder as Folder +from ._public_namespace import ForceDistributionOutput as ForceDistributionOutput +from ._public_namespace import ForceOutput as ForceOutput +from ._public_namespace import ForcePerArea as ForcePerArea +from ._public_namespace import Freestream as Freestream +from ._public_namespace import FromUserDefinedDynamics as FromUserDefinedDynamics +from ._public_namespace import FrozenSpecies as FrozenSpecies +from ._public_namespace import FullyMovingFloor as FullyMovingFloor +from ._public_namespace import GenericReferenceCondition as GenericReferenceCondition +from ._public_namespace import Geometry as Geometry +from ._public_namespace import GeometryRefinement as GeometryRefinement +from ._public_namespace import Gravity as Gravity +from ._public_namespace import ( + HeatEquationInitialCondition as HeatEquationInitialCondition, +) +from ._public_namespace import HeatEquationSolver as HeatEquationSolver +from ._public_namespace import HeatFlux as HeatFlux +from ._public_namespace import HeightBasedRefinement as HeightBasedRefinement +from ._public_namespace import Inflow as Inflow +from ._public_namespace import Isosurface as Isosurface +from ._public_namespace import IsosurfaceOutput as IsosurfaceOutput +from ._public_namespace import KOmegaSST as KOmegaSST +from ._public_namespace import KOmegaSSTModelConstants as KOmegaSSTModelConstants +from ._public_namespace import KrylovLinearSolver as KrylovLinearSolver +from ._public_namespace import LinearSolver as LinearSolver +from ._public_namespace import LineSearch as LineSearch +from ._public_namespace import LiquidOperatingCondition as LiquidOperatingCondition +from ._public_namespace import Mach as Mach +from ._public_namespace import MassFlowRate as MassFlowRate +from ._public_namespace import MeshingDefaults as MeshingDefaults +from ._public_namespace import MeshingParams as MeshingParams +from ._public_namespace import MeshSliceOutput as MeshSliceOutput +from ._public_namespace import MirrorPlane as MirrorPlane +from ._public_namespace import ModularMeshingWorkflow as ModularMeshingWorkflow +from ._public_namespace import MovingStatistic as MovingStatistic +from ._public_namespace import NASA9Coefficients as NASA9Coefficients +from ._public_namespace import NASA9CoefficientSet as NASA9CoefficientSet +from ._public_namespace import ( + NavierStokesInitialCondition as NavierStokesInitialCondition, +) +from ._public_namespace import ( + NavierStokesModifiedRestartSolution as NavierStokesModifiedRestartSolution, +) +from ._public_namespace import NavierStokesSolver as NavierStokesSolver +from ._public_namespace import NoneSolver as NoneSolver +from ._public_namespace import Observer as Observer +from ._public_namespace import OctreeSpacing as OctreeSpacing +from ._public_namespace import Outflow as Outflow +from ._public_namespace import PassiveSpacing as PassiveSpacing +from ._public_namespace import Periodic as Periodic +from ._public_namespace import Point as Point +from ._public_namespace import PointArray as PointArray +from ._public_namespace import PointArray2D as PointArray2D +from ._public_namespace import PorousJump as PorousJump +from ._public_namespace import PorousMedium as PorousMedium +from ._public_namespace import Pressure as Pressure +from ._public_namespace import ProbeOutput as ProbeOutput +from ._public_namespace import Project as Project +from ._public_namespace import ProjectAnisoSpacing as ProjectAnisoSpacing +from ._public_namespace import RampCFL as RampCFL +from ._public_namespace import ReferenceGeometry as ReferenceGeometry +from ._public_namespace import RenderOutput as RenderOutput +from ._public_namespace import RenderOutputGroup as RenderOutputGroup +from ._public_namespace import Rotation as Rotation +from ._public_namespace import Rotational as Rotational +from ._public_namespace import RotationCylinder as RotationCylinder +from ._public_namespace import RotationSphere as RotationSphere +from ._public_namespace import RotationVolume as RotationVolume +from ._public_namespace import RunControl as RunControl +from ._public_namespace import SeedpointVolume as SeedpointVolume +from ._public_namespace import SI_unit_system as SI_unit_system +from ._public_namespace import SimulationParams as SimulationParams +from ._public_namespace import SlaterPorousBleed as SlaterPorousBleed +from ._public_namespace import Slice as Slice +from ._public_namespace import SliceOutput as SliceOutput +from ._public_namespace import SlipWall as SlipWall +from ._public_namespace import Solid as Solid +from ._public_namespace import SolidMaterial as SolidMaterial +from ._public_namespace import SpalartAllmaras as SpalartAllmaras +from ._public_namespace import ( + SpalartAllmarasModelConstants as SpalartAllmarasModelConstants, +) +from ._public_namespace import Sphere as Sphere +from ._public_namespace import StaticFloor as StaticFloor +from ._public_namespace import Steady as Steady +from ._public_namespace import StoppingCriterion as StoppingCriterion +from ._public_namespace import StreamlineOutput as StreamlineOutput +from ._public_namespace import StructuredBoxRefinement as StructuredBoxRefinement +from ._public_namespace import Supersonic as Supersonic +from ._public_namespace import SurfaceEdgeRefinement as SurfaceEdgeRefinement +from ._public_namespace import SurfaceIntegralOutput as SurfaceIntegralOutput +from ._public_namespace import SurfaceMesh as SurfaceMesh +from ._public_namespace import SurfaceOutput as SurfaceOutput +from ._public_namespace import SurfaceProbeOutput as SurfaceProbeOutput +from ._public_namespace import SurfaceRefinement as SurfaceRefinement +from ._public_namespace import SurfaceSliceOutput as SurfaceSliceOutput +from ._public_namespace import Sutherland as Sutherland +from ._public_namespace import SymmetryPlane as SymmetryPlane +from ._public_namespace import Temperature as Temperature +from ._public_namespace import ThermallyPerfectGas as ThermallyPerfectGas +from ._public_namespace import ThermalState as ThermalState +from ._public_namespace import ( + TimeAverageForceDistributionOutput as TimeAverageForceDistributionOutput, +) +from ._public_namespace import ( + TimeAverageIsosurfaceOutput as TimeAverageIsosurfaceOutput, +) +from ._public_namespace import TimeAverageProbeOutput as TimeAverageProbeOutput +from ._public_namespace import TimeAverageSliceOutput as TimeAverageSliceOutput +from ._public_namespace import ( + TimeAverageStreamlineOutput as TimeAverageStreamlineOutput, +) +from ._public_namespace import TimeAverageSurfaceOutput as TimeAverageSurfaceOutput +from ._public_namespace import ( + TimeAverageSurfaceProbeOutput as TimeAverageSurfaceProbeOutput, +) +from ._public_namespace import TimeAverageVolumeOutput as TimeAverageVolumeOutput +from ._public_namespace import TotalPressure as TotalPressure +from ._public_namespace import TransitionModelSolver as TransitionModelSolver +from ._public_namespace import Translational as Translational +from ._public_namespace import TurbulenceModelControls as TurbulenceModelControls +from ._public_namespace import TurbulenceQuantities as TurbulenceQuantities +from ._public_namespace import UniformRefinement as UniformRefinement +from ._public_namespace import Unsteady as Unsteady +from ._public_namespace import UserDefinedDynamic as UserDefinedDynamic +from ._public_namespace import UserDefinedFarfield as UserDefinedFarfield +from ._public_namespace import UserDefinedField as UserDefinedField +from ._public_namespace import UserVariable as UserVariable +from ._public_namespace import VolumeMesh as VolumeMesh +from ._public_namespace import VolumeMeshingDefaults as VolumeMeshingDefaults +from ._public_namespace import VolumeMeshingParams as VolumeMeshingParams +from ._public_namespace import VolumeOutput as VolumeOutput +from ._public_namespace import VolumeSelector as VolumeSelector +from ._public_namespace import Wall as Wall +from ._public_namespace import WallFunction as WallFunction +from ._public_namespace import WallRotation as WallRotation +from ._public_namespace import Water as Water +from ._public_namespace import WheelBelts as WheelBelts +from ._public_namespace import WindTunnelFarfield as WindTunnelFarfield +from ._public_namespace import XFOILFile as XFOILFile +from ._public_namespace import XROTORFile as XROTORFile +from ._public_namespace import configure as configure +from ._public_namespace import create_draft as create_draft +from ._public_namespace import get_user_variable as get_user_variable +from ._public_namespace import imperial_unit_system as imperial_unit_system +from ._public_namespace import math as math +from ._public_namespace import migration as migration +from ._public_namespace import remove_user_variable as remove_user_variable +from ._public_namespace import render_config as render_config +from ._public_namespace import report as report +from ._public_namespace import services as services +from ._public_namespace import show_available_examples as show_available_examples +from ._public_namespace import show_user_variables as show_user_variables +from ._public_namespace import snappy as snappy +from ._public_namespace import solution as solution +from ._public_namespace import u as u diff --git a/flow360/_public_namespace.py b/flow360/_public_namespace.py new file mode 100644 index 000000000..29f5e078c --- /dev/null +++ b/flow360/_public_namespace.py @@ -0,0 +1,404 @@ +""" +This module is flow360 for simulation based models +""" + +from flow360_schema.framework.expression import ( + UserVariable, + get_user_variable, + remove_user_variable, + show_user_variables, +) +from flow360_schema.models.functions import math +from flow360_schema.models.variables import solution + +from flow360.accounts_utils import Accounts +from flow360.component.case import Case +from flow360.component.cloud_examples import show_available_examples +from flow360.component.geometry import Geometry +from flow360.component.project import Project, create_draft +from flow360.component.simulation import migration, services +from flow360.component.simulation import units as u +from flow360.component.simulation.draft_context.mirror import MirrorPlane +from flow360.component.simulation.entity_operation import CoordinateSystem +from flow360.component.simulation.folder import Folder +from flow360.component.simulation.framework.entity_selector import ( + BodyGroupSelector, + EdgeSelector, + VolumeSelector, +) +from flow360.component.simulation.meshing_param import snappy +from flow360.component.simulation.meshing_param.edge_params import ( + AngleBasedRefinement, + AspectRatioBasedRefinement, + HeightBasedRefinement, + ProjectAnisoSpacing, + SurfaceEdgeRefinement, +) +from flow360.component.simulation.meshing_param.face_params import ( + BoundaryLayer, + GeometryRefinement, + PassiveSpacing, + SurfaceRefinement, +) +from flow360.component.simulation.meshing_param.meshing_specs import ( + MeshingDefaults, + OctreeSpacing, + VolumeMeshingDefaults, +) +from flow360.component.simulation.meshing_param.params import ( + MeshingParams, + ModularMeshingWorkflow, + VolumeMeshingParams, +) +from flow360.component.simulation.meshing_param.volume_params import ( + AutomatedFarfield, + AxisymmetricRefinement, + CentralBelt, + CustomZones, + FullyMovingFloor, + MeshSliceOutput, + RotationCylinder, + RotationSphere, + RotationVolume, + StaticFloor, + StructuredBoxRefinement, + UniformRefinement, + UserDefinedFarfield, + WheelBelts, + WindTunnelFarfield, +) +from flow360.component.simulation.models.material import ( + Air, + FrozenSpecies, + NASA9Coefficients, + NASA9CoefficientSet, + SolidMaterial, + Sutherland, + ThermallyPerfectGas, + Water, +) +from flow360.component.simulation.models.solver_numerics import ( + DetachedEddySimulation, + HeatEquationSolver, + KOmegaSST, + KOmegaSSTModelConstants, + KrylovLinearSolver, + LinearSolver, + LineSearch, + NavierStokesSolver, + NoneSolver, + SpalartAllmaras, + SpalartAllmarasModelConstants, + TransitionModelSolver, + TurbulenceModelControls, +) +from flow360.component.simulation.models.surface_models import ( + Freestream, + HeatFlux, + Inflow, + Mach, + MassFlowRate, + Outflow, + Periodic, + PorousJump, + Pressure, + Rotational, + SlaterPorousBleed, + SlipWall, + Supersonic, + SymmetryPlane, + Temperature, + TotalPressure, + Translational, + Wall, + WallFunction, + WallRotation, +) +from flow360.component.simulation.models.turbulence_quantities import ( + TurbulenceQuantities, +) +from flow360.component.simulation.models.volume_models import ( + ActuatorDisk, + AngleExpression, + AngularVelocity, + BETDisk, + BETDiskChord, + BETDiskSectionalPolar, + BETDiskTwist, + C81File, + DFDCFile, + Fluid, + ForcePerArea, + FromUserDefinedDynamics, + Gravity, + HeatEquationInitialCondition, + NavierStokesInitialCondition, + NavierStokesModifiedRestartSolution, + PorousMedium, + Rotation, + Solid, + XFOILFile, + XROTORFile, +) +from flow360.component.simulation.operating_condition.operating_condition import ( + AerospaceCondition, + GenericReferenceCondition, + LiquidOperatingCondition, + ThermalState, +) +from flow360.component.simulation.outputs import render_config +from flow360.component.simulation.outputs.output_entities import ( + Isosurface, + Point, + PointArray, + PointArray2D, + Slice, +) +from flow360.component.simulation.outputs.outputs import ( + AeroAcousticOutput, + ForceDistributionOutput, + ForceOutput, + IsosurfaceOutput, + MovingStatistic, + Observer, + ProbeOutput, + RenderOutput, + RenderOutputGroup, + SliceOutput, + StreamlineOutput, + SurfaceIntegralOutput, + SurfaceOutput, + SurfaceProbeOutput, + SurfaceSliceOutput, + TimeAverageForceDistributionOutput, + TimeAverageIsosurfaceOutput, + TimeAverageProbeOutput, + TimeAverageSliceOutput, + TimeAverageStreamlineOutput, + TimeAverageSurfaceOutput, + TimeAverageSurfaceProbeOutput, + TimeAverageVolumeOutput, + UserDefinedField, + VolumeOutput, +) +from flow360.component.simulation.primitives import ( + AxisymmetricBody, + Box, + CustomVolume, + Cylinder, + ReferenceGeometry, + SeedpointVolume, + Sphere, +) +from flow360.component.simulation.run_control.run_control import RunControl +from flow360.component.simulation.run_control.stopping_criterion import ( + StoppingCriterion, +) +from flow360.component.simulation.simulation_params import SimulationParams +from flow360.component.simulation.time_stepping.time_stepping import ( + AdaptiveCFL, + RampCFL, + Steady, + Unsteady, +) +from flow360.component.simulation.unit_system import ( + CGS_unit_system, + SI_unit_system, + imperial_unit_system, +) +from flow360.component.simulation.user_defined_dynamics.user_defined_dynamics import ( + UserDefinedDynamic, +) +from flow360.component.surface_mesh_v2 import SurfaceMeshV2 as SurfaceMesh +from flow360.component.volume_mesh import VolumeMeshV2 as VolumeMesh +from flow360.environment import Env +from flow360.plugins import report +from flow360.version_utils import warn_if_prerelease_version as _warn_prerelease + + +def configure(apikey: str, environment: str = None, profile: str = "default") -> None: + """Function interface for configuring the API key for flow360.""" + # Keep the legacy configure path lazy so `import flow360` does not load Click. + # pylint: disable=import-outside-toplevel + from flow360.cli.api_set_func import configure_caller + + configure_caller(apikey=apikey, environment=environment, profile=profile) + + +__all__ = [ + "GeometryRefinement", + "Env", + "configure", + "Case", + "create_draft", + "CoordinateSystem", + "MirrorPlane", + "EdgeSelector", + "VolumeSelector", + "BodyGroupSelector", + "AngleBasedRefinement", + "AspectRatioBasedRefinement", + "ProjectAnisoSpacing", + "BoundaryLayer", + "PassiveSpacing", + "Accounts", + "Project", + "u", + "MeshSliceOutput", + "SimulationParams", + "SI_unit_system", + "imperial_unit_system", + "CGS_unit_system", + "services", + "MeshingParams", + "MeshingDefaults", + "SurfaceRefinement", + "AutomatedFarfield", + "AxisymmetricRefinement", + "CustomZones", + "StructuredBoxRefinement", + "RotationCylinder", + "RotationSphere", + "RotationVolume", + "UniformRefinement", + "SurfaceEdgeRefinement", + "HeightBasedRefinement", + "ReferenceGeometry", + "CustomVolume", + "Cylinder", + "Sphere", + "AxisymmetricBody", + "AerospaceCondition", + "ThermalState", + "LiquidOperatingCondition", + "Steady", + "Unsteady", + "RampCFL", + "AdaptiveCFL", + "Wall", + "WallFunction", + "Freestream", + "SlipWall", + "Outflow", + "Inflow", + "Periodic", + "PorousJump", + "SymmetryPlane", + "Fluid", + "Solid", + "ActuatorDisk", + "AngularVelocity", + "BETDisk", + "BETDiskChord", + "BETDiskSectionalPolar", + "BETDiskTwist", + "Rotation", + "PorousMedium", + "SurfaceOutput", + "TimeAverageSurfaceOutput", + "VolumeOutput", + "TimeAverageVolumeOutput", + "ForceDistributionOutput", + "TimeAverageForceDistributionOutput", + "SliceOutput", + "TimeAverageSliceOutput", + "IsosurfaceOutput", + "TimeAverageIsosurfaceOutput", + "SurfaceIntegralOutput", + "ProbeOutput", + "SurfaceProbeOutput", + "AeroAcousticOutput", + "StreamlineOutput", + "TimeAverageStreamlineOutput", + "Observer", + "HeatEquationSolver", + "NavierStokesSolver", + "NoneSolver", + "SpalartAllmaras", + "KOmegaSST", + "SpalartAllmarasModelConstants", + "DetachedEddySimulation", + "KOmegaSSTModelConstants", + "KrylovLinearSolver", + "LineSearch", + "LinearSolver", + "Folder", + "ForcePerArea", + "Air", + "NASA9CoefficientSet", + "NASA9Coefficients", + "FrozenSpecies", + "Sutherland", + "ThermallyPerfectGas", + "SolidMaterial", + "Slice", + "Isosurface", + "TurbulenceQuantities", + "UserDefinedDynamic", + "Translational", + "NavierStokesInitialCondition", + "NavierStokesModifiedRestartSolution", + "FromUserDefinedDynamics", + "Gravity", + "HeatEquationInitialCondition", + "Temperature", + "HeatFlux", + "Point", + "PointArray", + "AngleExpression", + "Box", + "GenericReferenceCondition", + "TransitionModelSolver", + "TurbulenceModelControls", + "Pressure", + "TotalPressure", + "Supersonic", + "Rotational", + "Mach", + "MassFlowRate", + "UserDefinedField", + "VolumeMesh", + "SurfaceMesh", + "UserDefinedFarfield", + "Geometry", + "XROTORFile", + "DFDCFile", + "C81File", + "XFOILFile", + "TimeAverageProbeOutput", + "TimeAverageSurfaceProbeOutput", + "SurfaceSliceOutput", + "SlaterPorousBleed", + "migration", + "Water", + "PointArray2D", + "WallRotation", + "UserVariable", + "math", + "solution", + "report", + "snappy", + "ModularMeshingWorkflow", + "SeedpointVolume", + "VolumeMeshingParams", + "VolumeMeshingDefaults", + "get_user_variable", + "show_user_variables", + "remove_user_variable", + "StoppingCriterion", + "MovingStatistic", + "OctreeSpacing", + "RunControl", + "WindTunnelFarfield", + "StaticFloor", + "FullyMovingFloor", + "CentralBelt", + "WheelBelts", + "show_available_examples", + "ForceOutput", + "RenderOutput", + "RenderOutputGroup", + "render_config", +] + +_warn_prerelease() diff --git a/tests/test_lazy_imports.py b/tests/test_lazy_imports.py index 75bb93771..1ca673929 100644 --- a/tests/test_lazy_imports.py +++ b/tests/test_lazy_imports.py @@ -1,48 +1,81 @@ +import ast import sys +from pathlib import Path +import pytest from click.testing import CliRunner +def _unload_modules(monkeypatch, *module_names): + for module_name in module_names: + monkeypatch.delitem(sys.modules, module_name, raising=False) + + +def _load_public_namespace_all(): + namespace_source = Path(__file__).parents[1] / "flow360" / "_public_namespace.py" + module_ast = ast.parse(namespace_source.read_text(encoding="utf-8")) + for node in module_ast.body: + if isinstance(node, ast.Assign): + for target in node.targets: + if isinstance(target, ast.Name) and target.id == "__all__": + return ast.literal_eval(node.value) + if ( + isinstance(node, ast.AnnAssign) + and isinstance(node.target, ast.Name) + and node.target.id == "__all__" + ): + return ast.literal_eval(node.value) + raise AssertionError("flow360._public_namespace must define __all__") + + def test_import_flow360_does_not_eagerly_import_heavy_dependencies(monkeypatch): monkeypatch.delenv("FLOW360_SUPPRESS_BETA_WARNING", raising=False) - sys.modules.pop("flow360", None) - sys.modules.pop("flow360._api", None) - sys.modules.pop("pandas", None) + _unload_modules(monkeypatch, "flow360", "flow360._public_namespace", "pandas") import flow360 # pylint: disable=import-outside-toplevel,import-error assert "pandas" not in sys.modules - assert hasattr(flow360, "Env") + assert "flow360._public_namespace" not in sys.modules + assert "Env" in flow360.__all__ def test_import_flow360_cli_app_does_not_eagerly_import_sdk_command_modules(monkeypatch): monkeypatch.delenv("FLOW360_SUPPRESS_BETA_WARNING", raising=False) - for module_name in ( + _unload_modules( + monkeypatch, "flow360.cli", "flow360.cli.app", "flow360.cli.project", + "flow360.cli.assets", + "flow360.cli.draft", "flow360.cli.folder", + "flow360.cli.wait", "flow360.cloud.flow360_requests", - ): - sys.modules.pop(module_name, None) + ) import flow360.cli.app # pylint: disable=import-outside-toplevel,import-error,unused-import assert "flow360.cli.project" not in sys.modules + assert "flow360.cli.assets" not in sys.modules + assert "flow360.cli.draft" not in sys.modules assert "flow360.cli.folder" not in sys.modules + assert "flow360.cli.wait" not in sys.modules assert "flow360.cloud.flow360_requests" not in sys.modules def test_flow360_root_help_does_not_eagerly_import_sdk_command_modules(monkeypatch): monkeypatch.delenv("FLOW360_SUPPRESS_BETA_WARNING", raising=False) - for module_name in ( + _unload_modules( + monkeypatch, "flow360.cli", "flow360.cli.app", "flow360.cli.project", + "flow360.cli.assets", + "flow360.cli.draft", "flow360.cli.folder", + "flow360.cli.wait", "flow360.cloud.flow360_requests", - ): - sys.modules.pop(module_name, None) + ) from flow360.cli import ( flow360, # pylint: disable=import-outside-toplevel,import-error @@ -52,5 +85,100 @@ def test_flow360_root_help_does_not_eagerly_import_sdk_command_modules(monkeypat assert result.exit_code == 0 assert "flow360.cli.project" not in sys.modules + assert "flow360.cli.assets" not in sys.modules + assert "flow360.cli.draft" not in sys.modules assert "flow360.cli.folder" not in sys.modules + assert "flow360.cli.wait" not in sys.modules assert "flow360.cloud.flow360_requests" not in sys.modules + + +def test_public_namespace_configure_does_not_eagerly_import_cli_modules(monkeypatch): + monkeypatch.delenv("FLOW360_SUPPRESS_BETA_WARNING", raising=False) + _unload_modules( + monkeypatch, + "flow360._public_namespace", + "flow360.cli", + "flow360.cli.app", + "flow360.cli.api_set_func", + ) + + from flow360 import ( + _public_namespace, # pylint: disable=import-outside-toplevel,import-error + ) + + assert callable(_public_namespace.configure) + assert "flow360.cli.app" not in sys.modules + assert "flow360.cli.api_set_func" not in sys.modules + + +def test_flow360_configure_is_exposed_without_importing_public_namespace_module(monkeypatch): + monkeypatch.delenv("FLOW360_SUPPRESS_BETA_WARNING", raising=False) + _unload_modules( + monkeypatch, + "flow360", + "flow360._public_namespace", + "flow360.cli", + "flow360.cli.app", + "flow360.cli.api_set_func", + ) + + import flow360 # pylint: disable=import-outside-toplevel,import-error + + assert "configure" in flow360.__all__ + assert "flow360._public_namespace" not in sys.modules + assert "flow360.cli.app" not in sys.modules + assert "flow360.cli.api_set_func" not in sys.modules + + +def test_exported_name_loader_fails_when_public_namespace_has_no_all(): + import flow360 # pylint: disable=import-outside-toplevel,import-error + + module_ast = ast.parse("PUBLIC_NAME = 'Env'") + + with pytest.raises(RuntimeError, match="must define __all__"): + flow360._extract_exported_names(module_ast) # pylint: disable=protected-access + + +def test_exported_name_loader_supports_annotated_all_assignment(): + import flow360 # pylint: disable=import-outside-toplevel,import-error + + module_ast = ast.parse("__all__: list[str] = ['Env', 'Project']") + + assert flow360._extract_exported_names(module_ast) == [ # pylint: disable=protected-access + "Env", + "Project", + ] + + +def test_flow360_version_check_legacy_lazy_attribute_does_not_import_public_namespace_module( + monkeypatch, +): + _unload_modules(monkeypatch, "flow360", "flow360._public_namespace", "flow360.version_check") + + import flow360 # pylint: disable=import-outside-toplevel,import-error + + assert flow360.version_check.__name__ == "flow360.version_check" + assert "flow360._public_namespace" not in sys.modules + + +def test_flow360_stub_reexports_match_lazy_public_namespace_exports(): + stub_source = Path(__file__).parents[1] / "flow360" / "__init__.pyi" + module_ast = ast.parse(stub_source.read_text(encoding="utf-8")) + + stub_namespace_reexports = set() + has_version_check_reexport = False + for node in module_ast.body: + if not isinstance(node, ast.ImportFrom): + continue + if node.module == "_public_namespace" and node.level == 1: + for imported_name in node.names: + assert imported_name.asname == imported_name.name + stub_namespace_reexports.add(imported_name.name) + if node.module is None and node.level == 1: + has_version_check_reexport = any( + imported_name.name == imported_name.asname == "version_check" + for imported_name in node.names + ) + + assert stub_namespace_reexports == set(_load_public_namespace_all()) + assert has_version_check_reexport