From 46dd4464bf33bd6e2255505102c5a290cedd68f6 Mon Sep 17 00:00:00 2001 From: octo-patch Date: Sun, 26 Apr 2026 10:45:41 +0800 Subject: [PATCH] fix: use Path(str()) instead of resources.as_file() for alembic dir on Python < 3.12 (fixes #273) resources.as_file() only supports files in Python < 3.12. When called with a MultiplexedPath representing a directory, it raises TypeError: 'MultiplexedPath(...) is not a file'. Convert via Path(str(resource)) instead, which returns the underlying filesystem path for installed packages and works on Python 3.11. Co-Authored-By: Octopus --- backend/pyspur/cli/utils.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/backend/pyspur/cli/utils.py b/backend/pyspur/cli/utils.py index 4b30fe35..4a7d35bf 100644 --- a/backend/pyspur/cli/utils.py +++ b/backend/pyspur/cli/utils.py @@ -121,11 +121,12 @@ def run_migrations() -> None: if not script_location.is_dir(): raise FileNotFoundError("Migration scripts not found in package") - # extract migration scripts directory to a temporary location - with ( - tempfile.TemporaryDirectory() as script_temp_dir, - resources.as_file(script_location) as script_location_path, - ): + # Extract migration scripts to a temporary location for Alembic. + # resources.as_file() only supports files in Python < 3.12, so we + # convert the MultiplexedPath to a regular Path via str(), which + # returns the underlying filesystem path for installed packages. + with tempfile.TemporaryDirectory() as script_temp_dir: + script_location_path = Path(str(script_location)) shutil.copytree(script_location_path, Path(script_temp_dir), dirs_exist_ok=True) # Create Alembic config programmatically config = Config()