Skip to content

FEAT: Add lock option removal for save_as method #1233

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/changelog.d/1233.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add lock option removal for `save_as` method
35 changes: 27 additions & 8 deletions src/ansys/mechanical/core/embedding/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
from pathlib import Path
import shutil
import typing
import warnings

from ansys.mechanical.core import LOG
from ansys.mechanical.core.embedding import initializer, runtime
Expand Down Expand Up @@ -289,11 +288,9 @@
lock_file = Path(self.DataModel.Project.ProjectDirectory) / ".mech_lock"
# Remove the lock file if it exists before opening the project file
if lock_file.exists():
warnings.warn(
f"Removing the lock file, {lock_file}, before opening the project. \
This may corrupt the project file.",
UserWarning,
stacklevel=2,
self.log_warning(
f"Removing the lock file, {lock_file}, before opening the project. "
"This may corrupt the project file."
)
lock_file.unlink()

Expand All @@ -306,7 +303,7 @@
else:
self.DataModel.Project.Save()

def save_as(self, path: str, overwrite: bool = False):
def save_as(self, path: str, overwrite: bool = False, remove_lock: bool = False):
"""
Save the project as a new file.

Expand All @@ -318,6 +315,8 @@
The path where the file needs to be saved.
overwrite : bool, optional
Whether the file should be overwritten if it already exists (default is False).
remove_lock : bool, optional
Whether to remove the lock file if it exists before saving the project file.

Raises
------
Expand Down Expand Up @@ -350,7 +349,27 @@
# Save the new file
self.DataModel.Project.SaveAs(path)
else:
self.DataModel.Project.SaveAs(path, overwrite)
if remove_lock:
file_path = Path(path)
associated_dir = file_path.parent / f"{file_path.stem}_Mech_Files"
lock_file = associated_dir / ".mech_lock"

Check warning on line 355 in src/ansys/mechanical/core/embedding/app.py

View check run for this annotation

Codecov / codecov/patch

src/ansys/mechanical/core/embedding/app.py#L353-L355

Added lines #L353 - L355 were not covered by tests
# Remove the lock file if it exists before saving the project file
if lock_file.exists():
self.log_warning(f"Removing the lock file, {lock_file}... ")
lock_file.unlink()

Check warning on line 359 in src/ansys/mechanical/core/embedding/app.py

View check run for this annotation

Codecov / codecov/patch

src/ansys/mechanical/core/embedding/app.py#L357-L359

Added lines #L357 - L359 were not covered by tests
try:
self.DataModel.Project.SaveAs(path, overwrite)
except Exception as e:
error_msg = str(e)
if "The project is locked by" in error_msg:
self.log_error(

Check warning on line 365 in src/ansys/mechanical/core/embedding/app.py

View check run for this annotation

Codecov / codecov/patch

src/ansys/mechanical/core/embedding/app.py#L362-L365

Added lines #L362 - L365 were not covered by tests
f"Failed to save project as {path}: {error_msg}\n"
"Hint: The project file is locked. "
"Try using the 'remove_lock=True' option when saving the project."
)
else:
self.log_error(f"Failed to save project as {path}: {error_msg}")
raise e

Check warning on line 372 in src/ansys/mechanical/core/embedding/app.py

View check run for this annotation

Codecov / codecov/patch

src/ansys/mechanical/core/embedding/app.py#L371-L372

Added lines #L371 - L372 were not covered by tests

def launch_gui(self, delete_tmp_on_close: bool = True, dry_run: bool = False):
"""Launch the GUI."""
Expand Down
7 changes: 5 additions & 2 deletions tests/embedding/test_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -539,7 +539,7 @@ def test_app_execute_script_from_file(embedded_app, rootdir, printer):


@pytest.mark.embedding
def test_app_lock_file_open(embedded_app, tmp_path: pytest.TempPathFactory):
def test_app_lock_file_open(embedded_app, tmp_path: pytest.TempPathFactory, caplog):
"""Test the lock file is removed on open if remove_lock=True."""
embedded_app.DataModel.Project.Name = "PROJECT 1"
project_file = os.path.join(tmp_path, f"{NamedTemporaryFile().name}.mechdat")
Expand All @@ -554,9 +554,12 @@ def test_app_lock_file_open(embedded_app, tmp_path: pytest.TempPathFactory):
assert lock_file.exists()

# Assert a warning is emitted if the lock file is going to be removed
with pytest.warns(UserWarning):

with caplog.at_level("WARNING"):
embedded_app.open(project_file, remove_lock=True)

assert any("Removing the lock file" in message for message in caplog.messages)


@pytest.mark.embedding
def test_app_initialized(embedded_app):
Expand Down
Loading