Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions .github/scripts/ci-centos.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#!/usr/bin/env bash
# Run inside the CentOS container; checkout and other Node actions run on the host.
set -euo pipefail

if [[ "$CENTOS_VERSION" == 7 ]]; then
vault_version=7.9.2009
else
vault_version=8.5.2111
fi

# Both CentOS releases have moved from the live mirrors to the vault.
sed -i \
-e 's|^mirrorlist=|#mirrorlist=|' \
-e "s|^#baseurl=http://mirror.centos.org/centos/\$releasever|baseurl=https://vault.centos.org/$vault_version|" \
-e 's|^#baseurl=http://mirror.centos.org/$contentdir/$releasever|baseurl=https://vault.centos.org/'"$vault_version"'|' \
/etc/yum.repos.d/CentOS-*.repo
yum update -y

if [[ "$CENTOS_VERSION" == 7 ]]; then
yum install -y centos-release-scl-rh
sed -i \
-e 's|^mirrorlist=|#mirrorlist=|' \
-e 's|^#baseurl=http://mirror.centos.org/centos/7|baseurl=https://vault.centos.org/7.9.2009|' \
/etc/yum.repos.d/CentOS-SCLo-scl-rh.repo
yum install -y https://packages.endpointdev.com/rhel/7/os/x86_64/endpoint-repo.x86_64.rpm
yum install -y --enablerepo=centos-sclo-rh rh-python38-python-pip rh-python38-python-devel
export PATH="/opt/rh/rh-python38/root/usr/bin:$PATH"
export LD_LIBRARY_PATH="/opt/rh/rh-python38/root/usr/lib64:${LD_LIBRARY_PATH:-}"
else
yum install -y python38-devel
fi

yum install -y git gcc-c++ make
git config --global --add safe.directory /src
python3 -m pip install -U pip setuptools wheel
python3 setup.py gen_reqfile --include-extras=test,azure-quantum,braket
python3 -m pip install -r requirements.txt --prefer-binary
if [[ "$CENTOS_VERSION" == 7 ]]; then
# Retain GCC 4.8 coverage with the last compatible pybind11 series.
python3 -m pip install 'pybind11<2.11' 'setuptools_scm[toml]>6'
python3 -m pip install --no-build-isolation -ve '.[azure-quantum,braket,test]'
else
python3 -m pip install -ve '.[azure-quantum,braket,test]'
fi
echo 'backend: Agg' > matplotlibrc
python3 -m pytest -p no:warnings
127 changes: 42 additions & 85 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
strategy:
fail-fast: false
matrix:
runs-on: [ubuntu-latest, windows-latest, macos-latest]
runs-on: [ubuntu-latest, windows-latest, macos-15-intel]
python:
- 3.8
- 3.9
Expand All @@ -41,6 +41,10 @@ jobs:
git fetch --prune --unshallow
git fetch --depth=1 origin +refs/tags/*:refs/tags/*

- name: Install Python runtime library (macOS)
if: runner.os == 'macOS'
run: brew install gettext

- name: Setup Python ${{ matrix.python }}
uses: actions/setup-python@v4
with:
Expand All @@ -65,9 +69,17 @@ jobs:
run: |
python setup.py gen_reqfile --include-extras=test,azure-quantum,braket

- name: Prepare env
- name: Install build tools
run: |
python -m pip install -U pip setuptools wheel pybind11

# RevKit's legacy build imports pybind11 without declaring it as a build dependency.
- name: Build RevKit with preinstalled pybind11 (Unix)
if: runner.os != 'Windows'
run: python -m pip install --no-build-isolation 'revkit==3.0a2.dev2'

- name: Install dependencies
run: |
cat requirements.txt
python -m pip install -r requirements.txt --prefer-binary
python -m pip install coveralls
Expand Down Expand Up @@ -123,9 +135,18 @@ jobs:
PROJECTQ_CLEANUP_COMPILER_FLAGS: ${{ (matrix.clang <= 10) && 1 || 0 }}

name: "Python 3 • Clang ${{ matrix.clang }} • x64"
container: "silkeh/clang:${{ matrix.clang }}"
container: "silkeh/clang:${{ matrix.clang == 11 && '11-bullseye' || matrix.clang }}"

steps:
# Bullseye security packages have left the live mirrors; keep this legacy toolchain reproducible.
- name: Refresh Debian repository URLs
run: |
security_snapshot=https://snapshot.debian.org/archive/debian-security/20260801T000000Z
security_source="deb [check-valid-until=no] $security_snapshot bullseye-security"
find /etc/apt -name '*.list' -exec sed -i \
-e "s|^deb http://deb.debian.org/debian-security bullseye-security|$security_source|" \
-e 's|http://deb.debian.org/debian|https://deb.debian.org/debian|g' {} +

- name: Install Git
run: |
apt-get update && apt-get install -y git --no-install-recommends
Expand Down Expand Up @@ -182,6 +203,15 @@ jobs:
container: "gcc:${{ matrix.gcc }}"

steps:
# Bullseye security packages have left the live mirrors; keep this legacy toolchain reproducible.
- name: Refresh Debian repository URLs
run: |
security_snapshot=https://snapshot.debian.org/archive/debian-security/20260801T000000Z
security_source="deb [check-valid-until=no] $security_snapshot bullseye-security"
find /etc/apt -name '*.list' -exec sed -i \
-e "s|^deb http://deb.debian.org/debian-security bullseye-security|$security_source|" \
-e 's|http://deb.debian.org/debian|https://deb.debian.org/debian|g' {} +

- uses: actions/checkout@v3

# Work-around for https://github.com/actions/runner-images/issues/6775
Expand Down Expand Up @@ -221,99 +251,26 @@ jobs:
./venv/bin/python3 -m pytest -p no:warnings


# Testing on CentOS (manylinux uses a centos base, and this is an easy way
# to get GCC 4.8, which is the manylinux1 compiler).
# Keep JavaScript actions on the host: Node 24 cannot run on CentOS 7's glibc.
# Build and test in the original containers to retain the older compiler coverage.
centos:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
centos:
- 7 # GCC 4.8
- 8
include:
- centos: 7
python_pkg: rh-python38-python-pip rh-python38-python-devel
enable_repo: --enablerepo=centos-sclo-rh
- centos: 8
python_pkg: python38-devel


centos: [7, 8]
name: "Python 3 • CentOS ${{ matrix.centos }} • x64"
container: "centos:${{ matrix.centos }}"

steps:
- name: Enable cache for yum
run: echo 'keepcache=1' >> /etc/yum.conf

- name: Setup yum cache
uses: actions/cache@v3
with:
path: |
/var/cache/yum/
/var/cache/dnf/
key: ${{ runner.os }}-centos${{ matrix.centos }}-yum-${{ secrets.yum_cache }}

- name: Fix repository URLs (CentOS 8 only)
if: matrix.centos == 8
run: |
sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-*
sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-*

- name: Update YUM/DNF
run: yum update -y

- name: Enable extra repositories && modify PATH (CentOS 7)
if: matrix.centos == 7
run: |
yum install -y centos-release-scl-rh
yum -y install https://packages.endpointdev.com/rhel/7/os/x86_64/endpoint-repo.x86_64.rpm
echo '/opt/rh/rh-python38/root/usr/bin' >> $GITHUB_PATH

- name: Add Python 3 and other dependencies
run: yum install -y ${{ matrix.enable_repo }} ${{ matrix.python_pkg }} gcc-c++ make

- name: Install Git > 2.18
run: |
yum install -y git
git config --global --add safe.directory /__w/ProjectQ/ProjectQ

# Work-around for https://github.com/actions/runner-images/issues/6775
- name: Change Owner of Container Working Directory
run: chown root:root .

- uses: actions/checkout@v3

- name: Get history and tags for SCM versioning to work
if: ${{ !env.ACT }}
run: |
git fetch --prune --unshallow
git fetch --depth=1 origin +refs/tags/*:refs/tags/*

- name: Create pip cache dir
run: mkdir -p ~/.cache/pip

- name: Cache wheels
uses: actions/cache@v3
with:
path: ~/.cache/pip
key: ${{ runner.os }}-centos${{ matrix.centos }}-pip-${{ hashFiles('**/setup.cfg', '**/pyproject.toml') }}
restore-keys: ${{ runner.os }}-centos-pip-
fetch-depth: 0

- name: Install dependencies
- name: Build and test in CentOS
run: |
python3 -m pip install -U pip setuptools wheel
python3 setup.py gen_reqfile --include-extras=test,azure-quantum,braket
cat requirements.txt
python3 -m pip install -r requirements.txt --prefer-binary

- name: Build and install package
run: python3 -m pip install -ve .[azure-quantum,braket,test]

- name: Pytest
run: |
echo 'backend: Agg' > matplotlibrc
python3 -m pytest -p no:warnings
docker run --rm \
-v "$GITHUB_WORKSPACE:/src" -w /src \
-e CENTOS_VERSION=${{ matrix.centos }} \
centos:${{ matrix.centos }} bash .github/scripts/ci-centos.sh


documentation:
Expand Down
9 changes: 9 additions & 0 deletions .github/workflows/format.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,15 @@ jobs:
CXX: clang++

steps:
# Bullseye security packages have left the live mirrors; keep this legacy toolchain reproducible.
- name: Refresh Debian repository URLs
run: |
security_snapshot=https://snapshot.debian.org/archive/debian-security/20260801T000000Z
security_source="deb [check-valid-until=no] $security_snapshot bullseye-security"
find /etc/apt -name '*.list' -exec sed -i \
-e "s|^deb http://deb.debian.org/debian-security bullseye-security|$security_source|" \
-e 's|http://deb.debian.org/debian|https://deb.debian.org/debian|g' {} +

- uses: actions/checkout@v3

- name: Prepare env
Expand Down
4 changes: 4 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ repos:
rev: v3.15.2
hooks:
- id: pyupgrade
# This pinned version predates Python 3.14 tokenizer changes.
language_version: python3.11
args: [--py37-plus, --keep-mock]

