Skip to content

Commit 6241b3e

Browse files
Merge branch 'develop' into snappy-main
2 parents 2f7744a + a9ac9fa commit 6241b3e

File tree

20 files changed

+88
-56
lines changed

20 files changed

+88
-56
lines changed

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ jobs:
1717
runs-on: ${{ matrix.platform }}
1818
strategy:
1919
matrix:
20-
python-version: ['3.9', '3.10', '3.11', '3.12']
20+
python-version: ['3.9', '3.10', '3.11', '3.12', '3.13']
2121
platform: [ubuntu-latest, macos-latest, windows-latest]
2222

2323
steps:

flow360/cloud/s3_utils.py

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,7 @@
99
from datetime import datetime
1010
from enum import Enum
1111

12-
import boto3
13-
from boto3.s3.transfer import TransferConfig
14-
from botocore.config import Config as BotocoreConfig
15-
1612
# pylint: disable=unused-import
17-
from botocore.exceptions import ClientError as CloudFileNotFoundError
1813
from pydantic.v1 import BaseModel, Field
1914

2015
from ..environment import Env
@@ -43,9 +38,14 @@ def __call__(self, bytes_chunk_transferred):
4338
pass
4439

4540

46-
def _get_dynamic_upload_config(file_size) -> TransferConfig:
41+
def _get_dynamic_upload_config(file_size):
4742
# pylint: disable=invalid-name
4843
# Constant definition: https://docs.aws.amazon.com/AmazonS3/latest/userguide/qfacts.html
44+
45+
from boto3.s3.transfer import ( # pylint: disable=import-outside-toplevel
46+
TransferConfig,
47+
)
48+
4949
MIN_CHUNK_SIZE = 5 * 1024 * 1024
5050
MAX_PART_COUNT = 100000
5151

@@ -143,6 +143,10 @@ def get_client(self):
143143
Get s3 client.
144144
:return:
145145
"""
146+
# pylint: disable=import-outside-toplevel
147+
from boto3 import client
148+
from botocore.config import Config as BotocoreConfig
149+
146150
# pylint: disable=no-member
147151
kwargs = {
148152
"region_name": self.user_credential.region,
@@ -155,7 +159,7 @@ def get_client(self):
155159
if Env.current.s3_endpoint_url is not None:
156160
kwargs["endpoint_url"] = Env.current.s3_endpoint_url
157161

158-
return boto3.client("s3", **kwargs)
162+
return client("s3", **kwargs)
159163

160164
def is_expired(self):
161165
"""
@@ -335,7 +339,7 @@ def _call_back(bytes_in_chunk):
335339
Config=_get_dynamic_upload_config(os.path.getsize(file_name)),
336340
)
337341

