Skip to content

Conversation

@asaites
Copy link

@asaites asaites commented Dec 5, 2025

The changes on this branch merge the old python crate into the lib crate, so that the code that generates the Python bindings for the SDK lives alongside the code itself.

The original approach to this PR was to generate a migration plan and feed it to Windsurf. That plan is the crate-merge-plan.md file in this PR (which will be removed before merging). Unfortunately, applying the plan using LLMs had pretty mixed results, mostly due to the changes necessary to upgrade the PyO3 code. Regardless, the migration plan is useful for context and reference material.

Currently, this PR is a work in progress; the full hierarchy from the original Python package is in place, but the following items remain to be done:

  • The Python tests and CI workflows need updates.
  • The Python-related telemetry is migrated but commented out (with a TODO)
    until pyo3-opentelemetry and pyo3-tracing-subscriber have their PyO3 code updated.
  • These bindings re-export #[pyclass]es from qcs-api-client-common,
    and likely that package will need to update to the latest PyO3 version, too.
    I'm currently wrapping these types to side-step a need to update that package as well,
    which I had thought the original package was doing, until I found missing methods.
  • There were a couple instances of __getstate__ and __setstate__
    that I've noted with a TODO: pickle comment that should get the same treatment as quil-rs.

Here is the "shape" of the original Python package, which this PR indends to retain:

  • qcs_sdk
    • qcs_sdk.client
    • qcs_sdk.compiler
      • qcs_sdk.compiler.quilc
    • qcs_sdk.qpu
      • qcs_sdk.qpu.api
      • qcs_sdk.qpu.isa
      • qcs_sdk.qpu.translation
      • qcs_sdk.qpu.experimental
        • qcs_sdk.qpu.experimental.random
    • qcs_sdk.qvm
      • qcs_sdk.qvm.api

As with the quil-rs merge, the Python-specific code is hidden behind a python feature. Whenever possible, PyO3 attributes are applied to the existing Rust code, so that it can be shared between the bindings and the main crate. When necessary, Python-specific code has been isolated to separate python modules.

The code in src/python/mod.rs configures the package as above. The Python-specific parts of the Rust code present at the root of the src/ directory lives in similarly-named counterparts within the src/python/ directory, while code for qpu, qvm, etc. lives in python.rs modules next to the relevant submodule code. In some cases, this meant moving existing <name>.rs modules to <name>/mod.rs to add a <name>/python.rs module alongside it. In most cases, the organization within the modules closely reflects to original code, which may aid in review, should you wish to compare them. I'm open to suggestions for a better organization, but this seemed most natural.

Recommendations for Reviewers

You can build the install the bindings to a local virtualenv by running maturin develop, or by using cargo make install-python-package. I have encountered significant linking difficulties when attempting cargo build --features=python directly, but maturin develop and maturin build have both worked successfully.

You can also run cargo make pytest-flow, but you should expect the pytest command itself to report failures, but the build should succeed. The actual failures should be due to changes in enumerations/lack of wrappers, as we had with the quil-rs merge (There are a lot fewer of these present in this package, though!).


Closes #566

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.

Integrate qcs_sdk crate into qcs-sdk-rust crate

2 participants