- repo: https://github.com/PyCQA/isort
Expand Down Expand Up @@ -116,6 +118,8 @@ repos:
rev: 'v3.0.0a5'
hooks:
- id: pylint
# This pinned version predates Python 3.14 AST changes.
language_version: python3.11
args: ['--score=n', '--disable=no-member']
additional_dependencies: [pybind11>=2.6, numpy, requests, matplotlib, networkx]

Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Fixed some typos (thanks to @eltociear, @Darkdragon84)
- Fixed support for Python 3.12
- Fixed obscure IndexError in optimizer when control and target qubits overlap or are not distinct (#343)
- Fixed installation failure with setuptools >= 81.0.0 due to compiler dry_run attribute (#485)

### Removed

Expand Down
73 changes: 73 additions & 0 deletions projectq/_setup_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# Copyright 2017, 2021 ProjectQ-Framework (www.projectq.ch)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Regression tests for source-tree packaging commands."""

import runpy
import subprocess
import sys
from pathlib import Path
from types import SimpleNamespace
from unittest.mock import patch

import pytest


def test_requirements_fallback_preserves_marker_quotes(tmp_path):
"""Requirement generation must work without an optional TOML parser."""
setup_path = Path(__file__).resolve().parents[1] / 'setup.py'
if not setup_path.is_file():
pytest.skip('Requires a source checkout')
script = """
import runpy
import sys
import setuptools

sys.modules['tomllib'] = None
sys.modules['toml'] = None
sys.argv = [sys.argv[1], 'gen_reqfile', '--include-extras=azure-quantum']
runpy.run_path(sys.argv[0], run_name='__main__')
"""
result = subprocess.run(
[sys.executable, '-c', script, str(setup_path)], cwd=tmp_path, capture_output=True, text=True, check=False
)
assert result.returncode == 0, result.stdout + result.stderr
requirements = (tmp_path / 'requirements.txt').read_text().splitlines()
assert 'azure-quantum <= 3.5.0; python_version <= "3.8"' in requirements
assert 'azure-quantum; python_version > "3.8"' in requirements


@pytest.mark.parametrize('dry_run', [False, True])
def test_clang_tidy_spawn_compatibility(dry_run):
"""Clang-Tidy respects dry runs without relying on removed spawn arguments."""
from setuptools import Distribution

setup_path = Path(__file__).resolve().parents[1] / 'setup.py'
if not setup_path.is_file():
pytest.skip('Requires a source checkout')
with patch('setuptools.setup'):
namespace = runpy.run_path(str(setup_path))
command = namespace['ClangTidy'](Distribution())
command.distribution.ext_modules = []
command.dry_run = dry_run
command.warning_as_errors = True
build = SimpleNamespace(run=lambda: None)
calls = []

def spawn(args):
calls.append(args)

with patch.object(command, 'get_finalized_command', return_value=build):
with patch.dict(command.run.__globals__, spawn=spawn):
command.run()
assert calls == ([] if dry_run else [['clang-tidy', '--warnings-as-errors=*']])
2 changes: 1 addition & 1 deletion projectq/backends/_azure/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

try:
from ._azure_quantum import AzureQuantumBackend
except ImportError: # pragma: no cover
except (ImportError, TypeError): # pragma: no cover

class AzureQuantumBackend:
"""Dummy class."""
Expand Down
2 changes: 1 addition & 1 deletion projectq/backends/_azure/_azure_quantum.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
from azure.quantum import Workspace
from azure.quantum.target import IonQ, Quantinuum, Target
from azure.quantum.target.target_factory import TargetFactory
except ImportError: # pragma: no cover
except (ImportError, TypeError): # pragma: no cover
raise ImportError( # pylint: disable=raise-missing-from
"Missing optional 'azure-quantum' dependencies. To install run: pip install projectq[azure-quantum]"
)
Expand Down
2 changes: 1 addition & 1 deletion projectq/backends/_azure/_azure_quantum_client_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
import azure.quantum # noqa: F401

from projectq.backends._azure._azure_quantum_client import retrieve, send
except ImportError:
except (ImportError, TypeError):
_has_azure_quantum = False

has_azure_quantum = pytest.mark.skipif(not _has_azure_quantum, reason="azure quantum package is not installed")
Expand Down
2 changes: 1 addition & 1 deletion projectq/backends/_azure/_azure_quantum_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
import projectq.backends._azure._azure_quantum
from projectq.backends import AzureQuantumBackend
from projectq.backends._azure._exceptions import AzureQuantumTargetNotFoundError
except ImportError:
except (ImportError, TypeError):
_has_azure_quantum = False

has_azure_quantum = pytest.mark.skipif(not _has_azure_quantum, reason="azure quantum package is not installed")
Expand Down
2 changes: 1 addition & 1 deletion projectq/backends/_azure/_utils_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
to_json,
to_qasm,
)
except ImportError:
except (ImportError, TypeError):
_has_azure_quantum = False

has_azure_quantum = pytest.mark.skipif(not _has_azure_quantum, reason="azure quantum package is not installed")
Expand Down
Loading
Loading