Skip to content

Feat: local storage improvements#182

Open
nm727 wants to merge 5 commits intoColibrITD-SAS:devfrom
nm727:changements
Open

Feat: local storage improvements#182
nm727 wants to merge 5 commits intoColibrITD-SAS:devfrom
nm727:changements

Conversation

@nm727
Copy link

@nm727 nm727 commented Feb 13, 2026

Fix 1 : SQL Placeholder Mismatch (save.py)

Problem: The [INSERT INTO jobs] had 6 column names ([type, circuit, device, measure, remote_id, status]) but only 4 ? placeholders. The list-of-jobs branch would crash with [sqlite3.OperationalError] every time. The single-job branch had the inverse issue, only 4 columns, silently dropping remote_id and [status].

Fix: Both branches now consistently write all 6 columns with 6 placeholders and pass the full 6-value tuple.

Fix 2 : Stale Database Dead-End (setup.py)

Problem: When the DB version didn't match, users got RuntimeError: "please contact library authors" a complete brick wall with no recovery path.

Fix: The decorator now automatically:

Backs up the old DB to [.v<old_version>.bak]
Emits a UserWarning explaining what happened
Deletes the stale DB and re-creates a fresh one
Users keep their old data as a backup file and can continue working immediately.

Fix 3 : Unsafe [eval()] Deserialization (load.py)

Problem: 20+ bare [eval()] calls on strings from the SQLite database. If a DB file is shared, downloaded, or tampered with, this is arbitrary code execution.

Fix: Introduced [_safe_eval()] which:

Builds a restricted namespace containing only known MPQP symbols (from [mpqp.all]) plus numpy helpers, [complex64], [float64])
Sets builtins to {} — blocking access to import, [open], os, exec, import, etc.
Wraps every call in try/except with a descriptive [ValueError] on failure
Namespace is lazily built once and cached in [_SAFE_NAMESPACE]
All 20 [eval()] calls are now [_safe_eval()] calls.

@nm727
Copy link
Author

nm727 commented Feb 15, 2026

Fix 1 : Gate matrix class-level constants

File: native_gates.py

Promoted [self.matrix = np.array(...)] from per-instance allocation in [init] to shared class-level attributes for 8 gates: [Id], [X], [Y], [Z], [H], [S], [S_dagger], [SWAP]. All matrices now use [dtype=np.complex128] explicitly. Verified that [x1.matrix is X.matrix] instances share the class constant (zero per-instance allocation).

Fix 2 : [Instruction.eq] pickle → structural

File: instruction.py

Replaced [pickle.dumps(self) == pickle.dumps(value)] with:

if not isinstance(value, type(self)):
    return False
return self.to_dict() == value.to_dict()

Removed the from pickle import dumps import. This is now consistent with how [Gate.eq] and [Breakpoint.eq] already worked.

Fix 3 : Job unit tests

File: test_job.py

Replaced the 4-line # 3M-TODO placeholder with 276 lines covering 25 test methods across 7 test classes: [TestJobStatus], [TestJobType], [TestJobConstruction], [TestJobStatusProperty], [TestJobEquality], [TestJobRepr], and [TestGenerateJob] (including symbolic substitution).

@Henri-ColibrITD
Copy link
Contributor

Hi @nm727, thanks for the work you did!

A few preliminary comments: we don't merge directly do main, because main represents the latest version of MPQP, instead we merge to dev and we merge dev to main only when we are ready to release a new version.

In addition, in order to facilitate the review process, we try to have single feature branches, and merge them one after the other. I see that your work is split into clearly separated fixes, would you be able to submit each of these changes as a separated PR?

Thanks!

@nm727 nm727 changed the base branch from main to dev February 16, 2026 08:46
@nm727
Copy link
Author

nm727 commented Feb 16, 2026

hello @Henri-ColibrITD thank you for the response! It should be resolved now.

@Henri-ColibrITD Henri-ColibrITD changed the title did some fixes Feat: local storage safe eval Feb 16, 2026
Comment on lines -52 to +65
raise RuntimeError(f"""\
Database version {db_version} is outdated. Current supported version: {DATABASE_VERSION}.
Automated migration is not yet supported, please contact library authors to get\
help for the migration.""")
import shutil
from warnings import warn

db_path = get_env_variable("DB_PATH")
backup_path = db_path + f".v{db_version}.bak"
shutil.copy2(db_path, backup_path)
warn(
f"Database version {db_version} is outdated (current: "
f"{DATABASE_VERSION}). The old database has been backed up to "
f"'{backup_path}' and a fresh database will be created.",
stacklevel=2,
)
Path(db_path).unlink()
setup_local_storage(db_path)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

interesting idea, for now we never changed db version so this problem cannot occur. We might prefer leaving the error as it was and create a proper migration script once we have a new version. To be discussed

@Henri-ColibrITD Henri-ColibrITD changed the title Feat: local storage safe eval Feat: local storage improvements Feb 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants