Skip to content

Commit

Permalink
fix(py): Type stubs for calibration types reflect breaking changes in…
Browse files Browse the repository at this point in the history
… 0.13.0 (#421)

* fix(py): Type stubs for calibration types have been updated to reflect breaking changes in 0.13.0

* update mypy

* implement workflow for checking changes against pyQuil

* fix run keyword

* missing |

* yamlyamlyaml

* tweaks to pyquil job

* maybe this is the magic spell?

* maybe this?

* install maturin

* point maturin to Cargo.toml

* install other deps

* give mypy the config

* maybe this?

* use ::warning::

* is this loud enough?

* maybe this?

* simplify

* yamldentation

* cleanup

* run all checks against pyquil, but still fail the job i

* separate into different workflow

* remove field

* try this

* conclusion?

* fix yaml

* missing jobs key

* dont want matrix for this job

* continue-on-error at workflow level

* continue-on-error too high

* fix

* maybe this?

* another try

* dont need to manually call core

* set working directory

* improve summary

* simplify and improve logic

* fix log link

* add )

* add async keyword

* js function syntax

* anotha one

* anotha one

* let

* missing backtick

* init missing vars

* simplify log URL construction

* fix f-string

* fix f-string

* fix syntax

* found the braket

* job id not available
  • Loading branch information
MarquessV authored Nov 21, 2024
1 parent 51a4145 commit 9369abc
Show file tree
Hide file tree
Showing 4 changed files with 160 additions and 54 deletions.
7 changes: 4 additions & 3 deletions .github/workflows/msrv.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,17 +58,18 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12']
python-version: ['3.9', '3.10', '3.11', '3.12']
steps:
- uses: actions/checkout@v4
- uses: actions-rs/toolchain@v1
with:
toolchain: stable
override: true
- uses: davidB/rust-cargo-make@v1
- uses: actions/checkout@v1
- uses: syphar/restore-virtualenv@v1
- name: Run quil-py tests, lints, and formatting checks.
run: cargo make --cwd quil-py
run: |
cargo make --cwd quil-py
fmt:
name: Rustfmt
Expand Down
116 changes: 116 additions & 0 deletions .github/workflows/validate-downstream.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
name: Check pyQuil Compatibility
on:
pull_request:

jobs:
check-pyquil:
name: Check compatibility with pyQuil
runs-on: ubuntu-latest
steps:
- name: Checkout quil-rs Repository
uses: actions/checkout@v4
with:
path: quil-rs

- name: Checkout pyQuil Repository
uses: actions/checkout@v4
with:
repository: "rigetti/pyquil"
path: pyquil

- name: Install Rust Toolchain
uses: actions-rs/toolchain@v1
with:
toolchain: stable
override: true

- name: Restore Python Virtual Environment
uses: syphar/restore-virtualenv@v1