338-
# pylint: disable=too-many-arguments
342+
# pylint: disable=too-many-arguments, too-many-locals
339343
def download_file(
340344
self,
341345
resource_id: str,
@@ -357,6 +361,8 @@ def download_file(
357361
:param progress_callback: provide custom callback for progress
358362
:return:
359363
"""
364+
# pylint: disable=import-outside-toplevel
365+
from botocore.exceptions import ClientError as CloudFileNotFoundError
360366

361367
to_file = get_local_filename_and_create_folders(remote_file_name, to_file, to_folder)
362368
if os.path.exists(to_file) and not overwrite:

flow360/component/case.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import json
99
import os
1010
import tempfile
11-
from typing import Any, Iterator, List, Optional, Union
11+
from typing import TYPE_CHECKING, Any, Iterator, List, Optional, Union
1212

1313
import pydantic as pd
1414
import pydantic.v1 as pd_v1
@@ -20,7 +20,6 @@
2020
RenameAssetRequestV2,
2121
)
2222
from ..cloud.rest_api import RestApi
23-
from ..cloud.s3_utils import CloudFileNotFoundError
2423
from ..exceptions import Flow360RuntimeError, Flow360ValidationError, Flow360ValueError
2524
from ..log import log
2625
from .folder import Folder
@@ -76,6 +75,9 @@
7675
from .v1.flow360_params import Flow360Params, UnvalidatedFlow360Params
7776
from .validator import Validator
7877

78+
if TYPE_CHECKING:
79+
from flow360.component.volume_mesh import VolumeMeshV2
80+
7981

8082
class CaseBase:
8183
"""
@@ -459,6 +461,8 @@ def get_simulation_params(self):
459461
"""
460462
returns simulation params
461463
"""
464+
# pylint: disable=import-outside-toplevel
465+
from botocore.exceptions import ClientError as CloudFileNotFoundError
462466

463467
try:
464468
params_as_dict = self._parse_json_from_cloud("simulation.json")
@@ -580,7 +584,7 @@ def tags(self) -> List[str]:
580584
return self._web_api_v2.info.tags
581585

582586
@property
583-
def volume_mesh(self) -> "VolumeMeshV2":
587+
def volume_mesh(self) -> VolumeMeshV2:
584588
"""
585589
returns volume mesh
586590
"""

flow360/component/results/base_results.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,7 @@
1717
import pandas
1818
import pydantic as pd
1919

20-
from flow360.cloud.s3_utils import (
21-
CloudFileNotFoundError,
22-
get_local_filename_and_create_folders,
23-
)
20+
from flow360.cloud.s3_utils import get_local_filename_and_create_folders
2421
from flow360.component.simulation.entity_info import GeometryEntityInfo
2522
from flow360.component.simulation.models.surface_models import BoundaryBase
2623
from flow360.component.simulation.simulation_params import SimulationParams
@@ -420,6 +417,8 @@ def wait(self, timeout_minutes=60):
420417
"""
421418
Wait until the Case finishes processing, refresh periodically. Useful for postprocessing, eg sectional data
422419
"""
420+
# pylint: disable=import-outside-toplevel
421+
from botocore.exceptions import ClientError as CloudFileNotFoundError
423422

424423
start_time = time.time()
425424
while time.time() - start_time < timeout_minutes * 60:

flow360/component/results/case_results.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
import numpy as np
1313
import pydantic as pd
1414

15-
from flow360.cloud.s3_utils import CloudFileNotFoundError
1615
from flow360.component.results.base_results import (
1716
_PHYSICAL_STEP,
1817
_PSEUDO_STEP,
@@ -584,6 +583,8 @@ def download(
584583
CloudFileNotFoundError
585584
If the cloud file for the results is not found.
586585
"""
586+
# pylint: disable=import-outside-toplevel
587+
from botocore.exceptions import ClientError as CloudFileNotFoundError
587588

588589
try:
589590
super().download(

flow360/component/simulation/models/bet/bet_translator_interface.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
from typing import Literal
66

77
import numpy as np
8-
from scipy.interpolate import interp1d
98

109
import flow360.component.simulation.units as u
1110
from flow360.component.simulation.unit_system import AngleType, LengthType
@@ -61,6 +60,9 @@ def parse_in_xfoil_polar(polar_file_content: str):
6160
----------
6261
return: alpha_list, mach_list, cl_list, cd_list
6362
"""
63+
64+
from scipy.interpolate import interp1d # pylint: disable=import-outside-toplevel
65+
6466
cl_alphas = []
6567
cl_values = {}
6668
cd_values = {}

flow360/component/simulation/primitives.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
import numpy as np
1010
import pydantic as pd
1111
from pydantic import PositiveFloat
12-
from scipy.linalg import eig
1312
from typing_extensions import Self
1413

1514
import flow360.component.simulation.units as u
@@ -367,6 +366,9 @@ def from_principal_axes(
367366
"""
368367
Construct box from principal axes
369368
"""
369+
370+
from scipy.linalg import eig # pylint: disable=import-outside-toplevel
371+
370372
# validate
371373
x_axis, y_axis = np.array(axes[0]), np.array(axes[1])
372374
z_axis = np.cross(x_axis, y_axis)

flow360/component/simulation/user_code/core/types.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1281,7 +1281,10 @@ def _deserialize(value) -> Self:
12811281
if value.type_name == "expression":
12821282
if value.expression is None:
12831283
raise ValueError("No expression found in the input")
1284-
return expr_type(expression=value.expression, output_units=value.output_units)
1284+
# Validate via Pydantic so that Expression validators and AfterValidator both run
1285+
return pd.TypeAdapter(expr_type).validate_python(
1286+
{"expression": value.expression, "output_units": value.output_units}
1287+
)
12851288

12861289
@deprecation_reminder("25.8.0")
12871290
def _handle_legacy_unyt_values(value):

flow360/component/volume_mesh.py

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -71,13 +71,6 @@
7171
from .v1.params_base import params_generic_validator
7272
from .validator import Validator
7373

74-
try:
75-
import h5py
76-
77-
_H5PY_AVAILABLE = True
78-
except ImportError:
79-
_H5PY_AVAILABLE = False
80-
8174

8275
def get_datatype(dataset):
8376
"""
@@ -142,6 +135,8 @@ def get_boundaries_from_file(cgns_file: str, solver_version: str = None):
142135
:param solver_version:
143136
:return:
144137
"""
138+
import h5py # pylint: disable=import-outside-toplevel
139+
145140
names = []
146141
with h5py.File(cgns_file, "r") as h5_file:
147142
base = h5_file["Base"]

flow360/examples/betEVTOL/disk13.json

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
"entities": {
55
"stored_entities": [
66
{
7-
"private_attribute_registry_bucket_name": "VolumetricEntityType",
87
"private_attribute_entity_type_name": "Cylinder",
98
"private_attribute_id": "394556ea-d865-488e-9cbc-316af4f0564e",
109
"name": "BET 1",
@@ -39,7 +38,6 @@
3938
}
4039
},
4140
{
42-
"private_attribute_registry_bucket_name": "VolumetricEntityType",
4341
"private_attribute_entity_type_name": "Cylinder",
4442
"private_attribute_id": "27cf7b71-c350-4192-8f79-95c7e8ad794f",
4543
"name": "BET 3",

0 commit comments

Comments
 (0)