diff --git a/openbb_platform/core/openbb/assets/reference.json b/openbb_platform/core/openbb/assets/reference.json index 885a9f88f5b..0a607df4569 100644 --- a/openbb_platform/core/openbb/assets/reference.json +++ b/openbb_platform/core/openbb/assets/reference.json @@ -1,9 +1,9 @@ { - "openbb": "1.5.1core", + "openbb": "1.5.2core", "info": { "title": "OpenBB Platform (Python)", "description": "Investment research for everyone, anywhere.", - "core": "1.5.1", + "core": "1.5.2", "extensions": { "openbb_core_extension": [], "openbb_provider_extension": [], diff --git a/openbb_platform/core/openbb_core/app/static/package_builder.py b/openbb_platform/core/openbb_core/app/static/package_builder.py index 235b6676b9a..e3ce281bb63 100644 --- a/openbb_platform/core/openbb_core/app/static/package_builder.py +++ b/openbb_platform/core/openbb_core/app/static/package_builder.py @@ -2,7 +2,7 @@ # pylint: disable=too-many-lines,too-many-locals,too-many-nested-blocks,too-many-statements,too-many-branches,too-many-positional-arguments import builtins -import fcntl +import contextlib import inspect import os import re @@ -59,6 +59,14 @@ try: except ImportError: CHARTING_INSTALLED = False +try: + import fcntl # type: ignore + + _HAS_FCNTL = True +except Exception: # pylint: disable=broad-except # noqa + _HAS_FCNTL = False + import msvcrt # pylint: disable=unused-import # noqa + DataProcessingSupportedTypes = TypeVar( "DataProcessingSupportedTypes", list, @@ -79,6 +87,45 @@ def create_indent(n: int) -> str: return TAB * n +class FileLock: + """Simple cross-platform file lock wrapper used only for this module.""" + + def __init__(self, file_obj): + """Initialize the file lock.""" + self._file = file_obj + + def acquire(self, blocking: bool = True) -> None: + """Acquire the file lock.""" + if _HAS_FCNTL: + flags = fcntl.LOCK_EX | (0 if blocking else fcntl.LOCK_NB) + fcntl.flock(self._file.fileno(), flags) + else: # Windows via msvcrt + + mode = msvcrt.LK_LOCK if blocking else msvcrt.LK_NBLCK # type: ignore # pylint: disable=E0601 + try: + # lock 1 byte at file start; file.seek(0) to ensure position + self._file.seek(0) + msvcrt.locking(self._file.fileno(), mode, 1) # type: ignore + except OSError as exc: # pragma: no cover - platform specific + # Normalize to BlockingIOError for parity with fcntl non-blocking + raise BlockingIOError from exc + + def release(self) -> None: + """Release the file lock.""" + try: + if _HAS_FCNTL: + fcntl.flock(self._file.fileno(), fcntl.LOCK_UN) + else: + try: + self._file.seek(0) + msvcrt.locking(self._file.fileno(), msvcrt.LK_UNLCK, 1) # type: ignore + except OSError: + # If unlocking fails on Windows, ignore - file will be closed soon + pass + except Exception: # pylint: disable=broad-except # noqa + pass + + class PackageBuilder: """Build the extension package for the Platform.""" @@ -123,12 +170,14 @@ class PackageBuilder: # Open lock file and acquire exclusive lock with open(self._lock_path, "w", encoding="utf-8") as lock_file: + file_lock = FileLock(lock_file) try: # Get exclusive lock on file - fcntl.flock(lock_file.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB) + file_lock.acquire(blocking=False) # Write PID to lock file for debugging lock_file.seek(0) + lock_file.truncate() lock_file.write(str(os.getpid())) lock_file.flush() @@ -141,14 +190,14 @@ class PackageBuilder: self._save_reference_file(ext_map) if self.lint: self._run_linters() - except BlockingIOError: raise RuntimeError( # noqa # pylint: disable=W0707 f"Another build process is running and has locked {self._lock_path}" ) finally: - # Release lock - fcntl.flock(lock_file.fileno(), fcntl.LOCK_UN) + # Release the file lock, suppressing any exceptions during cleanup + with contextlib.suppress(Exception): + file_lock.release() def _clean(self, modules: str | list[str] | None = None) -> None: """Delete the assets and package folder or modules before building.""" diff --git a/openbb_platform/core/pyproject.toml b/openbb_platform/core/pyproject.toml index 0551ed6ad20..4744f39c008 100644 --- a/openbb_platform/core/pyproject.toml +++ b/openbb_platform/core/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "openbb-core" -version = "1.5.1" +version = "1.5.2" description = "OpenBB package with core functionality." authors = ["OpenBB Team "] license = "AGPL-3.0-only" diff --git a/openbb_platform/core/tests/app/static/test_reference_loader.py b/openbb_platform/core/tests/app/static/test_reference_loader.py index 9c8b0041007..9a0f6661178 100644 --- a/openbb_platform/core/tests/app/static/test_reference_loader.py +++ b/openbb_platform/core/tests/app/static/test_reference_loader.py @@ -26,7 +26,7 @@ def mock_reference_data(tmp_path): mock_data = {"key": "value"} with open(reference_file, "w", encoding="utf-8") as f: json.dump(mock_data, f) - return directory + return tmp_path def test_load_reference_data(mock_reference_data, reference_loader): diff --git a/openbb_platform/poetry.lock b/openbb_platform/poetry.lock index 6200c18c5ec..5bd0f89e426 100644 --- a/openbb_platform/poetry.lock +++ b/openbb_platform/poetry.lock @@ -3070,14 +3070,14 @@ openbb-core = ">=1.5.1,<2.0.0" [[package]] name = "openbb-core" -version = "1.5.1" +version = "1.5.2" description = "OpenBB package with core functionality." optional = false -python-versions = "<3.14,>=3.9.21" +python-versions = "<3.14,>=3.10" groups = ["main"] files = [ - {file = "openbb_core-1.5.1-py3-none-any.whl", hash = "sha256:5ebd221f82c57dd15a84bc3787965df335604b26bfe71338b5d099ebf5cdfcf2"}, - {file = "openbb_core-1.5.1.tar.gz", hash = "sha256:57a424fdc0ae9eb10b855c77dc63e0bafdad4f981120b452e15cd973fedf25a2"}, + {file = "openbb_core-1.5.2-py3-none-any.whl", hash = "sha256:a3f1be561a5f6c87b8160f44293fc05f9308e365b0d76a744b6c18154d7c7473"}, + {file = "openbb_core-1.5.2.tar.gz", hash = "sha256:6017407025dd4f1ee326c0e99421267f6254efe83fc10099ba63241203d56153"}, ] [package.dependencies] @@ -6178,4 +6178,4 @@ wsj = ["openbb-wsj"] [metadata] lock-version = "2.1" python-versions = ">=3.10,<3.14" -content-hash = "ef984b27041496f4caabe2c31ed3ef94a42afa9bb05531872377aedd0fc8333e" +content-hash = "74aa34922fd5b5dde0b10df4e402878ea12dcb56bb549ea105768d47afff8309" diff --git a/openbb_platform/pyproject.toml b/openbb_platform/pyproject.toml index 87e2fe968da..04feae514cf 100644 --- a/openbb_platform/pyproject.toml +++ b/openbb_platform/pyproject.toml @@ -10,7 +10,7 @@ packages = [{ include = "openbb", from = "core" }] [tool.poetry.dependencies] python = ">=3.10,<3.14" -openbb-core = "^1.5.1" +openbb-core = "^1.5.2" openbb-platform-api = "^1.2.1" openbb-benzinga = "^1.5.0"