- name: Setup pyQuil Repository
run: |
pip uninstall -y -r <(pip freeze) || true
pip install "./pyquil[latex]" maturin mypy ruff pytest pytest-mock
maturin develop -m quil-rs/quil-py/Cargo.toml
- name: Run mypy
id: mypy
continue-on-error: true
working-directory: ./pyquil
run: |
mypy pyquil
- name: Run ruff
id: ruff
continue-on-error: true
working-directory: ./pyquil
run: |
ruff check pyquil
- name: Run pytest
id: pytest
continue-on-error: true
working-directory: ./pyquil
run: |
pytest test/unit -x
- name: Post PR Comment and Fail if Necessary
uses: actions/github-script@v6
with:
script: |
const mypyFailed = '${{ steps.mypy.outcome }}' === 'failure';
const ruffFailed = '${{ steps.ruff.outcome }}' === 'failure';
const pytestFailed = '${{ steps.pytest.outcome }}' === 'failure';
const owner = context.repo.owner;
const repo = context.repo.repo;
const issue_number = context.issue.number;
// Fetch existing comment, if it exists
const identifier = `pyQuil-checks-comment`;
const comments = await github.rest.issues.listComments({
owner,
repo,
issue_number,
});
const existingComment = comments.data.find(comment => comment.body.startsWith(`<!-- ${identifier} -->`));
async function postOrUpdateComment(body) {
if (existingComment) {
await github.rest.issues.updateComment({
owner,
repo,
comment_id: existingComment.id,
body
});
} else {
await github.rest.issues.createComment({
owner,
repo,
issue_number,
body
});
}
}
var body = ""
if (mypyFailed || ruffFailed || pytestFailed) {
body += `⚠️ **pyQuil Compatibility Checks Failed**:\n\n| Tool | Status |\n-----|-----|\n`;
if (mypyFailed) {
body += `| mypy | ❌ Failed |\n`;
}
if (ruffFailed) {
body += `| ruff | ❌ Failed |\n`;
}
if (pytestFailed) {
body += `| pytest | ❌ Failed |\n`;
}
body += `\n**Note**: These failures don't necessarily block the PR but both authors and reviewers should check the results for unintentional breaking changes.`;
} else {
body += `✅ **pyQuil Compatibility Checks Passed**. Great job!`;
}
await postOrUpdateComment(body);
2 changes: 1 addition & 1 deletion quil-py/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ sdist-include = ["README.md"]
dev = [
"ruff>=0.3.7",
"maturin>=1.2.3",
"mypy>=1.1.1",
"mypy>=1.13.0",
"pytest>=7.2.2",
"pdoc>=14.1.0",
"syrupy>=3.0.6"
Expand Down
89 changes: 39 additions & 50 deletions quil-py/quil/instructions/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -834,11 +834,13 @@ class UnaryLogic:
def __copy__(self) -> Self:
"""Returns a shallow copy of the class."""

class Calibration:
class CalibrationIdentifier:
def __new__(
cls,
identifier: CalibrationIdentifier,
instructions: Sequence[Instruction],
name: str,
parameters: Sequence[Expression],
qubits: Sequence[Qubit],
modifiers: Sequence[GateModifier],
) -> Self: ...
@property
def name(self) -> str: ...
Expand All @@ -853,14 +855,6 @@ class Calibration:
@qubits.setter
def qubits(self, qubits: Sequence[Qubit]) -> None: ...
@property
def identifier(self) -> CalibrationIdentifier: ...
@identifier.setter
def identifier(self, identifier: CalibrationIdentifier) -> None: ...
@property
def instructions(self) -> List[Instruction]: ...
@instructions.setter
def instructions(self, instructions: Sequence[Instruction]) -> None: ...
@property
def modifiers(self) -> List[GateModifier]: ...
@modifiers.setter
def modifiers(self, modifiers: Sequence[GateModifier]) -> None: ...
Expand All @@ -885,30 +879,31 @@ class Calibration:
def __copy__(self) -> Self:
"""Returns a shallow copy of the class."""

class CalibrationIdentifier:
class Calibration:
def __new__(
cls,
name: str,
parameters: Sequence[Expression],
qubits: Sequence[Qubit],
modifiers: Sequence[GateModifier],
identifier: CalibrationIdentifier,
instructions: Sequence[Instruction],
) -> Self: ...
def name(self) -> str:
"""Get the name that identifies this calibration."""
...
def parameters(self) -> List[Expression]:
"""Get the list of parameters that this calibration will expand into."""
...
def qubits(self) -> List[Qubit]:
"""Get the list of qubits that this calibration will expand into."""
...
def modifiers(self) -> List[GateModifier]:
"""Get the list of parameters that this calibration will expand into."""
@property
def name(self) -> str: ...
@name.setter
def name(self, name: str) -> None: ...
@property
def parameters(self) -> List[Expression]: ...
@parameters.setter
def parameters(self, parameters: Sequence[Expression]) -> None: ...
@property
def qubits(self) -> List[Qubit]: ...
@qubits.setter
def qubits(self, qubits: Sequence[Qubit]) -> None: ...
def identifier(self) -> CalibrationIdentifier: ...
@identifier.setter
def identifier(self, identifier: CalibrationIdentifier) -> None: ...
@property
def modifiers(self) -> List[GateModifier]: ...
@modifiers.setter
def modifiers(self, modifiers: Sequence[GateModifier]) -> None: ...
def instructions(self) -> List[Instruction]: ...
@instructions.setter
def instructions(self, instructions: Sequence[Instruction]) -> None: ...
def to_quil(self) -> str:
"""Attempt to convert the instruction to a valid Quil string.
Expand All @@ -930,11 +925,11 @@ class CalibrationIdentifier:
def __copy__(self) -> Self:
"""Returns a shallow copy of the class."""

class MeasureCalibrationDefinition:
class MeasureCalibrationIdentifier:
def __new__(
cls,
identifier: MeasureCalibrationIdentifier,
instructions: Sequence[Instruction],
qubit: Optional[Qubit],
parameter: str,
) -> Self: ...
@property
def qubit(self) -> Optional[Qubit]: ...
Expand All @@ -944,14 +939,6 @@ class MeasureCalibrationDefinition:
def parameter(self) -> str: ...
@parameter.setter
def parameter(self, parameter: str) -> None: ...
@property
def identifier(self) -> MeasureCalibrationIdentifier: ...
@identifier.setter
def identifier(self, identifier: MeasureCalibrationIdentifier) -> None: ...
@property
def instructions(self) -> List[Instruction]: ...
@instructions.setter
def instructions(self, instructions: Sequence[Instruction]) -> None: ...
def to_quil(self) -> str:
"""Attempt to convert the instruction to a valid Quil string.
Expand All @@ -973,20 +960,22 @@ class MeasureCalibrationDefinition:
def __copy__(self) -> Self:
"""Returns a shallow copy of the class."""

class MeasureCalibrationIdentifier:
class MeasureCalibrationDefinition:
def __new__(
cls,
qubit: Optional[Qubit],
parameter: str,
identifier: MeasureCalibrationIdentifier,
instructions: Sequence[Instruction],
) -> Self: ...
@property
def qubit(self) -> Optional[Qubit]: ...
@qubit.setter
def qubit(self, qubit: Optional[Qubit]) -> None: ...
@property
def parameter(self) -> str: ...
@parameter.setter
def parameter(self, parameter: str) -> None: ...
@property
def identifier(self) -> MeasureCalibrationIdentifier: ...
@identifier.setter
def identifier(self, identifier: MeasureCalibrationIdentifier) -> None: ...
@property
def instructions(self) -> List[Instruction]: ...
@instructions.setter
def instructions(self, instructions: Sequence[Instruction]) -> None: ...
def to_quil(self) -> str:
"""Attempt to convert the instruction to a valid Quil string.
Expand Down

0 comments on commit 9369abc

Please sign in to comment.