From e28ba3cafb896c80052471158f666070d39de2d0 Mon Sep 17 00:00:00 2001 From: Zhou Shaobo Date: Sat, 14 Mar 2026 15:09:20 +0100 Subject: [PATCH 01/13] Rebasing onto qce-experiments --- CHANGELOG.md | 5 + docs/setup.md | 2 +- noxfile.py | 2 +- pyproject.toml | 7 + src/mqt/predictor/reward.py | 48 +++- src/mqt/predictor/rl/approx_reward.py | 241 ++++++++++++++++++ src/mqt/predictor/rl/predictor.py | 7 +- src/mqt/predictor/rl/predictorenv.py | 241 ++++++++++++++---- tests/compilation/test_approx_reward.py | 187 ++++++++++++++ .../test_integration_further_SDKs.py | 2 +- tests/compilation/test_predictor_rl.py | 40 ++- tests/device_selection/test_predictor_ml.py | 6 +- uv.lock | 216 ++++++++-------- 13 files changed, 819 insertions(+), 185 deletions(-) create mode 100644 src/mqt/predictor/rl/approx_reward.py create mode 100644 tests/compilation/test_approx_reward.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 0488c7429..0b81df38f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,8 +13,12 @@ This project adheres to [Semantic Versioning], with the exception that minor rel - ✨ Improved the MDP and extended the RL predictor's action/state space (expanded observation vector, support for stochastic passes, wrapped stochastic actions) ([#449]) ([**@Shaobo-Zhou**]) - ✨ Added AIRouting and new optimization actions (KAKDecomposition, ElidePermutations) to the RL action set ([#449]) ([**@Shaobo-Zhou**]) +- ✨ Improve RL reward design by adding intermediate rewards ([#526]) ([**@Shaobo-Zhou**]) - 🔧 Replace `mypy` with `ty` ([#572]) ([**@denialhaag**]) - 🐛 Fix instruction duration unit in estimated success probability calculation ([#445]) ([**@Shaobo-Zhou**]) + +### Removed + - ✨ Remove support for custom names of trained models ([#489]) ([**@bachase**]) - 🔥 Drop support for x86 macOS systems ([#421]) ([**@denialhaag**]) @@ -50,6 +54,7 @@ _📚 Refer to the [GitHub Release Notes](https://github.com/munich-quantum-tool [#445]: https://github.com/munich-quantum-toolkit/predictor/pull/445 [#572]: https://github.com/munich-quantum-toolkit/predictor/pull/572 +[#526]: https://github.com/munich-quantum-toolkit/predictor/pull/526 [#489]: https://github.com/munich-quantum-toolkit/predictor/pull/489 [#445]: https://github.com/munich-quantum-toolkit/predictor/pull/445 [#421]: https://github.com/munich-quantum-toolkit/predictor/pull/421 diff --git a/docs/setup.md b/docs/setup.md index f0e83cd18..6d1218318 100644 --- a/docs/setup.md +++ b/docs/setup.md @@ -109,7 +109,7 @@ After setup, any quantum circuit can be compiled for the most suitable device wi from mqt.predictor import qcompile from mqt.bench import get_benchmark, BenchmarkLevel -uncompiled_qc = get_benchmark("ghz", level=BenchmarkLevel.ALG, circuit_size=5) +uncompiled_qc = get_benchmark("ghz", level=BenchmarkLevel.INDEP, circuit_size=5) compiled_qc, compilation_info, selected_device = qcompile( uncompiled_qc, figure_of_merit="expected_fidelity" ) diff --git a/noxfile.py b/noxfile.py index 5a75d07e4..ba9748466 100755 --- a/noxfile.py +++ b/noxfile.py @@ -92,7 +92,7 @@ def _run_tests( @nox.session(python=PYTHON_ALL_VERSIONS, reuse_venv=True, default=True) def tests(session: nox.Session) -> None: """Run the test suite.""" - _run_tests(session) + _run_tests(session, pytest_run_args=["-Wdefault"]) @nox.session(python=PYTHON_ALL_VERSIONS, reuse_venv=True, venv_backend="uv", default=True) diff --git a/pyproject.toml b/pyproject.toml index 33a06c5a3..c2b8fb387 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -35,6 +35,7 @@ dependencies = [ "pytket_qiskit>=0.65.0", "qiskit-ibm-runtime>=0.37.0", "sb3_contrib>=2.0.0", + "stable-baselines3>=2.7.0", "tqdm>=4.66.0", "rich>=12.6.0", "scikit-learn>=1.5.1", @@ -118,7 +119,13 @@ addopts = [ ] log_level = "INFO" filterwarnings = [ + # NOTE: qiskit-ibm-transpiler (>=0.14) imports wrappers/function_transpile.py during import, + # which currently triggers SyntaxWarnings (invalid escape sequence, and `is` with string literal). + # TODO: Remove these ignores once upstream fixes the warnings. 'error', + "ignore:invalid escape sequence '\\\\w':DeprecationWarning:qiskit_ibm_transpiler\\..*", + "ignore:invalid escape sequence '\\\\w':SyntaxWarning:qiskit_ibm_transpiler\\..*", + "ignore:\"is\" with a literal:SyntaxWarning:qiskit_ibm_transpiler\\..*", 'ignore:.*pytorch.*:UserWarning:', 'ignore:.*Values in x.*:RuntimeWarning:', 'ignore:.*The least populated class in y has only 3 members, which is less than n_splits=5.*:UserWarning:', diff --git a/src/mqt/predictor/reward.py b/src/mqt/predictor/reward.py index a8cd76952..16512e143 100644 --- a/src/mqt/predictor/reward.py +++ b/src/mqt/predictor/reward.py @@ -23,6 +23,7 @@ if TYPE_CHECKING: from qiskit import QuantumCircuit + from qiskit.circuit import QuantumRegister, Qubit from qiskit.transpiler import Target from sklearn.ensemble import RandomForestRegressor @@ -61,22 +62,44 @@ def expected_fidelity(qc: QuantumCircuit, device: Target, precision: int = 10) - if gate_type != "barrier": assert len(qargs) in [1, 2] - first_qubit_idx = qc.find_bit(qargs[0]).index + first_qubit_idx = calc_qubit_index(qargs, qc.qregs, 0) if len(qargs) == 1: specific_fidelity = 1 - device[gate_type][first_qubit_idx,].error else: - second_qubit_idx = qc.find_bit(qargs[1]).index - try: - specific_fidelity = 1 - device[gate_type][first_qubit_idx, second_qubit_idx].error - except KeyError: - msg = f"Error rate for gate {gate_type} on qubits {first_qubit_idx} and {second_qubit_idx} not found in device properties." - raise KeyError(msg) from None + second_qubit_idx = calc_qubit_index(qargs, qc.qregs, 1) + specific_fidelity = 1 - device[gate_type][first_qubit_idx, second_qubit_idx].error + res *= specific_fidelity return float(np.round(res, precision).item()) +def calc_qubit_index(qargs: list[Qubit], qregs: list[QuantumRegister], index: int) -> int: + """Calculates the global qubit index for a given quantum circuit and qubit index. + + Arguments: + qargs: The qubits of the quantum circuit. + qregs: The quantum registers of the quantum circuit. + index: The index of the qubit in the qargs list. + + Returns: + The global qubit index of the given qubit in the quantum circuit. + + Raises: + ValueError: If the qubit index is not found in the quantum registers. + """ + offset = 0 + for reg in qregs: + if qargs[index] not in reg: + offset += reg.size + else: + qubit_index: int = offset + reg.index(qargs[index]) + return qubit_index + error_msg = f"Global qubit index for local qubit {index} index not found." + raise ValueError(error_msg) + + def estimated_success_probability(qc: QuantumCircuit, device: Target, precision: int = 10) -> float: """Calculates the estimated success probability of a given quantum circuit on a given device. @@ -102,7 +125,7 @@ def estimated_success_probability(qc: QuantumCircuit, device: Target, precision: if gate_type == "barrier" or gate_type == "id": continue assert len(qargs) in (1, 2) - first_qubit_idx = qc.find_bit(qargs[0]).index + first_qubit_idx = calc_qubit_index(qargs, qc.qregs, 0) active_qubits.add(first_qubit_idx) if len(qargs) == 1: # single-qubit gate @@ -117,7 +140,7 @@ def estimated_success_probability(qc: QuantumCircuit, device: Target, precision: )) exec_time_per_qubit[first_qubit_idx] += duration else: # multi-qubit gate - second_qubit_idx = qc.find_bit(qargs[1]).index + second_qubit_idx = calc_qubit_index(qargs, qc.qregs, 1) active_qubits.add(second_qubit_idx) duration = device[gate_type][first_qubit_idx, second_qubit_idx].duration op_times.append((gate_type, [first_qubit_idx, second_qubit_idx], duration, "s")) @@ -168,7 +191,7 @@ def estimated_success_probability(qc: QuantumCircuit, device: Target, precision: continue assert len(qargs) in (1, 2) - first_qubit_idx = scheduled_circ.find_bit(qargs[0]).index + first_qubit_idx = calc_qubit_index(qargs, qc.qregs, 0) if len(qargs) == 1: if gate_type == "measure": @@ -181,7 +204,7 @@ def estimated_success_probability(qc: QuantumCircuit, device: Target, precision: if first_qubit_idx not in active_qubits: continue - dt = device.dt # instruction durations are stored in unit dt + dt = device.dt or 1.0 # discrete time unit; fallback to 1.0 if unavailable res *= np.exp( -instruction.duration * dt @@ -189,8 +212,9 @@ def estimated_success_probability(qc: QuantumCircuit, device: Target, precision: ) continue res *= 1 - device[gate_type][first_qubit_idx,].error + else: - second_qubit_idx = scheduled_circ.find_bit(qargs[1]).index + second_qubit_idx = calc_qubit_index(qargs, qc.qregs, 1) res *= 1 - device[gate_type][first_qubit_idx, second_qubit_idx].error if qiskit_version >= "2.0.0": diff --git a/src/mqt/predictor/rl/approx_reward.py b/src/mqt/predictor/rl/approx_reward.py new file mode 100644 index 000000000..95f237d5d --- /dev/null +++ b/src/mqt/predictor/rl/approx_reward.py @@ -0,0 +1,241 @@ +# Copyright (c) 2023 - 2026 Chair for Design Automation, TUM +# Copyright (c) 2025 - 2026 Munich Quantum Software Company GmbH +# All rights reserved. +# +# SPDX-License-Identifier: MIT +# +# Licensed under the MIT License + +"""This module provides helper functions to approximate expected fidelity and estimated success probability (ESP) by transpiling a circuit to a device's basis gate set and combining resulting gate counts with calibration-derived per-gate error rates and durations.""" + +from __future__ import annotations + +from contextlib import suppress +from typing import TYPE_CHECKING + +import numpy as np +from qiskit import transpile + +if TYPE_CHECKING: + from qiskit import QuantumCircuit + from qiskit.transpiler import InstructionProperties, Target + +BLACKLIST: set[str] = {"measure", "reset", "delay", "barrier"} # These gates do not directly contribute to the error + + +def get_basis_gates_from_target(device: Target) -> list[str]: + """Return the basis gate names from a Qiskit Target.""" + return sorted([g for g in device.operation_names if g not in BLACKLIST]) + + +def estimate_basis_gate_counts(qc: QuantumCircuit, *, basis_gates: list[str]) -> dict[str, int]: + """Transpile ``qc`` to ``basis_gates`` and count occurrences of each basis gate.""" + qc_t = transpile(qc, basis_gates=basis_gates, optimization_level=1, seed_transpiler=42) + counts = dict.fromkeys(basis_gates, 0) + for ci in qc_t.data: + name = ci.operation.name + if name in BLACKLIST: + continue + if name in counts: + counts[name] += 1 + return counts + + +def approx_expected_fidelity( + qc: QuantumCircuit, + *, + device: Target, + error_rates: dict[str, float], +) -> float: + """Approximate expected fidelity using per-basis-gate error rates. + + The circuit is first transpiled to the device basis. Then a simple product + model is applied: Π_g (1 - p_g)^{count_g}. + + Args: + qc: Circuit to evaluate. + device: Target providing the basis gate set. + error_rates: Mapping ``basis_gate: g -> error_probability: p_g``. + + Returns: + Approximate fidelity in [0, 1]. + """ + basis = get_basis_gates_from_target(device) + counts = estimate_basis_gate_counts(qc, basis_gates=basis) + f = 1.0 + for g, c in counts.items(): + f *= (1.0 - error_rates.get(g, 0.0)) ** c + return float(max(min(f, 1.0), 0.0)) + + +def approx_estimated_success_probability( + qc: QuantumCircuit, + *, + device: Target, + error_rates: dict[str, float], + gate_durations: dict[str, float], + tbar: float | None, + par_feature: float, + liv_feature: float, + n_qubits: int, +) -> float: + """Approximate ESP using per-basis-gate error rates, durations, and coherence. + + This combines: + (1) a gate-infidelity product term, and + (2) an idle/decoherence penalty based on an effective circuit duration. + + Args: + qc: Circuit to evaluate. + device: Target providing the basis gate set. + error_rates: Mapping ``basis_gate -> error_probability``. + gate_durations: Mapping ``basis_gate -> duration`` (seconds). + tbar: Representative coherence time (seconds). If None, idle penalty is skipped. + par_feature: Parallelism feature in [0, 1]. + liv_feature: Liveness feature in [0, 1]. + n_qubits: Number of qubits in the circuit. + + Returns: + Approximate ESP in [0, 1]. + """ + basis = get_basis_gates_from_target(device) + counts = estimate_basis_gate_counts(qc, basis_gates=basis) + + f_gate = 1.0 + for g, c in counts.items(): + f_gate *= (1.0 - error_rates.get(g, 0.0)) ** c + + n_q = max(n_qubits, 1) + k_eff = 1.0 + (n_q - 1.0) * float(par_feature) + + total_gate_time = sum(counts[g] * gate_durations.get(g, 0.0) for g in basis) / k_eff + + idle_fraction = max(0.0, 1.0 - float(liv_feature)) + idle_factor = 1.0 if tbar is None or tbar <= 0.0 else float(np.exp(-(total_gate_time * idle_fraction) / tbar)) + + esp = f_gate * idle_factor + return float(max(min(esp, 1.0), 0.0)) + + +def compute_device_averages_from_target( + device: Target, +) -> tuple[dict[str, float], dict[str, float], float | None]: + """Compute per-basis-gate averages for error, duration, and a coherence scale. + + Computes and returns: + - error_rates: dict[basis_gate -> mean error probability] + - gate_durations: dict[basis_gate -> mean duration (seconds)] + - tbar: median over qubits of min(T1, T2) (seconds) if available, else None + + Raises: + RuntimeError: if required Target API is missing or if no calibration data exists. + """ + # ---- Hard requirements ------------------------------------------------------- + try: + num_qubits = device.num_qubits + op_names = list(device.operation_names) + coupling_map = device.build_coupling_map() + qubit_props = device.qubit_properties + except AttributeError as exc: + msg = "Device target does not expose the required Target API for approximate reward computation." + raise RuntimeError(msg) from exc + + basis_ops = [name for name in op_names if name not in BLACKLIST] + twoq_edges = coupling_map.get_edges() # list[tuple[int, int]] + + # ---- Helpers ---------------------------------------------------------------- + def _get_props(name: str, qargs: tuple[int, ...]) -> InstructionProperties | None: + """Return calibration properties for (name, qargs) or None if unavailable.""" + with suppress(KeyError): + return device[name].get(qargs, None) + return None + + def _infer_arity(name: str) -> int | None: + """Infer operation arity from Target (best effort).""" + # Preferred: operation_from_name + with suppress(AttributeError, KeyError, TypeError): + op = device.operation_from_name(name) + return int(op.num_qubits) + + # Fallback: infer from any qargs key in device[name] + with suppress(KeyError, TypeError): + props_map = device[name] + for qargs in props_map: + return len(qargs) + return None + + # ---- Accumulate raw samples -------------------------------------------------- + err_samples: dict[str, list[float]] = {name: [] for name in basis_ops} + dur_samples: dict[str, list[float]] = {name: [] for name in basis_ops} + + arity_by_name: dict[str, int] = {} + for name in basis_ops: + arity = _infer_arity(name) + if arity is not None: + arity_by_name[name] = arity + + # ---- Aggregate error/duration per gate -------------------------------------- + for name in basis_ops: + arity = arity_by_name.get(name) + if arity is None: + continue + + if arity == 1: + for q in range(num_qubits): + props = _get_props(name, (q,)) + if props is None: + continue + err = getattr(props, "error", None) + if err is not None: + err_samples[name].append(float(err)) + dur = getattr(props, "duration", None) + if dur is not None: + dur_samples[name].append(float(dur)) + + elif arity == 2: + for i, j in twoq_edges: + props = _get_props(name, (i, j)) + if props is None: + props = _get_props(name, (j, i)) # flipped orientation + if props is None: + continue + err = getattr(props, "error", None) + if err is not None: + err_samples[name].append(float(err)) + dur = getattr(props, "duration", None) + if dur is not None: + dur_samples[name].append(float(dur)) + + else: + # Ignore gates with arity > 2 + continue + + # ---- Global fallbacks -------------------------------------------------------- + all_err = [x for xs in err_samples.values() for x in xs] + all_dur = [x for xs in dur_samples.values() for x in xs] + + if not all_err and not all_dur: + msg = "No valid calibration data found in Target, cannot compute approximate reward." + raise RuntimeError(msg) + + global_err = float(np.mean(all_err)) if all_err else 0.0 + global_dur = float(np.mean(all_dur)) if all_dur else 0.0 + + error_rates = {name: (float(np.mean(vals)) if vals else global_err) for name, vals in err_samples.items()} + gate_durations = {name: (float(np.mean(vals)) if vals else global_dur) for name, vals in dur_samples.items()} + + # ---- Coherence scale --------------------------------------------------------- + tmins: list[float] = [] + if qubit_props: + for i in range(num_qubits): + props = qubit_props[i] + if props is None: + continue + t1v = getattr(props, "t1", None) + t2v = getattr(props, "t2", None) + vals = [v for v in (t1v, t2v) if v is not None] + if vals: + tmins.append(float(min(vals))) + + tbar = float(np.median(tmins)) if tmins else None + return error_rates, gate_durations, tbar diff --git a/src/mqt/predictor/rl/predictor.py b/src/mqt/predictor/rl/predictor.py index 1f75b1901..2654f34fe 100644 --- a/src/mqt/predictor/rl/predictor.py +++ b/src/mqt/predictor/rl/predictor.py @@ -99,12 +99,11 @@ def train_model( """ if test: set_random_seed(0) # for reproducibility - n_steps = 32 - n_epochs = 2 - batch_size = 8 + n_steps = 10 + n_epochs = 1 + batch_size = 10 progress_bar = False else: - set_random_seed(0) # default PPO values n_steps = 2048 n_epochs = 10 diff --git a/src/mqt/predictor/rl/predictorenv.py b/src/mqt/predictor/rl/predictorenv.py index 9936e8ecc..2e9984b3f 100644 --- a/src/mqt/predictor/rl/predictorenv.py +++ b/src/mqt/predictor/rl/predictorenv.py @@ -21,7 +21,7 @@ from pytket._tket.passes import BasePass as TketBasePass from pytket.circuit import Node from qiskit.passmanager.base_tasks import Task - from qiskit.transpiler import Layout, Target + from qiskit.transpiler import Target from mqt.predictor.reward import figure_of_merit from mqt.predictor.rl.actions import Action @@ -31,6 +31,7 @@ import warnings +from math import isclose from typing import cast import numpy as np @@ -49,8 +50,10 @@ from qiskit.transpiler.passes import ( ApplyLayout, BasisTranslator, + CheckMap, EnlargeWithAncilla, FullAncillaAllocation, + GatesInBasis, SetLayout, ) from qiskit.transpiler.passes.layout.vf2_layout import VF2LayoutStopReason @@ -69,6 +72,11 @@ PassType, get_actions_by_pass_type, ) +from mqt.predictor.rl.approx_reward import ( + approx_estimated_success_probability, + approx_expected_fidelity, + compute_device_averages_from_target, +) from mqt.predictor.rl.helper import ( create_feature_dict, get_path_training_circuits, @@ -80,7 +88,7 @@ postprocess_vf2postlayout, prepare_noise_data, ) -from mqt.predictor.utils import get_openqasm_gates_for_rl +from mqt.predictor.utils import calc_supermarq_features, get_openqasm_gates_for_rl logger = logging.getLogger("mqt-predictor") @@ -94,6 +102,8 @@ def __init__( mdp: str = "paper", reward_function: figure_of_merit = "expected_fidelity", path_training_circuits: Path | None = None, + reward_scale: float = 1.0, + no_effect_penalty: float = -0.001, ) -> None: """Initializes the PredictorEnv object. @@ -102,6 +112,8 @@ def __init__( mdp: The MDP transition policy. "paper" (default) enforces a strict, linear pipeline (synthesis -> (layout->routing) / mapping), while "flexible" allows for a cyclical approach where actions can be interleaved or reversed. reward_function: The figure of merit to be used for the reward function. Defaults to "expected_fidelity". path_training_circuits: The path to the training circuits folder. Defaults to None, which uses the default path. + reward_scale: Scaling factor for rewards/penalties proportional to fidelity changes. + no_effect_penalty: Step penalty applied when an action does not change the circuit (no-op). Raises: ValueError: If the reward function is "estimated_success_probability" and no calibration data is available for the device or if the reward function is "estimated_hellinger_distance" and no trained model is available for the device. @@ -200,65 +212,182 @@ def __init__( self.node_err: dict[Node, float] | None = None self.edge_err: dict[tuple[Node, Node], float] | None = None self.readout_err: dict[Node, float] | None = None + self.reward_scale = reward_scale + self.no_effect_penalty = no_effect_penalty + self.prev_reward: float | None = None + self.prev_reward_kind: str | None = None + self._err_by_gate: dict[str, float] = {} + self._dur_by_gate: dict[str, float] = {} + self._tbar: float | None = None + self._dev_avgs_cached = False + self.state: QuantumCircuit = QuantumCircuit() - def step(self, action: int) -> tuple[dict[str, Any], float, bool, bool, dict[Any, Any]]: - """Executes the given action and returns the new state, the reward, whether the episode is done, whether the episode is truncated and additional information. - - Arguments: - action: The action to be executed, represented by its index in the action set. - - Returns: - A tuple containing the new state as a feature dictionary, the reward value, whether the episode is done, whether the episode is truncated, and additional information. + self.error_occurred = False - Raises: - RuntimeError: If no valid actions are left. - """ - self.used_actions.append(str(self.action_set[action].name)) + def _apply_and_update(self, action: int) -> QuantumCircuit | None: + """Apply an action, normalize the circuit, and update internal state.""" altered_qc = self.apply_action(action) - if not altered_qc: - return ( - create_feature_dict(self.state), - 0, - True, - False, - {}, - ) + if altered_qc is None: + return None self.state: QuantumCircuit = altered_qc self.num_steps += 1 - self.state._layout = self.layout # noqa: SLF001 - self.valid_actions = self.determine_valid_actions_for_state() - if len(self.valid_actions) == 0: + if not self.valid_actions: msg = "No valid actions left." raise RuntimeError(msg) - if action == self.action_terminate_index: + return altered_qc + + def step(self, action: int) -> tuple[dict[str, Any], float, bool, bool, dict[Any, Any]]: + """Run one environment step. + + This method: + 1. Evaluates the current circuit with the configured reward function + (using either the exact or approximate metric, depending on state). + 2. Applies the selected transpiler pass (the action). + 3. Computes a shaped step reward based on the change in the figure of merit. + + Reward design: + - For non-terminal actions, the step reward is a scaled delta between + the new and previous reward (plus an optional step penalty). + - For the terminate action, the episode ends and the final reward is + the exact (calibration-aware) metric. + """ + self.used_actions.append(str(self.action_set[action].name)) + logger.info("Applying %s", self.action_set[action].name) + + altered_qc = self._apply_and_update(action) + if altered_qc is None: + return create_feature_dict(self.state), 0.0, True, False, {} + + done = action == self.action_terminate_index + + if self.reward_function == "estimated_hellinger_distance": + reward_val = self.calculate_reward(mode="exact")[0] if done else 0.0 + self.state._layout = self.layout # noqa: SLF001 + return create_feature_dict(self.state), reward_val, done, False, {} + + # Lazy init: compute prev_reward only once per episode (or if missing) + if self.prev_reward is None: + self.prev_reward, self.prev_reward_kind = self.calculate_reward(mode="auto") + + if done: assert action in self.valid_actions, "Terminate action is not valid but was chosen." - reward_val = self.calculate_reward() - done = True + self.prev_reward, self.prev_reward_kind = self.calculate_reward(mode="exact") + reward_val = self.prev_reward else: - reward_val = 0 - done = False + new_val, new_kind = self.calculate_reward(mode="auto") + delta_reward = new_val - self.prev_reward + + if self.prev_reward_kind != new_kind: + delta_reward = 0.0 + + reward_val = ( + self.reward_scale * delta_reward + if not isclose(delta_reward, 0.0, abs_tol=1e-12) + else self.no_effect_penalty + ) + self.prev_reward, self.prev_reward_kind = new_val, new_kind obs = create_feature_dict(self.state) return obs, reward_val, done, False, {} - def calculate_reward(self, qc: QuantumCircuit | None = None) -> float: - """Calculates and returns the reward for either the current state or a quantum circuit (if provided).""" - circuit = self.state if qc is None else qc + def calculate_reward(self, qc: QuantumCircuit | None = None, mode: str = "auto") -> tuple[float, str]: + """Compute the reward for a circuit and report whether it was computed exactly or approximately. + + This environment supports two evaluation regimes for selected figures of merit: + + - **Exact**: uses the calibration-aware implementation on the full circuit/device + (e.g., uses the device Target calibration data as-is). + - **Approximate**: uses a transpile-based proxy: + the circuit is transpiled to the device's basis gates and the resulting basis-gate + counts are combined with cached **per-basis-gate** calibration statistics + (error rates and durations) to estimate the metric. This approximation ignores + additional mapping/routing overhead beyond what is reflected in the transpiled + basis-gate counts. + + Args: + qc: + Circuit to evaluate. If ``None``, evaluates the environment's current state. + mode: + Selects how the method chooses between exact and approximate evaluation: + + - ``"auto"`` (default): compute the exact metric if the circuit is already + **native and mapped** for the device; otherwise compute the approximate metric. + - ``"exact"``: always compute the exact, calibration-aware metric. + - ``"approx"``: always compute the approximate, transpile-based proxy. + + Returns: + A pair ``(value, kind)`` where: + + - ``value`` is the scalar reward value (typically in ``[0, 1]`` for EF/ESP). + - ``kind`` is ``"exact"`` or ``"approx"`` indicating which regime was used. + """ + if qc is None: + qc = self.state + + # Reward functions that are always computed exactly. + if self.reward_function not in {"expected_fidelity", "estimated_success_probability"}: + if self.reward_function == "critical_depth": + return crit_depth(qc), "exact" + if self.reward_function == "estimated_hellinger_distance": + return estimated_hellinger_distance(qc, self.device, self.hellinger_model), "exact" + # Fallback for other unknown / not-yet-implemented reward functions: + logger.warning( + "Reward function '%s' is not supported in PredictorEnv. Returning 0.0 as a fallback reward.", + self.reward_function, + ) + return 0.0, "exact" + + # Dual-path evaluation (exact vs. approximate) for EF / ESP. + if mode == "exact": + kind = "exact" + elif mode == "approx": + kind = "approx" + else: # "auto" + check_nat_gates = GatesInBasis(basis_gates=self.device.operation_names) + check_nat_gates(qc) + only_native = bool(check_nat_gates.property_set["all_gates_in_basis"]) + + check_mapping = CheckMap(coupling_map=self.device.build_coupling_map()) + check_mapping(qc) + mapped = bool(check_mapping.property_set["is_swap_mapped"]) + + kind = "exact" if (only_native and mapped) else "approx" + + if kind == "exact": + if self.reward_function == "expected_fidelity": + return expected_fidelity(qc, self.device), "exact" + + return estimated_success_probability(qc, self.device), "exact" + + # Approximate metrics use per-basis-gate averages cached from device calibration + self._ensure_device_averages_cached() + if self.reward_function == "expected_fidelity": - return expected_fidelity(circuit, self.device) - if self.reward_function == "estimated_success_probability": - return estimated_success_probability(circuit, self.device) - if self.reward_function == "estimated_hellinger_distance": - return estimated_hellinger_distance(circuit, self.device, self.hellinger_model) - if self.reward_function == "critical_depth": - return crit_depth(self.state) - msg = f"No implementation for reward function {self.reward_function}." - raise NotImplementedError(msg) + val = approx_expected_fidelity( + qc, + device=self.device, + error_rates=self._err_by_gate, + ) + return val, "approx" + + feats = calc_supermarq_features(qc) + + val = approx_estimated_success_probability( + qc, + device=self.device, + error_rates=self._err_by_gate, + gate_durations=self._dur_by_gate, + tbar=self._tbar, + par_feature=float(feats.parallelism), + liv_feature=float(feats.liveness), + n_qubits=int(qc.num_qubits), + ) + return val, "approx" def render(self) -> None: """Renders the current state.""" @@ -285,7 +414,7 @@ def reset( if isinstance(qc, QuantumCircuit): self.state = qc elif qc: - self.state = QuantumCircuit.from_qasm_file(qc) # ty: ignore[invalid-argument-type] + self.state = QuantumCircuit.from_qasm_file(str(qc)) else: self.state, self.filename = get_state_sample(self.device.num_qubits, self.path_training_circuits, self.rng) @@ -307,6 +436,9 @@ def reset( self.error_occurred = False + self.prev_reward = None + self.prev_reward_kind = None + self.num_qubits_uncompiled_circuit = self.state.num_qubits self.has_parameterized_gates = len(self.state.parameters) > 0 @@ -316,9 +448,8 @@ def action_masks(self) -> list[bool]: """Returns a list of valid actions for the current state.""" action_mask = [action in self.valid_actions for action in self.action_set] - # TKET layout/optimization actions must not run after a Qiskit layout has been set - # (it is not clear how tket will handle the layout). TKET routing actions are - # designed to work after a Qiskit layout via PreProcessTKETRoutingAfterQiskitLayout. + # TKET layout/optimization actions must not run after a Qiskit layout has been set. + # TKET routing actions are explicitly supported through preprocessing. if self.layout is not None: action_mask = [ action_mask[i] @@ -414,7 +545,7 @@ def fom_aware_compile( BasisTranslator(StandardEquivalenceLibrary, target_basis=device.operation_names) ]) synth_circ = synth_pass.run(out_circ.copy()) - fom = self.calculate_reward(synth_circ) + fom, _ = self.calculate_reward(synth_circ) if fom > best_fom: best_fom = fom @@ -486,7 +617,6 @@ def _apply_qiskit_action(self, action: Action, action_index: int) -> QuantumCirc altered_qc = altered_qc.decompose(gates_to_decompose="unitary") elif altered_qc.count_ops().get("clifford"): # ty: ignore[invalid-argument-type] altered_qc = altered_qc.decompose(gates_to_decompose="clifford") - return altered_qc def _handle_qiskit_layout_postprocessing( @@ -704,18 +834,15 @@ def is_circuit_routed(self, circuit: QuantumCircuit, coupling_map: CouplingMap) if (q0, q1) not in directed_edges: return False return True - def determine_valid_actions_for_state(self) -> list[int]: """Determine valid actions based on circuit state: synthesized, mapped, routed.""" synthesized = self.is_circuit_synthesized(self.state) laid_out = self.is_circuit_laid_out(self.state, self.layout) if self.layout else False - # Routing is only allowed after layout routed = ( self.is_circuit_routed(self.state, CouplingMap(self.device.build_coupling_map())) if laid_out else False ) actions = [] - # Initial state if not synthesized and not laid_out and not routed: if self.mdp == "flexible": @@ -794,3 +921,15 @@ def determine_valid_actions_for_state(self) -> list[int]: actions.extend(self.actions_final_optimization_indices) return actions + + def _ensure_device_averages_cached(self) -> None: + """Cache per-basis-gate averages for error, duration, and a coherence scale.""" + if self._dev_avgs_cached: + return + + err_by_gate, dur_by_gate, tbar = compute_device_averages_from_target(self.device) + + self._err_by_gate = err_by_gate + self._dur_by_gate = dur_by_gate + self._tbar = tbar + self._dev_avgs_cached = True diff --git a/tests/compilation/test_approx_reward.py b/tests/compilation/test_approx_reward.py new file mode 100644 index 000000000..0a7858b13 --- /dev/null +++ b/tests/compilation/test_approx_reward.py @@ -0,0 +1,187 @@ +# Copyright (c) 2023 - 2026 Chair for Design Automation, TUM +# Copyright (c) 2025 - 2026 Munich Quantum Software Company GmbH +# All rights reserved. +# +# SPDX-License-Identifier: MIT +# +# Licensed under the MIT License + +"""Tests for approximate reward helper functions.""" + +from __future__ import annotations + +from dataclasses import dataclass +from typing import TYPE_CHECKING, cast + +import pytest + +from mqt.predictor.rl.approx_reward import compute_device_averages_from_target + +if TYPE_CHECKING: + from qiskit.transpiler import Target + + +@dataclass +class FakeInstructionProperties: + """Minimal stand-in for Qiskit's InstructionProperties.""" + + error: float | None = None + duration: float | None = None + + +@dataclass +class FakeQubitProperties: + """Minimal stand-in for Qiskit's QubitProperties.""" + + t1: float | None = None + t2: float | None = None + + +@dataclass +class FakeOperation: + """Minimal operation object exposing `num_qubits`.""" + + num_qubits: int + + +class FakeCouplingMap: + """Minimal coupling map exposing directed edges.""" + + def __init__(self, edges: list[tuple[int, int]]) -> None: + """Store directed coupling edges.""" + self._edges = edges + + def get_edges(self) -> list[tuple[int, int]]: + """Return directed coupling edges.""" + return self._edges + + +class FakeTarget: + """Minimal Target-like object for testing branch behavior.""" + + def __init__( + self, + *, + num_qubits: int, + operation_names: list[str], + op_props: dict[str, dict[tuple[int, ...], FakeInstructionProperties]], + arities: dict[str, int], + edges: list[tuple[int, int]], + qubit_properties: list[FakeQubitProperties | None] | None, + operation_from_name_raises_for: set[str] | None = None, + ) -> None: + """Initialize operation data, arities, connectivity, and qubit properties.""" + self.num_qubits = num_qubits + self.operation_names = operation_names + self._op_props = op_props + self._arities = arities + self._edges = edges + self.qubit_properties = qubit_properties + self._operation_from_name_raises_for = operation_from_name_raises_for or set() + + def build_coupling_map(self) -> FakeCouplingMap: + """Return a minimal coupling map.""" + return FakeCouplingMap(self._edges) + + def operation_from_name(self, name: str) -> FakeOperation: + """Return operation metadata or raise to trigger fallback inference.""" + if name in self._operation_from_name_raises_for: + msg = f"Operation {name} metadata unavailable." + raise KeyError(msg) + return FakeOperation(num_qubits=self._arities[name]) + + def __getitem__(self, name: str) -> dict[tuple[int, ...], FakeInstructionProperties]: + """Return calibration map for an operation.""" + return self._op_props[name] + + +def test_compute_device_averages_nominal_path() -> None: + """Compute per-gate means and qubit coherence median on a nominal target.""" + target = FakeTarget( + num_qubits=2, + operation_names=["measure", "x", "cx"], # measure should be ignored + op_props={ + "x": { + (0,): FakeInstructionProperties(error=0.1, duration=10.0), + (1,): FakeInstructionProperties(error=0.3, duration=30.0), + }, + "cx": { + (0, 1): FakeInstructionProperties(error=0.4, duration=40.0), + }, + }, + arities={"x": 1, "cx": 2}, + edges=[(0, 1)], + qubit_properties=[ + FakeQubitProperties(t1=100.0, t2=50.0), # min = 50 + FakeQubitProperties(t1=200.0, t2=None), # min = 200 + ], + ) + + err_by_gate, dur_by_gate, tbar = compute_device_averages_from_target(cast("Target", target)) + + assert err_by_gate == {"x": pytest.approx(0.2), "cx": pytest.approx(0.4)} + assert dur_by_gate == {"x": pytest.approx(20.0), "cx": pytest.approx(40.0)} + assert tbar == pytest.approx(125.0) + + +def test_compute_device_averages_fallbacks_are_used() -> None: + """Use orientation fallback, arity fallback, and global per-gate fallback.""" + target = FakeTarget( + num_qubits=2, + operation_names=["x", "cx", "rz"], + op_props={ + "x": { + (0,): FakeInstructionProperties(error=0.1, duration=10.0), + (1,): FakeInstructionProperties(error=0.3, duration=30.0), + }, + # Only reverse orientation is available; edge scan uses (0, 1) + "cx": { + (1, 0): FakeInstructionProperties(error=0.2, duration=20.0), + }, + # No data for rz; should get global fallback values + "rz": { + (0,): FakeInstructionProperties(error=None, duration=None), + (1,): FakeInstructionProperties(error=None, duration=None), + }, + }, + arities={"x": 1, "cx": 2, "rz": 1}, + edges=[(0, 1)], + qubit_properties=None, + # Force arity fallback for "cx" by raising in operation_from_name + operation_from_name_raises_for={"cx"}, + ) + + err_by_gate, dur_by_gate, tbar = compute_device_averages_from_target(cast("Target", target)) + + # all available samples are 0.1, 0.3, 0.2 for error and 10, 30, 20 for duration + assert err_by_gate["rz"] == pytest.approx(0.2) + assert dur_by_gate["rz"] == pytest.approx(20.0) + assert err_by_gate["cx"] == pytest.approx(0.2) + assert dur_by_gate["cx"] == pytest.approx(20.0) + assert tbar is None + + +def test_compute_device_averages_missing_target_api_raises() -> None: + """Raise a clear RuntimeError if the object is not Target-compatible.""" + with pytest.raises(RuntimeError, match="required Target API"): + compute_device_averages_from_target(cast("Target", object())) + + +def test_compute_device_averages_without_calibration_data_raises() -> None: + """Raise if calibration data contains neither error nor duration samples.""" + target = FakeTarget( + num_qubits=2, + operation_names=["x"], + op_props={ + "x": { + (0,): FakeInstructionProperties(error=None, duration=None), + (1,): FakeInstructionProperties(error=None, duration=None), + } + }, + arities={"x": 1}, + edges=[], + qubit_properties=[None, None], + ) + + with pytest.raises(RuntimeError, match="No valid calibration data found in Target"): + compute_device_averages_from_target(cast("Target", target)) diff --git a/tests/compilation/test_integration_further_SDKs.py b/tests/compilation/test_integration_further_SDKs.py index 150363ea3..9aa33bb6f 100644 --- a/tests/compilation/test_integration_further_SDKs.py +++ b/tests/compilation/test_integration_further_SDKs.py @@ -241,7 +241,7 @@ def test_tket_routing(available_actions_dict: dict[PassType, list[Action]]) -> N qubit_map = {qbs[i]: Qubit("q", i) for i in range(len(qbs))} tket_qc.rename_units(qubit_map) - mapped_qc = tk_to_qiskit(tket_qc, replace_implicit_swaps=True) + mapped_qc = tk_to_qiskit(tket_qc) final_layout = final_layout_pytket_to_qiskit(tket_qc, mapped_qc) diff --git a/tests/compilation/test_predictor_rl.py b/tests/compilation/test_predictor_rl.py index a36e32dac..5d8989339 100644 --- a/tests/compilation/test_predictor_rl.py +++ b/tests/compilation/test_predictor_rl.py @@ -37,6 +37,7 @@ if TYPE_CHECKING: from _pytest.monkeypatch import MonkeyPatch + from mqt.predictor.reward import figure_of_merit def test_predictor_env_reset_from_string() -> None: @@ -44,7 +45,7 @@ def test_predictor_env_reset_from_string() -> None: device = get_device("ibm_eagle_127") predictor = Predictor(figure_of_merit="expected_fidelity", device=device) qasm_path = Path("test.qasm") - qc = get_benchmark("dj", BenchmarkLevel.ALG, 3) + qc = get_benchmark("dj", BenchmarkLevel.INDEP, 3) with qasm_path.open("w", encoding="utf-8") as f: dump(qc, f) assert predictor.env.reset(qc=qasm_path)[0] == create_feature_dict(qc) @@ -77,6 +78,7 @@ def test_qcompile_with_newly_trained_models() -> None: figure_of_merit = "expected_fidelity" device = get_device("ibm_falcon_127") qc = get_benchmark("ghz", BenchmarkLevel.ALG, 3) + predictor = Predictor(figure_of_merit=figure_of_merit, device=device) model_name = "model_" + figure_of_merit + "_" + device.description @@ -91,7 +93,7 @@ def test_qcompile_with_newly_trained_models() -> None: rl_compile(qc, device=device, figure_of_merit=figure_of_merit) predictor.train_model( - timesteps=1000, + timesteps=100, test=True, ) @@ -112,7 +114,7 @@ def test_qcompile_with_newly_trained_models() -> None: def test_qcompile_with_false_input() -> None: """Test the qcompile function with false input.""" - qc = get_benchmark("dj", BenchmarkLevel.ALG, 5) + qc = get_benchmark("dj", BenchmarkLevel.INDEP, 5) with pytest.raises(ValueError, match=re.escape("figure_of_merit must not be None if predictor_singleton is None.")): rl_compile(qc, device=get_device("quantinuum_h2_56"), figure_of_merit=None) with pytest.raises(ValueError, match=re.escape("device must not be None if predictor_singleton is None.")): @@ -198,3 +200,35 @@ def test_register_action() -> None: with pytest.raises(KeyError, match=re.escape("No action with name wrong_action_name is registered")): remove_action("wrong_action_name") + + +@pytest.mark.parametrize( + "fom", + ["expected_fidelity", "estimated_success_probability"], +) +def test_approx_reward_paths_use_cached_per_gate_maps(fom: figure_of_merit) -> None: + """Ensure approx reward path runs and uses cached per-basis-gate calibration maps. + + We don't test exact numeric values (backend-dependent), only that: + - approx path runs, + - cached maps are populated, + - output is a valid probability in [0, 1]. + """ + qc = get_benchmark("ghz", BenchmarkLevel.INDEP, 3) + device = get_device("ibm_heron_133") + predictor = Predictor(figure_of_merit=fom, device=device) + + val, kind = predictor.env.calculate_reward(qc=qc, mode="approx") + assert kind == "approx" + assert 0.0 <= val <= 1.0 + + # Ensure caching produced per-gate mappings + assert predictor.env._dev_avgs_cached # noqa: SLF001 + assert isinstance(predictor.env._err_by_gate, dict) # noqa: SLF001 + assert isinstance(predictor.env._dur_by_gate, dict) # noqa: SLF001 + assert len(predictor.env._err_by_gate) > 0 # noqa: SLF001 + + if fom == "estimated_success_probability": + assert len(predictor.env._dur_by_gate) > 0 # noqa: SLF001 + # tbar is optional depending on backend calibration; just sanity-check type + assert predictor.env._tbar is None or predictor.env._tbar > 0.0 # noqa: SLF001 diff --git a/tests/device_selection/test_predictor_ml.py b/tests/device_selection/test_predictor_ml.py index db07cd1c4..32bbf6f8f 100644 --- a/tests/device_selection/test_predictor_ml.py +++ b/tests/device_selection/test_predictor_ml.py @@ -43,7 +43,7 @@ def test_setup_device_predictor_with_prediction(path_uncompiled_circuits: Path, path_compiled_circuits.mkdir() for i in range(2, 8): - qc = get_benchmark("ghz", BenchmarkLevel.ALG, i) + qc = get_benchmark("ghz", BenchmarkLevel.INDEP, i) path = path_uncompiled_circuits / f"qc{i}.qasm" with path.open("w", encoding="utf-8") as f: dump(qc, f) @@ -63,7 +63,7 @@ def test_setup_device_predictor_with_prediction(path_uncompiled_circuits: Path, assert (data_path / "names_list_expected_fidelity.npy").exists() assert (data_path / "scores_list_expected_fidelity.npy").exists() - test_qc = get_benchmark("ghz", BenchmarkLevel.ALG, 3) + test_qc = get_benchmark("ghz", BenchmarkLevel.INDEP, 3) predicted = predict_device_for_figure_of_merit(test_qc, figure_of_merit="expected_fidelity") assert predicted.description == "ibm_falcon_127" @@ -93,7 +93,7 @@ def test_remove_files(path_uncompiled_circuits: Path, path_compiled_circuits: Pa def test_predict_device_for_figure_of_merit_no_suitable_device() -> None: """Test the prediction of the device for a given figure of merit with a wrong device name.""" num_qubits = 130 - qc = get_benchmark("ghz", BenchmarkLevel.ALG, num_qubits) + qc = get_benchmark("ghz", BenchmarkLevel.INDEP, num_qubits) with pytest.raises( ValueError, match=re.escape(f"No suitable device found for the given quantum circuit with {num_qubits} qubits.") ): diff --git a/uv.lock b/uv.lock index 8320148a0..522320d68 100644 --- a/uv.lock +++ b/uv.lock @@ -1115,59 +1115,59 @@ wheels = [ [[package]] name = "fonttools" -version = "4.62.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/5a/96/686339e0fda8142b7ebed39af53f4a5694602a729662f42a6209e3be91d0/fonttools-4.62.0.tar.gz", hash = "sha256:0dc477c12b8076b4eb9af2e440421b0433ffa9e1dcb39e0640a6c94665ed1098", size = 3579521, upload-time = "2026-03-09T16:50:06.217Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/82/e0/9db48ec7f6b95bae7b20667ded54f18dba8e759ef66232c8683822ae26fc/fonttools-4.62.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:62b6a3d0028e458e9b59501cf7124a84cd69681c433570e4861aff4fb54a236c", size = 2873527, upload-time = "2026-03-09T16:48:12.416Z" }, - { url = "https://files.pythonhosted.org/packages/dd/45/86eccfdc922cb9fafc63189a9793fa9f6dd60e68a07be42e454ef2c0deae/fonttools-4.62.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:966557078b55e697f65300b18025c54e872d7908d1899b7314d7c16e64868cb2", size = 2417427, upload-time = "2026-03-09T16:48:15.122Z" }, - { url = "https://files.pythonhosted.org/packages/d3/98/f547a1fceeae81a9a5c6461bde2badac8bf50bda7122a8012b32b1e65396/fonttools-4.62.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9cf34861145b516cddd19b07ae6f4a61ea1c6326031b960ec9ddce8ee815e888", size = 4934993, upload-time = "2026-03-09T16:48:18.186Z" }, - { url = "https://files.pythonhosted.org/packages/5c/57/a23a051fcff998fdfabdd33c6721b5bad499da08b586d3676993410071f0/fonttools-4.62.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3e2ff573de2775508c8a366351fb901c4ced5dc6cf2d87dd15c973bedcdd5216", size = 4892154, upload-time = "2026-03-09T16:48:20.736Z" }, - { url = "https://files.pythonhosted.org/packages/e2/62/e27644b433dc6db1d47bc6028a27d772eec5cc8338e24a9a1fce5d7120aa/fonttools-4.62.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:55b189a1b3033860a38e4e5bd0626c5aa25c7ce9caee7bc784a8caec7a675401", size = 4911635, upload-time = "2026-03-09T16:48:23.174Z" }, - { url = "https://files.pythonhosted.org/packages/7e/e2/1bf141911a5616bacfe9cf237c80ccd69d0d92482c38c0f7f6a55d063ad9/fonttools-4.62.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:825f98cd14907c74a4d0a3f7db8570886ffce9c6369fed1385020febf919abf6", size = 5031492, upload-time = "2026-03-09T16:48:25.095Z" }, - { url = "https://files.pythonhosted.org/packages/2f/59/790c292f4347ecfa77d9c7e0d1d91e04ab227f6e4a337ed4fe37ca388048/fonttools-4.62.0-cp310-cp310-win32.whl", hash = "sha256:c858030560f92a054444c6e46745227bfd3bb4e55383c80d79462cd47289e4b5", size = 1507656, upload-time = "2026-03-09T16:48:26.973Z" }, - { url = "https://files.pythonhosted.org/packages/e9/ee/08c0b7f8bac6e44638de6fe9a3e710a623932f60eccd58912c4d4743516d/fonttools-4.62.0-cp310-cp310-win_amd64.whl", hash = "sha256:9bf75eb69330e34ad2a096fac67887102c8537991eb6cac1507fc835bbb70e0a", size = 1556540, upload-time = "2026-03-09T16:48:30.359Z" }, - { url = "https://files.pythonhosted.org/packages/e4/33/63d79ca41020dd460b51f1e0f58ad1ff0a36b7bcbdf8f3971d52836581e9/fonttools-4.62.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:196cafef9aeec5258425bd31a4e9a414b2ee0d1557bca184d7923d3d3bcd90f9", size = 2870816, upload-time = "2026-03-09T16:48:32.39Z" }, - { url = "https://files.pythonhosted.org/packages/c0/7a/9aeec114bc9fc00d757a41f092f7107863d372e684a5b5724c043654477c/fonttools-4.62.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:153afc3012ff8761b1733e8fbe5d98623409774c44ffd88fbcb780e240c11d13", size = 2416127, upload-time = "2026-03-09T16:48:34.627Z" }, - { url = "https://files.pythonhosted.org/packages/5a/71/12cfd8ae0478b7158ffa8850786781f67e73c00fd897ef9d053415c5f88b/fonttools-4.62.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:13b663fb197334de84db790353d59da2a7288fd14e9be329f5debc63ec0500a5", size = 5100678, upload-time = "2026-03-09T16:48:36.454Z" }, - { url = "https://files.pythonhosted.org/packages/8a/d7/8e4845993ee233c2023d11babe9b3dae7d30333da1d792eeccebcb77baab/fonttools-4.62.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:591220d5333264b1df0d3285adbdfe2af4f6a45bbf9ca2b485f97c9f577c49ff", size = 5070859, upload-time = "2026-03-09T16:48:38.786Z" }, - { url = "https://files.pythonhosted.org/packages/ae/a0/287ae04cd883a52e7bb1d92dfc4997dcffb54173761c751106845fa9e316/fonttools-4.62.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:579f35c121528a50c96bf6fcb6a393e81e7f896d4326bf40e379f1c971603db9", size = 5076689, upload-time = "2026-03-09T16:48:41.886Z" }, - { url = "https://files.pythonhosted.org/packages/6d/4e/a2377ad26c36fcd3e671a1c316ea5ed83107de1588e2d897a98349363bc7/fonttools-4.62.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:44956b003151d5a289eba6c71fe590d63509267c37e26de1766ba15d9c589582", size = 5202053, upload-time = "2026-03-09T16:48:43.867Z" }, - { url = "https://files.pythonhosted.org/packages/44/2e/ad0472e69b02f83dc88983a9910d122178461606404be5b4838af6d1744a/fonttools-4.62.0-cp311-cp311-win32.whl", hash = "sha256:42c7848fa8836ab92c23b1617c407a905642521ff2d7897fe2bf8381530172f1", size = 2292852, upload-time = "2026-03-09T16:48:46.962Z" }, - { url = "https://files.pythonhosted.org/packages/77/ce/f5a4c42c117f8113ce04048053c128d17426751a508f26398110c993a074/fonttools-4.62.0-cp311-cp311-win_amd64.whl", hash = "sha256:4da779e8f342a32856075ddb193b2a024ad900bc04ecb744014c32409ae871ed", size = 2344367, upload-time = "2026-03-09T16:48:48.818Z" }, - { url = "https://files.pythonhosted.org/packages/ab/9d/7ad1ffc080619f67d0b1e0fa6a0578f0be077404f13fd8e448d1616a94a3/fonttools-4.62.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:22bde4dc12a9e09b5ced77f3b5053d96cf10c4976c6ac0dee293418ef289d221", size = 2870004, upload-time = "2026-03-09T16:48:50.837Z" }, - { url = "https://files.pythonhosted.org/packages/4d/8b/ba59069a490f61b737e064c3129453dbd28ee38e81d56af0d04d7e6b4de4/fonttools-4.62.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7199c73b326bad892f1cb53ffdd002128bfd58a89b8f662204fbf1daf8d62e85", size = 2414662, upload-time = "2026-03-09T16:48:53.295Z" }, - { url = "https://files.pythonhosted.org/packages/8c/8c/c52a4310de58deeac7e9ea800892aec09b00bb3eb0c53265b31ec02be115/fonttools-4.62.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d732938633681d6e2324e601b79e93f7f72395ec8681f9cdae5a8c08bc167e72", size = 5032975, upload-time = "2026-03-09T16:48:55.718Z" }, - { url = "https://files.pythonhosted.org/packages/0b/a1/d16318232964d786907b9b3613b8409f74cf0be2da400854509d3a864e43/fonttools-4.62.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:31a804c16d76038cc4e3826e07678efb0a02dc4f15396ea8e07088adbfb2578e", size = 4988544, upload-time = "2026-03-09T16:48:57.715Z" }, - { url = "https://files.pythonhosted.org/packages/b2/8d/7e745ca3e65852adc5e52a83dc213fe1b07d61cb5b394970fcd4b1199d1e/fonttools-4.62.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:090e74ac86e68c20150e665ef8e7e0c20cb9f8b395302c9419fa2e4d332c3b51", size = 4971296, upload-time = "2026-03-09T16:48:59.678Z" }, - { url = "https://files.pythonhosted.org/packages/e6/d4/b717a4874175146029ca1517e85474b1af80c9d9a306fc3161e71485eea5/fonttools-4.62.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8f086120e8be9e99ca1288aa5ce519833f93fe0ec6ebad2380c1dee18781f0b5", size = 5122503, upload-time = "2026-03-09T16:49:02.464Z" }, - { url = "https://files.pythonhosted.org/packages/cb/4b/92cfcba4bf8373f51c49c5ae4b512ead6fbda7d61a0e8c35a369d0db40a0/fonttools-4.62.0-cp312-cp312-win32.whl", hash = "sha256:37a73e5e38fd05c637daede6ffed5f3496096be7df6e4a3198d32af038f87527", size = 2281060, upload-time = "2026-03-09T16:49:04.385Z" }, - { url = "https://files.pythonhosted.org/packages/cd/06/cc96468781a4dc8ae2f14f16f32b32f69bde18cb9384aad27ccc7adf76f7/fonttools-4.62.0-cp312-cp312-win_amd64.whl", hash = "sha256:658ab837c878c4d2a652fcbb319547ea41693890e6434cf619e66f79387af3b8", size = 2331193, upload-time = "2026-03-09T16:49:06.598Z" }, - { url = "https://files.pythonhosted.org/packages/82/c7/985c1670aa6d82ef270f04cde11394c168f2002700353bd2bde405e59b8f/fonttools-4.62.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:274c8b8a87e439faf565d3bcd3f9f9e31bca7740755776a4a90a4bfeaa722efa", size = 2864929, upload-time = "2026-03-09T16:49:09.331Z" }, - { url = "https://files.pythonhosted.org/packages/c1/dc/c409c8ceec0d3119e9ab0b7b1a2e3c76d1f4d66e4a9db5c59e6b7652e7df/fonttools-4.62.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:93e27131a5a0ae82aaadcffe309b1bae195f6711689722af026862bede05c07c", size = 2412586, upload-time = "2026-03-09T16:49:11.378Z" }, - { url = "https://files.pythonhosted.org/packages/5f/ac/8e300dbf7b4d135287c261ffd92ede02d9f48f0d2db14665fbc8b059588a/fonttools-4.62.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:83c6524c5b93bad9c2939d88e619fedc62e913c19e673f25d5ab74e7a5d074e5", size = 5013708, upload-time = "2026-03-09T16:49:14.063Z" }, - { url = "https://files.pythonhosted.org/packages/fb/bc/60d93477b653eeb1ddf5f9ec34be689b79234d82dbdded269ac0252715b8/fonttools-4.62.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:106aec9226f9498fc5345125ff7200842c01eda273ae038f5049b0916907acee", size = 4964355, upload-time = "2026-03-09T16:49:16.515Z" }, - { url = "https://files.pythonhosted.org/packages/cb/eb/6dc62bcc3c3598c28a3ecb77e69018869c3e109bd83031d4973c059d318b/fonttools-4.62.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:15d86b96c79013320f13bc1b15f94789edb376c0a2d22fb6088f33637e8dfcbc", size = 4953472, upload-time = "2026-03-09T16:49:18.494Z" }, - { url = "https://files.pythonhosted.org/packages/82/b3/3af7592d9b254b7b7fec018135f8776bfa0d1ad335476c2791b1334dc5e4/fonttools-4.62.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4f16c07e5250d5d71d0f990a59460bc5620c3cc456121f2cfb5b60475699905f", size = 5094701, upload-time = "2026-03-09T16:49:21.67Z" }, - { url = "https://files.pythonhosted.org/packages/31/3d/976645583ab567d3ee75ff87b33aa1330fa2baeeeae5fc46210b4274dd45/fonttools-4.62.0-cp313-cp313-win32.whl", hash = "sha256:d31558890f3fa00d4f937d12708f90c7c142c803c23eaeb395a71f987a77ebe3", size = 2279710, upload-time = "2026-03-09T16:49:23.812Z" }, - { url = "https://files.pythonhosted.org/packages/f5/7a/e25245a30457595740041dba9d0ea8ec1b2517f2f1a6a741f15eba1a4edc/fonttools-4.62.0-cp313-cp313-win_amd64.whl", hash = "sha256:6826a5aa53fb6def8a66bf423939745f415546c4e92478a7c531b8b6282b6c3b", size = 2330291, upload-time = "2026-03-09T16:49:26.237Z" }, - { url = "https://files.pythonhosted.org/packages/1a/64/61f69298aa6e7c363dcf00dd6371a654676900abe27d1effd1a74b43e5d0/fonttools-4.62.0-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:4fa5a9c716e2f75ef34b5a5c2ca0ee4848d795daa7e6792bf30fd4abf8993449", size = 2864222, upload-time = "2026-03-09T16:49:28.285Z" }, - { url = "https://files.pythonhosted.org/packages/c6/57/6b08756fe4455336b1fe160ab3c11fccc90768ccb6ee03fb0b45851aace4/fonttools-4.62.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:625f5cbeb0b8f4e42343eaeb4bc2786718ddd84760a2f5e55fdd3db049047c00", size = 2410674, upload-time = "2026-03-09T16:49:30.504Z" }, - { url = "https://files.pythonhosted.org/packages/6f/86/db65b63bb1b824b63e602e9be21b18741ddc99bcf5a7850f9181159ae107/fonttools-4.62.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6247e58b96b982709cd569a91a2ba935d406dccf17b6aa615afaed37ac3856aa", size = 4999387, upload-time = "2026-03-09T16:49:32.593Z" }, - { url = "https://files.pythonhosted.org/packages/86/c8/c6669e42d2f4efd60d38a3252cebbb28851f968890efb2b9b15f9d1092b0/fonttools-4.62.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:840632ea9c1eab7b7f01c369e408c0721c287dfd7500ab937398430689852fd1", size = 4912506, upload-time = "2026-03-09T16:49:34.927Z" }, - { url = "https://files.pythonhosted.org/packages/2e/49/0ae552aa098edd0ec548413fbf818f52ceb70535016215094a5ce9bf8f70/fonttools-4.62.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:28a9ea2a7467a816d1bec22658b0cce4443ac60abac3e293bdee78beb74588f3", size = 4951202, upload-time = "2026-03-09T16:49:37.1Z" }, - { url = "https://files.pythonhosted.org/packages/71/65/ae38fc8a4cea6f162d74cf11f58e9aeef1baa7d0e3d1376dabd336c129e5/fonttools-4.62.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5ae611294f768d413949fd12693a8cba0e6332fbc1e07aba60121be35eac68d0", size = 5060758, upload-time = "2026-03-09T16:49:39.464Z" }, - { url = "https://files.pythonhosted.org/packages/db/3d/bb797496f35c60544cd5af71ffa5aad62df14ef7286908d204cb5c5096fe/fonttools-4.62.0-cp314-cp314-win32.whl", hash = "sha256:273acb61f316d07570a80ed5ff0a14a23700eedbec0ad968b949abaa4d3f6bb5", size = 2283496, upload-time = "2026-03-09T16:49:42.448Z" }, - { url = "https://files.pythonhosted.org/packages/2e/9f/91081ffe5881253177c175749cce5841f5ec6e931f5d52f4a817207b7429/fonttools-4.62.0-cp314-cp314-win_amd64.whl", hash = "sha256:a5f974006d14f735c6c878fc4b117ad031dc93638ddcc450ca69f8fd64d5e104", size = 2335426, upload-time = "2026-03-09T16:49:44.228Z" }, - { url = "https://files.pythonhosted.org/packages/f8/65/f47f9b3db1ec156a1f222f1089ba076b2cc9ee1d024a8b0a60c54258517e/fonttools-4.62.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:0361a7d41d86937f1f752717c19f719d0fde064d3011038f9f19bdf5fc2f5c95", size = 2947079, upload-time = "2026-03-09T16:49:46.471Z" }, - { url = "https://files.pythonhosted.org/packages/52/73/bc62e5058a0c22cf02b1e0169ef0c3ca6c3247216d719f95bead3c05a991/fonttools-4.62.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:d4108c12773b3c97aa592311557c405d5b4fc03db2b969ed928fcf68e7b3c887", size = 2448802, upload-time = "2026-03-09T16:49:48.328Z" }, - { url = "https://files.pythonhosted.org/packages/2b/df/bfaa0e845884935355670e6e68f137185ab87295f8bc838db575e4a66064/fonttools-4.62.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b448075f32708e8fb377fe7687f769a5f51a027172c591ba9a58693631b077a8", size = 5137378, upload-time = "2026-03-09T16:49:50.223Z" }, - { url = "https://files.pythonhosted.org/packages/32/32/04f616979a18b48b52e634988b93d847b6346260faf85ecccaf7e2e9057f/fonttools-4.62.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e5f1fa8cc9f1a56a3e33ee6b954d6d9235e6b9d11eb7a6c9dfe2c2f829dc24db", size = 4920714, upload-time = "2026-03-09T16:49:53.172Z" }, - { url = "https://files.pythonhosted.org/packages/3b/2e/274e16689c1dfee5c68302cd7c444213cfddd23cf4620374419625037ec6/fonttools-4.62.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:f8c8ea812f82db1e884b9cdb663080453e28f0f9a1f5027a5adb59c4cc8d38d1", size = 5016012, upload-time = "2026-03-09T16:49:55.762Z" }, - { url = "https://files.pythonhosted.org/packages/7f/0c/b08117270626e7117ac2f89d732fdd4386ec37d2ab3a944462d29e6f89a1/fonttools-4.62.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:03c6068adfdc67c565d217e92386b1cdd951abd4240d65180cec62fa74ba31b2", size = 5042766, upload-time = "2026-03-09T16:49:57.726Z" }, - { url = "https://files.pythonhosted.org/packages/11/83/a48b73e54efa272ee65315a6331b30a9b3a98733310bc11402606809c50e/fonttools-4.62.0-cp314-cp314t-win32.whl", hash = "sha256:d28d5baacb0017d384df14722a63abe6e0230d8ce642b1615a27d78ffe3bc983", size = 2347785, upload-time = "2026-03-09T16:49:59.698Z" }, - { url = "https://files.pythonhosted.org/packages/f8/27/c67eab6dc3525bdc39586511b1b3d7161e972dacc0f17476dbaf932e708b/fonttools-4.62.0-cp314-cp314t-win_amd64.whl", hash = "sha256:3f9e20c4618f1e04190c802acae6dc337cb6db9fa61e492fd97cd5c5a9ff6d07", size = 2413914, upload-time = "2026-03-09T16:50:02.251Z" }, - { url = "https://files.pythonhosted.org/packages/9c/57/c2487c281dde03abb2dec244fd67059b8d118bd30a653cbf69e94084cb23/fonttools-4.62.0-py3-none-any.whl", hash = "sha256:75064f19a10c50c74b336aa5ebe7b1f89fd0fb5255807bfd4b0c6317098f4af3", size = 1152427, upload-time = "2026-03-09T16:50:04.074Z" }, +version = "4.62.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9a/08/7012b00a9a5874311b639c3920270c36ee0c445b69d9989a85e5c92ebcb0/fonttools-4.62.1.tar.gz", hash = "sha256:e54c75fd6041f1122476776880f7c3c3295ffa31962dc6ebe2543c00dca58b5d", size = 3580737, upload-time = "2026-03-13T13:54:25.52Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5a/ff/532ed43808b469c807e8cb6b21358da3fe6fd51486b3a8c93db0bb5d957f/fonttools-4.62.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ad5cca75776cd453b1b035b530e943334957ae152a36a88a320e779d61fc980c", size = 2873740, upload-time = "2026-03-13T13:52:11.822Z" }, + { url = "https://files.pythonhosted.org/packages/85/e4/2318d2b430562da7227010fb2bb029d2fa54d7b46443ae8942bab224e2a0/fonttools-4.62.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0b3ae47e8636156a9accff64c02c0924cbebad62854c4a6dbdc110cd5b4b341a", size = 2417649, upload-time = "2026-03-13T13:52:14.605Z" }, + { url = "https://files.pythonhosted.org/packages/4c/28/40f15523b5188598018e7956899fed94eb7debec89e2dd70cb4a8df90492/fonttools-4.62.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c9b9e288b4da2f64fd6180644221749de651703e8d0c16bd4b719533a3a7d6e3", size = 4935213, upload-time = "2026-03-13T13:52:17.399Z" }, + { url = "https://files.pythonhosted.org/packages/42/09/7dbe3d7023f57d9b580cfa832109d521988112fd59dddfda3fddda8218f9/fonttools-4.62.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7bca7a1c1faf235ffe25d4f2e555246b4750220b38de8261d94ebc5ce8a23c23", size = 4892374, upload-time = "2026-03-13T13:52:20.175Z" }, + { url = "https://files.pythonhosted.org/packages/d1/2d/84509a2e32cb925371560ef5431365d8da2183c11d98e5b4b8b4e42426a5/fonttools-4.62.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b4e0fcf265ad26e487c56cb12a42dffe7162de708762db951e1b3f755319507d", size = 4911856, upload-time = "2026-03-13T13:52:22.777Z" }, + { url = "https://files.pythonhosted.org/packages/a5/80/df28131379eed93d9e6e6fccd3bf6e3d077bebbfe98cc83f21bbcd83ed02/fonttools-4.62.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:2d850f66830a27b0d498ee05adb13a3781637b1826982cd7e2b3789ef0cc71ae", size = 5031712, upload-time = "2026-03-13T13:52:25.14Z" }, + { url = "https://files.pythonhosted.org/packages/3d/03/3c8f09aad64230cd6d921ae7a19f9603c36f70930b00459f112706f6769a/fonttools-4.62.1-cp310-cp310-win32.whl", hash = "sha256:486f32c8047ccd05652aba17e4a8819a3a9d78570eb8a0e3b4503142947880ed", size = 1507878, upload-time = "2026-03-13T13:52:28.149Z" }, + { url = "https://files.pythonhosted.org/packages/dd/ec/f53f626f8f3e89f4cadd8fc08f3452c8fd182c951ad5caa35efac22b29ab/fonttools-4.62.1-cp310-cp310-win_amd64.whl", hash = "sha256:5a648bde915fba9da05ae98856987ca91ba832949a9e2888b48c47ef8b96c5a9", size = 1556766, upload-time = "2026-03-13T13:52:30.814Z" }, + { url = "https://files.pythonhosted.org/packages/88/39/23ff32561ec8d45a4d48578b4d241369d9270dc50926c017570e60893701/fonttools-4.62.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:40975849bac44fb0b9253d77420c6d8b523ac4dcdcefeff6e4d706838a5b80f7", size = 2871039, upload-time = "2026-03-13T13:52:33.127Z" }, + { url = "https://files.pythonhosted.org/packages/24/7f/66d3f8a9338a9b67fe6e1739f47e1cd5cee78bd3bc1206ef9b0b982289a5/fonttools-4.62.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9dde91633f77fa576879a0c76b1d89de373cae751a98ddf0109d54e173b40f14", size = 2416346, upload-time = "2026-03-13T13:52:35.676Z" }, + { url = "https://files.pythonhosted.org/packages/aa/53/5276ceba7bff95da7793a07c5284e1da901cf00341ce5e2f3273056c0cca/fonttools-4.62.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6acb4109f8bee00fec985c8c7afb02299e35e9c94b57287f3ea542f28bd0b0a7", size = 5100897, upload-time = "2026-03-13T13:52:38.102Z" }, + { url = "https://files.pythonhosted.org/packages/cc/a1/40a5c4d8e28b0851d53a8eeeb46fbd73c325a2a9a165f290a5ed90e6c597/fonttools-4.62.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1c5c25671ce8805e0d080e2ffdeca7f1e86778c5cbfbeae86d7f866d8830517b", size = 5071078, upload-time = "2026-03-13T13:52:41.305Z" }, + { url = "https://files.pythonhosted.org/packages/e3/be/d378fca4c65ea1956fee6d90ace6e861776809cbbc5af22388a090c3c092/fonttools-4.62.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:a5d8825e1140f04e6c99bb7d37a9e31c172f3bc208afbe02175339e699c710e1", size = 5076908, upload-time = "2026-03-13T13:52:44.122Z" }, + { url = "https://files.pythonhosted.org/packages/f8/d9/ae6a1d0693a4185a84605679c8a1f719a55df87b9c6e8e817bfdd9ef5936/fonttools-4.62.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:268abb1cb221e66c014acc234e872b7870d8b5d4657a83a8f4205094c32d2416", size = 5202275, upload-time = "2026-03-13T13:52:46.591Z" }, + { url = "https://files.pythonhosted.org/packages/54/6c/af95d9c4efb15cabff22642b608342f2bd67137eea6107202d91b5b03184/fonttools-4.62.1-cp311-cp311-win32.whl", hash = "sha256:942b03094d7edbb99bdf1ae7e9090898cad7bf9030b3d21f33d7072dbcb51a53", size = 2293075, upload-time = "2026-03-13T13:52:48.711Z" }, + { url = "https://files.pythonhosted.org/packages/d3/97/bf54c5b3f2be34e1f143e6db838dfdc54f2ffa3e68c738934c82f3b2a08d/fonttools-4.62.1-cp311-cp311-win_amd64.whl", hash = "sha256:e8514f4924375f77084e81467e63238b095abda5107620f49421c368a6017ed2", size = 2344593, upload-time = "2026-03-13T13:52:50.725Z" }, + { url = "https://files.pythonhosted.org/packages/47/d4/dbacced3953544b9a93088cc10ef2b596d348c983d5c67a404fa41ec51ba/fonttools-4.62.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:90365821debbd7db678809c7491ca4acd1e0779b9624cdc6ddaf1f31992bf974", size = 2870219, upload-time = "2026-03-13T13:52:53.664Z" }, + { url = "https://files.pythonhosted.org/packages/66/9e/a769c8e99b81e5a87ab7e5e7236684de4e96246aae17274e5347d11ebd78/fonttools-4.62.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:12859ff0b47dd20f110804c3e0d0970f7b832f561630cd879969011541a464a9", size = 2414891, upload-time = "2026-03-13T13:52:56.493Z" }, + { url = "https://files.pythonhosted.org/packages/69/64/f19a9e3911968c37e1e620e14dfc5778299e1474f72f4e57c5ec771d9489/fonttools-4.62.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9c125ffa00c3d9003cdaaf7f2c79e6e535628093e14b5de1dccb08859b680936", size = 5033197, upload-time = "2026-03-13T13:52:59.179Z" }, + { url = "https://files.pythonhosted.org/packages/9b/8a/99c8b3c3888c5c474c08dbfd7c8899786de9604b727fcefb055b42c84bba/fonttools-4.62.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:149f7d84afca659d1a97e39a4778794a2f83bf344c5ee5134e09995086cc2392", size = 4988768, upload-time = "2026-03-13T13:53:02.761Z" }, + { url = "https://files.pythonhosted.org/packages/d1/c6/0f904540d3e6ab463c1243a0d803504826a11604c72dd58c2949796a1762/fonttools-4.62.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0aa72c43a601cfa9273bb1ae0518f1acadc01ee181a6fc60cd758d7fdadffc04", size = 4971512, upload-time = "2026-03-13T13:53:05.678Z" }, + { url = "https://files.pythonhosted.org/packages/29/0b/5cbef6588dc9bd6b5c9ad6a4d5a8ca384d0cea089da31711bbeb4f9654a6/fonttools-4.62.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:19177c8d96c7c36359266e571c5173bcee9157b59cfc8cb0153c5673dc5a3a7d", size = 5122723, upload-time = "2026-03-13T13:53:08.662Z" }, + { url = "https://files.pythonhosted.org/packages/4a/47/b3a5342d381595ef439adec67848bed561ab7fdb1019fa522e82101b7d9c/fonttools-4.62.1-cp312-cp312-win32.whl", hash = "sha256:a24decd24d60744ee8b4679d38e88b8303d86772053afc29b19d23bb8207803c", size = 2281278, upload-time = "2026-03-13T13:53:10.998Z" }, + { url = "https://files.pythonhosted.org/packages/28/b1/0c2ab56a16f409c6c8a68816e6af707827ad5d629634691ff60a52879792/fonttools-4.62.1-cp312-cp312-win_amd64.whl", hash = "sha256:9e7863e10b3de72376280b515d35b14f5eeed639d1aa7824f4cf06779ec65e42", size = 2331414, upload-time = "2026-03-13T13:53:13.992Z" }, + { url = "https://files.pythonhosted.org/packages/3b/56/6f389de21c49555553d6a5aeed5ac9767631497ac836c4f076273d15bd72/fonttools-4.62.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:c22b1014017111c401469e3acc5433e6acf6ebcc6aa9efb538a533c800971c79", size = 2865155, upload-time = "2026-03-13T13:53:16.132Z" }, + { url = "https://files.pythonhosted.org/packages/03/c5/0e3966edd5ec668d41dfe418787726752bc07e2f5fd8c8f208615e61fa89/fonttools-4.62.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:68959f5fc58ed4599b44aad161c2837477d7f35f5f79402d97439974faebfebe", size = 2412802, upload-time = "2026-03-13T13:53:18.878Z" }, + { url = "https://files.pythonhosted.org/packages/52/94/e6ac4b44026de7786fe46e3bfa0c87e51d5d70a841054065d49cd62bb909/fonttools-4.62.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ef46db46c9447103b8f3ff91e8ba009d5fe181b1920a83757a5762551e32bb68", size = 5013926, upload-time = "2026-03-13T13:53:21.379Z" }, + { url = "https://files.pythonhosted.org/packages/e2/98/8b1e801939839d405f1f122e7d175cebe9aeb4e114f95bfc45e3152af9a7/fonttools-4.62.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6706d1cb1d5e6251a97ad3c1b9347505c5615c112e66047abbef0f8545fa30d1", size = 4964575, upload-time = "2026-03-13T13:53:23.857Z" }, + { url = "https://files.pythonhosted.org/packages/46/76/7d051671e938b1881670528fec69cc4044315edd71a229c7fd712eaa5119/fonttools-4.62.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:2e7abd2b1e11736f58c1de27819e1955a53267c21732e78243fa2fa2e5c1e069", size = 4953693, upload-time = "2026-03-13T13:53:26.569Z" }, + { url = "https://files.pythonhosted.org/packages/1f/ae/b41f8628ec0be3c1b934fc12b84f4576a5c646119db4d3bdd76a217c90b5/fonttools-4.62.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:403d28ce06ebfc547fbcb0cb8b7f7cc2f7a2d3e1a67ba9a34b14632df9e080f9", size = 5094920, upload-time = "2026-03-13T13:53:29.329Z" }, + { url = "https://files.pythonhosted.org/packages/f2/f6/53a1e9469331a23dcc400970a27a4caa3d9f6edbf5baab0260285238b884/fonttools-4.62.1-cp313-cp313-win32.whl", hash = "sha256:93c316e0f5301b2adbe6a5f658634307c096fd5aae60a5b3412e4f3e1728ab24", size = 2279928, upload-time = "2026-03-13T13:53:32.352Z" }, + { url = "https://files.pythonhosted.org/packages/38/60/35186529de1db3c01f5ad625bde07c1f576305eab6d86bbda4c58445f721/fonttools-4.62.1-cp313-cp313-win_amd64.whl", hash = "sha256:7aa21ff53e28a9c2157acbc44e5b401149d3c9178107130e82d74ceb500e5056", size = 2330514, upload-time = "2026-03-13T13:53:34.991Z" }, + { url = "https://files.pythonhosted.org/packages/36/f0/2888cdac391807d68d90dcb16ef858ddc1b5309bfc6966195a459dd326e2/fonttools-4.62.1-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:fa1d16210b6b10a826d71bed68dd9ec24a9e218d5a5e2797f37c573e7ec215ca", size = 2864442, upload-time = "2026-03-13T13:53:37.509Z" }, + { url = "https://files.pythonhosted.org/packages/4b/b2/e521803081f8dc35990816b82da6360fa668a21b44da4b53fc9e77efcd62/fonttools-4.62.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:aa69d10ed420d8121118e628ad47d86e4caa79ba37f968597b958f6cceab7eca", size = 2410901, upload-time = "2026-03-13T13:53:40.55Z" }, + { url = "https://files.pythonhosted.org/packages/00/a4/8c3511ff06e53110039358dbbdc1a65d72157a054638387aa2ada300a8b8/fonttools-4.62.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bd13b7999d59c5eb1c2b442eb2d0c427cb517a0b7a1f5798fc5c9e003f5ff782", size = 4999608, upload-time = "2026-03-13T13:53:42.798Z" }, + { url = "https://files.pythonhosted.org/packages/28/63/cd0c3b26afe60995a5295f37c246a93d454023726c3261cfbb3559969bb9/fonttools-4.62.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8d337fdd49a79b0d51c4da87bc38169d21c3abbf0c1aa9367eff5c6656fb6dae", size = 4912726, upload-time = "2026-03-13T13:53:45.405Z" }, + { url = "https://files.pythonhosted.org/packages/70/b9/ac677cb07c24c685cf34f64e140617d58789d67a3dd524164b63648c6114/fonttools-4.62.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:d241cdc4a67b5431c6d7f115fdf63335222414995e3a1df1a41e1182acd4bcc7", size = 4951422, upload-time = "2026-03-13T13:53:48.326Z" }, + { url = "https://files.pythonhosted.org/packages/e6/10/11c08419a14b85b7ca9a9faca321accccc8842dd9e0b1c8a72908de05945/fonttools-4.62.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:c05557a78f8fa514da0f869556eeda40887a8abc77c76ee3f74cf241778afd5a", size = 5060979, upload-time = "2026-03-13T13:53:51.366Z" }, + { url = "https://files.pythonhosted.org/packages/4e/3c/12eea4a4cf054e7ab058ed5ceada43b46809fce2bf319017c4d63ae55bb4/fonttools-4.62.1-cp314-cp314-win32.whl", hash = "sha256:49a445d2f544ce4a69338694cad575ba97b9a75fff02720da0882d1a73f12800", size = 2283733, upload-time = "2026-03-13T13:53:53.606Z" }, + { url = "https://files.pythonhosted.org/packages/6b/67/74b070029043186b5dd13462c958cb7c7f811be0d2e634309d9a1ffb1505/fonttools-4.62.1-cp314-cp314-win_amd64.whl", hash = "sha256:1eecc128c86c552fb963fe846ca4e011b1be053728f798185a1687502f6d398e", size = 2335663, upload-time = "2026-03-13T13:53:56.23Z" }, + { url = "https://files.pythonhosted.org/packages/42/c5/4d2ed3ca6e33617fc5624467da353337f06e7f637707478903c785bd8e20/fonttools-4.62.1-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:1596aeaddf7f78e21e68293c011316a25267b3effdaccaf4d59bc9159d681b82", size = 2947288, upload-time = "2026-03-13T13:53:59.397Z" }, + { url = "https://files.pythonhosted.org/packages/1f/e9/7ab11ddfda48ed0f89b13380e5595ba572619c27077be0b2c447a63ff351/fonttools-4.62.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:8f8fca95d3bb3208f59626a4b0ea6e526ee51f5a8ad5d91821c165903e8d9260", size = 2449023, upload-time = "2026-03-13T13:54:01.642Z" }, + { url = "https://files.pythonhosted.org/packages/b2/10/a800fa090b5e8819942e54e19b55fc7c21fe14a08757c3aa3ca8db358939/fonttools-4.62.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee91628c08e76f77b533d65feb3fbe6d9dad699f95be51cf0d022db94089cdc4", size = 5137599, upload-time = "2026-03-13T13:54:04.495Z" }, + { url = "https://files.pythonhosted.org/packages/37/dc/8ccd45033fffd74deb6912fa1ca524643f584b94c87a16036855b498a1ed/fonttools-4.62.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5f37df1cac61d906e7b836abe356bc2f34c99d4477467755c216b72aa3dc748b", size = 4920933, upload-time = "2026-03-13T13:54:07.557Z" }, + { url = "https://files.pythonhosted.org/packages/99/eb/e618adefb839598d25ac8136cd577925d6c513dc0d931d93b8af956210f0/fonttools-4.62.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:92bb00a947e666169c99b43753c4305fc95a890a60ef3aeb2a6963e07902cc87", size = 5016232, upload-time = "2026-03-13T13:54:10.611Z" }, + { url = "https://files.pythonhosted.org/packages/d9/5f/9b5c9bfaa8ec82def8d8168c4f13615990d6ce5996fe52bd49bfb5e05134/fonttools-4.62.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:bdfe592802ef939a0e33106ea4a318eeb17822c7ee168c290273cbd5fabd746c", size = 5042987, upload-time = "2026-03-13T13:54:13.569Z" }, + { url = "https://files.pythonhosted.org/packages/90/aa/dfbbe24c6a6afc5c203d90cc0343e24bcbb09e76d67c4d6eef8c2558d7ba/fonttools-4.62.1-cp314-cp314t-win32.whl", hash = "sha256:b820fcb92d4655513d8402d5b219f94481c4443d825b4372c75a2072aa4b357a", size = 2348021, upload-time = "2026-03-13T13:54:16.98Z" }, + { url = "https://files.pythonhosted.org/packages/13/6f/ae9c4e4dd417948407b680855c2c7790efb52add6009aaecff1e3bc50e8e/fonttools-4.62.1-cp314-cp314t-win_amd64.whl", hash = "sha256:59b372b4f0e113d3746b88985f1c796e7bf830dd54b28374cd85c2b8acd7583e", size = 2414147, upload-time = "2026-03-13T13:54:19.416Z" }, + { url = "https://files.pythonhosted.org/packages/fd/ba/56147c165442cc5ba7e82ecf301c9a68353cede498185869e6e02b4c264f/fonttools-4.62.1-py3-none-any.whl", hash = "sha256:7487782e2113861f4ddcc07c3436450659e3caa5e470b27dc2177cade2d8e7fd", size = 1152647, upload-time = "2026-03-13T13:54:22.735Z" }, ] [[package]] @@ -1336,16 +1336,15 @@ wheels = [ [[package]] name = "google-auth" -version = "2.49.0" +version = "2.49.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cryptography" }, { name = "pyasn1-modules" }, - { name = "rsa" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/7d/59/7371175bfd949abfb1170aa076352131d7281bd9449c0f978604fc4431c3/google_auth-2.49.0.tar.gz", hash = "sha256:9cc2d9259d3700d7a257681f81052db6737495a1a46b610597f4b8bafe5286ae", size = 333444, upload-time = "2026-03-06T21:53:06.07Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ea/80/6a696a07d3d3b0a92488933532f03dbefa4a24ab80fb231395b9a2a1be77/google_auth-2.49.1.tar.gz", hash = "sha256:16d40da1c3c5a0533f57d268fe72e0ebb0ae1cc3b567024122651c045d879b64", size = 333825, upload-time = "2026-03-12T19:30:58.135Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/37/45/de64b823b639103de4b63dd193480dce99526bd36be6530c2dba85bf7817/google_auth-2.49.0-py3-none-any.whl", hash = "sha256:f893ef7307f19cf53700b7e2f61b5a6affe3aa0edf9943b13788920ab92d8d87", size = 240676, upload-time = "2026-03-06T21:52:38.304Z" }, + { url = "https://files.pythonhosted.org/packages/e9/eb/c6c2478d8a8d633460be40e2a8a6f8f429171997a35a96f81d3b680dec83/google_auth-2.49.1-py3-none-any.whl", hash = "sha256:195ebe3dca18eddd1b3db5edc5189b76c13e96f29e73043b923ebcf3f1a860f7", size = 240737, upload-time = "2026-03-12T19:30:53.159Z" }, ] [[package]] @@ -1378,6 +1377,7 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/38/3f/9859f655d11901e7b2996c6e3d33e0caa9a1d4572c3bc61ed0faa64b2f4c/greenlet-3.3.2-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:9bc885b89709d901859cf95179ec9f6bb67a3d2bb1f0e88456461bd4b7f8fd0d", size = 277747, upload-time = "2026-02-20T20:16:21.325Z" }, { url = "https://files.pythonhosted.org/packages/fb/07/cb284a8b5c6498dbd7cba35d31380bb123d7dceaa7907f606c8ff5993cbf/greenlet-3.3.2-cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b568183cf65b94919be4438dc28416b234b678c608cafac8874dfeeb2a9bbe13", size = 579202, upload-time = "2026-02-20T20:47:28.955Z" }, { url = "https://files.pythonhosted.org/packages/ed/45/67922992b3a152f726163b19f890a85129a992f39607a2a53155de3448b8/greenlet-3.3.2-cp310-cp310-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:527fec58dc9f90efd594b9b700662ed3fb2493c2122067ac9c740d98080a620e", size = 590620, upload-time = "2026-02-20T20:55:55.581Z" }, + { url = "https://files.pythonhosted.org/packages/03/5f/6e2a7d80c353587751ef3d44bb947f0565ec008a2e0927821c007e96d3a7/greenlet-3.3.2-cp310-cp310-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:508c7f01f1791fbc8e011bd508f6794cb95397fdb198a46cb6635eb5b78d85a7", size = 602132, upload-time = "2026-02-20T21:02:43.261Z" }, { url = "https://files.pythonhosted.org/packages/ad/55/9f1ebb5a825215fadcc0f7d5073f6e79e3007e3282b14b22d6aba7ca6cb8/greenlet-3.3.2-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ad0c8917dd42a819fe77e6bdfcb84e3379c0de956469301d9fd36427a1ca501f", size = 591729, upload-time = "2026-02-20T20:20:58.395Z" }, { url = "https://files.pythonhosted.org/packages/24/b4/21f5455773d37f94b866eb3cf5caed88d6cea6dd2c6e1f9c34f463cba3ec/greenlet-3.3.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:97245cc10e5515dbc8c3104b2928f7f02b6813002770cfaffaf9a6e0fc2b94ef", size = 1551946, upload-time = "2026-02-20T20:49:31.102Z" }, { url = "https://files.pythonhosted.org/packages/00/68/91f061a926abead128fe1a87f0b453ccf07368666bd59ffa46016627a930/greenlet-3.3.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8c1fdd7d1b309ff0da81d60a9688a8bd044ac4e18b250320a96fc68d31c209ca", size = 1618494, upload-time = "2026-02-20T20:21:06.541Z" }, @@ -1385,6 +1385,7 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f3/47/16400cb42d18d7a6bb46f0626852c1718612e35dcb0dffa16bbaffdf5dd2/greenlet-3.3.2-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:c56692189a7d1c7606cb794be0a8381470d95c57ce5be03fb3d0ef57c7853b86", size = 278890, upload-time = "2026-02-20T20:19:39.263Z" }, { url = "https://files.pythonhosted.org/packages/a3/90/42762b77a5b6aa96cd8c0e80612663d39211e8ae8a6cd47c7f1249a66262/greenlet-3.3.2-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1ebd458fa8285960f382841da585e02201b53a5ec2bac6b156fc623b5ce4499f", size = 581120, upload-time = "2026-02-20T20:47:30.161Z" }, { url = "https://files.pythonhosted.org/packages/bf/6f/f3d64f4fa0a9c7b5c5b3c810ff1df614540d5aa7d519261b53fba55d4df9/greenlet-3.3.2-cp311-cp311-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a443358b33c4ec7b05b79a7c8b466f5d275025e750298be7340f8fc63dff2a55", size = 594363, upload-time = "2026-02-20T20:55:56.965Z" }, + { url = "https://files.pythonhosted.org/packages/9c/8b/1430a04657735a3f23116c2e0d5eb10220928846e4537a938a41b350bed6/greenlet-3.3.2-cp311-cp311-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4375a58e49522698d3e70cc0b801c19433021b5c37686f7ce9c65b0d5c8677d2", size = 605046, upload-time = "2026-02-20T21:02:45.234Z" }, { url = "https://files.pythonhosted.org/packages/72/83/3e06a52aca8128bdd4dcd67e932b809e76a96ab8c232a8b025b2850264c5/greenlet-3.3.2-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8e2cd90d413acbf5e77ae41e5d3c9b3ac1d011a756d7284d7f3f2b806bbd6358", size = 594156, upload-time = "2026-02-20T20:20:59.955Z" }, { url = "https://files.pythonhosted.org/packages/70/79/0de5e62b873e08fe3cef7dbe84e5c4bc0e8ed0c7ff131bccb8405cd107c8/greenlet-3.3.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:442b6057453c8cb29b4fb36a2ac689382fc71112273726e2423f7f17dc73bf99", size = 1554649, upload-time = "2026-02-20T20:49:32.293Z" }, { url = "https://files.pythonhosted.org/packages/5a/00/32d30dee8389dc36d42170a9c66217757289e2afb0de59a3565260f38373/greenlet-3.3.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:45abe8eb6339518180d5a7fa47fa01945414d7cca5ecb745346fc6a87d2750be", size = 1619472, upload-time = "2026-02-20T20:21:07.966Z" }, @@ -1393,6 +1394,7 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ea/ab/1608e5a7578e62113506740b88066bf09888322a311cff602105e619bd87/greenlet-3.3.2-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:ac8d61d4343b799d1e526db579833d72f23759c71e07181c2d2944e429eb09cd", size = 280358, upload-time = "2026-02-20T20:17:43.971Z" }, { url = "https://files.pythonhosted.org/packages/a5/23/0eae412a4ade4e6623ff7626e38998cb9b11e9ff1ebacaa021e4e108ec15/greenlet-3.3.2-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3ceec72030dae6ac0c8ed7591b96b70410a8be370b6a477b1dbc072856ad02bd", size = 601217, upload-time = "2026-02-20T20:47:31.462Z" }, { url = "https://files.pythonhosted.org/packages/f8/16/5b1678a9c07098ecb9ab2dd159fafaf12e963293e61ee8d10ecb55273e5e/greenlet-3.3.2-cp312-cp312-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a2a5be83a45ce6188c045bcc44b0ee037d6a518978de9a5d97438548b953a1ac", size = 611792, upload-time = "2026-02-20T20:55:58.423Z" }, + { url = "https://files.pythonhosted.org/packages/5c/c5/cc09412a29e43406eba18d61c70baa936e299bc27e074e2be3806ed29098/greenlet-3.3.2-cp312-cp312-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ae9e21c84035c490506c17002f5c8ab25f980205c3e61ddb3a2a2a2e6c411fcb", size = 626250, upload-time = "2026-02-20T21:02:46.596Z" }, { url = "https://files.pythonhosted.org/packages/50/1f/5155f55bd71cabd03765a4aac9ac446be129895271f73872c36ebd4b04b6/greenlet-3.3.2-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:43e99d1749147ac21dde49b99c9abffcbc1e2d55c67501465ef0930d6e78e070", size = 613875, upload-time = "2026-02-20T20:21:01.102Z" }, { url = "https://files.pythonhosted.org/packages/fc/dd/845f249c3fcd69e32df80cdab059b4be8b766ef5830a3d0aa9d6cad55beb/greenlet-3.3.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4c956a19350e2c37f2c48b336a3afb4bff120b36076d9d7fb68cb44e05d95b79", size = 1571467, upload-time = "2026-02-20T20:49:33.495Z" }, { url = "https://files.pythonhosted.org/packages/2a/50/2649fe21fcc2b56659a452868e695634722a6655ba245d9f77f5656010bf/greenlet-3.3.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6c6f8ba97d17a1e7d664151284cb3315fc5f8353e75221ed4324f84eb162b395", size = 1640001, upload-time = "2026-02-20T20:21:09.154Z" }, @@ -1401,6 +1403,7 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ac/48/f8b875fa7dea7dd9b33245e37f065af59df6a25af2f9561efa8d822fde51/greenlet-3.3.2-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:aa6ac98bdfd716a749b84d4034486863fd81c3abde9aa3cf8eff9127981a4ae4", size = 279120, upload-time = "2026-02-20T20:19:01.9Z" }, { url = "https://files.pythonhosted.org/packages/49/8d/9771d03e7a8b1ee456511961e1b97a6d77ae1dea4a34a5b98eee706689d3/greenlet-3.3.2-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ab0c7e7901a00bc0a7284907273dc165b32e0d109a6713babd04471327ff7986", size = 603238, upload-time = "2026-02-20T20:47:32.873Z" }, { url = "https://files.pythonhosted.org/packages/59/0e/4223c2bbb63cd5c97f28ffb2a8aee71bdfb30b323c35d409450f51b91e3e/greenlet-3.3.2-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:d248d8c23c67d2291ffd47af766e2a3aa9fa1c6703155c099feb11f526c63a92", size = 614219, upload-time = "2026-02-20T20:55:59.817Z" }, + { url = "https://files.pythonhosted.org/packages/94/2b/4d012a69759ac9d77210b8bfb128bc621125f5b20fc398bce3940d036b1c/greenlet-3.3.2-cp313-cp313-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ccd21bb86944ca9be6d967cf7691e658e43417782bce90b5d2faeda0ff78a7dd", size = 628268, upload-time = "2026-02-20T21:02:48.024Z" }, { url = "https://files.pythonhosted.org/packages/7a/34/259b28ea7a2a0c904b11cd36c79b8cef8019b26ee5dbe24e73b469dea347/greenlet-3.3.2-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b6997d360a4e6a4e936c0f9625b1c20416b8a0ea18a8e19cabbefc712e7397ab", size = 616774, upload-time = "2026-02-20T20:21:02.454Z" }, { url = "https://files.pythonhosted.org/packages/0a/03/996c2d1689d486a6e199cb0f1cf9e4aa940c500e01bdf201299d7d61fa69/greenlet-3.3.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:64970c33a50551c7c50491671265d8954046cb6e8e2999aacdd60e439b70418a", size = 1571277, upload-time = "2026-02-20T20:49:34.795Z" }, { url = "https://files.pythonhosted.org/packages/d9/c4/2570fc07f34a39f2caf0bf9f24b0a1a0a47bc2e8e465b2c2424821389dfc/greenlet-3.3.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1a9172f5bf6bd88e6ba5a84e0a68afeac9dc7b6b412b245dd64f52d83c81e55b", size = 1640455, upload-time = "2026-02-20T20:21:10.261Z" }, @@ -1409,6 +1412,7 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/3f/ae/8bffcbd373b57a5992cd077cbe8858fff39110480a9d50697091faea6f39/greenlet-3.3.2-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:8d1658d7291f9859beed69a776c10822a0a799bc4bfe1bd4272bb60e62507dab", size = 279650, upload-time = "2026-02-20T20:18:00.783Z" }, { url = "https://files.pythonhosted.org/packages/d1/c0/45f93f348fa49abf32ac8439938726c480bd96b2a3c6f4d949ec0124b69f/greenlet-3.3.2-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:18cb1b7337bca281915b3c5d5ae19f4e76d35e1df80f4ad3c1a7be91fadf1082", size = 650295, upload-time = "2026-02-20T20:47:34.036Z" }, { url = "https://files.pythonhosted.org/packages/b3/de/dd7589b3f2b8372069ab3e4763ea5329940fc7ad9dcd3e272a37516d7c9b/greenlet-3.3.2-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c2e47408e8ce1c6f1ceea0dffcdf6ebb85cc09e55c7af407c99f1112016e45e9", size = 662163, upload-time = "2026-02-20T20:56:01.295Z" }, + { url = "https://files.pythonhosted.org/packages/cd/ac/85804f74f1ccea31ba518dcc8ee6f14c79f73fe36fa1beba38930806df09/greenlet-3.3.2-cp314-cp314-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e3cb43ce200f59483eb82949bf1835a99cf43d7571e900d7c8d5c62cdf25d2f9", size = 675371, upload-time = "2026-02-20T21:02:49.664Z" }, { url = "https://files.pythonhosted.org/packages/d2/d8/09bfa816572a4d83bccd6750df1926f79158b1c36c5f73786e26dbe4ee38/greenlet-3.3.2-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:63d10328839d1973e5ba35e98cccbca71b232b14051fd957b6f8b6e8e80d0506", size = 664160, upload-time = "2026-02-20T20:21:04.015Z" }, { url = "https://files.pythonhosted.org/packages/48/cf/56832f0c8255d27f6c35d41b5ec91168d74ec721d85f01a12131eec6b93c/greenlet-3.3.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:8e4ab3cfb02993c8cc248ea73d7dae6cec0253e9afa311c9b37e603ca9fad2ce", size = 1619181, upload-time = "2026-02-20T20:49:36.052Z" }, { url = "https://files.pythonhosted.org/packages/0a/23/b90b60a4aabb4cec0796e55f25ffbfb579a907c3898cd2905c8918acaa16/greenlet-3.3.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:94ad81f0fd3c0c0681a018a976e5c2bd2ca2d9d94895f23e7bb1af4e8af4e2d5", size = 1687713, upload-time = "2026-02-20T20:21:11.684Z" }, @@ -1417,6 +1421,7 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/98/6d/8f2ef704e614bcf58ed43cfb8d87afa1c285e98194ab2cfad351bf04f81e/greenlet-3.3.2-cp314-cp314t-macosx_11_0_universal2.whl", hash = "sha256:e26e72bec7ab387ac80caa7496e0f908ff954f31065b0ffc1f8ecb1338b11b54", size = 286617, upload-time = "2026-02-20T20:19:29.856Z" }, { url = "https://files.pythonhosted.org/packages/5e/0d/93894161d307c6ea237a43988f27eba0947b360b99ac5239ad3fe09f0b47/greenlet-3.3.2-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8b466dff7a4ffda6ca975979bab80bdadde979e29fc947ac3be4451428d8b0e4", size = 655189, upload-time = "2026-02-20T20:47:35.742Z" }, { url = "https://files.pythonhosted.org/packages/f5/2c/d2d506ebd8abcb57386ec4f7ba20f4030cbe56eae541bc6fd6ef399c0b41/greenlet-3.3.2-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b8bddc5b73c9720bea487b3bffdb1840fe4e3656fba3bd40aa1489e9f37877ff", size = 658225, upload-time = "2026-02-20T20:56:02.527Z" }, + { url = "https://files.pythonhosted.org/packages/d1/67/8197b7e7e602150938049d8e7f30de1660cfb87e4c8ee349b42b67bdb2e1/greenlet-3.3.2-cp314-cp314t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:59b3e2c40f6706b05a9cd299c836c6aa2378cabe25d021acd80f13abf81181cf", size = 666581, upload-time = "2026-02-20T21:02:51.526Z" }, { url = "https://files.pythonhosted.org/packages/8e/30/3a09155fbf728673a1dea713572d2d31159f824a37c22da82127056c44e4/greenlet-3.3.2-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b26b0f4428b871a751968285a1ac9648944cea09807177ac639b030bddebcea4", size = 657907, upload-time = "2026-02-20T20:21:05.259Z" }, { url = "https://files.pythonhosted.org/packages/f3/fd/d05a4b7acd0154ed758797f0a43b4c0962a843bedfe980115e842c5b2d08/greenlet-3.3.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:1fb39a11ee2e4d94be9a76671482be9398560955c9e568550de0224e41104727", size = 1618857, upload-time = "2026-02-20T20:49:37.309Z" }, { url = "https://files.pythonhosted.org/packages/6f/e1/50ee92a5db521de8f35075b5eff060dd43d39ebd46c2181a2042f7070385/greenlet-3.3.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:20154044d9085151bc309e7689d6f7ba10027f8f5a8c0676ad398b951913d89e", size = 1680010, upload-time = "2026-02-20T20:21:13.427Z" }, @@ -1502,34 +1507,34 @@ wheels = [ [[package]] name = "hf-xet" -version = "1.4.0" +version = "1.4.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/68/01/928fd82663fb0ab455551a178303a2960e65029da66b21974594f3a20a94/hf_xet-1.4.0.tar.gz", hash = "sha256:48e6ba7422b0885c9bbd8ac8fdf5c4e1306c3499b82d489944609cc4eae8ecbd", size = 660350, upload-time = "2026-03-11T18:50:03.354Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/05/4b/2351e30dddc6f3b47b3da0a0693ec1e82f8303b1a712faa299cf3552002b/hf_xet-1.4.0-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:76725fcbc5f59b23ac778f097d3029d6623e3cf6f4057d99d1fce1a7e3cff8fc", size = 3796397, upload-time = "2026-03-11T18:49:47.382Z" }, - { url = "https://files.pythonhosted.org/packages/48/3d/3db90ec0afb4e26e3330b1346b89fe0e9a3b7bfc2d6a2b2262787790d25f/hf_xet-1.4.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:76f1f73bee81a6e6f608b583908aa24c50004965358ac92c1dc01080a21bcd09", size = 3556235, upload-time = "2026-03-11T18:49:45.785Z" }, - { url = "https://files.pythonhosted.org/packages/57/6e/2a662af2cbc6c0a64ebe9fcdb8faf05b5205753d45a75a3011bb2209d0b4/hf_xet-1.4.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1818c2e5d6f15354c595d5111c6eb0e5a30a6c5c1a43eeaec20f19607cff0b34", size = 4213145, upload-time = "2026-03-11T18:49:38.009Z" }, - { url = "https://files.pythonhosted.org/packages/b9/4a/47c129affb540767e0e3e101039a95f4a73a292ec689c26e8f0c5b633f9d/hf_xet-1.4.0-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:70764d295f485db9cc9a6af76634ea00ec4f96311be7485f8f2b6144739b4ccf", size = 3991951, upload-time = "2026-03-11T18:49:36.396Z" }, - { url = "https://files.pythonhosted.org/packages/76/81/ec516cfc6281cfeef027b0919166b2fe11ab61fbe6131a2c43fafbed8b68/hf_xet-1.4.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9d3bd2a1e289f772c715ca88cdca8ceb3d8b5c9186534d5925410e531d849a3e", size = 4193205, upload-time = "2026-03-11T18:49:54.415Z" }, - { url = "https://files.pythonhosted.org/packages/49/48/0945b5e542ed6c6ce758b589b27895a449deab630dfcdee5a6ee0f699d21/hf_xet-1.4.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:06da3797f1fdd9a8f8dbc8c1bddfa0b914789b14580c375d29c32ee35c2c66ca", size = 4431022, upload-time = "2026-03-11T18:49:55.677Z" }, - { url = "https://files.pythonhosted.org/packages/e8/ad/a4859c55ab4b67a4fde2849be8bde81917f54062050419b821071f199a9c/hf_xet-1.4.0-cp313-cp313t-win_amd64.whl", hash = "sha256:30b9d8f384ccec848124d51d883e91f3c88d430589e02a7b6d867730ab8d53ac", size = 3674977, upload-time = "2026-03-11T18:50:06.369Z" }, - { url = "https://files.pythonhosted.org/packages/4b/17/5bf3791e3a53e597913c2a775a48a98aaded9c2ddb5d1afaedabb55e2ed8/hf_xet-1.4.0-cp313-cp313t-win_arm64.whl", hash = "sha256:07ffdbf7568fa3245b24d949f0f3790b5276fb7293a5554ac4ec02e5f7e2b38d", size = 3536778, upload-time = "2026-03-11T18:50:04.974Z" }, - { url = "https://files.pythonhosted.org/packages/3f/a1/05a7f9d6069bf78405d3fc2464b6c76b167128501e13b4f1d6266e1d1f54/hf_xet-1.4.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:e2731044f3a18442f9f7a3dcf03b96af13dee311f03846a1df1f0553a3ea0fc6", size = 3796727, upload-time = "2026-03-11T18:49:52.889Z" }, - { url = "https://files.pythonhosted.org/packages/ac/8a/67abc642c2b32efcb7a257cdad8555c2904e23f18a1b4fec3aef1ebfe0fc/hf_xet-1.4.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:b6f3729335fbc4baef60fe14fe32ef13ac9d377bdc898148c541e20c6056b504", size = 3555869, upload-time = "2026-03-11T18:49:51.313Z" }, - { url = "https://files.pythonhosted.org/packages/19/3d/4765367c64ee70db15fa771d5b94bf12540b85076a1d3210ebbfec42d477/hf_xet-1.4.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:9c0c9f052738a024073d332c573275c8e33697a3ef3f5dd2fb4ef98216e1e74a", size = 4212980, upload-time = "2026-03-11T18:49:44.21Z" }, - { url = "https://files.pythonhosted.org/packages/0e/bf/6ad99ee0e7ca2318f912a87318e493d82d8f9aace6be81f774bd14b996df/hf_xet-1.4.0-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:f44b2324be75bfa399735996ac299fd478684c48ce47d12a42b5f24b1a99ccb8", size = 3991136, upload-time = "2026-03-11T18:49:42.512Z" }, - { url = "https://files.pythonhosted.org/packages/50/aa/932e25c69699076088f57e3c14f83ccae87bac25e755994f3362acc908d5/hf_xet-1.4.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:01de78b1ceddf8b38da001f7cc728b3bc3eb956948b18e8a1997ad6fc80fbe9d", size = 4192676, upload-time = "2026-03-11T18:50:00.216Z" }, - { url = "https://files.pythonhosted.org/packages/5c/0a/5e41339a294fd3450948989a47ecba9824d5bc1950cf767f928ecaf53a55/hf_xet-1.4.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6cac8616e7a974105c3494735313f5ab0fb79b5accadec1a7a992859a15536a9", size = 4430729, upload-time = "2026-03-11T18:50:01.923Z" }, - { url = "https://files.pythonhosted.org/packages/9c/c1/c3d8ed9b7118e9166b0cf71dfd501da82f1abe306387e34e0f3ee59553ec/hf_xet-1.4.0-cp314-cp314t-win_amd64.whl", hash = "sha256:3a5d9cb25095ceb3beab4843ae2d1b3e5746371ddbf2e5849f7be6a7d6f44df4", size = 3674989, upload-time = "2026-03-11T18:50:12.633Z" }, - { url = "https://files.pythonhosted.org/packages/65/bc/ea26cf774063cb09d7aaaa6cba9d341fb72b42ea99b8a94ca254dbafbbb0/hf_xet-1.4.0-cp314-cp314t-win_arm64.whl", hash = "sha256:9b777674499dc037317db372c90a2dd91329b5f1ee93c645bb89155bb974f5bf", size = 3536805, upload-time = "2026-03-11T18:50:11.082Z" }, - { url = "https://files.pythonhosted.org/packages/9f/f9/a0b01945726aea81d2f213457cd5f5102a51e6fd1ca9f9769f561fb57501/hf_xet-1.4.0-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:981d2b5222c3baadf9567c135cf1d1073786f546b7745686978d46b5df179e16", size = 3799223, upload-time = "2026-03-11T18:49:49.884Z" }, - { url = "https://files.pythonhosted.org/packages/5d/30/ee62b0c00412f49a7e6f509f0104ee8808692278d247234336df48029349/hf_xet-1.4.0-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:cc8bd050349d0d7995ce7b3a3a18732a2a8062ce118a82431602088abb373428", size = 3560682, upload-time = "2026-03-11T18:49:48.633Z" }, - { url = "https://files.pythonhosted.org/packages/93/d0/0fe5c44dbced465a651a03212e1135d0d7f95d19faada692920cb56f8e38/hf_xet-1.4.0-cp37-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5d0c38d2a280d814280b8c15eead4a43c9781e7bf6fc37843cffab06dcdc76b9", size = 4218323, upload-time = "2026-03-11T18:49:40.921Z" }, - { url = "https://files.pythonhosted.org/packages/73/df/7b3c99a4e50442039eae498e5c23db634538eb3e02214109880cf1165d4c/hf_xet-1.4.0-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:6a883f0250682ea888a1bd0af0631feda377e59ad7aae6fb75860ecee7ae0f93", size = 3997156, upload-time = "2026-03-11T18:49:39.634Z" }, - { url = "https://files.pythonhosted.org/packages/a9/26/47dfedf271c21d95346660ae1698e7ece5ab10791fa6c4f20c59f3713083/hf_xet-1.4.0-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:99e1d9255fe8ecdf57149bb0543d49e7b7bd8d491ddf431eb57e114253274df5", size = 4199052, upload-time = "2026-03-11T18:49:57.097Z" }, - { url = "https://files.pythonhosted.org/packages/8d/c0/346b9aad1474e881e65f998d5c1981695f0af045bc7a99204d9d86759a89/hf_xet-1.4.0-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b25f06ce42bd2d5f2e79d4a2d72f783d3ac91827c80d34a38cf8e5290dd717b0", size = 4434346, upload-time = "2026-03-11T18:49:58.67Z" }, - { url = "https://files.pythonhosted.org/packages/2e/d6/88ce9d6caa397c3b935263d5bcbe3ebf6c443f7c76098b8c523d206116b9/hf_xet-1.4.0-cp37-abi3-win_amd64.whl", hash = "sha256:8d6d7816d01e0fa33f315c8ca21b05eca0ce4cdc314f13b81d953e46cc6db11d", size = 3678921, upload-time = "2026-03-11T18:50:09.496Z" }, - { url = "https://files.pythonhosted.org/packages/65/eb/17d99ed253b28a9550ca479867c66a8af4c9bcd8cdc9a26b0c8007c2000a/hf_xet-1.4.0-cp37-abi3-win_arm64.whl", hash = "sha256:cb8d9549122b5b42f34b23b14c6b662a88a586a919d418c774d8dbbc4b3ce2aa", size = 3541054, upload-time = "2026-03-11T18:50:07.963Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/09/08/23c84a26716382c89151b5b447b4beb19e3345f3a93d3b73009a71a57ad3/hf_xet-1.4.2.tar.gz", hash = "sha256:b7457b6b482d9e0743bd116363239b1fa904a5e65deede350fbc0c4ea67c71ea", size = 672357, upload-time = "2026-03-13T06:58:51.077Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/18/06/e8cf74c3c48e5485c7acc5a990d0d8516cdfb5fdf80f799174f1287cc1b5/hf_xet-1.4.2-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:ac8202ae1e664b2c15cdfc7298cbb25e80301ae596d602ef7870099a126fcad4", size = 3796125, upload-time = "2026-03-13T06:58:33.177Z" }, + { url = "https://files.pythonhosted.org/packages/66/d4/b73ebab01cbf60777323b7de9ef05550790451eb5172a220d6b9845385ec/hf_xet-1.4.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:6d2f8ee39fa9fba9af929f8c0d0482f8ee6e209179ad14a909b6ad78ffcb7c81", size = 3555985, upload-time = "2026-03-13T06:58:31.797Z" }, + { url = "https://files.pythonhosted.org/packages/ff/e7/ded6d1bd041c3f2bca9e913a0091adfe32371988e047dd3a68a2463c15a2/hf_xet-1.4.2-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4642a6cf249c09da8c1f87fe50b24b2a3450b235bf8adb55700b52f0ea6e2eb6", size = 4212085, upload-time = "2026-03-13T06:58:24.323Z" }, + { url = "https://files.pythonhosted.org/packages/97/c1/a0a44d1f98934f7bdf17f7a915b934f9fca44bb826628c553589900f6df8/hf_xet-1.4.2-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:769431385e746c92dc05492dde6f687d304584b89c33d79def8367ace06cb555", size = 3988266, upload-time = "2026-03-13T06:58:22.887Z" }, + { url = "https://files.pythonhosted.org/packages/7a/82/be713b439060e7d1f1d93543c8053d4ef2fe7e6922c5b31642eaa26f3c4b/hf_xet-1.4.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:c9dd1c1bc4cc56168f81939b0e05b4c36dd2d28c13dc1364b17af89aa0082496", size = 4188513, upload-time = "2026-03-13T06:58:40.858Z" }, + { url = "https://files.pythonhosted.org/packages/21/a6/cbd4188b22abd80ebd0edbb2b3e87f2633e958983519980815fb8314eae5/hf_xet-1.4.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:fca58a2ae4e6f6755cc971ac6fcdf777ea9284d7e540e350bb000813b9a3008d", size = 4428287, upload-time = "2026-03-13T06:58:42.601Z" }, + { url = "https://files.pythonhosted.org/packages/b2/4e/84e45b25e2e3e903ed3db68d7eafa96dae9a1d1f6d0e7fc85120347a852f/hf_xet-1.4.2-cp313-cp313t-win_amd64.whl", hash = "sha256:163aab46854ccae0ab6a786f8edecbbfbaa38fcaa0184db6feceebf7000c93c0", size = 3665574, upload-time = "2026-03-13T06:58:53.881Z" }, + { url = "https://files.pythonhosted.org/packages/ee/71/c5ac2b9a7ae39c14e91973035286e73911c31980fe44e7b1d03730c00adc/hf_xet-1.4.2-cp313-cp313t-win_arm64.whl", hash = "sha256:09b138422ecbe50fd0c84d4da5ff537d27d487d3607183cd10e3e53f05188e82", size = 3528760, upload-time = "2026-03-13T06:58:52.187Z" }, + { url = "https://files.pythonhosted.org/packages/1e/0f/fcd2504015eab26358d8f0f232a1aed6b8d363a011adef83fe130bff88f7/hf_xet-1.4.2-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:949dcf88b484bb9d9276ca83f6599e4aa03d493c08fc168c124ad10b2e6f75d7", size = 3796493, upload-time = "2026-03-13T06:58:39.267Z" }, + { url = "https://files.pythonhosted.org/packages/82/56/19c25105ff81731ca6d55a188b5de2aa99d7a2644c7aa9de1810d5d3b726/hf_xet-1.4.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:41659966020d59eb9559c57de2cde8128b706a26a64c60f0531fa2318f409418", size = 3555797, upload-time = "2026-03-13T06:58:37.546Z" }, + { url = "https://files.pythonhosted.org/packages/bf/e3/8933c073186849b5e06762aa89847991d913d10a95d1603eb7f2c3834086/hf_xet-1.4.2-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5c588e21d80010119458dd5d02a69093f0d115d84e3467efe71ffb2c67c19146", size = 4212127, upload-time = "2026-03-13T06:58:30.539Z" }, + { url = "https://files.pythonhosted.org/packages/eb/01/f89ebba4e369b4ed699dcb60d3152753870996f41c6d22d3d7cac01310e1/hf_xet-1.4.2-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:a296744d771a8621ad1d50c098d7ab975d599800dae6d48528ba3944e5001ba0", size = 3987788, upload-time = "2026-03-13T06:58:29.139Z" }, + { url = "https://files.pythonhosted.org/packages/84/4d/8a53e5ffbc2cc33bbf755382ac1552c6d9af13f623ed125fe67cc3e6772f/hf_xet-1.4.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:f563f7efe49588b7d0629d18d36f46d1658fe7e08dce3fa3d6526e1c98315e2d", size = 4188315, upload-time = "2026-03-13T06:58:48.017Z" }, + { url = "https://files.pythonhosted.org/packages/d1/b8/b7a1c1b5592254bd67050632ebbc1b42cc48588bf4757cb03c2ef87e704a/hf_xet-1.4.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5b2e0132c56d7ee1bf55bdb638c4b62e7106f6ac74f0b786fed499d5548c5570", size = 4428306, upload-time = "2026-03-13T06:58:49.502Z" }, + { url = "https://files.pythonhosted.org/packages/a0/0c/40779e45b20e11c7c5821a94135e0207080d6b3d76e7b78ccb413c6f839b/hf_xet-1.4.2-cp314-cp314t-win_amd64.whl", hash = "sha256:2f45c712c2fa1215713db10df6ac84b49d0e1c393465440e9cb1de73ecf7bbf6", size = 3665826, upload-time = "2026-03-13T06:58:59.88Z" }, + { url = "https://files.pythonhosted.org/packages/51/4c/e2688c8ad1760d7c30f7c429c79f35f825932581bc7c9ec811436d2f21a0/hf_xet-1.4.2-cp314-cp314t-win_arm64.whl", hash = "sha256:6d53df40616f7168abfccff100d232e9d460583b9d86fa4912c24845f192f2b8", size = 3529113, upload-time = "2026-03-13T06:58:58.491Z" }, + { url = "https://files.pythonhosted.org/packages/b4/86/b40b83a2ff03ef05c4478d2672b1fc2b9683ff870e2b25f4f3af240f2e7b/hf_xet-1.4.2-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:71f02d6e4cdd07f344f6844845d78518cc7186bd2bc52d37c3b73dc26a3b0bc5", size = 3800339, upload-time = "2026-03-13T06:58:36.245Z" }, + { url = "https://files.pythonhosted.org/packages/64/2e/af4475c32b4378b0e92a587adb1aa3ec53e3450fd3e5fe0372a874531c00/hf_xet-1.4.2-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:e9b38d876e94d4bdcf650778d6ebbaa791dd28de08db9736c43faff06ede1b5a", size = 3559664, upload-time = "2026-03-13T06:58:34.787Z" }, + { url = "https://files.pythonhosted.org/packages/3c/4c/781267da3188db679e601de18112021a5cb16506fe86b246e22c5401a9c4/hf_xet-1.4.2-cp37-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:77e8c180b7ef12d8a96739a4e1e558847002afe9ea63b6f6358b2271a8bdda1c", size = 4217422, upload-time = "2026-03-13T06:58:27.472Z" }, + { url = "https://files.pythonhosted.org/packages/68/47/d6cf4a39ecf6c7705f887a46f6ef5c8455b44ad9eb0d391aa7e8a2ff7fea/hf_xet-1.4.2-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:c3b3c6a882016b94b6c210957502ff7877802d0dbda8ad142c8595db8b944271", size = 3992847, upload-time = "2026-03-13T06:58:25.989Z" }, + { url = "https://files.pythonhosted.org/packages/2d/ef/e80815061abff54697239803948abc665c6b1d237102c174f4f7a9a5ffc5/hf_xet-1.4.2-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:9d9a634cc929cfbaf2e1a50c0e532ae8c78fa98618426769480c58501e8c8ac2", size = 4193843, upload-time = "2026-03-13T06:58:44.59Z" }, + { url = "https://files.pythonhosted.org/packages/54/75/07f6aa680575d9646c4167db6407c41340cbe2357f5654c4e72a1b01ca14/hf_xet-1.4.2-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:6b0932eb8b10317ea78b7da6bab172b17be03bbcd7809383d8d5abd6a2233e04", size = 4432751, upload-time = "2026-03-13T06:58:46.533Z" }, + { url = "https://files.pythonhosted.org/packages/cd/71/193eabd7e7d4b903c4aa983a215509c6114915a5a237525ec562baddb868/hf_xet-1.4.2-cp37-abi3-win_amd64.whl", hash = "sha256:ad185719fb2e8ac26f88c8100562dbf9dbdcc3d9d2add00faa94b5f106aea53f", size = 3671149, upload-time = "2026-03-13T06:58:57.07Z" }, + { url = "https://files.pythonhosted.org/packages/b4/7e/ccf239da366b37ba7f0b36095450efae4a64980bdc7ec2f51354205fdf39/hf_xet-1.4.2-cp37-abi3-win_arm64.whl", hash = "sha256:32c012286b581f783653e718c1862aea5b9eb140631685bb0c5e7012c8719a87", size = 3533426, upload-time = "2026-03-13T06:58:55.46Z" }, ] [[package]] @@ -2248,6 +2253,7 @@ dependencies = [ { name = "sb3-contrib" }, { name = "scikit-learn", version = "1.7.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, { name = "scikit-learn", version = "1.8.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "stable-baselines3" }, { name = "tensorboard" }, { name = "tqdm" }, { name = "typing-extensions" }, @@ -2297,6 +2303,7 @@ requires-dist = [ { name = "rich", specifier = ">=12.6.0" }, { name = "sb3-contrib", specifier = ">=2.0.0" }, { name = "scikit-learn", specifier = ">=1.5.1" }, + { name = "stable-baselines3", specifier = ">=2.7.0" }, { name = "tensorboard", specifier = ">=2.17.0" }, { name = "tqdm", specifier = ">=4.66.0" }, { name = "typing-extensions", specifier = ">=4.1" }, @@ -3294,7 +3301,7 @@ name = "pexpect" version = "4.9.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "ptyprocess" }, + { name = "ptyprocess", marker = "(python_full_version < '3.11' and sys_platform == 'emscripten') or (python_full_version < '3.11' and sys_platform == 'win32') or (sys_platform != 'emscripten' and sys_platform != 'win32')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/42/92/cc564bf6381ff43ce1f4d06852fc19a2f11d180f23dc32d9588bee2f149d/pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f", size = 166450, upload-time = "2023-11-25T09:07:26.339Z" } wheels = [ @@ -3884,11 +3891,14 @@ wheels = [ [[package]] name = "pyjwt" -version = "2.11.0" +version = "2.12.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/5c/5a/b46fa56bf322901eee5b0454a34343cdbdae202cd421775a8ee4e42fd519/pyjwt-2.11.0.tar.gz", hash = "sha256:35f95c1f0fbe5d5ba6e43f00271c275f7a1a4db1dab27bf708073b75318ea623", size = 98019, upload-time = "2026-01-30T19:59:55.694Z" } +dependencies = [ + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c2/27/a3b6e5bf6ff856d2509292e95c8f57f0df7017cf5394921fc4e4ef40308a/pyjwt-2.12.1.tar.gz", hash = "sha256:c74a7a2adf861c04d002db713dd85f84beb242228e671280bf709d765b03672b", size = 102564, upload-time = "2026-03-13T19:27:37.25Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/6f/01/c26ce75ba460d5cd503da9e13b21a33804d38c2165dec7b716d06b13010c/pyjwt-2.11.0-py3-none-any.whl", hash = "sha256:94a6bde30eb5c8e04fee991062b534071fd1439ef58d2adc9ccb823e7bcd0469", size = 28224, upload-time = "2026-01-30T19:59:54.539Z" }, + { url = "https://files.pythonhosted.org/packages/e5/7a/8dd906bd22e79e47397a61742927f6747fe93242ef86645ee9092e610244/pyjwt-2.12.1-py3-none-any.whl", hash = "sha256:28ca37c070cad8ba8cd9790cd940535d40274d22f80ab87f3ac6a713e6e8454c", size = 29726, upload-time = "2026-03-13T19:27:35.677Z" }, ] [[package]] @@ -4170,7 +4180,7 @@ wheels = [ [[package]] name = "qiskit" -version = "2.3.0" +version = "2.3.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "dill" }, @@ -4182,15 +4192,15 @@ dependencies = [ { name = "stevedore" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/13/8e/d5279454717d780f32eec4dfa6a7ef256ea7382b2f8fef2c715fc6f1180e/qiskit-2.3.0.tar.gz", hash = "sha256:e0a00c6681b8d04171c5cdb928837d992676f8aa4a07c390d446e54babaf6c1e", size = 3903621, upload-time = "2026-01-08T19:36:33.691Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f9/9a/a366dd56b6a4520e5b2856e47d573c6813b4c3f62f28969a37205fd845ab/qiskit-2.3.1.tar.gz", hash = "sha256:7b3b7e1c8a50f7f423204143a1bd9f21bf27659c57459d582eaff4035d8d7f75", size = 3909915, upload-time = "2026-03-13T00:43:03.257Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d6/79/22a6c61a94fef8eac09f968355c15c0d3b0800110152bbcf9cbed5bfc807/qiskit-2.3.0-cp310-abi3-macosx_10_12_x86_64.whl", hash = "sha256:bfeba21f216f64b051f9ac98653e9999d4c1bcb4f328aca06ad059aaef86586b", size = 8791989, upload-time = "2026-01-08T21:32:53.48Z" }, - { url = "https://files.pythonhosted.org/packages/d7/55/bb8efb2b6e46e5b8c7d147973646fa71677e63ecd2378af4db2829795be6/qiskit-2.3.0-cp310-abi3-macosx_11_0_arm64.whl", hash = "sha256:5f29f3b6a2b5738463bc667ddb2bcc79a83fb434ab9a8033487b64a399f71bef", size = 7872461, upload-time = "2026-01-08T19:36:26.458Z" }, - { url = "https://files.pythonhosted.org/packages/d1/c6/d928648d417c5c2e0c50481ef4f197f2ad8ca74d361e163e0c5d73253cbf/qiskit-2.3.0-cp310-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b437262a14ab961703153f79f38de5fde408601b0eda1f9c34b57498c912ef33", size = 8223957, upload-time = "2026-01-08T19:36:28.767Z" }, - { url = "https://files.pythonhosted.org/packages/54/76/33ee3519c3ff88b6154ccce13d24a33c0dc0fc9b22df8f216f1833cb0981/qiskit-2.3.0-cp310-abi3-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:7c413dace7a9b1d30bbbfeb2f90c4564dfcf6ed3c0744e026d4aca84f8fbd2bb", size = 9042802, upload-time = "2026-01-08T21:32:55.692Z" }, - { url = "https://files.pythonhosted.org/packages/73/9f/478788b16f653cdf151c7f2f040ba41b97e355d3bf9348ee2f0f685a5ea6/qiskit-2.3.0-cp310-abi3-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:ae0b1ec4c24ff8867599a5e8a46efaaf6d5477d1c4533427b7ae516054f52b2f", size = 8701281, upload-time = "2026-01-08T21:32:57.947Z" }, - { url = "https://files.pythonhosted.org/packages/de/22/fd8e7d4869641f60d9b7ce6d688b59520c8c8be8c8e4b51d76fb85b59f42/qiskit-2.3.0-cp310-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:24fd70ee3ac47fe029096e39b1c39abf3e7f145c723df90f9600468099c12aa4", size = 8888244, upload-time = "2026-01-08T19:36:30.259Z" }, - { url = "https://files.pythonhosted.org/packages/c3/bb/0fbcf43f9daba43f1eb31ecf7d36afcbcf705457d9df6e8e6f38f07b4851/qiskit-2.3.0-cp310-abi3-win_amd64.whl", hash = "sha256:8679a426725785701629f0af905a7a5b6bc25b0dcd7fe4f4c9f8be63d89e832c", size = 8630467, upload-time = "2026-01-08T19:36:31.958Z" }, + { url = "https://files.pythonhosted.org/packages/47/70/dba6afec66d2bf4df64b7059cd144bf0c775d998cb57b941d1065b331d28/qiskit-2.3.1-cp310-abi3-macosx_10_12_x86_64.whl", hash = "sha256:25a85465e8c860627e8a565cb9af824b2df1a2c42f5958b1a7b014aa085b32d6", size = 8614500, upload-time = "2026-03-13T02:30:24.247Z" }, + { url = "https://files.pythonhosted.org/packages/55/0b/47d67d58b4de120e10d49255b635429bc162a982b0cd58cf75b1a9f594fa/qiskit-2.3.1-cp310-abi3-macosx_11_0_arm64.whl", hash = "sha256:b1404b72987d0c7db32203a87565775115f6a77b2a3539d40eb1e354df6d08bb", size = 7819922, upload-time = "2026-03-13T00:42:54.205Z" }, + { url = "https://files.pythonhosted.org/packages/02/f0/2af86ce0e11b06248bc6a66550acf98c19e606cb317c27bab4fbed2ce37f/qiskit-2.3.1-cp310-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:68eec14320654065a158bf73b3d6fffaa31e865fe61b0db1510cfeeea76c87b0", size = 8176336, upload-time = "2026-03-13T00:42:56.891Z" }, + { url = "https://files.pythonhosted.org/packages/8a/fc/0bf71353c68b9090ed05e5c1d08730301c58a2b00f3001f0050f032bdcc9/qiskit-2.3.1-cp310-abi3-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:96545ad531c5e2ff6eecd348501620e0db0f3d73f49c20037ec3b5b2e9268f94", size = 8915234, upload-time = "2026-03-13T02:30:27.055Z" }, + { url = "https://files.pythonhosted.org/packages/1b/0c/19ffdb15d2e72156de406fe27cad26c6015071a385e6b48c6db87d8ce676/qiskit-2.3.1-cp310-abi3-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:a1a030b4a0cd75f3299c9866a3e9489a02078efc343abd42eec74ad2a5f2fa80", size = 8513126, upload-time = "2026-03-13T02:30:30.288Z" }, + { url = "https://files.pythonhosted.org/packages/11/06/41f4197fcb3c38e99f22f400ea25375c9057190cd094cd6c0f97be730796/qiskit-2.3.1-cp310-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:350027279bb171e9746fee5756c674872df97f4608b079129d4edb25b5bb1fdd", size = 8833222, upload-time = "2026-03-13T00:42:59.092Z" }, + { url = "https://files.pythonhosted.org/packages/a5/db/6ddc52eaf22ab1f95ee6251ff7a375c0a1a7453b5864528992303b166198/qiskit-2.3.1-cp310-abi3-win_amd64.whl", hash = "sha256:f884abd92c0173e246705f89f8b4808badaa0e1b167ed3277a3cb83c2564b4b8", size = 8639580, upload-time = "2026-03-13T00:43:01.022Z" }, ] [package.optional-dependencies] @@ -4664,18 +4674,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d1/b7/b95708304cd49b7b6f82fdd039f1748b66ec2b21d6a45180910802f1abf1/rpds_py-0.30.0-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:ac37f9f516c51e5753f27dfdef11a88330f04de2d564be3991384b2f3535d02e", size = 562191, upload-time = "2025-11-30T20:24:36.853Z" }, ] -[[package]] -name = "rsa" -version = "4.9.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "pyasn1" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/da/8a/22b7beea3ee0d44b1916c0c1cb0ee3af23b700b6da9f04991899d0c555d4/rsa-4.9.1.tar.gz", hash = "sha256:e7bdbfdb5497da4c07dfd35530e1a902659db6ff241e39d9953cad06ebd0ae75", size = 29034, upload-time = "2025-04-16T09:51:18.218Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/64/8d/0133e4eb4beed9e425d9a98ed6e081a55d195481b7632472be1af08d2f6b/rsa-4.9.1-py3-none-any.whl", hash = "sha256:68635866661c6836b8d39430f97a996acbd61bfa49406748ea243539fe239762", size = 34696, upload-time = "2025-04-16T09:51:17.142Z" }, -] - [[package]] name = "rustworkx" version = "0.17.1" From 96fa16edf1e2a95694d0bcd42cd11fe1ef97047d Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 14 Mar 2026 15:41:47 +0000 Subject: [PATCH 02/13] =?UTF-8?q?=F0=9F=8E=A8=20pre-commit=20fixes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/mqt/predictor/rl/predictorenv.py | 1 + tests/compilation/test_predictor_rl.py | 1 + 2 files changed, 2 insertions(+) diff --git a/src/mqt/predictor/rl/predictorenv.py b/src/mqt/predictor/rl/predictorenv.py index 2e9984b3f..64d963f05 100644 --- a/src/mqt/predictor/rl/predictorenv.py +++ b/src/mqt/predictor/rl/predictorenv.py @@ -834,6 +834,7 @@ def is_circuit_routed(self, circuit: QuantumCircuit, coupling_map: CouplingMap) if (q0, q1) not in directed_edges: return False return True + def determine_valid_actions_for_state(self) -> list[int]: """Determine valid actions based on circuit state: synthesized, mapped, routed.""" synthesized = self.is_circuit_synthesized(self.state) diff --git a/tests/compilation/test_predictor_rl.py b/tests/compilation/test_predictor_rl.py index 5d8989339..8f8474738 100644 --- a/tests/compilation/test_predictor_rl.py +++ b/tests/compilation/test_predictor_rl.py @@ -37,6 +37,7 @@ if TYPE_CHECKING: from _pytest.monkeypatch import MonkeyPatch + from mqt.predictor.reward import figure_of_merit From 8d1760c4854ff9288e206746b49cc1880dbb1340 Mon Sep 17 00:00:00 2001 From: Zhou Shaobo Date: Sat, 14 Mar 2026 16:49:43 +0100 Subject: [PATCH 03/13] Fixes uv.lock --- uv.lock | 462 +++++++++++++++++++++++++++++--------------------------- 1 file changed, 236 insertions(+), 226 deletions(-) diff --git a/uv.lock b/uv.lock index 522320d68..cde1864e9 100644 --- a/uv.lock +++ b/uv.lock @@ -55,14 +55,14 @@ name = "aiohttp" version = "3.13.3" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "aiohappyeyeballs" }, - { name = "aiosignal" }, + { name = "aiohappyeyeballs", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "aiosignal", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, { name = "async-timeout", marker = "python_full_version < '3.11'" }, - { name = "attrs" }, - { name = "frozenlist" }, - { name = "multidict" }, - { name = "propcache" }, - { name = "yarl" }, + { name = "attrs", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "frozenlist", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "multidict", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "propcache", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "yarl", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/50/42/32cf8e7704ceb4481406eb87161349abb46a57fee3f008ba9cb610968646/aiohttp-3.13.3.tar.gz", hash = "sha256:a949eee43d3782f2daae4f4a2819b2cb9b0c5d3b7f7a927067cc84dafdbb9f88", size = 7844556, upload-time = "2026-01-03T17:33:05.204Z" } wheels = [ @@ -175,7 +175,7 @@ name = "aiohttp-cors" version = "0.8.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "aiohttp" }, + { name = "aiohttp", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/6f/6d/d89e846a5444b3d5eb8985a6ddb0daef3774928e1bfbce8e84ec97b0ffa7/aiohttp_cors-0.8.1.tar.gz", hash = "sha256:ccacf9cb84b64939ea15f859a146af1f662a6b1d68175754a07315e305fb1403", size = 38626, upload-time = "2025-03-31T14:16:20.048Z" } wheels = [ @@ -187,7 +187,7 @@ name = "aiosignal" version = "1.4.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "frozenlist" }, + { name = "frozenlist", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, { name = "typing-extensions", marker = "python_full_version < '3.13'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/61/62/06741b579156360248d1ec624842ad0edf697050bbaf7c3e46394e106ad1/aiosignal-1.4.0.tar.gz", hash = "sha256:f47eecd9468083c2029cc99945502cb7708b082c232f9aca65da147157b251c7", size = 25007, upload-time = "2025-07-03T22:54:43.528Z" } @@ -555,7 +555,7 @@ name = "colorful" version = "0.5.8" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "colorama", marker = "python_full_version != '3.13.*' and sys_platform == 'win32'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/82/31/109ef4bedeb32b4202e02ddb133162457adc4eb890a9ed9c05c9dd126ed0/colorful-0.5.8.tar.gz", hash = "sha256:bb16502b198be2f1c42ba3c52c703d5f651d826076817185f0294c1a549a7445", size = 209361, upload-time = "2025-10-29T11:53:21.663Z" } wheels = [ @@ -1115,59 +1115,59 @@ wheels = [ [[package]] name = "fonttools" -version = "4.62.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/9a/08/7012b00a9a5874311b639c3920270c36ee0c445b69d9989a85e5c92ebcb0/fonttools-4.62.1.tar.gz", hash = "sha256:e54c75fd6041f1122476776880f7c3c3295ffa31962dc6ebe2543c00dca58b5d", size = 3580737, upload-time = "2026-03-13T13:54:25.52Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/5a/ff/532ed43808b469c807e8cb6b21358da3fe6fd51486b3a8c93db0bb5d957f/fonttools-4.62.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ad5cca75776cd453b1b035b530e943334957ae152a36a88a320e779d61fc980c", size = 2873740, upload-time = "2026-03-13T13:52:11.822Z" }, - { url = "https://files.pythonhosted.org/packages/85/e4/2318d2b430562da7227010fb2bb029d2fa54d7b46443ae8942bab224e2a0/fonttools-4.62.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0b3ae47e8636156a9accff64c02c0924cbebad62854c4a6dbdc110cd5b4b341a", size = 2417649, upload-time = "2026-03-13T13:52:14.605Z" }, - { url = "https://files.pythonhosted.org/packages/4c/28/40f15523b5188598018e7956899fed94eb7debec89e2dd70cb4a8df90492/fonttools-4.62.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c9b9e288b4da2f64fd6180644221749de651703e8d0c16bd4b719533a3a7d6e3", size = 4935213, upload-time = "2026-03-13T13:52:17.399Z" }, - { url = "https://files.pythonhosted.org/packages/42/09/7dbe3d7023f57d9b580cfa832109d521988112fd59dddfda3fddda8218f9/fonttools-4.62.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7bca7a1c1faf235ffe25d4f2e555246b4750220b38de8261d94ebc5ce8a23c23", size = 4892374, upload-time = "2026-03-13T13:52:20.175Z" }, - { url = "https://files.pythonhosted.org/packages/d1/2d/84509a2e32cb925371560ef5431365d8da2183c11d98e5b4b8b4e42426a5/fonttools-4.62.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b4e0fcf265ad26e487c56cb12a42dffe7162de708762db951e1b3f755319507d", size = 4911856, upload-time = "2026-03-13T13:52:22.777Z" }, - { url = "https://files.pythonhosted.org/packages/a5/80/df28131379eed93d9e6e6fccd3bf6e3d077bebbfe98cc83f21bbcd83ed02/fonttools-4.62.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:2d850f66830a27b0d498ee05adb13a3781637b1826982cd7e2b3789ef0cc71ae", size = 5031712, upload-time = "2026-03-13T13:52:25.14Z" }, - { url = "https://files.pythonhosted.org/packages/3d/03/3c8f09aad64230cd6d921ae7a19f9603c36f70930b00459f112706f6769a/fonttools-4.62.1-cp310-cp310-win32.whl", hash = "sha256:486f32c8047ccd05652aba17e4a8819a3a9d78570eb8a0e3b4503142947880ed", size = 1507878, upload-time = "2026-03-13T13:52:28.149Z" }, - { url = "https://files.pythonhosted.org/packages/dd/ec/f53f626f8f3e89f4cadd8fc08f3452c8fd182c951ad5caa35efac22b29ab/fonttools-4.62.1-cp310-cp310-win_amd64.whl", hash = "sha256:5a648bde915fba9da05ae98856987ca91ba832949a9e2888b48c47ef8b96c5a9", size = 1556766, upload-time = "2026-03-13T13:52:30.814Z" }, - { url = "https://files.pythonhosted.org/packages/88/39/23ff32561ec8d45a4d48578b4d241369d9270dc50926c017570e60893701/fonttools-4.62.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:40975849bac44fb0b9253d77420c6d8b523ac4dcdcefeff6e4d706838a5b80f7", size = 2871039, upload-time = "2026-03-13T13:52:33.127Z" }, - { url = "https://files.pythonhosted.org/packages/24/7f/66d3f8a9338a9b67fe6e1739f47e1cd5cee78bd3bc1206ef9b0b982289a5/fonttools-4.62.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9dde91633f77fa576879a0c76b1d89de373cae751a98ddf0109d54e173b40f14", size = 2416346, upload-time = "2026-03-13T13:52:35.676Z" }, - { url = "https://files.pythonhosted.org/packages/aa/53/5276ceba7bff95da7793a07c5284e1da901cf00341ce5e2f3273056c0cca/fonttools-4.62.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6acb4109f8bee00fec985c8c7afb02299e35e9c94b57287f3ea542f28bd0b0a7", size = 5100897, upload-time = "2026-03-13T13:52:38.102Z" }, - { url = "https://files.pythonhosted.org/packages/cc/a1/40a5c4d8e28b0851d53a8eeeb46fbd73c325a2a9a165f290a5ed90e6c597/fonttools-4.62.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1c5c25671ce8805e0d080e2ffdeca7f1e86778c5cbfbeae86d7f866d8830517b", size = 5071078, upload-time = "2026-03-13T13:52:41.305Z" }, - { url = "https://files.pythonhosted.org/packages/e3/be/d378fca4c65ea1956fee6d90ace6e861776809cbbc5af22388a090c3c092/fonttools-4.62.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:a5d8825e1140f04e6c99bb7d37a9e31c172f3bc208afbe02175339e699c710e1", size = 5076908, upload-time = "2026-03-13T13:52:44.122Z" }, - { url = "https://files.pythonhosted.org/packages/f8/d9/ae6a1d0693a4185a84605679c8a1f719a55df87b9c6e8e817bfdd9ef5936/fonttools-4.62.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:268abb1cb221e66c014acc234e872b7870d8b5d4657a83a8f4205094c32d2416", size = 5202275, upload-time = "2026-03-13T13:52:46.591Z" }, - { url = "https://files.pythonhosted.org/packages/54/6c/af95d9c4efb15cabff22642b608342f2bd67137eea6107202d91b5b03184/fonttools-4.62.1-cp311-cp311-win32.whl", hash = "sha256:942b03094d7edbb99bdf1ae7e9090898cad7bf9030b3d21f33d7072dbcb51a53", size = 2293075, upload-time = "2026-03-13T13:52:48.711Z" }, - { url = "https://files.pythonhosted.org/packages/d3/97/bf54c5b3f2be34e1f143e6db838dfdc54f2ffa3e68c738934c82f3b2a08d/fonttools-4.62.1-cp311-cp311-win_amd64.whl", hash = "sha256:e8514f4924375f77084e81467e63238b095abda5107620f49421c368a6017ed2", size = 2344593, upload-time = "2026-03-13T13:52:50.725Z" }, - { url = "https://files.pythonhosted.org/packages/47/d4/dbacced3953544b9a93088cc10ef2b596d348c983d5c67a404fa41ec51ba/fonttools-4.62.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:90365821debbd7db678809c7491ca4acd1e0779b9624cdc6ddaf1f31992bf974", size = 2870219, upload-time = "2026-03-13T13:52:53.664Z" }, - { url = "https://files.pythonhosted.org/packages/66/9e/a769c8e99b81e5a87ab7e5e7236684de4e96246aae17274e5347d11ebd78/fonttools-4.62.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:12859ff0b47dd20f110804c3e0d0970f7b832f561630cd879969011541a464a9", size = 2414891, upload-time = "2026-03-13T13:52:56.493Z" }, - { url = "https://files.pythonhosted.org/packages/69/64/f19a9e3911968c37e1e620e14dfc5778299e1474f72f4e57c5ec771d9489/fonttools-4.62.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9c125ffa00c3d9003cdaaf7f2c79e6e535628093e14b5de1dccb08859b680936", size = 5033197, upload-time = "2026-03-13T13:52:59.179Z" }, - { url = "https://files.pythonhosted.org/packages/9b/8a/99c8b3c3888c5c474c08dbfd7c8899786de9604b727fcefb055b42c84bba/fonttools-4.62.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:149f7d84afca659d1a97e39a4778794a2f83bf344c5ee5134e09995086cc2392", size = 4988768, upload-time = "2026-03-13T13:53:02.761Z" }, - { url = "https://files.pythonhosted.org/packages/d1/c6/0f904540d3e6ab463c1243a0d803504826a11604c72dd58c2949796a1762/fonttools-4.62.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0aa72c43a601cfa9273bb1ae0518f1acadc01ee181a6fc60cd758d7fdadffc04", size = 4971512, upload-time = "2026-03-13T13:53:05.678Z" }, - { url = "https://files.pythonhosted.org/packages/29/0b/5cbef6588dc9bd6b5c9ad6a4d5a8ca384d0cea089da31711bbeb4f9654a6/fonttools-4.62.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:19177c8d96c7c36359266e571c5173bcee9157b59cfc8cb0153c5673dc5a3a7d", size = 5122723, upload-time = "2026-03-13T13:53:08.662Z" }, - { url = "https://files.pythonhosted.org/packages/4a/47/b3a5342d381595ef439adec67848bed561ab7fdb1019fa522e82101b7d9c/fonttools-4.62.1-cp312-cp312-win32.whl", hash = "sha256:a24decd24d60744ee8b4679d38e88b8303d86772053afc29b19d23bb8207803c", size = 2281278, upload-time = "2026-03-13T13:53:10.998Z" }, - { url = "https://files.pythonhosted.org/packages/28/b1/0c2ab56a16f409c6c8a68816e6af707827ad5d629634691ff60a52879792/fonttools-4.62.1-cp312-cp312-win_amd64.whl", hash = "sha256:9e7863e10b3de72376280b515d35b14f5eeed639d1aa7824f4cf06779ec65e42", size = 2331414, upload-time = "2026-03-13T13:53:13.992Z" }, - { url = "https://files.pythonhosted.org/packages/3b/56/6f389de21c49555553d6a5aeed5ac9767631497ac836c4f076273d15bd72/fonttools-4.62.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:c22b1014017111c401469e3acc5433e6acf6ebcc6aa9efb538a533c800971c79", size = 2865155, upload-time = "2026-03-13T13:53:16.132Z" }, - { url = "https://files.pythonhosted.org/packages/03/c5/0e3966edd5ec668d41dfe418787726752bc07e2f5fd8c8f208615e61fa89/fonttools-4.62.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:68959f5fc58ed4599b44aad161c2837477d7f35f5f79402d97439974faebfebe", size = 2412802, upload-time = "2026-03-13T13:53:18.878Z" }, - { url = "https://files.pythonhosted.org/packages/52/94/e6ac4b44026de7786fe46e3bfa0c87e51d5d70a841054065d49cd62bb909/fonttools-4.62.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ef46db46c9447103b8f3ff91e8ba009d5fe181b1920a83757a5762551e32bb68", size = 5013926, upload-time = "2026-03-13T13:53:21.379Z" }, - { url = "https://files.pythonhosted.org/packages/e2/98/8b1e801939839d405f1f122e7d175cebe9aeb4e114f95bfc45e3152af9a7/fonttools-4.62.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6706d1cb1d5e6251a97ad3c1b9347505c5615c112e66047abbef0f8545fa30d1", size = 4964575, upload-time = "2026-03-13T13:53:23.857Z" }, - { url = "https://files.pythonhosted.org/packages/46/76/7d051671e938b1881670528fec69cc4044315edd71a229c7fd712eaa5119/fonttools-4.62.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:2e7abd2b1e11736f58c1de27819e1955a53267c21732e78243fa2fa2e5c1e069", size = 4953693, upload-time = "2026-03-13T13:53:26.569Z" }, - { url = "https://files.pythonhosted.org/packages/1f/ae/b41f8628ec0be3c1b934fc12b84f4576a5c646119db4d3bdd76a217c90b5/fonttools-4.62.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:403d28ce06ebfc547fbcb0cb8b7f7cc2f7a2d3e1a67ba9a34b14632df9e080f9", size = 5094920, upload-time = "2026-03-13T13:53:29.329Z" }, - { url = "https://files.pythonhosted.org/packages/f2/f6/53a1e9469331a23dcc400970a27a4caa3d9f6edbf5baab0260285238b884/fonttools-4.62.1-cp313-cp313-win32.whl", hash = "sha256:93c316e0f5301b2adbe6a5f658634307c096fd5aae60a5b3412e4f3e1728ab24", size = 2279928, upload-time = "2026-03-13T13:53:32.352Z" }, - { url = "https://files.pythonhosted.org/packages/38/60/35186529de1db3c01f5ad625bde07c1f576305eab6d86bbda4c58445f721/fonttools-4.62.1-cp313-cp313-win_amd64.whl", hash = "sha256:7aa21ff53e28a9c2157acbc44e5b401149d3c9178107130e82d74ceb500e5056", size = 2330514, upload-time = "2026-03-13T13:53:34.991Z" }, - { url = "https://files.pythonhosted.org/packages/36/f0/2888cdac391807d68d90dcb16ef858ddc1b5309bfc6966195a459dd326e2/fonttools-4.62.1-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:fa1d16210b6b10a826d71bed68dd9ec24a9e218d5a5e2797f37c573e7ec215ca", size = 2864442, upload-time = "2026-03-13T13:53:37.509Z" }, - { url = "https://files.pythonhosted.org/packages/4b/b2/e521803081f8dc35990816b82da6360fa668a21b44da4b53fc9e77efcd62/fonttools-4.62.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:aa69d10ed420d8121118e628ad47d86e4caa79ba37f968597b958f6cceab7eca", size = 2410901, upload-time = "2026-03-13T13:53:40.55Z" }, - { url = "https://files.pythonhosted.org/packages/00/a4/8c3511ff06e53110039358dbbdc1a65d72157a054638387aa2ada300a8b8/fonttools-4.62.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bd13b7999d59c5eb1c2b442eb2d0c427cb517a0b7a1f5798fc5c9e003f5ff782", size = 4999608, upload-time = "2026-03-13T13:53:42.798Z" }, - { url = "https://files.pythonhosted.org/packages/28/63/cd0c3b26afe60995a5295f37c246a93d454023726c3261cfbb3559969bb9/fonttools-4.62.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8d337fdd49a79b0d51c4da87bc38169d21c3abbf0c1aa9367eff5c6656fb6dae", size = 4912726, upload-time = "2026-03-13T13:53:45.405Z" }, - { url = "https://files.pythonhosted.org/packages/70/b9/ac677cb07c24c685cf34f64e140617d58789d67a3dd524164b63648c6114/fonttools-4.62.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:d241cdc4a67b5431c6d7f115fdf63335222414995e3a1df1a41e1182acd4bcc7", size = 4951422, upload-time = "2026-03-13T13:53:48.326Z" }, - { url = "https://files.pythonhosted.org/packages/e6/10/11c08419a14b85b7ca9a9faca321accccc8842dd9e0b1c8a72908de05945/fonttools-4.62.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:c05557a78f8fa514da0f869556eeda40887a8abc77c76ee3f74cf241778afd5a", size = 5060979, upload-time = "2026-03-13T13:53:51.366Z" }, - { url = "https://files.pythonhosted.org/packages/4e/3c/12eea4a4cf054e7ab058ed5ceada43b46809fce2bf319017c4d63ae55bb4/fonttools-4.62.1-cp314-cp314-win32.whl", hash = "sha256:49a445d2f544ce4a69338694cad575ba97b9a75fff02720da0882d1a73f12800", size = 2283733, upload-time = "2026-03-13T13:53:53.606Z" }, - { url = "https://files.pythonhosted.org/packages/6b/67/74b070029043186b5dd13462c958cb7c7f811be0d2e634309d9a1ffb1505/fonttools-4.62.1-cp314-cp314-win_amd64.whl", hash = "sha256:1eecc128c86c552fb963fe846ca4e011b1be053728f798185a1687502f6d398e", size = 2335663, upload-time = "2026-03-13T13:53:56.23Z" }, - { url = "https://files.pythonhosted.org/packages/42/c5/4d2ed3ca6e33617fc5624467da353337f06e7f637707478903c785bd8e20/fonttools-4.62.1-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:1596aeaddf7f78e21e68293c011316a25267b3effdaccaf4d59bc9159d681b82", size = 2947288, upload-time = "2026-03-13T13:53:59.397Z" }, - { url = "https://files.pythonhosted.org/packages/1f/e9/7ab11ddfda48ed0f89b13380e5595ba572619c27077be0b2c447a63ff351/fonttools-4.62.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:8f8fca95d3bb3208f59626a4b0ea6e526ee51f5a8ad5d91821c165903e8d9260", size = 2449023, upload-time = "2026-03-13T13:54:01.642Z" }, - { url = "https://files.pythonhosted.org/packages/b2/10/a800fa090b5e8819942e54e19b55fc7c21fe14a08757c3aa3ca8db358939/fonttools-4.62.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee91628c08e76f77b533d65feb3fbe6d9dad699f95be51cf0d022db94089cdc4", size = 5137599, upload-time = "2026-03-13T13:54:04.495Z" }, - { url = "https://files.pythonhosted.org/packages/37/dc/8ccd45033fffd74deb6912fa1ca524643f584b94c87a16036855b498a1ed/fonttools-4.62.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5f37df1cac61d906e7b836abe356bc2f34c99d4477467755c216b72aa3dc748b", size = 4920933, upload-time = "2026-03-13T13:54:07.557Z" }, - { url = "https://files.pythonhosted.org/packages/99/eb/e618adefb839598d25ac8136cd577925d6c513dc0d931d93b8af956210f0/fonttools-4.62.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:92bb00a947e666169c99b43753c4305fc95a890a60ef3aeb2a6963e07902cc87", size = 5016232, upload-time = "2026-03-13T13:54:10.611Z" }, - { url = "https://files.pythonhosted.org/packages/d9/5f/9b5c9bfaa8ec82def8d8168c4f13615990d6ce5996fe52bd49bfb5e05134/fonttools-4.62.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:bdfe592802ef939a0e33106ea4a318eeb17822c7ee168c290273cbd5fabd746c", size = 5042987, upload-time = "2026-03-13T13:54:13.569Z" }, - { url = "https://files.pythonhosted.org/packages/90/aa/dfbbe24c6a6afc5c203d90cc0343e24bcbb09e76d67c4d6eef8c2558d7ba/fonttools-4.62.1-cp314-cp314t-win32.whl", hash = "sha256:b820fcb92d4655513d8402d5b219f94481c4443d825b4372c75a2072aa4b357a", size = 2348021, upload-time = "2026-03-13T13:54:16.98Z" }, - { url = "https://files.pythonhosted.org/packages/13/6f/ae9c4e4dd417948407b680855c2c7790efb52add6009aaecff1e3bc50e8e/fonttools-4.62.1-cp314-cp314t-win_amd64.whl", hash = "sha256:59b372b4f0e113d3746b88985f1c796e7bf830dd54b28374cd85c2b8acd7583e", size = 2414147, upload-time = "2026-03-13T13:54:19.416Z" }, - { url = "https://files.pythonhosted.org/packages/fd/ba/56147c165442cc5ba7e82ecf301c9a68353cede498185869e6e02b4c264f/fonttools-4.62.1-py3-none-any.whl", hash = "sha256:7487782e2113861f4ddcc07c3436450659e3caa5e470b27dc2177cade2d8e7fd", size = 1152647, upload-time = "2026-03-13T13:54:22.735Z" }, +version = "4.62.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/5a/96/686339e0fda8142b7ebed39af53f4a5694602a729662f42a6209e3be91d0/fonttools-4.62.0.tar.gz", hash = "sha256:0dc477c12b8076b4eb9af2e440421b0433ffa9e1dcb39e0640a6c94665ed1098", size = 3579521, upload-time = "2026-03-09T16:50:06.217Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/82/e0/9db48ec7f6b95bae7b20667ded54f18dba8e759ef66232c8683822ae26fc/fonttools-4.62.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:62b6a3d0028e458e9b59501cf7124a84cd69681c433570e4861aff4fb54a236c", size = 2873527, upload-time = "2026-03-09T16:48:12.416Z" }, + { url = "https://files.pythonhosted.org/packages/dd/45/86eccfdc922cb9fafc63189a9793fa9f6dd60e68a07be42e454ef2c0deae/fonttools-4.62.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:966557078b55e697f65300b18025c54e872d7908d1899b7314d7c16e64868cb2", size = 2417427, upload-time = "2026-03-09T16:48:15.122Z" }, + { url = "https://files.pythonhosted.org/packages/d3/98/f547a1fceeae81a9a5c6461bde2badac8bf50bda7122a8012b32b1e65396/fonttools-4.62.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9cf34861145b516cddd19b07ae6f4a61ea1c6326031b960ec9ddce8ee815e888", size = 4934993, upload-time = "2026-03-09T16:48:18.186Z" }, + { url = "https://files.pythonhosted.org/packages/5c/57/a23a051fcff998fdfabdd33c6721b5bad499da08b586d3676993410071f0/fonttools-4.62.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3e2ff573de2775508c8a366351fb901c4ced5dc6cf2d87dd15c973bedcdd5216", size = 4892154, upload-time = "2026-03-09T16:48:20.736Z" }, + { url = "https://files.pythonhosted.org/packages/e2/62/e27644b433dc6db1d47bc6028a27d772eec5cc8338e24a9a1fce5d7120aa/fonttools-4.62.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:55b189a1b3033860a38e4e5bd0626c5aa25c7ce9caee7bc784a8caec7a675401", size = 4911635, upload-time = "2026-03-09T16:48:23.174Z" }, + { url = "https://files.pythonhosted.org/packages/7e/e2/1bf141911a5616bacfe9cf237c80ccd69d0d92482c38c0f7f6a55d063ad9/fonttools-4.62.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:825f98cd14907c74a4d0a3f7db8570886ffce9c6369fed1385020febf919abf6", size = 5031492, upload-time = "2026-03-09T16:48:25.095Z" }, + { url = "https://files.pythonhosted.org/packages/2f/59/790c292f4347ecfa77d9c7e0d1d91e04ab227f6e4a337ed4fe37ca388048/fonttools-4.62.0-cp310-cp310-win32.whl", hash = "sha256:c858030560f92a054444c6e46745227bfd3bb4e55383c80d79462cd47289e4b5", size = 1507656, upload-time = "2026-03-09T16:48:26.973Z" }, + { url = "https://files.pythonhosted.org/packages/e9/ee/08c0b7f8bac6e44638de6fe9a3e710a623932f60eccd58912c4d4743516d/fonttools-4.62.0-cp310-cp310-win_amd64.whl", hash = "sha256:9bf75eb69330e34ad2a096fac67887102c8537991eb6cac1507fc835bbb70e0a", size = 1556540, upload-time = "2026-03-09T16:48:30.359Z" }, + { url = "https://files.pythonhosted.org/packages/e4/33/63d79ca41020dd460b51f1e0f58ad1ff0a36b7bcbdf8f3971d52836581e9/fonttools-4.62.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:196cafef9aeec5258425bd31a4e9a414b2ee0d1557bca184d7923d3d3bcd90f9", size = 2870816, upload-time = "2026-03-09T16:48:32.39Z" }, + { url = "https://files.pythonhosted.org/packages/c0/7a/9aeec114bc9fc00d757a41f092f7107863d372e684a5b5724c043654477c/fonttools-4.62.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:153afc3012ff8761b1733e8fbe5d98623409774c44ffd88fbcb780e240c11d13", size = 2416127, upload-time = "2026-03-09T16:48:34.627Z" }, + { url = "https://files.pythonhosted.org/packages/5a/71/12cfd8ae0478b7158ffa8850786781f67e73c00fd897ef9d053415c5f88b/fonttools-4.62.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:13b663fb197334de84db790353d59da2a7288fd14e9be329f5debc63ec0500a5", size = 5100678, upload-time = "2026-03-09T16:48:36.454Z" }, + { url = "https://files.pythonhosted.org/packages/8a/d7/8e4845993ee233c2023d11babe9b3dae7d30333da1d792eeccebcb77baab/fonttools-4.62.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:591220d5333264b1df0d3285adbdfe2af4f6a45bbf9ca2b485f97c9f577c49ff", size = 5070859, upload-time = "2026-03-09T16:48:38.786Z" }, + { url = "https://files.pythonhosted.org/packages/ae/a0/287ae04cd883a52e7bb1d92dfc4997dcffb54173761c751106845fa9e316/fonttools-4.62.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:579f35c121528a50c96bf6fcb6a393e81e7f896d4326bf40e379f1c971603db9", size = 5076689, upload-time = "2026-03-09T16:48:41.886Z" }, + { url = "https://files.pythonhosted.org/packages/6d/4e/a2377ad26c36fcd3e671a1c316ea5ed83107de1588e2d897a98349363bc7/fonttools-4.62.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:44956b003151d5a289eba6c71fe590d63509267c37e26de1766ba15d9c589582", size = 5202053, upload-time = "2026-03-09T16:48:43.867Z" }, + { url = "https://files.pythonhosted.org/packages/44/2e/ad0472e69b02f83dc88983a9910d122178461606404be5b4838af6d1744a/fonttools-4.62.0-cp311-cp311-win32.whl", hash = "sha256:42c7848fa8836ab92c23b1617c407a905642521ff2d7897fe2bf8381530172f1", size = 2292852, upload-time = "2026-03-09T16:48:46.962Z" }, + { url = "https://files.pythonhosted.org/packages/77/ce/f5a4c42c117f8113ce04048053c128d17426751a508f26398110c993a074/fonttools-4.62.0-cp311-cp311-win_amd64.whl", hash = "sha256:4da779e8f342a32856075ddb193b2a024ad900bc04ecb744014c32409ae871ed", size = 2344367, upload-time = "2026-03-09T16:48:48.818Z" }, + { url = "https://files.pythonhosted.org/packages/ab/9d/7ad1ffc080619f67d0b1e0fa6a0578f0be077404f13fd8e448d1616a94a3/fonttools-4.62.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:22bde4dc12a9e09b5ced77f3b5053d96cf10c4976c6ac0dee293418ef289d221", size = 2870004, upload-time = "2026-03-09T16:48:50.837Z" }, + { url = "https://files.pythonhosted.org/packages/4d/8b/ba59069a490f61b737e064c3129453dbd28ee38e81d56af0d04d7e6b4de4/fonttools-4.62.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7199c73b326bad892f1cb53ffdd002128bfd58a89b8f662204fbf1daf8d62e85", size = 2414662, upload-time = "2026-03-09T16:48:53.295Z" }, + { url = "https://files.pythonhosted.org/packages/8c/8c/c52a4310de58deeac7e9ea800892aec09b00bb3eb0c53265b31ec02be115/fonttools-4.62.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d732938633681d6e2324e601b79e93f7f72395ec8681f9cdae5a8c08bc167e72", size = 5032975, upload-time = "2026-03-09T16:48:55.718Z" }, + { url = "https://files.pythonhosted.org/packages/0b/a1/d16318232964d786907b9b3613b8409f74cf0be2da400854509d3a864e43/fonttools-4.62.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:31a804c16d76038cc4e3826e07678efb0a02dc4f15396ea8e07088adbfb2578e", size = 4988544, upload-time = "2026-03-09T16:48:57.715Z" }, + { url = "https://files.pythonhosted.org/packages/b2/8d/7e745ca3e65852adc5e52a83dc213fe1b07d61cb5b394970fcd4b1199d1e/fonttools-4.62.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:090e74ac86e68c20150e665ef8e7e0c20cb9f8b395302c9419fa2e4d332c3b51", size = 4971296, upload-time = "2026-03-09T16:48:59.678Z" }, + { url = "https://files.pythonhosted.org/packages/e6/d4/b717a4874175146029ca1517e85474b1af80c9d9a306fc3161e71485eea5/fonttools-4.62.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8f086120e8be9e99ca1288aa5ce519833f93fe0ec6ebad2380c1dee18781f0b5", size = 5122503, upload-time = "2026-03-09T16:49:02.464Z" }, + { url = "https://files.pythonhosted.org/packages/cb/4b/92cfcba4bf8373f51c49c5ae4b512ead6fbda7d61a0e8c35a369d0db40a0/fonttools-4.62.0-cp312-cp312-win32.whl", hash = "sha256:37a73e5e38fd05c637daede6ffed5f3496096be7df6e4a3198d32af038f87527", size = 2281060, upload-time = "2026-03-09T16:49:04.385Z" }, + { url = "https://files.pythonhosted.org/packages/cd/06/cc96468781a4dc8ae2f14f16f32b32f69bde18cb9384aad27ccc7adf76f7/fonttools-4.62.0-cp312-cp312-win_amd64.whl", hash = "sha256:658ab837c878c4d2a652fcbb319547ea41693890e6434cf619e66f79387af3b8", size = 2331193, upload-time = "2026-03-09T16:49:06.598Z" }, + { url = "https://files.pythonhosted.org/packages/82/c7/985c1670aa6d82ef270f04cde11394c168f2002700353bd2bde405e59b8f/fonttools-4.62.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:274c8b8a87e439faf565d3bcd3f9f9e31bca7740755776a4a90a4bfeaa722efa", size = 2864929, upload-time = "2026-03-09T16:49:09.331Z" }, + { url = "https://files.pythonhosted.org/packages/c1/dc/c409c8ceec0d3119e9ab0b7b1a2e3c76d1f4d66e4a9db5c59e6b7652e7df/fonttools-4.62.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:93e27131a5a0ae82aaadcffe309b1bae195f6711689722af026862bede05c07c", size = 2412586, upload-time = "2026-03-09T16:49:11.378Z" }, + { url = "https://files.pythonhosted.org/packages/5f/ac/8e300dbf7b4d135287c261ffd92ede02d9f48f0d2db14665fbc8b059588a/fonttools-4.62.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:83c6524c5b93bad9c2939d88e619fedc62e913c19e673f25d5ab74e7a5d074e5", size = 5013708, upload-time = "2026-03-09T16:49:14.063Z" }, + { url = "https://files.pythonhosted.org/packages/fb/bc/60d93477b653eeb1ddf5f9ec34be689b79234d82dbdded269ac0252715b8/fonttools-4.62.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:106aec9226f9498fc5345125ff7200842c01eda273ae038f5049b0916907acee", size = 4964355, upload-time = "2026-03-09T16:49:16.515Z" }, + { url = "https://files.pythonhosted.org/packages/cb/eb/6dc62bcc3c3598c28a3ecb77e69018869c3e109bd83031d4973c059d318b/fonttools-4.62.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:15d86b96c79013320f13bc1b15f94789edb376c0a2d22fb6088f33637e8dfcbc", size = 4953472, upload-time = "2026-03-09T16:49:18.494Z" }, + { url = "https://files.pythonhosted.org/packages/82/b3/3af7592d9b254b7b7fec018135f8776bfa0d1ad335476c2791b1334dc5e4/fonttools-4.62.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4f16c07e5250d5d71d0f990a59460bc5620c3cc456121f2cfb5b60475699905f", size = 5094701, upload-time = "2026-03-09T16:49:21.67Z" }, + { url = "https://files.pythonhosted.org/packages/31/3d/976645583ab567d3ee75ff87b33aa1330fa2baeeeae5fc46210b4274dd45/fonttools-4.62.0-cp313-cp313-win32.whl", hash = "sha256:d31558890f3fa00d4f937d12708f90c7c142c803c23eaeb395a71f987a77ebe3", size = 2279710, upload-time = "2026-03-09T16:49:23.812Z" }, + { url = "https://files.pythonhosted.org/packages/f5/7a/e25245a30457595740041dba9d0ea8ec1b2517f2f1a6a741f15eba1a4edc/fonttools-4.62.0-cp313-cp313-win_amd64.whl", hash = "sha256:6826a5aa53fb6def8a66bf423939745f415546c4e92478a7c531b8b6282b6c3b", size = 2330291, upload-time = "2026-03-09T16:49:26.237Z" }, + { url = "https://files.pythonhosted.org/packages/1a/64/61f69298aa6e7c363dcf00dd6371a654676900abe27d1effd1a74b43e5d0/fonttools-4.62.0-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:4fa5a9c716e2f75ef34b5a5c2ca0ee4848d795daa7e6792bf30fd4abf8993449", size = 2864222, upload-time = "2026-03-09T16:49:28.285Z" }, + { url = "https://files.pythonhosted.org/packages/c6/57/6b08756fe4455336b1fe160ab3c11fccc90768ccb6ee03fb0b45851aace4/fonttools-4.62.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:625f5cbeb0b8f4e42343eaeb4bc2786718ddd84760a2f5e55fdd3db049047c00", size = 2410674, upload-time = "2026-03-09T16:49:30.504Z" }, + { url = "https://files.pythonhosted.org/packages/6f/86/db65b63bb1b824b63e602e9be21b18741ddc99bcf5a7850f9181159ae107/fonttools-4.62.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6247e58b96b982709cd569a91a2ba935d406dccf17b6aa615afaed37ac3856aa", size = 4999387, upload-time = "2026-03-09T16:49:32.593Z" }, + { url = "https://files.pythonhosted.org/packages/86/c8/c6669e42d2f4efd60d38a3252cebbb28851f968890efb2b9b15f9d1092b0/fonttools-4.62.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:840632ea9c1eab7b7f01c369e408c0721c287dfd7500ab937398430689852fd1", size = 4912506, upload-time = "2026-03-09T16:49:34.927Z" }, + { url = "https://files.pythonhosted.org/packages/2e/49/0ae552aa098edd0ec548413fbf818f52ceb70535016215094a5ce9bf8f70/fonttools-4.62.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:28a9ea2a7467a816d1bec22658b0cce4443ac60abac3e293bdee78beb74588f3", size = 4951202, upload-time = "2026-03-09T16:49:37.1Z" }, + { url = "https://files.pythonhosted.org/packages/71/65/ae38fc8a4cea6f162d74cf11f58e9aeef1baa7d0e3d1376dabd336c129e5/fonttools-4.62.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5ae611294f768d413949fd12693a8cba0e6332fbc1e07aba60121be35eac68d0", size = 5060758, upload-time = "2026-03-09T16:49:39.464Z" }, + { url = "https://files.pythonhosted.org/packages/db/3d/bb797496f35c60544cd5af71ffa5aad62df14ef7286908d204cb5c5096fe/fonttools-4.62.0-cp314-cp314-win32.whl", hash = "sha256:273acb61f316d07570a80ed5ff0a14a23700eedbec0ad968b949abaa4d3f6bb5", size = 2283496, upload-time = "2026-03-09T16:49:42.448Z" }, + { url = "https://files.pythonhosted.org/packages/2e/9f/91081ffe5881253177c175749cce5841f5ec6e931f5d52f4a817207b7429/fonttools-4.62.0-cp314-cp314-win_amd64.whl", hash = "sha256:a5f974006d14f735c6c878fc4b117ad031dc93638ddcc450ca69f8fd64d5e104", size = 2335426, upload-time = "2026-03-09T16:49:44.228Z" }, + { url = "https://files.pythonhosted.org/packages/f8/65/f47f9b3db1ec156a1f222f1089ba076b2cc9ee1d024a8b0a60c54258517e/fonttools-4.62.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:0361a7d41d86937f1f752717c19f719d0fde064d3011038f9f19bdf5fc2f5c95", size = 2947079, upload-time = "2026-03-09T16:49:46.471Z" }, + { url = "https://files.pythonhosted.org/packages/52/73/bc62e5058a0c22cf02b1e0169ef0c3ca6c3247216d719f95bead3c05a991/fonttools-4.62.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:d4108c12773b3c97aa592311557c405d5b4fc03db2b969ed928fcf68e7b3c887", size = 2448802, upload-time = "2026-03-09T16:49:48.328Z" }, + { url = "https://files.pythonhosted.org/packages/2b/df/bfaa0e845884935355670e6e68f137185ab87295f8bc838db575e4a66064/fonttools-4.62.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b448075f32708e8fb377fe7687f769a5f51a027172c591ba9a58693631b077a8", size = 5137378, upload-time = "2026-03-09T16:49:50.223Z" }, + { url = "https://files.pythonhosted.org/packages/32/32/04f616979a18b48b52e634988b93d847b6346260faf85ecccaf7e2e9057f/fonttools-4.62.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e5f1fa8cc9f1a56a3e33ee6b954d6d9235e6b9d11eb7a6c9dfe2c2f829dc24db", size = 4920714, upload-time = "2026-03-09T16:49:53.172Z" }, + { url = "https://files.pythonhosted.org/packages/3b/2e/274e16689c1dfee5c68302cd7c444213cfddd23cf4620374419625037ec6/fonttools-4.62.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:f8c8ea812f82db1e884b9cdb663080453e28f0f9a1f5027a5adb59c4cc8d38d1", size = 5016012, upload-time = "2026-03-09T16:49:55.762Z" }, + { url = "https://files.pythonhosted.org/packages/7f/0c/b08117270626e7117ac2f89d732fdd4386ec37d2ab3a944462d29e6f89a1/fonttools-4.62.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:03c6068adfdc67c565d217e92386b1cdd951abd4240d65180cec62fa74ba31b2", size = 5042766, upload-time = "2026-03-09T16:49:57.726Z" }, + { url = "https://files.pythonhosted.org/packages/11/83/a48b73e54efa272ee65315a6331b30a9b3a98733310bc11402606809c50e/fonttools-4.62.0-cp314-cp314t-win32.whl", hash = "sha256:d28d5baacb0017d384df14722a63abe6e0230d8ce642b1615a27d78ffe3bc983", size = 2347785, upload-time = "2026-03-09T16:49:59.698Z" }, + { url = "https://files.pythonhosted.org/packages/f8/27/c67eab6dc3525bdc39586511b1b3d7161e972dacc0f17476dbaf932e708b/fonttools-4.62.0-cp314-cp314t-win_amd64.whl", hash = "sha256:3f9e20c4618f1e04190c802acae6dc337cb6db9fa61e492fd97cd5c5a9ff6d07", size = 2413914, upload-time = "2026-03-09T16:50:02.251Z" }, + { url = "https://files.pythonhosted.org/packages/9c/57/c2487c281dde03abb2dec244fd67059b8d118bd30a653cbf69e94084cb23/fonttools-4.62.0-py3-none-any.whl", hash = "sha256:75064f19a10c50c74b336aa5ebe7b1f89fd0fb5255807bfd4b0c6317098f4af3", size = 1152427, upload-time = "2026-03-09T16:50:04.074Z" }, ] [[package]] @@ -1323,11 +1323,11 @@ name = "google-api-core" version = "2.30.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "google-auth" }, - { name = "googleapis-common-protos" }, - { name = "proto-plus" }, - { name = "protobuf" }, - { name = "requests" }, + { name = "google-auth", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "googleapis-common-protos", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "proto-plus", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "protobuf", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "requests", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/22/98/586ec94553b569080caef635f98a3723db36a38eac0e3d7eb3ea9d2e4b9a/google_api_core-2.30.0.tar.gz", hash = "sha256:02edfa9fab31e17fc0befb5f161b3bf93c9096d99aed584625f38065c511ad9b", size = 176959, upload-time = "2026-02-18T20:28:11.926Z" } wheels = [ @@ -1336,15 +1336,16 @@ wheels = [ [[package]] name = "google-auth" -version = "2.49.1" +version = "2.49.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "cryptography" }, - { name = "pyasn1-modules" }, + { name = "cryptography", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "pyasn1-modules", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "rsa", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ea/80/6a696a07d3d3b0a92488933532f03dbefa4a24ab80fb231395b9a2a1be77/google_auth-2.49.1.tar.gz", hash = "sha256:16d40da1c3c5a0533f57d268fe72e0ebb0ae1cc3b567024122651c045d879b64", size = 333825, upload-time = "2026-03-12T19:30:58.135Z" } +sdist = { url = "https://files.pythonhosted.org/packages/7d/59/7371175bfd949abfb1170aa076352131d7281bd9449c0f978604fc4431c3/google_auth-2.49.0.tar.gz", hash = "sha256:9cc2d9259d3700d7a257681f81052db6737495a1a46b610597f4b8bafe5286ae", size = 333444, upload-time = "2026-03-06T21:53:06.07Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e9/eb/c6c2478d8a8d633460be40e2a8a6f8f429171997a35a96f81d3b680dec83/google_auth-2.49.1-py3-none-any.whl", hash = "sha256:195ebe3dca18eddd1b3db5edc5189b76c13e96f29e73043b923ebcf3f1a860f7", size = 240737, upload-time = "2026-03-12T19:30:53.159Z" }, + { url = "https://files.pythonhosted.org/packages/37/45/de64b823b639103de4b63dd193480dce99526bd36be6530c2dba85bf7817/google_auth-2.49.0-py3-none-any.whl", hash = "sha256:f893ef7307f19cf53700b7e2f61b5a6affe3aa0edf9943b13788920ab92d8d87", size = 240676, upload-time = "2026-03-06T21:52:38.304Z" }, ] [[package]] @@ -1352,7 +1353,7 @@ name = "googleapis-common-protos" version = "1.73.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "protobuf" }, + { name = "protobuf", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/99/96/a0205167fa0154f4a542fd6925bdc63d039d88dab3588b875078107e6f06/googleapis_common_protos-1.73.0.tar.gz", hash = "sha256:778d07cd4fbeff84c6f7c72102f0daf98fa2bfd3fa8bea426edc545588da0b5a", size = 147323, upload-time = "2026-03-06T21:53:09.727Z" } wheels = [ @@ -1507,34 +1508,34 @@ wheels = [ [[package]] name = "hf-xet" -version = "1.4.2" +version = "1.4.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/09/08/23c84a26716382c89151b5b447b4beb19e3345f3a93d3b73009a71a57ad3/hf_xet-1.4.2.tar.gz", hash = "sha256:b7457b6b482d9e0743bd116363239b1fa904a5e65deede350fbc0c4ea67c71ea", size = 672357, upload-time = "2026-03-13T06:58:51.077Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/18/06/e8cf74c3c48e5485c7acc5a990d0d8516cdfb5fdf80f799174f1287cc1b5/hf_xet-1.4.2-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:ac8202ae1e664b2c15cdfc7298cbb25e80301ae596d602ef7870099a126fcad4", size = 3796125, upload-time = "2026-03-13T06:58:33.177Z" }, - { url = "https://files.pythonhosted.org/packages/66/d4/b73ebab01cbf60777323b7de9ef05550790451eb5172a220d6b9845385ec/hf_xet-1.4.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:6d2f8ee39fa9fba9af929f8c0d0482f8ee6e209179ad14a909b6ad78ffcb7c81", size = 3555985, upload-time = "2026-03-13T06:58:31.797Z" }, - { url = "https://files.pythonhosted.org/packages/ff/e7/ded6d1bd041c3f2bca9e913a0091adfe32371988e047dd3a68a2463c15a2/hf_xet-1.4.2-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4642a6cf249c09da8c1f87fe50b24b2a3450b235bf8adb55700b52f0ea6e2eb6", size = 4212085, upload-time = "2026-03-13T06:58:24.323Z" }, - { url = "https://files.pythonhosted.org/packages/97/c1/a0a44d1f98934f7bdf17f7a915b934f9fca44bb826628c553589900f6df8/hf_xet-1.4.2-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:769431385e746c92dc05492dde6f687d304584b89c33d79def8367ace06cb555", size = 3988266, upload-time = "2026-03-13T06:58:22.887Z" }, - { url = "https://files.pythonhosted.org/packages/7a/82/be713b439060e7d1f1d93543c8053d4ef2fe7e6922c5b31642eaa26f3c4b/hf_xet-1.4.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:c9dd1c1bc4cc56168f81939b0e05b4c36dd2d28c13dc1364b17af89aa0082496", size = 4188513, upload-time = "2026-03-13T06:58:40.858Z" }, - { url = "https://files.pythonhosted.org/packages/21/a6/cbd4188b22abd80ebd0edbb2b3e87f2633e958983519980815fb8314eae5/hf_xet-1.4.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:fca58a2ae4e6f6755cc971ac6fcdf777ea9284d7e540e350bb000813b9a3008d", size = 4428287, upload-time = "2026-03-13T06:58:42.601Z" }, - { url = "https://files.pythonhosted.org/packages/b2/4e/84e45b25e2e3e903ed3db68d7eafa96dae9a1d1f6d0e7fc85120347a852f/hf_xet-1.4.2-cp313-cp313t-win_amd64.whl", hash = "sha256:163aab46854ccae0ab6a786f8edecbbfbaa38fcaa0184db6feceebf7000c93c0", size = 3665574, upload-time = "2026-03-13T06:58:53.881Z" }, - { url = "https://files.pythonhosted.org/packages/ee/71/c5ac2b9a7ae39c14e91973035286e73911c31980fe44e7b1d03730c00adc/hf_xet-1.4.2-cp313-cp313t-win_arm64.whl", hash = "sha256:09b138422ecbe50fd0c84d4da5ff537d27d487d3607183cd10e3e53f05188e82", size = 3528760, upload-time = "2026-03-13T06:58:52.187Z" }, - { url = "https://files.pythonhosted.org/packages/1e/0f/fcd2504015eab26358d8f0f232a1aed6b8d363a011adef83fe130bff88f7/hf_xet-1.4.2-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:949dcf88b484bb9d9276ca83f6599e4aa03d493c08fc168c124ad10b2e6f75d7", size = 3796493, upload-time = "2026-03-13T06:58:39.267Z" }, - { url = "https://files.pythonhosted.org/packages/82/56/19c25105ff81731ca6d55a188b5de2aa99d7a2644c7aa9de1810d5d3b726/hf_xet-1.4.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:41659966020d59eb9559c57de2cde8128b706a26a64c60f0531fa2318f409418", size = 3555797, upload-time = "2026-03-13T06:58:37.546Z" }, - { url = "https://files.pythonhosted.org/packages/bf/e3/8933c073186849b5e06762aa89847991d913d10a95d1603eb7f2c3834086/hf_xet-1.4.2-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5c588e21d80010119458dd5d02a69093f0d115d84e3467efe71ffb2c67c19146", size = 4212127, upload-time = "2026-03-13T06:58:30.539Z" }, - { url = "https://files.pythonhosted.org/packages/eb/01/f89ebba4e369b4ed699dcb60d3152753870996f41c6d22d3d7cac01310e1/hf_xet-1.4.2-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:a296744d771a8621ad1d50c098d7ab975d599800dae6d48528ba3944e5001ba0", size = 3987788, upload-time = "2026-03-13T06:58:29.139Z" }, - { url = "https://files.pythonhosted.org/packages/84/4d/8a53e5ffbc2cc33bbf755382ac1552c6d9af13f623ed125fe67cc3e6772f/hf_xet-1.4.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:f563f7efe49588b7d0629d18d36f46d1658fe7e08dce3fa3d6526e1c98315e2d", size = 4188315, upload-time = "2026-03-13T06:58:48.017Z" }, - { url = "https://files.pythonhosted.org/packages/d1/b8/b7a1c1b5592254bd67050632ebbc1b42cc48588bf4757cb03c2ef87e704a/hf_xet-1.4.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5b2e0132c56d7ee1bf55bdb638c4b62e7106f6ac74f0b786fed499d5548c5570", size = 4428306, upload-time = "2026-03-13T06:58:49.502Z" }, - { url = "https://files.pythonhosted.org/packages/a0/0c/40779e45b20e11c7c5821a94135e0207080d6b3d76e7b78ccb413c6f839b/hf_xet-1.4.2-cp314-cp314t-win_amd64.whl", hash = "sha256:2f45c712c2fa1215713db10df6ac84b49d0e1c393465440e9cb1de73ecf7bbf6", size = 3665826, upload-time = "2026-03-13T06:58:59.88Z" }, - { url = "https://files.pythonhosted.org/packages/51/4c/e2688c8ad1760d7c30f7c429c79f35f825932581bc7c9ec811436d2f21a0/hf_xet-1.4.2-cp314-cp314t-win_arm64.whl", hash = "sha256:6d53df40616f7168abfccff100d232e9d460583b9d86fa4912c24845f192f2b8", size = 3529113, upload-time = "2026-03-13T06:58:58.491Z" }, - { url = "https://files.pythonhosted.org/packages/b4/86/b40b83a2ff03ef05c4478d2672b1fc2b9683ff870e2b25f4f3af240f2e7b/hf_xet-1.4.2-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:71f02d6e4cdd07f344f6844845d78518cc7186bd2bc52d37c3b73dc26a3b0bc5", size = 3800339, upload-time = "2026-03-13T06:58:36.245Z" }, - { url = "https://files.pythonhosted.org/packages/64/2e/af4475c32b4378b0e92a587adb1aa3ec53e3450fd3e5fe0372a874531c00/hf_xet-1.4.2-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:e9b38d876e94d4bdcf650778d6ebbaa791dd28de08db9736c43faff06ede1b5a", size = 3559664, upload-time = "2026-03-13T06:58:34.787Z" }, - { url = "https://files.pythonhosted.org/packages/3c/4c/781267da3188db679e601de18112021a5cb16506fe86b246e22c5401a9c4/hf_xet-1.4.2-cp37-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:77e8c180b7ef12d8a96739a4e1e558847002afe9ea63b6f6358b2271a8bdda1c", size = 4217422, upload-time = "2026-03-13T06:58:27.472Z" }, - { url = "https://files.pythonhosted.org/packages/68/47/d6cf4a39ecf6c7705f887a46f6ef5c8455b44ad9eb0d391aa7e8a2ff7fea/hf_xet-1.4.2-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:c3b3c6a882016b94b6c210957502ff7877802d0dbda8ad142c8595db8b944271", size = 3992847, upload-time = "2026-03-13T06:58:25.989Z" }, - { url = "https://files.pythonhosted.org/packages/2d/ef/e80815061abff54697239803948abc665c6b1d237102c174f4f7a9a5ffc5/hf_xet-1.4.2-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:9d9a634cc929cfbaf2e1a50c0e532ae8c78fa98618426769480c58501e8c8ac2", size = 4193843, upload-time = "2026-03-13T06:58:44.59Z" }, - { url = "https://files.pythonhosted.org/packages/54/75/07f6aa680575d9646c4167db6407c41340cbe2357f5654c4e72a1b01ca14/hf_xet-1.4.2-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:6b0932eb8b10317ea78b7da6bab172b17be03bbcd7809383d8d5abd6a2233e04", size = 4432751, upload-time = "2026-03-13T06:58:46.533Z" }, - { url = "https://files.pythonhosted.org/packages/cd/71/193eabd7e7d4b903c4aa983a215509c6114915a5a237525ec562baddb868/hf_xet-1.4.2-cp37-abi3-win_amd64.whl", hash = "sha256:ad185719fb2e8ac26f88c8100562dbf9dbdcc3d9d2add00faa94b5f106aea53f", size = 3671149, upload-time = "2026-03-13T06:58:57.07Z" }, - { url = "https://files.pythonhosted.org/packages/b4/7e/ccf239da366b37ba7f0b36095450efae4a64980bdc7ec2f51354205fdf39/hf_xet-1.4.2-cp37-abi3-win_arm64.whl", hash = "sha256:32c012286b581f783653e718c1862aea5b9eb140631685bb0c5e7012c8719a87", size = 3533426, upload-time = "2026-03-13T06:58:55.46Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/68/01/928fd82663fb0ab455551a178303a2960e65029da66b21974594f3a20a94/hf_xet-1.4.0.tar.gz", hash = "sha256:48e6ba7422b0885c9bbd8ac8fdf5c4e1306c3499b82d489944609cc4eae8ecbd", size = 660350, upload-time = "2026-03-11T18:50:03.354Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/05/4b/2351e30dddc6f3b47b3da0a0693ec1e82f8303b1a712faa299cf3552002b/hf_xet-1.4.0-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:76725fcbc5f59b23ac778f097d3029d6623e3cf6f4057d99d1fce1a7e3cff8fc", size = 3796397, upload-time = "2026-03-11T18:49:47.382Z" }, + { url = "https://files.pythonhosted.org/packages/48/3d/3db90ec0afb4e26e3330b1346b89fe0e9a3b7bfc2d6a2b2262787790d25f/hf_xet-1.4.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:76f1f73bee81a6e6f608b583908aa24c50004965358ac92c1dc01080a21bcd09", size = 3556235, upload-time = "2026-03-11T18:49:45.785Z" }, + { url = "https://files.pythonhosted.org/packages/57/6e/2a662af2cbc6c0a64ebe9fcdb8faf05b5205753d45a75a3011bb2209d0b4/hf_xet-1.4.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1818c2e5d6f15354c595d5111c6eb0e5a30a6c5c1a43eeaec20f19607cff0b34", size = 4213145, upload-time = "2026-03-11T18:49:38.009Z" }, + { url = "https://files.pythonhosted.org/packages/b9/4a/47c129affb540767e0e3e101039a95f4a73a292ec689c26e8f0c5b633f9d/hf_xet-1.4.0-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:70764d295f485db9cc9a6af76634ea00ec4f96311be7485f8f2b6144739b4ccf", size = 3991951, upload-time = "2026-03-11T18:49:36.396Z" }, + { url = "https://files.pythonhosted.org/packages/76/81/ec516cfc6281cfeef027b0919166b2fe11ab61fbe6131a2c43fafbed8b68/hf_xet-1.4.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9d3bd2a1e289f772c715ca88cdca8ceb3d8b5c9186534d5925410e531d849a3e", size = 4193205, upload-time = "2026-03-11T18:49:54.415Z" }, + { url = "https://files.pythonhosted.org/packages/49/48/0945b5e542ed6c6ce758b589b27895a449deab630dfcdee5a6ee0f699d21/hf_xet-1.4.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:06da3797f1fdd9a8f8dbc8c1bddfa0b914789b14580c375d29c32ee35c2c66ca", size = 4431022, upload-time = "2026-03-11T18:49:55.677Z" }, + { url = "https://files.pythonhosted.org/packages/e8/ad/a4859c55ab4b67a4fde2849be8bde81917f54062050419b821071f199a9c/hf_xet-1.4.0-cp313-cp313t-win_amd64.whl", hash = "sha256:30b9d8f384ccec848124d51d883e91f3c88d430589e02a7b6d867730ab8d53ac", size = 3674977, upload-time = "2026-03-11T18:50:06.369Z" }, + { url = "https://files.pythonhosted.org/packages/4b/17/5bf3791e3a53e597913c2a775a48a98aaded9c2ddb5d1afaedabb55e2ed8/hf_xet-1.4.0-cp313-cp313t-win_arm64.whl", hash = "sha256:07ffdbf7568fa3245b24d949f0f3790b5276fb7293a5554ac4ec02e5f7e2b38d", size = 3536778, upload-time = "2026-03-11T18:50:04.974Z" }, + { url = "https://files.pythonhosted.org/packages/3f/a1/05a7f9d6069bf78405d3fc2464b6c76b167128501e13b4f1d6266e1d1f54/hf_xet-1.4.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:e2731044f3a18442f9f7a3dcf03b96af13dee311f03846a1df1f0553a3ea0fc6", size = 3796727, upload-time = "2026-03-11T18:49:52.889Z" }, + { url = "https://files.pythonhosted.org/packages/ac/8a/67abc642c2b32efcb7a257cdad8555c2904e23f18a1b4fec3aef1ebfe0fc/hf_xet-1.4.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:b6f3729335fbc4baef60fe14fe32ef13ac9d377bdc898148c541e20c6056b504", size = 3555869, upload-time = "2026-03-11T18:49:51.313Z" }, + { url = "https://files.pythonhosted.org/packages/19/3d/4765367c64ee70db15fa771d5b94bf12540b85076a1d3210ebbfec42d477/hf_xet-1.4.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:9c0c9f052738a024073d332c573275c8e33697a3ef3f5dd2fb4ef98216e1e74a", size = 4212980, upload-time = "2026-03-11T18:49:44.21Z" }, + { url = "https://files.pythonhosted.org/packages/0e/bf/6ad99ee0e7ca2318f912a87318e493d82d8f9aace6be81f774bd14b996df/hf_xet-1.4.0-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:f44b2324be75bfa399735996ac299fd478684c48ce47d12a42b5f24b1a99ccb8", size = 3991136, upload-time = "2026-03-11T18:49:42.512Z" }, + { url = "https://files.pythonhosted.org/packages/50/aa/932e25c69699076088f57e3c14f83ccae87bac25e755994f3362acc908d5/hf_xet-1.4.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:01de78b1ceddf8b38da001f7cc728b3bc3eb956948b18e8a1997ad6fc80fbe9d", size = 4192676, upload-time = "2026-03-11T18:50:00.216Z" }, + { url = "https://files.pythonhosted.org/packages/5c/0a/5e41339a294fd3450948989a47ecba9824d5bc1950cf767f928ecaf53a55/hf_xet-1.4.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6cac8616e7a974105c3494735313f5ab0fb79b5accadec1a7a992859a15536a9", size = 4430729, upload-time = "2026-03-11T18:50:01.923Z" }, + { url = "https://files.pythonhosted.org/packages/9c/c1/c3d8ed9b7118e9166b0cf71dfd501da82f1abe306387e34e0f3ee59553ec/hf_xet-1.4.0-cp314-cp314t-win_amd64.whl", hash = "sha256:3a5d9cb25095ceb3beab4843ae2d1b3e5746371ddbf2e5849f7be6a7d6f44df4", size = 3674989, upload-time = "2026-03-11T18:50:12.633Z" }, + { url = "https://files.pythonhosted.org/packages/65/bc/ea26cf774063cb09d7aaaa6cba9d341fb72b42ea99b8a94ca254dbafbbb0/hf_xet-1.4.0-cp314-cp314t-win_arm64.whl", hash = "sha256:9b777674499dc037317db372c90a2dd91329b5f1ee93c645bb89155bb974f5bf", size = 3536805, upload-time = "2026-03-11T18:50:11.082Z" }, + { url = "https://files.pythonhosted.org/packages/9f/f9/a0b01945726aea81d2f213457cd5f5102a51e6fd1ca9f9769f561fb57501/hf_xet-1.4.0-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:981d2b5222c3baadf9567c135cf1d1073786f546b7745686978d46b5df179e16", size = 3799223, upload-time = "2026-03-11T18:49:49.884Z" }, + { url = "https://files.pythonhosted.org/packages/5d/30/ee62b0c00412f49a7e6f509f0104ee8808692278d247234336df48029349/hf_xet-1.4.0-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:cc8bd050349d0d7995ce7b3a3a18732a2a8062ce118a82431602088abb373428", size = 3560682, upload-time = "2026-03-11T18:49:48.633Z" }, + { url = "https://files.pythonhosted.org/packages/93/d0/0fe5c44dbced465a651a03212e1135d0d7f95d19faada692920cb56f8e38/hf_xet-1.4.0-cp37-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5d0c38d2a280d814280b8c15eead4a43c9781e7bf6fc37843cffab06dcdc76b9", size = 4218323, upload-time = "2026-03-11T18:49:40.921Z" }, + { url = "https://files.pythonhosted.org/packages/73/df/7b3c99a4e50442039eae498e5c23db634538eb3e02214109880cf1165d4c/hf_xet-1.4.0-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:6a883f0250682ea888a1bd0af0631feda377e59ad7aae6fb75860ecee7ae0f93", size = 3997156, upload-time = "2026-03-11T18:49:39.634Z" }, + { url = "https://files.pythonhosted.org/packages/a9/26/47dfedf271c21d95346660ae1698e7ece5ab10791fa6c4f20c59f3713083/hf_xet-1.4.0-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:99e1d9255fe8ecdf57149bb0543d49e7b7bd8d491ddf431eb57e114253274df5", size = 4199052, upload-time = "2026-03-11T18:49:57.097Z" }, + { url = "https://files.pythonhosted.org/packages/8d/c0/346b9aad1474e881e65f998d5c1981695f0af045bc7a99204d9d86759a89/hf_xet-1.4.0-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b25f06ce42bd2d5f2e79d4a2d72f783d3ac91827c80d34a38cf8e5290dd717b0", size = 4434346, upload-time = "2026-03-11T18:49:58.67Z" }, + { url = "https://files.pythonhosted.org/packages/2e/d6/88ce9d6caa397c3b935263d5bcbe3ebf6c443f7c76098b8c523d206116b9/hf_xet-1.4.0-cp37-abi3-win_amd64.whl", hash = "sha256:8d6d7816d01e0fa33f315c8ca21b05eca0ce4cdc314f13b81d953e46cc6db11d", size = 3678921, upload-time = "2026-03-11T18:50:09.496Z" }, + { url = "https://files.pythonhosted.org/packages/65/eb/17d99ed253b28a9550ca479867c66a8af4c9bcd8cdc9a26b0c8007c2000a/hf_xet-1.4.0-cp37-abi3-win_arm64.whl", hash = "sha256:cb8d9549122b5b42f34b23b14c6b662a88a586a919d418c774d8dbbc4b3ce2aa", size = 3541054, upload-time = "2026-03-11T18:50:07.963Z" }, ] [[package]] @@ -1542,14 +1543,14 @@ name = "huggingface-hub" version = "0.34.6" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "filelock" }, - { name = "fsspec" }, - { name = "hf-xet", marker = "platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'arm64' or platform_machine == 'x86_64'" }, - { name = "packaging" }, - { name = "pyyaml" }, - { name = "requests" }, - { name = "tqdm" }, - { name = "typing-extensions" }, + { name = "filelock", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "fsspec", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "hf-xet", marker = "(python_full_version != '3.13.*' and platform_machine == 'aarch64') or (python_full_version != '3.13.*' and platform_machine == 'amd64') or (python_full_version != '3.13.*' and platform_machine == 'arm64') or (python_full_version != '3.13.*' and platform_machine == 'x86_64') or (platform_machine == 'aarch64' and sys_platform != 'win32') or (platform_machine == 'amd64' and sys_platform != 'win32') or (platform_machine == 'arm64' and sys_platform != 'win32') or (platform_machine == 'x86_64' and sys_platform != 'win32')" }, + { name = "packaging", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "pyyaml", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "requests", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "tqdm", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "typing-extensions", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/53/8a/ea019110b644bfd2470fb0c5dd252bd087b5c15c9641dec9be9659ebc4b4/huggingface_hub-0.34.6.tar.gz", hash = "sha256:d0824eb012e37594357bb1790dfbe26c8f45eed7e701c1cdae02539e0c06f3f8", size = 460139, upload-time = "2025-09-16T08:10:51.142Z" } wheels = [ @@ -1682,11 +1683,11 @@ name = "ipywidgets" version = "8.1.8" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "comm" }, - { name = "ipython" }, - { name = "jupyterlab-widgets" }, - { name = "traitlets" }, - { name = "widgetsnbextension" }, + { name = "comm", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "ipython", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "jupyterlab-widgets", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "traitlets", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "widgetsnbextension", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/4c/ae/c5ce1edc1afe042eadb445e95b0671b03cee61895264357956e61c0d2ac0/ipywidgets-8.1.8.tar.gz", hash = "sha256:61f969306b95f85fba6b6986b7fe45d73124d1d9e3023a8068710d47a22ea668", size = 116739, upload-time = "2025-11-01T21:18:12.393Z" } wheels = [ @@ -1957,8 +1958,8 @@ name = "loguru" version = "0.7.3" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "colorama", marker = "sys_platform == 'win32'" }, - { name = "win32-setctime", marker = "sys_platform == 'win32'" }, + { name = "colorama", marker = "python_full_version != '3.13.*' and sys_platform == 'win32'" }, + { name = "win32-setctime", marker = "python_full_version != '3.13.*' and sys_platform == 'win32'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/3a/05/a1dae3dffd1116099471c643b8924f5aa6524411dc6c63fdae648c4f1aca/loguru-0.7.3.tar.gz", hash = "sha256:19480589e77d47b8d85b2c827ad95d49bf31b0dcde16593892eb51dd18706eb6", size = 63559, upload-time = "2024-12-06T11:20:56.608Z" } wheels = [ @@ -2973,9 +2974,9 @@ name = "opencensus" version = "0.11.4" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "google-api-core" }, - { name = "opencensus-context" }, - { name = "six" }, + { name = "google-api-core", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "opencensus-context", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "six", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/15/a7/a46dcffa1b63084f9f17fe3c8cb20724c4c8f91009fd0b2cfdb27d5d2b35/opencensus-0.11.4.tar.gz", hash = "sha256:cbef87d8b8773064ab60e5c2a1ced58bbaa38a6d052c41aec224958ce544eff2", size = 64966, upload-time = "2024-01-03T18:04:07.085Z" } wheels = [ @@ -3010,8 +3011,8 @@ name = "opentelemetry-api" version = "1.39.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "importlib-metadata" }, - { name = "typing-extensions" }, + { name = "importlib-metadata", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "typing-extensions", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/97/b9/3161be15bb8e3ad01be8be5a968a9237c3027c5be504362ff800fca3e442/opentelemetry_api-1.39.1.tar.gz", hash = "sha256:fbde8c80e1b937a2c61f20347e91c0c18a1940cecf012d62e65a7caf08967c9c", size = 65767, upload-time = "2025-12-11T13:32:39.182Z" } wheels = [ @@ -3023,7 +3024,7 @@ name = "opentelemetry-exporter-otlp-proto-common" version = "1.39.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "opentelemetry-proto" }, + { name = "opentelemetry-proto", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/e9/9d/22d241b66f7bbde88a3bfa6847a351d2c46b84de23e71222c6aae25c7050/opentelemetry_exporter_otlp_proto_common-1.39.1.tar.gz", hash = "sha256:763370d4737a59741c89a67b50f9e39271639ee4afc999dadfe768541c027464", size = 20409, upload-time = "2025-12-11T13:32:40.885Z" } wheels = [ @@ -3035,13 +3036,13 @@ name = "opentelemetry-exporter-otlp-proto-grpc" version = "1.39.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "googleapis-common-protos" }, - { name = "grpcio" }, - { name = "opentelemetry-api" }, - { name = "opentelemetry-exporter-otlp-proto-common" }, - { name = "opentelemetry-proto" }, - { name = "opentelemetry-sdk" }, - { name = "typing-extensions" }, + { name = "googleapis-common-protos", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "grpcio", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "opentelemetry-api", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "opentelemetry-exporter-otlp-proto-common", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "opentelemetry-proto", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "opentelemetry-sdk", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "typing-extensions", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/53/48/b329fed2c610c2c32c9366d9dc597202c9d1e58e631c137ba15248d8850f/opentelemetry_exporter_otlp_proto_grpc-1.39.1.tar.gz", hash = "sha256:772eb1c9287485d625e4dbe9c879898e5253fea111d9181140f51291b5fec3ad", size = 24650, upload-time = "2025-12-11T13:32:41.429Z" } wheels = [ @@ -3053,9 +3054,9 @@ name = "opentelemetry-exporter-prometheus" version = "0.60b1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "opentelemetry-api" }, - { name = "opentelemetry-sdk" }, - { name = "prometheus-client" }, + { name = "opentelemetry-api", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "opentelemetry-sdk", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "prometheus-client", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/14/39/7dafa6fff210737267bed35a8855b6ac7399b9e582b8cf1f25f842517012/opentelemetry_exporter_prometheus-0.60b1.tar.gz", hash = "sha256:a4011b46906323f71724649d301b4dc188aaa068852e814f4df38cc76eac616b", size = 14976, upload-time = "2025-12-11T13:32:42.944Z" } wheels = [ @@ -3067,10 +3068,10 @@ name = "opentelemetry-instrumentation" version = "0.60b1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "opentelemetry-api" }, - { name = "opentelemetry-semantic-conventions" }, - { name = "packaging" }, - { name = "wrapt" }, + { name = "opentelemetry-api", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "opentelemetry-semantic-conventions", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "packaging", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "wrapt", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/41/0f/7e6b713ac117c1f5e4e3300748af699b9902a2e5e34c9cf443dde25a01fa/opentelemetry_instrumentation-0.60b1.tar.gz", hash = "sha256:57ddc7974c6eb35865af0426d1a17132b88b2ed8586897fee187fd5b8944bd6a", size = 31706, upload-time = "2025-12-11T13:36:42.515Z" } wheels = [ @@ -3082,10 +3083,10 @@ name = "opentelemetry-instrumentation-requests" version = "0.60b1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "opentelemetry-api" }, - { name = "opentelemetry-instrumentation" }, - { name = "opentelemetry-semantic-conventions" }, - { name = "opentelemetry-util-http" }, + { name = "opentelemetry-api", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "opentelemetry-instrumentation", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "opentelemetry-semantic-conventions", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "opentelemetry-util-http", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/9d/4a/bb9d47d7424fc33aeba75275256ae6e6031f44b6a9a3f778d611c0c3ac27/opentelemetry_instrumentation_requests-0.60b1.tar.gz", hash = "sha256:9a1063c16c44a3ba6e81870c4fa42a0fac3ecef5a4d60a11d0976eec9046f3d4", size = 16366, upload-time = "2025-12-11T13:37:12.456Z" } wheels = [ @@ -3097,7 +3098,7 @@ name = "opentelemetry-proto" version = "1.39.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "protobuf" }, + { name = "protobuf", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/49/1d/f25d76d8260c156c40c97c9ed4511ec0f9ce353f8108ca6e7561f82a06b2/opentelemetry_proto-1.39.1.tar.gz", hash = "sha256:6c8e05144fc0d3ed4d22c2289c6b126e03bcd0e6a7da0f16cedd2e1c2772e2c8", size = 46152, upload-time = "2025-12-11T13:32:48.681Z" } wheels = [ @@ -3109,9 +3110,9 @@ name = "opentelemetry-sdk" version = "1.39.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "opentelemetry-api" }, - { name = "opentelemetry-semantic-conventions" }, - { name = "typing-extensions" }, + { name = "opentelemetry-api", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "opentelemetry-semantic-conventions", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "typing-extensions", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/eb/fb/c76080c9ba07e1e8235d24cdcc4d125ef7aa3edf23eb4e497c2e50889adc/opentelemetry_sdk-1.39.1.tar.gz", hash = "sha256:cf4d4563caf7bff906c9f7967e2be22d0d6b349b908be0d90fb21c8e9c995cc6", size = 171460, upload-time = "2025-12-11T13:32:49.369Z" } wheels = [ @@ -3123,8 +3124,8 @@ name = "opentelemetry-semantic-conventions" version = "0.60b1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "opentelemetry-api" }, - { name = "typing-extensions" }, + { name = "opentelemetry-api", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "typing-extensions", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/91/df/553f93ed38bf22f4b999d9be9c185adb558982214f33eae539d3b5cd0858/opentelemetry_semantic_conventions-0.60b1.tar.gz", hash = "sha256:87c228b5a0669b748c76d76df6c364c369c28f1c465e50f661e39737e84bc953", size = 137935, upload-time = "2025-12-11T13:32:50.487Z" } wheels = [ @@ -3564,7 +3565,7 @@ name = "proto-plus" version = "1.27.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "protobuf" }, + { name = "protobuf", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/3a/02/8832cde80e7380c600fbf55090b6ab7b62bd6825dbedde6d6657c15a1f8e/proto_plus-1.27.1.tar.gz", hash = "sha256:912a7460446625b792f6448bade9e55cd4e41e6ac10e27009ef71a7f317fa147", size = 56929, upload-time = "2026-02-02T17:34:49.035Z" } wheels = [ @@ -3704,7 +3705,7 @@ name = "pyasn1-modules" version = "0.4.2" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pyasn1" }, + { name = "pyasn1", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/e9/e6/78ebbb10a8c8e4b61a59249394a4a594c1a7af95593dc933a349c8d00964/pyasn1_modules-0.4.2.tar.gz", hash = "sha256:677091de870a80aae844b1ca6134f54652fa2c8c5a52aa396440ac3106e941e6", size = 307892, upload-time = "2025-03-28T02:41:22.17Z" } wheels = [ @@ -3891,14 +3892,11 @@ wheels = [ [[package]] name = "pyjwt" -version = "2.12.1" +version = "2.11.0" source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "typing-extensions", marker = "python_full_version < '3.11'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/c2/27/a3b6e5bf6ff856d2509292e95c8f57f0df7017cf5394921fc4e4ef40308a/pyjwt-2.12.1.tar.gz", hash = "sha256:c74a7a2adf861c04d002db713dd85f84beb242228e671280bf709d765b03672b", size = 102564, upload-time = "2026-03-13T19:27:37.25Z" } +sdist = { url = "https://files.pythonhosted.org/packages/5c/5a/b46fa56bf322901eee5b0454a34343cdbdae202cd421775a8ee4e42fd519/pyjwt-2.11.0.tar.gz", hash = "sha256:35f95c1f0fbe5d5ba6e43f00271c275f7a1a4db1dab27bf708073b75318ea623", size = 98019, upload-time = "2026-01-30T19:59:55.694Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e5/7a/8dd906bd22e79e47397a61742927f6747fe93242ef86645ee9092e610244/pyjwt-2.12.1-py3-none-any.whl", hash = "sha256:28ca37c070cad8ba8cd9790cd940535d40274d22f80ab87f3ac6a713e6e8454c", size = 29726, upload-time = "2026-03-13T19:27:35.677Z" }, + { url = "https://files.pythonhosted.org/packages/6f/01/c26ce75ba460d5cd503da9e13b21a33804d38c2165dec7b716d06b13010c/pyjwt-2.11.0-py3-none-any.whl", hash = "sha256:94a6bde30eb5c8e04fee991062b534071fd1439ef58d2adc9ccb823e7bcd0469", size = 28224, upload-time = "2026-01-30T19:59:54.539Z" }, ] [[package]] @@ -4180,7 +4178,7 @@ wheels = [ [[package]] name = "qiskit" -version = "2.3.1" +version = "2.3.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "dill" }, @@ -4192,15 +4190,15 @@ dependencies = [ { name = "stevedore" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f9/9a/a366dd56b6a4520e5b2856e47d573c6813b4c3f62f28969a37205fd845ab/qiskit-2.3.1.tar.gz", hash = "sha256:7b3b7e1c8a50f7f423204143a1bd9f21bf27659c57459d582eaff4035d8d7f75", size = 3909915, upload-time = "2026-03-13T00:43:03.257Z" } +sdist = { url = "https://files.pythonhosted.org/packages/13/8e/d5279454717d780f32eec4dfa6a7ef256ea7382b2f8fef2c715fc6f1180e/qiskit-2.3.0.tar.gz", hash = "sha256:e0a00c6681b8d04171c5cdb928837d992676f8aa4a07c390d446e54babaf6c1e", size = 3903621, upload-time = "2026-01-08T19:36:33.691Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/47/70/dba6afec66d2bf4df64b7059cd144bf0c775d998cb57b941d1065b331d28/qiskit-2.3.1-cp310-abi3-macosx_10_12_x86_64.whl", hash = "sha256:25a85465e8c860627e8a565cb9af824b2df1a2c42f5958b1a7b014aa085b32d6", size = 8614500, upload-time = "2026-03-13T02:30:24.247Z" }, - { url = "https://files.pythonhosted.org/packages/55/0b/47d67d58b4de120e10d49255b635429bc162a982b0cd58cf75b1a9f594fa/qiskit-2.3.1-cp310-abi3-macosx_11_0_arm64.whl", hash = "sha256:b1404b72987d0c7db32203a87565775115f6a77b2a3539d40eb1e354df6d08bb", size = 7819922, upload-time = "2026-03-13T00:42:54.205Z" }, - { url = "https://files.pythonhosted.org/packages/02/f0/2af86ce0e11b06248bc6a66550acf98c19e606cb317c27bab4fbed2ce37f/qiskit-2.3.1-cp310-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:68eec14320654065a158bf73b3d6fffaa31e865fe61b0db1510cfeeea76c87b0", size = 8176336, upload-time = "2026-03-13T00:42:56.891Z" }, - { url = "https://files.pythonhosted.org/packages/8a/fc/0bf71353c68b9090ed05e5c1d08730301c58a2b00f3001f0050f032bdcc9/qiskit-2.3.1-cp310-abi3-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:96545ad531c5e2ff6eecd348501620e0db0f3d73f49c20037ec3b5b2e9268f94", size = 8915234, upload-time = "2026-03-13T02:30:27.055Z" }, - { url = "https://files.pythonhosted.org/packages/1b/0c/19ffdb15d2e72156de406fe27cad26c6015071a385e6b48c6db87d8ce676/qiskit-2.3.1-cp310-abi3-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:a1a030b4a0cd75f3299c9866a3e9489a02078efc343abd42eec74ad2a5f2fa80", size = 8513126, upload-time = "2026-03-13T02:30:30.288Z" }, - { url = "https://files.pythonhosted.org/packages/11/06/41f4197fcb3c38e99f22f400ea25375c9057190cd094cd6c0f97be730796/qiskit-2.3.1-cp310-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:350027279bb171e9746fee5756c674872df97f4608b079129d4edb25b5bb1fdd", size = 8833222, upload-time = "2026-03-13T00:42:59.092Z" }, - { url = "https://files.pythonhosted.org/packages/a5/db/6ddc52eaf22ab1f95ee6251ff7a375c0a1a7453b5864528992303b166198/qiskit-2.3.1-cp310-abi3-win_amd64.whl", hash = "sha256:f884abd92c0173e246705f89f8b4808badaa0e1b167ed3277a3cb83c2564b4b8", size = 8639580, upload-time = "2026-03-13T00:43:01.022Z" }, + { url = "https://files.pythonhosted.org/packages/d6/79/22a6c61a94fef8eac09f968355c15c0d3b0800110152bbcf9cbed5bfc807/qiskit-2.3.0-cp310-abi3-macosx_10_12_x86_64.whl", hash = "sha256:bfeba21f216f64b051f9ac98653e9999d4c1bcb4f328aca06ad059aaef86586b", size = 8791989, upload-time = "2026-01-08T21:32:53.48Z" }, + { url = "https://files.pythonhosted.org/packages/d7/55/bb8efb2b6e46e5b8c7d147973646fa71677e63ecd2378af4db2829795be6/qiskit-2.3.0-cp310-abi3-macosx_11_0_arm64.whl", hash = "sha256:5f29f3b6a2b5738463bc667ddb2bcc79a83fb434ab9a8033487b64a399f71bef", size = 7872461, upload-time = "2026-01-08T19:36:26.458Z" }, + { url = "https://files.pythonhosted.org/packages/d1/c6/d928648d417c5c2e0c50481ef4f197f2ad8ca74d361e163e0c5d73253cbf/qiskit-2.3.0-cp310-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b437262a14ab961703153f79f38de5fde408601b0eda1f9c34b57498c912ef33", size = 8223957, upload-time = "2026-01-08T19:36:28.767Z" }, + { url = "https://files.pythonhosted.org/packages/54/76/33ee3519c3ff88b6154ccce13d24a33c0dc0fc9b22df8f216f1833cb0981/qiskit-2.3.0-cp310-abi3-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:7c413dace7a9b1d30bbbfeb2f90c4564dfcf6ed3c0744e026d4aca84f8fbd2bb", size = 9042802, upload-time = "2026-01-08T21:32:55.692Z" }, + { url = "https://files.pythonhosted.org/packages/73/9f/478788b16f653cdf151c7f2f040ba41b97e355d3bf9348ee2f0f685a5ea6/qiskit-2.3.0-cp310-abi3-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:ae0b1ec4c24ff8867599a5e8a46efaaf6d5477d1c4533427b7ae516054f52b2f", size = 8701281, upload-time = "2026-01-08T21:32:57.947Z" }, + { url = "https://files.pythonhosted.org/packages/de/22/fd8e7d4869641f60d9b7ce6d688b59520c8c8be8c8e4b51d76fb85b59f42/qiskit-2.3.0-cp310-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:24fd70ee3ac47fe029096e39b1c39abf3e7f145c723df90f9600468099c12aa4", size = 8888244, upload-time = "2026-01-08T19:36:30.259Z" }, + { url = "https://files.pythonhosted.org/packages/c3/bb/0fbcf43f9daba43f1eb31ecf7d36afcbcf705457d9df6e8e6f38f07b4851/qiskit-2.3.0-cp310-abi3-win_amd64.whl", hash = "sha256:8679a426725785701629f0af905a7a5b6bc25b0dcd7fe4f4c9f8be63d89e832c", size = 8630467, upload-time = "2026-01-08T19:36:31.958Z" }, ] [package.optional-dependencies] @@ -4208,8 +4206,8 @@ qasm3-import = [ { name = "qiskit-qasm3-import" }, ] qpy-compat = [ - { name = "symengine" }, - { name = "sympy" }, + { name = "symengine", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "sympy", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, ] [[package]] @@ -4269,9 +4267,9 @@ name = "qiskit-gym" version = "0.4.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "gymnasium" }, - { name = "qiskit" }, - { name = "twisterl" }, + { name = "gymnasium", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "qiskit", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "twisterl", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/16/95/9547510aa2bede0815a6d254f1215325abbad383f6bd85b30f718745fda0/qiskit_gym-0.4.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:e10efe4a5ee15437e28e9c76eaca8c22b68e8d25c5496e7cc56cf2c74b32aeba", size = 1089055, upload-time = "2026-02-13T16:15:49.458Z" }, @@ -4353,14 +4351,14 @@ name = "qiskit-ibm-transpiler" version = "0.18.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "backoff" }, - { name = "networkx" }, - { name = "pyyaml" }, - { name = "qiskit" }, - { name = "qiskit-gym" }, - { name = "qiskit-qasm3-import" }, - { name = "qiskit-serverless" }, - { name = "requests" }, + { name = "backoff", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "networkx", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "pyyaml", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "qiskit", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "qiskit-gym", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "qiskit-qasm3-import", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "qiskit-serverless", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "requests", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/c8/83/040e1c7a4c8f33e5c1c9c2ba3da007f9ed4b5f9774d30c2286d323fbd039/qiskit_ibm_transpiler-0.18.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:13ff3c7e79a536a824d2c108df98e9a163045abc399ca45d240a02e4b97a319b", size = 423908, upload-time = "2026-03-10T11:06:05.701Z" }, @@ -4399,25 +4397,25 @@ name = "qiskit-serverless" version = "0.30.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "aiohttp" }, - { name = "certifi" }, - { name = "cloudpickle" }, - { name = "importlib-metadata" }, - { name = "ipython" }, - { name = "ipywidgets" }, + { name = "aiohttp", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "certifi", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "cloudpickle", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "importlib-metadata", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "ipython", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "ipywidgets", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.4.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, - { name = "opentelemetry-api" }, - { name = "opentelemetry-exporter-otlp-proto-grpc" }, - { name = "opentelemetry-instrumentation-requests" }, - { name = "opentelemetry-sdk" }, - { name = "pyarrow" }, - { name = "qiskit", extra = ["qpy-compat"] }, - { name = "qiskit-ibm-runtime" }, - { name = "ray", extra = ["default"] }, - { name = "requests" }, - { name = "tqdm" }, - { name = "zipp" }, + { name = "numpy", version = "2.4.3", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and python_full_version < '3.13') or (python_full_version >= '3.11' and sys_platform != 'win32') or (python_full_version >= '3.14' and sys_platform == 'win32')" }, + { name = "opentelemetry-api", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "opentelemetry-exporter-otlp-proto-grpc", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "opentelemetry-instrumentation-requests", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "opentelemetry-sdk", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "pyarrow", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "qiskit", extra = ["qpy-compat"], marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "qiskit-ibm-runtime", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "ray", extra = ["default"], marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "requests", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "tqdm", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "zipp", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/38/5d/747b875afc82ee80df16f0084a9b145727917b52fc29f4375f09beaf7811/qiskit_serverless-0.30.0.tar.gz", hash = "sha256:d4e0a4fa14f596916a4adc86df8d5e9a9a0c75aae919eb81c3d9fbacb2e4f66e", size = 39614, upload-time = "2026-03-04T17:09:05.42Z" } wheels = [ @@ -4441,14 +4439,14 @@ name = "ray" version = "2.54.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "click" }, - { name = "filelock" }, - { name = "jsonschema" }, - { name = "msgpack" }, - { name = "packaging" }, - { name = "protobuf" }, - { name = "pyyaml" }, - { name = "requests" }, + { name = "click", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "filelock", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "jsonschema", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "msgpack", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "packaging", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "protobuf", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "pyyaml", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "requests", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/64/13/b86d791b41f33220335eba18fc4841f1ebddae41e562c6a216846404c88d/ray-2.54.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:a22937f09ee74a43171df338d84b45ef882c1c05748947ca9d5343a44d4b9379", size = 70097079, upload-time = "2026-02-18T04:04:35.409Z" }, @@ -4470,20 +4468,20 @@ wheels = [ [package.optional-dependencies] default = [ - { name = "aiohttp" }, - { name = "aiohttp-cors" }, - { name = "colorful" }, - { name = "grpcio" }, - { name = "opencensus" }, - { name = "opentelemetry-exporter-prometheus" }, - { name = "opentelemetry-proto" }, - { name = "opentelemetry-sdk" }, - { name = "prometheus-client" }, - { name = "py-spy" }, - { name = "pydantic" }, - { name = "requests" }, - { name = "smart-open" }, - { name = "virtualenv" }, + { name = "aiohttp", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "aiohttp-cors", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "colorful", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "grpcio", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "opencensus", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "opentelemetry-exporter-prometheus", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "opentelemetry-proto", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "opentelemetry-sdk", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "prometheus-client", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "py-spy", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "pydantic", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "requests", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "smart-open", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "virtualenv", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, ] [[package]] @@ -4674,6 +4672,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d1/b7/b95708304cd49b7b6f82fdd039f1748b66ec2b21d6a45180910802f1abf1/rpds_py-0.30.0-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:ac37f9f516c51e5753f27dfdef11a88330f04de2d564be3991384b2f3535d02e", size = 562191, upload-time = "2025-11-30T20:24:36.853Z" }, ] +[[package]] +name = "rsa" +version = "4.9.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pyasn1", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/da/8a/22b7beea3ee0d44b1916c0c1cb0ee3af23b700b6da9f04991899d0c555d4/rsa-4.9.1.tar.gz", hash = "sha256:e7bdbfdb5497da4c07dfd35530e1a902659db6ff241e39d9953cad06ebd0ae75", size = 29034, upload-time = "2025-04-16T09:51:18.218Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/64/8d/0133e4eb4beed9e425d9a98ed6e081a55d195481b7632472be1af08d2f6b/rsa-4.9.1-py3-none-any.whl", hash = "sha256:68635866661c6836b8d39430f97a996acbd61bfa49406748ea243539fe239762", size = 34696, upload-time = "2025-04-16T09:51:17.142Z" }, +] + [[package]] name = "rustworkx" version = "0.17.1" @@ -5027,7 +5037,7 @@ name = "smart-open" version = "7.5.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "wrapt" }, + { name = "wrapt", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/e8/be/a66598b305763861a9ab15ff0f2fbc44e47b1ce7a776797337a4eef37c66/smart_open-7.5.1.tar.gz", hash = "sha256:3f08e16827c4733699e6b2cc40328a3568f900cb12ad9a3ad233ba6c872d9fe7", size = 54034, upload-time = "2026-02-23T11:01:28.979Z" } wheels = [ @@ -5742,13 +5752,13 @@ name = "twisterl" version = "0.5.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "huggingface-hub" }, - { name = "loguru" }, + { name = "huggingface-hub", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "loguru", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.4.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, - { name = "safetensors" }, - { name = "tensorboard" }, - { name = "torch" }, + { name = "numpy", version = "2.4.3", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and python_full_version < '3.13') or (python_full_version >= '3.11' and sys_platform != 'win32') or (python_full_version >= '3.14' and sys_platform == 'win32')" }, + { name = "safetensors", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "tensorboard", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "torch", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/92/8d/243962b1ef50c3600cdbf02ab49919963d35c7de75305f66801a9fb65e14/twisterl-0.5.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:e9ac89abaa3a5289899159f139167e1da042000dc2022086c34f0901f92ded1a", size = 428020, upload-time = "2026-01-12T09:34:44.757Z" }, @@ -5963,9 +5973,9 @@ name = "yarl" version = "1.23.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "idna" }, - { name = "multidict" }, - { name = "propcache" }, + { name = "idna", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "multidict", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, + { name = "propcache", marker = "python_full_version != '3.13.*' or sys_platform != 'win32'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/23/6e/beb1beec874a72f23815c1434518bfc4ed2175065173fb138c3705f658d4/yarl-1.23.0.tar.gz", hash = "sha256:53b1ea6ca88ebd4420379c330aea57e258408dd0df9af0992e5de2078dc9f5d5", size = 194676, upload-time = "2026-03-01T22:07:53.373Z" } wheels = [ From e90adbfccf2b89204e623698fa0372e8862581af Mon Sep 17 00:00:00 2001 From: flowerthrower Date: Mon, 16 Mar 2026 12:51:57 +0100 Subject: [PATCH 04/13] =?UTF-8?q?=F0=9F=9A=A7=20debug=20CI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- noxfile.py | 2 +- src/mqt/predictor/rl/predictorenv.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/noxfile.py b/noxfile.py index ba9748466..5a75d07e4 100755 --- a/noxfile.py +++ b/noxfile.py @@ -92,7 +92,7 @@ def _run_tests( @nox.session(python=PYTHON_ALL_VERSIONS, reuse_venv=True, default=True) def tests(session: nox.Session) -> None: """Run the test suite.""" - _run_tests(session, pytest_run_args=["-Wdefault"]) + _run_tests(session) @nox.session(python=PYTHON_ALL_VERSIONS, reuse_venv=True, venv_backend="uv", default=True) diff --git a/src/mqt/predictor/rl/predictorenv.py b/src/mqt/predictor/rl/predictorenv.py index 64d963f05..eda3f8a6e 100644 --- a/src/mqt/predictor/rl/predictorenv.py +++ b/src/mqt/predictor/rl/predictorenv.py @@ -839,6 +839,7 @@ def determine_valid_actions_for_state(self) -> list[int]: """Determine valid actions based on circuit state: synthesized, mapped, routed.""" synthesized = self.is_circuit_synthesized(self.state) laid_out = self.is_circuit_laid_out(self.state, self.layout) if self.layout else False + # Routing is only allowed after layout routed = ( self.is_circuit_routed(self.state, CouplingMap(self.device.build_coupling_map())) if laid_out else False ) From 73120d5f255d277f57619b96903703cdadd2303f Mon Sep 17 00:00:00 2001 From: Zhou Shaobo Date: Mon, 16 Mar 2026 13:51:24 +0100 Subject: [PATCH 05/13] Small adjustments --- docs/setup.md | 2 +- pyproject.toml | 6 ---- src/mqt/predictor/reward.py | 48 +++++++------------------- src/mqt/predictor/rl/predictor.py | 6 ++-- src/mqt/predictor/rl/predictorenv.py | 11 ++---- tests/compilation/test_predictor_rl.py | 18 ++++------ 6 files changed, 25 insertions(+), 66 deletions(-) diff --git a/docs/setup.md b/docs/setup.md index 6d1218318..f0e83cd18 100644 --- a/docs/setup.md +++ b/docs/setup.md @@ -109,7 +109,7 @@ After setup, any quantum circuit can be compiled for the most suitable device wi from mqt.predictor import qcompile from mqt.bench import get_benchmark, BenchmarkLevel -uncompiled_qc = get_benchmark("ghz", level=BenchmarkLevel.INDEP, circuit_size=5) +uncompiled_qc = get_benchmark("ghz", level=BenchmarkLevel.ALG, circuit_size=5) compiled_qc, compilation_info, selected_device = qcompile( uncompiled_qc, figure_of_merit="expected_fidelity" ) diff --git a/pyproject.toml b/pyproject.toml index c2b8fb387..767e5c6cc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -119,13 +119,7 @@ addopts = [ ] log_level = "INFO" filterwarnings = [ - # NOTE: qiskit-ibm-transpiler (>=0.14) imports wrappers/function_transpile.py during import, - # which currently triggers SyntaxWarnings (invalid escape sequence, and `is` with string literal). - # TODO: Remove these ignores once upstream fixes the warnings. 'error', - "ignore:invalid escape sequence '\\\\w':DeprecationWarning:qiskit_ibm_transpiler\\..*", - "ignore:invalid escape sequence '\\\\w':SyntaxWarning:qiskit_ibm_transpiler\\..*", - "ignore:\"is\" with a literal:SyntaxWarning:qiskit_ibm_transpiler\\..*", 'ignore:.*pytorch.*:UserWarning:', 'ignore:.*Values in x.*:RuntimeWarning:', 'ignore:.*The least populated class in y has only 3 members, which is less than n_splits=5.*:UserWarning:', diff --git a/src/mqt/predictor/reward.py b/src/mqt/predictor/reward.py index 16512e143..a8cd76952 100644 --- a/src/mqt/predictor/reward.py +++ b/src/mqt/predictor/reward.py @@ -23,7 +23,6 @@ if TYPE_CHECKING: from qiskit import QuantumCircuit - from qiskit.circuit import QuantumRegister, Qubit from qiskit.transpiler import Target from sklearn.ensemble import RandomForestRegressor @@ -62,44 +61,22 @@ def expected_fidelity(qc: QuantumCircuit, device: Target, precision: int = 10) - if gate_type != "barrier": assert len(qargs) in [1, 2] - first_qubit_idx = calc_qubit_index(qargs, qc.qregs, 0) + first_qubit_idx = qc.find_bit(qargs[0]).index if len(qargs) == 1: specific_fidelity = 1 - device[gate_type][first_qubit_idx,].error else: - second_qubit_idx = calc_qubit_index(qargs, qc.qregs, 1) - specific_fidelity = 1 - device[gate_type][first_qubit_idx, second_qubit_idx].error - + second_qubit_idx = qc.find_bit(qargs[1]).index + try: + specific_fidelity = 1 - device[gate_type][first_qubit_idx, second_qubit_idx].error + except KeyError: + msg = f"Error rate for gate {gate_type} on qubits {first_qubit_idx} and {second_qubit_idx} not found in device properties." + raise KeyError(msg) from None res *= specific_fidelity return float(np.round(res, precision).item()) -def calc_qubit_index(qargs: list[Qubit], qregs: list[QuantumRegister], index: int) -> int: - """Calculates the global qubit index for a given quantum circuit and qubit index. - - Arguments: - qargs: The qubits of the quantum circuit. - qregs: The quantum registers of the quantum circuit. - index: The index of the qubit in the qargs list. - - Returns: - The global qubit index of the given qubit in the quantum circuit. - - Raises: - ValueError: If the qubit index is not found in the quantum registers. - """ - offset = 0 - for reg in qregs: - if qargs[index] not in reg: - offset += reg.size - else: - qubit_index: int = offset + reg.index(qargs[index]) - return qubit_index - error_msg = f"Global qubit index for local qubit {index} index not found." - raise ValueError(error_msg) - - def estimated_success_probability(qc: QuantumCircuit, device: Target, precision: int = 10) -> float: """Calculates the estimated success probability of a given quantum circuit on a given device. @@ -125,7 +102,7 @@ def estimated_success_probability(qc: QuantumCircuit, device: Target, precision: if gate_type == "barrier" or gate_type == "id": continue assert len(qargs) in (1, 2) - first_qubit_idx = calc_qubit_index(qargs, qc.qregs, 0) + first_qubit_idx = qc.find_bit(qargs[0]).index active_qubits.add(first_qubit_idx) if len(qargs) == 1: # single-qubit gate @@ -140,7 +117,7 @@ def estimated_success_probability(qc: QuantumCircuit, device: Target, precision: )) exec_time_per_qubit[first_qubit_idx] += duration else: # multi-qubit gate - second_qubit_idx = calc_qubit_index(qargs, qc.qregs, 1) + second_qubit_idx = qc.find_bit(qargs[1]).index active_qubits.add(second_qubit_idx) duration = device[gate_type][first_qubit_idx, second_qubit_idx].duration op_times.append((gate_type, [first_qubit_idx, second_qubit_idx], duration, "s")) @@ -191,7 +168,7 @@ def estimated_success_probability(qc: QuantumCircuit, device: Target, precision: continue assert len(qargs) in (1, 2) - first_qubit_idx = calc_qubit_index(qargs, qc.qregs, 0) + first_qubit_idx = scheduled_circ.find_bit(qargs[0]).index if len(qargs) == 1: if gate_type == "measure": @@ -204,7 +181,7 @@ def estimated_success_probability(qc: QuantumCircuit, device: Target, precision: if first_qubit_idx not in active_qubits: continue - dt = device.dt or 1.0 # discrete time unit; fallback to 1.0 if unavailable + dt = device.dt # instruction durations are stored in unit dt res *= np.exp( -instruction.duration * dt @@ -212,9 +189,8 @@ def estimated_success_probability(qc: QuantumCircuit, device: Target, precision: ) continue res *= 1 - device[gate_type][first_qubit_idx,].error - else: - second_qubit_idx = calc_qubit_index(qargs, qc.qregs, 1) + second_qubit_idx = scheduled_circ.find_bit(qargs[1]).index res *= 1 - device[gate_type][first_qubit_idx, second_qubit_idx].error if qiskit_version >= "2.0.0": diff --git a/src/mqt/predictor/rl/predictor.py b/src/mqt/predictor/rl/predictor.py index 2654f34fe..57cbdb54f 100644 --- a/src/mqt/predictor/rl/predictor.py +++ b/src/mqt/predictor/rl/predictor.py @@ -99,9 +99,9 @@ def train_model( """ if test: set_random_seed(0) # for reproducibility - n_steps = 10 - n_epochs = 1 - batch_size = 10 + n_steps = 32 + n_epochs = 2 + batch_size = 8 progress_bar = False else: # default PPO values diff --git a/src/mqt/predictor/rl/predictorenv.py b/src/mqt/predictor/rl/predictorenv.py index eda3f8a6e..da455f63b 100644 --- a/src/mqt/predictor/rl/predictorenv.py +++ b/src/mqt/predictor/rl/predictorenv.py @@ -50,10 +50,8 @@ from qiskit.transpiler.passes import ( ApplyLayout, BasisTranslator, - CheckMap, EnlargeWithAncilla, FullAncillaAllocation, - GatesInBasis, SetLayout, ) from qiskit.transpiler.passes.layout.vf2_layout import VF2LayoutStopReason @@ -348,13 +346,8 @@ def calculate_reward(self, qc: QuantumCircuit | None = None, mode: str = "auto") elif mode == "approx": kind = "approx" else: # "auto" - check_nat_gates = GatesInBasis(basis_gates=self.device.operation_names) - check_nat_gates(qc) - only_native = bool(check_nat_gates.property_set["all_gates_in_basis"]) - - check_mapping = CheckMap(coupling_map=self.device.build_coupling_map()) - check_mapping(qc) - mapped = bool(check_mapping.property_set["is_swap_mapped"]) + only_native = self.is_circuit_synthesized(qc) + mapped = self.is_circuit_routed(qc, CouplingMap(self.device.build_coupling_map())) kind = "exact" if (only_native and mapped) else "approx" diff --git a/tests/compilation/test_predictor_rl.py b/tests/compilation/test_predictor_rl.py index 8f8474738..ec49890ed 100644 --- a/tests/compilation/test_predictor_rl.py +++ b/tests/compilation/test_predictor_rl.py @@ -21,7 +21,6 @@ from qiskit.circuit.library import CXGate from qiskit.qasm2 import dump from qiskit.transpiler import CouplingMap, InstructionProperties, Target -from qiskit.transpiler.passes import CheckMap, GatesInBasis from mqt.predictor.rl import Predictor, rl_compile from mqt.predictor.rl.actions import ( @@ -94,23 +93,20 @@ def test_qcompile_with_newly_trained_models() -> None: rl_compile(qc, device=device, figure_of_merit=figure_of_merit) predictor.train_model( - timesteps=100, + timesteps=1000, test=True, ) qc_compiled, compilation_information = rl_compile(qc, device=device, figure_of_merit=figure_of_merit) - check_nat_gates = GatesInBasis(basis_gates=device.operation_names) - check_nat_gates(qc_compiled) - only_nat_gates = check_nat_gates.property_set["all_gates_in_basis"] - check_mapping = CheckMap(coupling_map=CouplingMap(device.build_coupling_map())) - check_mapping(qc_compiled) - mapped = check_mapping.property_set["is_swap_mapped"] - assert qc_compiled.layout is not None assert compilation_information is not None - assert only_nat_gates, "Circuit should only contain native gates but was not detected as such." - assert mapped, "Circuit should be mapped to the device's coupling map." + assert predictor.env.is_circuit_synthesized(qc_compiled), ( + "Circuit should only contain native gates but was not detected as such." + ) + assert predictor.env.is_circuit_routed(qc_compiled, CouplingMap(device.build_coupling_map())), ( + "Circuit should be mapped to the device's coupling map." + ) def test_qcompile_with_false_input() -> None: From 346fa3485fb2fb2e1bb856f00bcd1a4b0b622462 Mon Sep 17 00:00:00 2001 From: Zhou Shaobo Date: Mon, 16 Mar 2026 15:16:16 +0100 Subject: [PATCH 06/13] Clean up stuffs --- src/mqt/predictor/rl/approx_reward.py | 43 +++++++++----------------- src/mqt/predictor/rl/predictorenv.py | 26 ++++++++-------- tests/compilation/test_predictor_rl.py | 12 +++---- 3 files changed, 33 insertions(+), 48 deletions(-) diff --git a/src/mqt/predictor/rl/approx_reward.py b/src/mqt/predictor/rl/approx_reward.py index 95f237d5d..847d09f88 100644 --- a/src/mqt/predictor/rl/approx_reward.py +++ b/src/mqt/predictor/rl/approx_reward.py @@ -10,7 +10,6 @@ from __future__ import annotations -from contextlib import suppress from typing import TYPE_CHECKING import numpy as np @@ -20,12 +19,19 @@ from qiskit import QuantumCircuit from qiskit.transpiler import InstructionProperties, Target -BLACKLIST: set[str] = {"measure", "reset", "delay", "barrier"} # These gates do not directly contribute to the error +ALWAYS_EXCLUDED_OPS: set[str] = {"barrier", "delay", "id"} def get_basis_gates_from_target(device: Target) -> list[str]: """Return the basis gate names from a Qiskit Target.""" - return sorted([g for g in device.operation_names if g not in BLACKLIST]) + basis_gates = [g for g in device.operation_names if g not in ALWAYS_EXCLUDED_OPS] + + # Reset fidelity is SPAM-related and not consistently exposed on all targets. + # Only include it when the target actually provides calibration entries. + if "reset" in basis_gates and not device["reset"]: + basis_gates.remove("reset") + + return sorted(basis_gates) def estimate_basis_gate_counts(qc: QuantumCircuit, *, basis_gates: list[str]) -> dict[str, int]: @@ -34,7 +40,7 @@ def estimate_basis_gate_counts(qc: QuantumCircuit, *, basis_gates: list[str]) -> counts = dict.fromkeys(basis_gates, 0) for ci in qc_t.data: name = ci.operation.name - if name in BLACKLIST: + if name in ALWAYS_EXCLUDED_OPS: continue if name in counts: counts[name] += 1 @@ -133,46 +139,25 @@ def compute_device_averages_from_target( # ---- Hard requirements ------------------------------------------------------- try: num_qubits = device.num_qubits - op_names = list(device.operation_names) + list(device.operation_names) coupling_map = device.build_coupling_map() qubit_props = device.qubit_properties except AttributeError as exc: msg = "Device target does not expose the required Target API for approximate reward computation." raise RuntimeError(msg) from exc - basis_ops = [name for name in op_names if name not in BLACKLIST] + basis_ops = get_basis_gates_from_target(device) twoq_edges = coupling_map.get_edges() # list[tuple[int, int]] # ---- Helpers ---------------------------------------------------------------- def _get_props(name: str, qargs: tuple[int, ...]) -> InstructionProperties | None: """Return calibration properties for (name, qargs) or None if unavailable.""" - with suppress(KeyError): - return device[name].get(qargs, None) - return None - - def _infer_arity(name: str) -> int | None: - """Infer operation arity from Target (best effort).""" - # Preferred: operation_from_name - with suppress(AttributeError, KeyError, TypeError): - op = device.operation_from_name(name) - return int(op.num_qubits) - - # Fallback: infer from any qargs key in device[name] - with suppress(KeyError, TypeError): - props_map = device[name] - for qargs in props_map: - return len(qargs) - return None + return device[name].get(qargs, None) # ---- Accumulate raw samples -------------------------------------------------- err_samples: dict[str, list[float]] = {name: [] for name in basis_ops} dur_samples: dict[str, list[float]] = {name: [] for name in basis_ops} - - arity_by_name: dict[str, int] = {} - for name in basis_ops: - arity = _infer_arity(name) - if arity is not None: - arity_by_name[name] = arity + arity_by_name = {name: int(device.operation_from_name(name).num_qubits) for name in basis_ops} # ---- Aggregate error/duration per gate -------------------------------------- for name in basis_ops: diff --git a/src/mqt/predictor/rl/predictorenv.py b/src/mqt/predictor/rl/predictorenv.py index da455f63b..52ccda125 100644 --- a/src/mqt/predictor/rl/predictorenv.py +++ b/src/mqt/predictor/rl/predictorenv.py @@ -214,10 +214,10 @@ def __init__( self.no_effect_penalty = no_effect_penalty self.prev_reward: float | None = None self.prev_reward_kind: str | None = None - self._err_by_gate: dict[str, float] = {} - self._dur_by_gate: dict[str, float] = {} - self._tbar: float | None = None - self._dev_avgs_cached = False + self.err_by_gate: dict[str, float] = {} + self.dur_by_gate: dict[str, float] = {} + self.tbar: float | None = None + self.dev_avgs_cached = False self.state: QuantumCircuit = QuantumCircuit() self.error_occurred = False @@ -364,7 +364,7 @@ def calculate_reward(self, qc: QuantumCircuit | None = None, mode: str = "auto") val = approx_expected_fidelity( qc, device=self.device, - error_rates=self._err_by_gate, + error_rates=self.err_by_gate, ) return val, "approx" @@ -373,9 +373,9 @@ def calculate_reward(self, qc: QuantumCircuit | None = None, mode: str = "auto") val = approx_estimated_success_probability( qc, device=self.device, - error_rates=self._err_by_gate, - gate_durations=self._dur_by_gate, - tbar=self._tbar, + error_rates=self.err_by_gate, + gate_durations=self.dur_by_gate, + tbar=self.tbar, par_feature=float(feats.parallelism), liv_feature=float(feats.liveness), n_qubits=int(qc.num_qubits), @@ -919,12 +919,12 @@ def determine_valid_actions_for_state(self) -> list[int]: def _ensure_device_averages_cached(self) -> None: """Cache per-basis-gate averages for error, duration, and a coherence scale.""" - if self._dev_avgs_cached: + if self.dev_avgs_cached: return err_by_gate, dur_by_gate, tbar = compute_device_averages_from_target(self.device) - self._err_by_gate = err_by_gate - self._dur_by_gate = dur_by_gate - self._tbar = tbar - self._dev_avgs_cached = True + self.err_by_gate = err_by_gate + self.dur_by_gate = dur_by_gate + self.tbar = tbar + self.dev_avgs_cached = True diff --git a/tests/compilation/test_predictor_rl.py b/tests/compilation/test_predictor_rl.py index ec49890ed..30c370f66 100644 --- a/tests/compilation/test_predictor_rl.py +++ b/tests/compilation/test_predictor_rl.py @@ -220,12 +220,12 @@ def test_approx_reward_paths_use_cached_per_gate_maps(fom: figure_of_merit) -> N assert 0.0 <= val <= 1.0 # Ensure caching produced per-gate mappings - assert predictor.env._dev_avgs_cached # noqa: SLF001 - assert isinstance(predictor.env._err_by_gate, dict) # noqa: SLF001 - assert isinstance(predictor.env._dur_by_gate, dict) # noqa: SLF001 - assert len(predictor.env._err_by_gate) > 0 # noqa: SLF001 + assert predictor.env.dev_avgs_cached + assert isinstance(predictor.env.err_by_gate, dict) + assert isinstance(predictor.env.dur_by_gate, dict) + assert len(predictor.env.err_by_gate) > 0 if fom == "estimated_success_probability": - assert len(predictor.env._dur_by_gate) > 0 # noqa: SLF001 + assert len(predictor.env.dur_by_gate) > 0 # tbar is optional depending on backend calibration; just sanity-check type - assert predictor.env._tbar is None or predictor.env._tbar > 0.0 # noqa: SLF001 + assert predictor.env.tbar is None or predictor.env.tbar > 0.0 From 4055610417b0d0e8b21fef71d5ddfbbf78eb2163 Mon Sep 17 00:00:00 2001 From: Zhou Shaobo Date: Mon, 16 Mar 2026 21:27:31 +0100 Subject: [PATCH 07/13] Clean up stuffs --- src/mqt/predictor/rl/approx_reward.py | 12 ++++- tests/compilation/test_approx_reward.py | 64 +++++++------------------ 2 files changed, 28 insertions(+), 48 deletions(-) diff --git a/src/mqt/predictor/rl/approx_reward.py b/src/mqt/predictor/rl/approx_reward.py index 847d09f88..0813eb015 100644 --- a/src/mqt/predictor/rl/approx_reward.py +++ b/src/mqt/predictor/rl/approx_reward.py @@ -154,10 +154,20 @@ def _get_props(name: str, qargs: tuple[int, ...]) -> InstructionProperties | Non """Return calibration properties for (name, qargs) or None if unavailable.""" return device[name].get(qargs, None) + def _infer_arity(name: str) -> int | None: + """Infer operation arity from Target (best effort).""" + op = device.operation_from_name(name) + return int(op.num_qubits) + # ---- Accumulate raw samples -------------------------------------------------- err_samples: dict[str, list[float]] = {name: [] for name in basis_ops} dur_samples: dict[str, list[float]] = {name: [] for name in basis_ops} - arity_by_name = {name: int(device.operation_from_name(name).num_qubits) for name in basis_ops} + + arity_by_name: dict[str, int] = {} + for name in basis_ops: + arity = _infer_arity(name) + if arity is not None: + arity_by_name[name] = arity # ---- Aggregate error/duration per gate -------------------------------------- for name in basis_ops: diff --git a/tests/compilation/test_approx_reward.py b/tests/compilation/test_approx_reward.py index 0a7858b13..1daa55f05 100644 --- a/tests/compilation/test_approx_reward.py +++ b/tests/compilation/test_approx_reward.py @@ -68,7 +68,6 @@ def __init__( arities: dict[str, int], edges: list[tuple[int, int]], qubit_properties: list[FakeQubitProperties | None] | None, - operation_from_name_raises_for: set[str] | None = None, ) -> None: """Initialize operation data, arities, connectivity, and qubit properties.""" self.num_qubits = num_qubits @@ -77,17 +76,13 @@ def __init__( self._arities = arities self._edges = edges self.qubit_properties = qubit_properties - self._operation_from_name_raises_for = operation_from_name_raises_for or set() def build_coupling_map(self) -> FakeCouplingMap: """Return a minimal coupling map.""" return FakeCouplingMap(self._edges) def operation_from_name(self, name: str) -> FakeOperation: - """Return operation metadata or raise to trigger fallback inference.""" - if name in self._operation_from_name_raises_for: - msg = f"Operation {name} metadata unavailable." - raise KeyError(msg) + """Return operation metadata.""" return FakeOperation(num_qubits=self._arities[name]) def __getitem__(self, name: str) -> dict[tuple[int, ...], FakeInstructionProperties]: @@ -99,8 +94,12 @@ def test_compute_device_averages_nominal_path() -> None: """Compute per-gate means and qubit coherence median on a nominal target.""" target = FakeTarget( num_qubits=2, - operation_names=["measure", "x", "cx"], # measure should be ignored + operation_names=["measure", "x", "cx"], op_props={ + "measure": { + (0,): FakeInstructionProperties(error=0.01, duration=100.0), + (1,): FakeInstructionProperties(error=0.03, duration=120.0), + }, "x": { (0,): FakeInstructionProperties(error=0.1, duration=10.0), (1,): FakeInstructionProperties(error=0.3, duration=30.0), @@ -109,7 +108,7 @@ def test_compute_device_averages_nominal_path() -> None: (0, 1): FakeInstructionProperties(error=0.4, duration=40.0), }, }, - arities={"x": 1, "cx": 2}, + arities={"measure": 1, "x": 1, "cx": 2}, edges=[(0, 1)], qubit_properties=[ FakeQubitProperties(t1=100.0, t2=50.0), # min = 50 @@ -119,48 +118,19 @@ def test_compute_device_averages_nominal_path() -> None: err_by_gate, dur_by_gate, tbar = compute_device_averages_from_target(cast("Target", target)) - assert err_by_gate == {"x": pytest.approx(0.2), "cx": pytest.approx(0.4)} - assert dur_by_gate == {"x": pytest.approx(20.0), "cx": pytest.approx(40.0)} + assert err_by_gate == { + "measure": pytest.approx(0.02), + "x": pytest.approx(0.2), + "cx": pytest.approx(0.4), + } + assert dur_by_gate == { + "measure": pytest.approx(110.0), + "x": pytest.approx(20.0), + "cx": pytest.approx(40.0), + } assert tbar == pytest.approx(125.0) -def test_compute_device_averages_fallbacks_are_used() -> None: - """Use orientation fallback, arity fallback, and global per-gate fallback.""" - target = FakeTarget( - num_qubits=2, - operation_names=["x", "cx", "rz"], - op_props={ - "x": { - (0,): FakeInstructionProperties(error=0.1, duration=10.0), - (1,): FakeInstructionProperties(error=0.3, duration=30.0), - }, - # Only reverse orientation is available; edge scan uses (0, 1) - "cx": { - (1, 0): FakeInstructionProperties(error=0.2, duration=20.0), - }, - # No data for rz; should get global fallback values - "rz": { - (0,): FakeInstructionProperties(error=None, duration=None), - (1,): FakeInstructionProperties(error=None, duration=None), - }, - }, - arities={"x": 1, "cx": 2, "rz": 1}, - edges=[(0, 1)], - qubit_properties=None, - # Force arity fallback for "cx" by raising in operation_from_name - operation_from_name_raises_for={"cx"}, - ) - - err_by_gate, dur_by_gate, tbar = compute_device_averages_from_target(cast("Target", target)) - - # all available samples are 0.1, 0.3, 0.2 for error and 10, 30, 20 for duration - assert err_by_gate["rz"] == pytest.approx(0.2) - assert dur_by_gate["rz"] == pytest.approx(20.0) - assert err_by_gate["cx"] == pytest.approx(0.2) - assert dur_by_gate["cx"] == pytest.approx(20.0) - assert tbar is None - - def test_compute_device_averages_missing_target_api_raises() -> None: """Raise a clear RuntimeError if the object is not Target-compatible.""" with pytest.raises(RuntimeError, match="required Target API"): From 77cbb354193f89738a10bba3f32b29528c1e0055 Mon Sep 17 00:00:00 2001 From: flowerthrower Date: Tue, 17 Mar 2026 09:44:56 +0100 Subject: [PATCH 08/13] =?UTF-8?q?=F0=9F=8E=A8=20implement=20review?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 +++- docs/quickstart.md | 2 +- docs/setup.md | 2 +- src/mqt/predictor/rl/predictor.py | 1 + tests/compilation/test_helper_rl.py | 4 ++-- tests/compilation/test_predictor_rl.py | 2 +- tests/compilation/test_reward.py | 2 +- tests/device_selection/test_helper_ml.py | 2 +- tests/hellinger_distance/test_estimated_hellinger_distance.py | 4 ++-- 9 files changed, 13 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 1485b2139..fcb625fd7 100644 --- a/README.md +++ b/README.md @@ -100,7 +100,9 @@ from mqt.predictor import qcompile from mqt.bench import get_benchmark, BenchmarkLevel # Get a benchmark circuit from MQT Bench -qc_uncompiled = get_benchmark(benchmark="ghz", level=BenchmarkLevel.ALG, circuit_size=5) +qc_uncompiled = get_benchmark( + benchmark="ghz", level=BenchmarkLevel.INDEP, circuit_size=5 +) # Compile it using the MQT Predictor qc_compiled, compilation_information, quantum_device = qcompile( diff --git a/docs/quickstart.md b/docs/quickstart.md index a0657b9f2..a0cc5dc62 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -22,7 +22,7 @@ from mqt.predictor import qcompile ## Get Uncompiled Quantum Circuit ```{code-cell} ipython3 -qc = get_benchmark("ghz", level=BenchmarkLevel.ALG, circuit_size=5) +qc = get_benchmark("ghz", level=BenchmarkLevel.INDEP, circuit_size=5) qc.draw() ``` diff --git a/docs/setup.md b/docs/setup.md index f0e83cd18..6d1218318 100644 --- a/docs/setup.md +++ b/docs/setup.md @@ -109,7 +109,7 @@ After setup, any quantum circuit can be compiled for the most suitable device wi from mqt.predictor import qcompile from mqt.bench import get_benchmark, BenchmarkLevel -uncompiled_qc = get_benchmark("ghz", level=BenchmarkLevel.ALG, circuit_size=5) +uncompiled_qc = get_benchmark("ghz", level=BenchmarkLevel.INDEP, circuit_size=5) compiled_qc, compilation_info, selected_device = qcompile( uncompiled_qc, figure_of_merit="expected_fidelity" ) diff --git a/src/mqt/predictor/rl/predictor.py b/src/mqt/predictor/rl/predictor.py index 57cbdb54f..1f75b1901 100644 --- a/src/mqt/predictor/rl/predictor.py +++ b/src/mqt/predictor/rl/predictor.py @@ -104,6 +104,7 @@ def train_model( batch_size = 8 progress_bar = False else: + set_random_seed(0) # default PPO values n_steps = 2048 n_epochs = 10 diff --git a/tests/compilation/test_helper_rl.py b/tests/compilation/test_helper_rl.py index a933f1f31..96c9c759f 100644 --- a/tests/compilation/test_helper_rl.py +++ b/tests/compilation/test_helper_rl.py @@ -33,7 +33,7 @@ def test_create_feature_dict() -> None: """Test the creation of a feature dictionary.""" - qc = get_benchmark("dj", BenchmarkLevel.ALG, 5) + qc = get_benchmark("dj", BenchmarkLevel.INDEP, 5) features = create_feature_dict(qc) for feature in features.values(): assert isinstance(feature, np.ndarray | int) @@ -55,7 +55,7 @@ def test_get_path_training_circuits() -> None: def test_vf2_layout_and_postlayout() -> None: """Test the VF2Layout and VF2PostLayout passes.""" - qc = get_benchmark("ghz", BenchmarkLevel.ALG, 3) + qc = get_benchmark("ghz", BenchmarkLevel.INDEP, 3) for dev in [get_device("ibm_falcon_27"), get_device("quantinuum_h2_56")]: passes: list[Task] | None = None diff --git a/tests/compilation/test_predictor_rl.py b/tests/compilation/test_predictor_rl.py index 30c370f66..afc6b74ae 100644 --- a/tests/compilation/test_predictor_rl.py +++ b/tests/compilation/test_predictor_rl.py @@ -77,7 +77,7 @@ def test_qcompile_with_newly_trained_models() -> None: """ figure_of_merit = "expected_fidelity" device = get_device("ibm_falcon_127") - qc = get_benchmark("ghz", BenchmarkLevel.ALG, 3) + qc = get_benchmark("ghz", BenchmarkLevel.INDEP, 3) predictor = Predictor(figure_of_merit=figure_of_merit, device=device) diff --git a/tests/compilation/test_reward.py b/tests/compilation/test_reward.py index 5e36fcc8a..00c340992 100644 --- a/tests/compilation/test_reward.py +++ b/tests/compilation/test_reward.py @@ -43,7 +43,7 @@ def device() -> Target: @pytest.fixture def compiled_qc(device: Target) -> QuantumCircuit: """Return a compiled quantum circuit.""" - qc = get_benchmark("ghz", BenchmarkLevel.ALG, 3) + qc = get_benchmark("ghz", BenchmarkLevel.INDEP, 3) return transpile(qc, target=device) diff --git a/tests/device_selection/test_helper_ml.py b/tests/device_selection/test_helper_ml.py index 87f69f009..6f64e613c 100644 --- a/tests/device_selection/test_helper_ml.py +++ b/tests/device_selection/test_helper_ml.py @@ -23,7 +23,7 @@ def test_create_feature_vector() -> None: """Test the creation of a feature dictionary.""" - qc = get_benchmark("dj", BenchmarkLevel.ALG, 3) + qc = get_benchmark("dj", BenchmarkLevel.INDEP, 3) feature_vector = create_feature_vector(qc) assert feature_vector is not None diff --git a/tests/hellinger_distance/test_estimated_hellinger_distance.py b/tests/hellinger_distance/test_estimated_hellinger_distance.py index 02e5fa670..c9f6ca494 100644 --- a/tests/hellinger_distance/test_estimated_hellinger_distance.py +++ b/tests/hellinger_distance/test_estimated_hellinger_distance.py @@ -211,7 +211,7 @@ def test_train_and_qcompile_with_hellinger_model(source_path: Path, target_path: target_path.mkdir() for i in range(2, 5): - qc = get_benchmark("ghz", BenchmarkLevel.ALG, i) + qc = get_benchmark("ghz", BenchmarkLevel.INDEP, i) path = source_path / f"qc{i}.qasm" with path.open("w", encoding="utf-8") as f: dump(qc, f) @@ -234,7 +234,7 @@ def test_train_and_qcompile_with_hellinger_model(source_path: Path, target_path: # Train the ML model ml_predictor.train_random_forest_model() - qc = get_benchmark("ghz", BenchmarkLevel.ALG, 3) + qc = get_benchmark("ghz", BenchmarkLevel.INDEP, 3) # Test the prediction predicted_dev = predict_device_for_figure_of_merit(qc, figure_of_merit) From 9a4f3ccdac5eb57c630b40ae27da1109495d5f6d Mon Sep 17 00:00:00 2001 From: flowerthrower Date: Tue, 17 Mar 2026 13:04:41 +0100 Subject: [PATCH 09/13] =?UTF-8?q?=F0=9F=8E=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- docs/quickstart.md | 2 +- docs/setup.md | 2 +- tests/compilation/test_helper_rl.py | 4 ++-- tests/compilation/test_predictor_rl.py | 8 ++++---- tests/compilation/test_reward.py | 2 +- tests/device_selection/test_helper_ml.py | 2 +- tests/device_selection/test_predictor_ml.py | 6 +++--- .../test_estimated_hellinger_distance.py | 4 ++-- 9 files changed, 16 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index fcb625fd7..bca6a753b 100644 --- a/README.md +++ b/README.md @@ -101,7 +101,7 @@ from mqt.bench import get_benchmark, BenchmarkLevel # Get a benchmark circuit from MQT Bench qc_uncompiled = get_benchmark( - benchmark="ghz", level=BenchmarkLevel.INDEP, circuit_size=5 + benchmark="ghz", level=BenchmarkLevel.ALG, circuit_size=5 ) # Compile it using the MQT Predictor diff --git a/docs/quickstart.md b/docs/quickstart.md index a0cc5dc62..a0657b9f2 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -22,7 +22,7 @@ from mqt.predictor import qcompile ## Get Uncompiled Quantum Circuit ```{code-cell} ipython3 -qc = get_benchmark("ghz", level=BenchmarkLevel.INDEP, circuit_size=5) +qc = get_benchmark("ghz", level=BenchmarkLevel.ALG, circuit_size=5) qc.draw() ``` diff --git a/docs/setup.md b/docs/setup.md index 6d1218318..f0e83cd18 100644 --- a/docs/setup.md +++ b/docs/setup.md @@ -109,7 +109,7 @@ After setup, any quantum circuit can be compiled for the most suitable device wi from mqt.predictor import qcompile from mqt.bench import get_benchmark, BenchmarkLevel -uncompiled_qc = get_benchmark("ghz", level=BenchmarkLevel.INDEP, circuit_size=5) +uncompiled_qc = get_benchmark("ghz", level=BenchmarkLevel.ALG, circuit_size=5) compiled_qc, compilation_info, selected_device = qcompile( uncompiled_qc, figure_of_merit="expected_fidelity" ) diff --git a/tests/compilation/test_helper_rl.py b/tests/compilation/test_helper_rl.py index 96c9c759f..a933f1f31 100644 --- a/tests/compilation/test_helper_rl.py +++ b/tests/compilation/test_helper_rl.py @@ -33,7 +33,7 @@ def test_create_feature_dict() -> None: """Test the creation of a feature dictionary.""" - qc = get_benchmark("dj", BenchmarkLevel.INDEP, 5) + qc = get_benchmark("dj", BenchmarkLevel.ALG, 5) features = create_feature_dict(qc) for feature in features.values(): assert isinstance(feature, np.ndarray | int) @@ -55,7 +55,7 @@ def test_get_path_training_circuits() -> None: def test_vf2_layout_and_postlayout() -> None: """Test the VF2Layout and VF2PostLayout passes.""" - qc = get_benchmark("ghz", BenchmarkLevel.INDEP, 3) + qc = get_benchmark("ghz", BenchmarkLevel.ALG, 3) for dev in [get_device("ibm_falcon_27"), get_device("quantinuum_h2_56")]: passes: list[Task] | None = None diff --git a/tests/compilation/test_predictor_rl.py b/tests/compilation/test_predictor_rl.py index afc6b74ae..ff3449ba3 100644 --- a/tests/compilation/test_predictor_rl.py +++ b/tests/compilation/test_predictor_rl.py @@ -45,7 +45,7 @@ def test_predictor_env_reset_from_string() -> None: device = get_device("ibm_eagle_127") predictor = Predictor(figure_of_merit="expected_fidelity", device=device) qasm_path = Path("test.qasm") - qc = get_benchmark("dj", BenchmarkLevel.INDEP, 3) + qc = get_benchmark("dj", BenchmarkLevel.ALG, 3) with qasm_path.open("w", encoding="utf-8") as f: dump(qc, f) assert predictor.env.reset(qc=qasm_path)[0] == create_feature_dict(qc) @@ -77,7 +77,7 @@ def test_qcompile_with_newly_trained_models() -> None: """ figure_of_merit = "expected_fidelity" device = get_device("ibm_falcon_127") - qc = get_benchmark("ghz", BenchmarkLevel.INDEP, 3) + qc = get_benchmark("ghz", BenchmarkLevel.ALG, 3) predictor = Predictor(figure_of_merit=figure_of_merit, device=device) @@ -111,7 +111,7 @@ def test_qcompile_with_newly_trained_models() -> None: def test_qcompile_with_false_input() -> None: """Test the qcompile function with false input.""" - qc = get_benchmark("dj", BenchmarkLevel.INDEP, 5) + qc = get_benchmark("dj", BenchmarkLevel.ALG, 5) with pytest.raises(ValueError, match=re.escape("figure_of_merit must not be None if predictor_singleton is None.")): rl_compile(qc, device=get_device("quantinuum_h2_56"), figure_of_merit=None) with pytest.raises(ValueError, match=re.escape("device must not be None if predictor_singleton is None.")): @@ -211,7 +211,7 @@ def test_approx_reward_paths_use_cached_per_gate_maps(fom: figure_of_merit) -> N - cached maps are populated, - output is a valid probability in [0, 1]. """ - qc = get_benchmark("ghz", BenchmarkLevel.INDEP, 3) + qc = get_benchmark("ghz", BenchmarkLevel.ALG, 3) device = get_device("ibm_heron_133") predictor = Predictor(figure_of_merit=fom, device=device) diff --git a/tests/compilation/test_reward.py b/tests/compilation/test_reward.py index 00c340992..5e36fcc8a 100644 --- a/tests/compilation/test_reward.py +++ b/tests/compilation/test_reward.py @@ -43,7 +43,7 @@ def device() -> Target: @pytest.fixture def compiled_qc(device: Target) -> QuantumCircuit: """Return a compiled quantum circuit.""" - qc = get_benchmark("ghz", BenchmarkLevel.INDEP, 3) + qc = get_benchmark("ghz", BenchmarkLevel.ALG, 3) return transpile(qc, target=device) diff --git a/tests/device_selection/test_helper_ml.py b/tests/device_selection/test_helper_ml.py index 6f64e613c..87f69f009 100644 --- a/tests/device_selection/test_helper_ml.py +++ b/tests/device_selection/test_helper_ml.py @@ -23,7 +23,7 @@ def test_create_feature_vector() -> None: """Test the creation of a feature dictionary.""" - qc = get_benchmark("dj", BenchmarkLevel.INDEP, 3) + qc = get_benchmark("dj", BenchmarkLevel.ALG, 3) feature_vector = create_feature_vector(qc) assert feature_vector is not None diff --git a/tests/device_selection/test_predictor_ml.py b/tests/device_selection/test_predictor_ml.py index 32bbf6f8f..db07cd1c4 100644 --- a/tests/device_selection/test_predictor_ml.py +++ b/tests/device_selection/test_predictor_ml.py @@ -43,7 +43,7 @@ def test_setup_device_predictor_with_prediction(path_uncompiled_circuits: Path, path_compiled_circuits.mkdir() for i in range(2, 8): - qc = get_benchmark("ghz", BenchmarkLevel.INDEP, i) + qc = get_benchmark("ghz", BenchmarkLevel.ALG, i) path = path_uncompiled_circuits / f"qc{i}.qasm" with path.open("w", encoding="utf-8") as f: dump(qc, f) @@ -63,7 +63,7 @@ def test_setup_device_predictor_with_prediction(path_uncompiled_circuits: Path, assert (data_path / "names_list_expected_fidelity.npy").exists() assert (data_path / "scores_list_expected_fidelity.npy").exists() - test_qc = get_benchmark("ghz", BenchmarkLevel.INDEP, 3) + test_qc = get_benchmark("ghz", BenchmarkLevel.ALG, 3) predicted = predict_device_for_figure_of_merit(test_qc, figure_of_merit="expected_fidelity") assert predicted.description == "ibm_falcon_127" @@ -93,7 +93,7 @@ def test_remove_files(path_uncompiled_circuits: Path, path_compiled_circuits: Pa def test_predict_device_for_figure_of_merit_no_suitable_device() -> None: """Test the prediction of the device for a given figure of merit with a wrong device name.""" num_qubits = 130 - qc = get_benchmark("ghz", BenchmarkLevel.INDEP, num_qubits) + qc = get_benchmark("ghz", BenchmarkLevel.ALG, num_qubits) with pytest.raises( ValueError, match=re.escape(f"No suitable device found for the given quantum circuit with {num_qubits} qubits.") ): diff --git a/tests/hellinger_distance/test_estimated_hellinger_distance.py b/tests/hellinger_distance/test_estimated_hellinger_distance.py index c9f6ca494..02e5fa670 100644 --- a/tests/hellinger_distance/test_estimated_hellinger_distance.py +++ b/tests/hellinger_distance/test_estimated_hellinger_distance.py @@ -211,7 +211,7 @@ def test_train_and_qcompile_with_hellinger_model(source_path: Path, target_path: target_path.mkdir() for i in range(2, 5): - qc = get_benchmark("ghz", BenchmarkLevel.INDEP, i) + qc = get_benchmark("ghz", BenchmarkLevel.ALG, i) path = source_path / f"qc{i}.qasm" with path.open("w", encoding="utf-8") as f: dump(qc, f) @@ -234,7 +234,7 @@ def test_train_and_qcompile_with_hellinger_model(source_path: Path, target_path: # Train the ML model ml_predictor.train_random_forest_model() - qc = get_benchmark("ghz", BenchmarkLevel.INDEP, 3) + qc = get_benchmark("ghz", BenchmarkLevel.ALG, 3) # Test the prediction predicted_dev = predict_device_for_figure_of_merit(qc, figure_of_merit) From 012eb36ad0c11b4332055c395888de29f31e7e74 Mon Sep 17 00:00:00 2001 From: flowerthrower Date: Tue, 17 Mar 2026 13:05:45 +0100 Subject: [PATCH 10/13] =?UTF-8?q?=F0=9F=8E=A8=20format?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../trained_clf_expected_fidelity.joblib | Bin 0 -> 81263 bytes ...r_distance_regressor_quantinuum_h2_56.joblib | Bin 0 -> 74927 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/mqt/predictor/ml/training_data/trained_model/trained_clf_expected_fidelity.joblib create mode 100644 src/mqt/predictor/ml/training_data/trained_model/trained_hellinger_distance_regressor_quantinuum_h2_56.joblib diff --git a/src/mqt/predictor/ml/training_data/trained_model/trained_clf_expected_fidelity.joblib b/src/mqt/predictor/ml/training_data/trained_model/trained_clf_expected_fidelity.joblib new file mode 100644 index 0000000000000000000000000000000000000000..576f8f16c6055c8eff5117795dd32304a7a13e87 GIT binary patch literal 81263 zcmeHw2Uru?*M6wdMMdn2=qfe@dp{OzL=jK{K@ABBOpp|lfS`y$k)ly4!S33-tJwRB zW$lGsUAw#3yNkW7%75nGj2nmH`?C+f@Am}0;d#R0zB%X2eb0ODy^{!0YnkhA%|lQZ+fP5hTtMs7mzIMoHyTz0O9h zjFDKE{zaGkVW>>ISULm z6vRnXRLS%@D{s#(o?iM`kph5SL`}k#s72H!>JW8_ z`b0gVA<>A`&sL;RXw({&P^nMX*(www0o4K$eTL3jE{Il$NRmW7K2KMLys$_?QXzk~ zn;=xlD9S30K7(lBr?aQ(VkkT5UyZ0v)bt}<`Q}6|z8O*b8+)RT&Qd*|j3Vm#5%vFp z8~G6p{~5UvjblYbbH0tvN+pSuYRHM1N5tv*mV^g+aR;SJA`nZ}N}+~oWSe#^4fE95 zOH?X_$}s4LQ3E@hO%&D=2sAcr?59H738Io8b*(tFxl zq4)Fi^DQR7&^JC$qZjqFp?g)IO8OZti#Q7OL@%O`&OFj63DLjw6h(kjIG~y1z7e3p z{E$x6hS4A$yeL%^tCWNHye6#7~&kB{8+TqOleQO6&NsE!*9scPD zBqhHK-;!@b_JPh$7!#wIAdtz>I1pX;_^?`1pjO* zRQ-(GB$!;L^ua>blUzV0`{jQWvYziIyD1LFyGMzx8O8S|!pMzhG$AmwqKFU^5~{XD z6hRPDVkjX`ClpjAY^ViAePL20Kb7GpLP;(lpMExGhB00qj>bm<*$-88R@AXZHbeFA zk2wk@4=L(wBNsC{qtfQ$^KC8;cqaHeec9Y`hM)Lm)K)N=ELcry52j8aazlxgYpABQ z!Us~R7a`jxsFP9q=*$xJejYlz7)hi?5J5;|#N_6oLWiMYRK;-akw=7vAdf#nLHXFw zXPcf{IA{*^zOSo=Pg9AQY=rNhsV!q(@eyr<-n9Q$2BoWEw=>JZJ{NMFI zkxs7f3}!{Yt?xPCr2MwNnUel%JzLN`H!&|;ija=qT@pwCC-jV6n{np&Dtzu(zewxgF`*+}qFiy|Pvp$c;O}6Ls zEUTWTzdoZT-{;OxrkthT51GE6wyQKT-1=k+TH5`srOBV47ynq^h|{yIdYbRIahLnd>7`|5I}h|{yIdYb~{EJx%}o4DQxy2&ZRR^)&tcc0dpE z-!r-QhZurZ-228QW!2O4?}v2f&i3c@tUP*l>)L{Q zy~32U0`Iqn`wp7Otxu+)rQHvi{(k#l@@8L7&&s1`bKfV!I6cd%r|I9{2CtJ;;q)x4 zo~FOwZa(=ZcYZSEtibm}A!El?n zP-Z<%e|^^JYa7Jvw@g7R?tVLTT-)lLo@Le3^!M9A^99`cWXf5A&rjQWey-g5WC~hw z_gnqE7u@fIG36|EeVYFLklLn=6}LW_f|j;EP5=BXsL_8cr)OF9H2wAYI=k6OPS47t z=PwOyVmUo4kDgx#b{xp*S$XsvR^>$#PS47t=avS0x%(leoE7->O1|ySoSv0P&%phu z+`ng+Sx?h{{TUJ7D}g&dnSxf__Y= zcZ(+Ry|FBzjeFyEBAgpQ_c!}e|s2;UAXnh6tv==pSI_=HRbdytDdI6 z-|qFzvgPzFtDf}#+hDq%XFTP%-^X)$mQ_#FU!QI(I`rlAtUP))x;~G4zmF+r1-`#M zeWZRpZhbNZE$#l+^goaB&7kJdoStRX)AZl(n^)MA`~3u_oE3P#UHN2hKW=?81ubpA zHU0JZHDP;OPS3LHY5K2M&a~+;fYY<`=&9PcrU$2IS@ksi``g_<$2FXuW!2O4_uKkc z72N+9$&|AK-`~35P2oNttjv0v{{5|X-4b_hzhw$qabK@!i3^sTo|Q+>RS!P}a(b3k zPt(7@?Krvt_xpWJIZM4CGX3*&daZzF-1=k+T5-?MW`5i1b9$ClPt$+>`N;7J_xra@ zIVs)4#t>+3Fm{ z?YB%pOWSWve|<`i&-CQjMuFC0IRy|Gs{(-W>o@Le3^zUyY+jeNq=~-4iO@F_g z@N9D{PS47tr~UqXPEV$srM~_&{q?zd`Hha;`eX`PabJH1-rN$#=~;R74D&Z@%;{NH zJx%}p1nv9Qy*WM0s;B9npR*qy^5^s{tDdI+`ZMD6Lhkd2m~xhSe{1@Bc5GIE47Wa+ zf|hoFYx?`Gj^AlGr>Dv2xgURWCofh+xDkzGMG|au_9{uFR3p$xWfFmYAgmZ(n{w1u zQAa3L5|u!&tECC5=#f3h+~UU3G!KP_5PwDn)D*F&z2pbM!5e^^^5F zJAp(^<`ilaDm`JR7U}FG;sh#*IyOe57LX1eI!BpAC>PMz))N90=s}1GF(Kh!ovtUM z2!fCjLkW30q2N2miY&-tQj=50ZU)Lmg&jaPu-&i7=DYlaY_E=cD64(?9^=~@tVeiK z@qT14*7yzC8Fg`V zZe%~iVE@+b*P`(&5tlyKZb4Rg z^=HbuSvS8=S*_ECqXL$W}e7_ap0j}6T`b;6h zFFZnZ(R#i)gZ#hjxP|a%{+LfzpVQPhKmFu$gumW%3i-XbiTvCwHr%1c+6@Wldb|+b z5%m0wIv0_@t|_kDh_gsX-W^A*uR~9)@4T0YueQof+z%05&^&q4V63~a*AR)54-du%QkM_RqM5@@qrtT*C7|j`1-wu`XUS zaNpjs#P!VUxfA)>biw`yRv=uPTnp*W>wn=YdVZZf%A?(N7sYFPjl%WmFcQ~S6@v8A z?&yX3j@Psb&L2B|I~A{e&o5S3|WbAr3KF4WEA!f{Dl2u z52AVU#M4eAKl7R^koB94{CPKhFy7@k#y`Ep{=0W$Ue(v&`CsDWdOCH+b#}GE`-%EJ z!nJ>SVZL?e;rZ)gu>Kd8;5?V7;=Z*E#X4sxPoR0M>x%KC*q_(X1?Q>%6Ta?J7wkX9 z5zo`+3idx8g86Q_j{RerEJgWttjF`@?ZWs0D?FcWf8crE_Qmsg;g08jtOLdm_@71b zsw|v;=xUt*nG*XqeSqt{vM;V%%I|nS%GeDku9^<_%Qh{}v!Mv_s{jdIs{jYjp|1~{uzr8m<2D$CX&ZE9`4r-0~Umbsz)V+j- z=b4p$jtcPTzWTuK$y#Wy2y~y{W;)a~U-agW+fgw7nD4$hW~uPSM{DkWHx<6Nx3XO5 zI|^zgckJ^eAQiGYcxK!pX2WEGYeV;}1o$+m<@Uj{nQ$g+m^yiRHr(4j(j(|)EbOk@ zy{_HfSh)S_Z;LleGr*z7on3oBYGG2u7}cv*6XB23?aqZBO@YOm+DEKAnhg5~3_aEB zY9cHQUfZ|%hUsvB=-c6rscIM@OwN9)nFcuv^@FWCXMjhNU%}HgU54n+I)Q@f|FH$)7^fqf?KWc{h9MD9n9j}=4aej!;a7`yK1*dh2GD+$JlO8 zgKKfFuRqOK!{)jtZzd0(1RtjjZ&oZyg|23So8zq$;bqSet3pZsYr0rH$Q?QzmOfd0 zE`3iT4Ba_o@}4INP;9e%Sx)33m{U0O4#bP#?$QE3s}pm>t?~MRdd=Fk6Qqn zs;u=e@45_jE<3t!>gNq`hwnbZWlIVaSkxT3V(dbw)!FIRvy5FZt7q26D_t|;-d`_P z@@r>li0~{&?n`P{^AT6 zFyDWrk46JlbAAqeF)syrExdO6bLY8mYf;*CMch=FCw;!i@>Vv8{8zc8WXy(V;UVDX zlLJw?=9WHYOJIp$omoVq6wqluZAibYh6TI%PfquagRsz1*J|6O13%tuRKs^k(4^_E z29oL{Vd$>nql1oRz(w9_^^m2}FiWXTY1LW_XWU*by7@L8rj6Ot&9B+W~6DM=t1ZY@;L{gU55+p9!^SulV^)Z)$5l6H(Nj4 zBK4aNw$tat@U!yZqHpu*HzKkjDP;b!hZ`0E5%lcP%^Vffi`>_EMX?5|*7j)iac3I5 zbDeRrXlObtuQOBiz2|UYryjpG_wq&`49j`<1QTMmbq1O!f zLt*Jv+ae2ysAflc+vUKblM8x2ygeD@+t%$`u^<(CJ~%rm^>Zi;t+B}*HfO+^bqAyG z4w?hje=U_=X_5x{@$!vZh(y?XFEIPznB~yG(<}Sju%AKW^l`*58)w6!Do^Uath*fS z>YW|-wc9!v^Wc(4d(Rw5`&E|msL^crwbk)iH5zBYI+vQ0pV!EMqesmW3msCR{<~E* z>bhmZ(nZI&E^3TferW=D9=i_xhbBV2 zo7IT%9Yf*o;}L_}^$vzHXVbb|UosAU>$-ceD0(8qg*t~^-O3tf1OfS{ix(>jiv3bi_p z3IFrgg>bgx<+rEiXyJuZc2Jd_Q(&XE)zbwn=E2~s8JkY5od^X%e2r$?45$%2tggkS zxv*=I`B%q+H2C%K=sNL(Q=!qBP(Mf2eDLH?X<5fS0p9oMB(73R371xcT|crS4ECso z+~W0C!-Ex%mNyDZg>xC^x3Uh#z#MUP|8X~B;g^8%=7}DeU|}|}cY+3(lJfvtO=&dVO8g1!3FZp8pST(oEz_ji?vaLjE<>SD=k z@LoJ&dfj@HVdCpYK4!-?(DZfQTIG#t(EsyW>%z~Oa6oh><e}--2Ic!2Ju}#A)9QIPfukLET2l@Wbm~QSsGP5Ymfycc?fO zayz2ak39dXqSt@uwIq7=S(aCTX2mEvG8UcN1-p`wC33Qn%|9$h_R(oAvi{;6j4zKt zc9|dr*@B7lkuBV$MmGKCG-REN<|6CWNQG=c<2YpfPi7(O<`ac%`1}N9cPz?9wqV+L zWS6zW*Cjmhe0s-Ye_|2FGwb2`_@Bi2oyR4jxE=x6-);FgG}e;mGR3o~KE|CV;{18a z$q3hfHSoGR0gat|$8}=KcMF2 zR$GBAFA3-Gl7i>MTa9(+S>pVgUg?ov_-pK6G;#_WJ9yzd+N0RNXk!w>^$+oN{bjh$ zHV(M1pX=wL=ks>s`7BGo^&6tW^$ZWgI_00j_>Sv1PriacakU-s{B>Q{qH*SLIKR&X z+{bUM79d>N7O$_69@zi0)e?j+^TyY8lVZGoD?FcYGu+3@Pq>aDPC`xhj5=i^H_$i>qX#oTeuF_!P*Vy5C4q&%7M2K`5pKJ z`{z%`c|)>rU)}V^{h#NE`zJgV*GKsV^VVA9eu(d#j`GyD#(2>sJRj{KtYc;Z?u&54 z`t@3c*OBEJtYiKw+y{9#@Vr(v#@Eekj_aU2kMqp$i1T}W7>}-}e2;l8-eJJ682W8W z8s@(a*DpT``+pdR{hO}9b>rpXeJ{QP=CznSpQ!#^wjKM&f5i2eKMUh|%W?fbT)^{j zX^H!@a0sr$)s{GqW&@tTe+ZsW{GFL7Z|^+Ab$`YDmD}+=LvG;t^NR6&_Dsd|j8S9V zi*j+E`C<6F1zT|43Xb7&Ww%szXs5j1voR9b$%K+^Yl5vqz2b9dbN>?fhsIw`UFRJ8e3?ZeBG!&&-E- z{+}D-x)t@o^(_1y*Ucsy&%fXqUKa&hvA_0&4sttCGa|oqPSoqae|P+u7Z>+9=RT#+ z))8>wcEG9n7sf*E-8I@@Z7zjZDbi6cKlXv{hqg+s+KXYx<|A`Omz1D=d+d_KMStk{ zi{i$_rZU(jcz>bM0P?-laj((Ahpm2!9s&u)2Y>NwrUcve*?wlfMnL@-*t6-q5}r1w z>iHyyfR97O-Q>>ida0&+*85@^0sdPG;|_{taH;y%?l(S$gY;3p`OMQH(Du(HReJ46 z7@qAi5t?Iwy($QXL4Sxw?VcY3O;+fJuPcs#Lj8{;4*W41j$H}zS?8;U)7vA& zkK0P%UWbXI{Tn1Ov042eAA4xv?1eQwYjcK!S2J#B=r>QeJT9nVI<+80xo^>q#f z$B(}ddts0gTyN6&)8TN;B`f-lj}q#h*uMH&bAO1>K6P&DpK;*( zcBiDhw-&AruIKFIFM_=z_uQ)`oCr-?Ib9B09|=*j2C1$`1;B%&MRED5li;w-%v--! z3LgiBc1*dH0zK~}cDnpx0=T<2_1t?l9Db?QE_2EG(J*^Q-y50XTFA0L-6rq85DHc) zoW~9g1HrER9gp+GaC$F)eM+Yhps0Iz;MKW7uya)BlJRlK;q0IE&tC>(uV2*iM0AGL3X!>Wyw8t24>Km(@+P3Hyr!z1^% zGtN9sgEKE?bWDpM4c)hnJ=bES7zQ_;v~={*X%HrUvwp$)G0;5s>E7Jv+3@<~54Rg0 z&Vu-7H{FjXM#IES=QCeVQ-PguQ?J6XXt??|#pd{zQJ`Fv)8v41EL`5&gCB1d2oGG+m86Fhl19(W4u2H@my4z!IMY5HPQ7V#&g|#_=oR(#(~BCT zp{|2#hpvqWK>I)M6z%9Mf-pZp%M7=0aF{x7WAm<~;r`~RZtGVif&GBfH8P_V@bE=r z#TrEnxFnrlUZq7eX!+~hs+|{u{T4f$WNQJ;_Sv&EqjeOR+53ph(!yYz^a{CQ$l&hI zNgsSe#Xt;PV%zTVVA%e8LxaURq43lGshup$q;TN*%OMHJdO?wF+e> zcG+n9O$}7SwMlza*5Q-kTx2I3>B-^H@@&H+%UuLe>wepbOGT3)sD9w}_xvEx*jX%n z+Ij>Weh}DkR%0dXJTURb>&3$%G}&eUO|M8e71g@$tzt1e8`){c4yUp3sPN9YF2{u6 zS9RN7RdxadZ9MSz@56&3iGO6D#4Zd*x9GavAzB86{pc_Ci$}p(mG0c|V?$xgO3$0l zA7zmGAA_4G+2A|du&VgJTKesJ!mptS+^UB;6nNTH(P{_&WV$&zE{56@BCL zGsP|98IY`(6F-TU5ZlA<`U@CQ}^vAn3I^Na#F?tVTIQe(o#1H92O}-6Li*HW2 zk`H(O$yhdc=o_<=xDDwpW`|j_klw6WoY=EaFiRE^E|JB?Fm=XUXqb`30JCOcVMMu8 zFiRFTMwB}XBN}GO!p6vnoe>Q)vKZhJj3}Ii5e>6sVPizOvoNAzmMlz0PDbrzq>(Xf zl*I`CjuDMB7#YJXS(uDycLpP4m?aAvBSRkX&LsV#t^5e+l47~m3&D4c~64YOonV??>LFrs0WEKEi&>|JLJ8)Y$qzhgw> z3`WKS+cM(qTE>+(J)IEHb#`B zER1NFk;MR)U_{|8jA)o83mYTKorMt%vt(g1s>|MW#;{QqBltT;G|pgT46|fmGNRoX zjErHHENqM@Nf{bZS!kG%#Q>LJMByxqXqY7n8zah{g%J(2WMN}ONy@^Ah8bB5a0x~f z&ccX>S+cM(qTE>+(J)IEV@4T_8#u%6&4dkE81Oen#<&q9Cd`t>n31u&5hEtdl7)>C zC8?1{bQT(BWHG=c7*RM2BN}GO!p4YlXJJIcELqqXQIfJSqG3iB16+a;g|jfCVU{dx zj3{>&Ml{Tlg~^D%X<{%khK;fq!QU~WaRwt}m?aC75$(=kWDK)pVPix|%EE|-8CeW) z2}Tso!ia`hvam6t+*ugWFiRFTMwFy1jA)pV#Q>LJMByxqXqY7n8zah{g%J(2WMML* zZ<-j4jA5fJM(}rxXq>^w7-q@BWJJ3&7#YJXS=bm+lCm(OVMZ1MT!ImWvoNAzmMm6sVPix| z%EE|-8CeW)2}Tso!ia`hvam6t+*ugWFiRE#BZ;mW`o$VAfrk8CM*L^TW%ys0wg>!1V#w2d2CZay#P=x0U;4w&a*d+t2s z_B(FB=icW>2Of9sbLam5t#hCGdHw(HpAXHr_eZ&XgRB6zZ*u$Q|E+zK)4Ou$&G@|j ze|P+mpVyE3fcwr>fU5vk0j>gE1u9kra)S-?)m2pq<>SiqZYcSg`_c|ZpSj<^YQXit|4t9&x*FDVtj?DFTxIIR7S#eh-;!`68pnz}{~wco&kXMz6~q!m1Qh`_CJ>kaAt4D>svv^KN>EW$Y}nRb zu#2KD_TE?5vTI)#+p4Q8-^{%kHx9G^|Lz0)zAy6&&jTm-opa9I_q}KCoy<%^TAjQ* zbq&yusX#R{@lV@SMmq{=i{E>?= zkc&e2BDtLEkcmPTDOQqO)v7u|)DKgMAf6v0k|_zY?+qm4D851T6(L@DP1(Oll~0|Yr@8xXw0icG~pQ%O~0}y znhk|=tS-^qn`rUZhE{*QZ0$|h5p80GL?@n!%1AB>6)VZE)e4SP^Na|4a`zT8xriSk zR>%ZOs-jJLb=LG$Wsa&u!(eFY2hCAoEfQi-Gr`Ibr$KT*)8J8R}oAv7c!{arD5 zQ$=9=O&zrKCfG`W+#}JBXitzG>6k-wLM2Jn0^vZ_AJJJ;b7UWJ(bf9*MW?ci`g*97 z!^T(hhN#T=UuP3FuaU|uiZ6{(%3_oXa;u@L(O+Bne;q}XpSCLF$f~3#R5FgNm&)?| zlYZNd_}(nlLi?Dhq}6!d5F(K5SUv4&3lTA*reLxRt-qa;DU_T@sd<~EtQ8*Q?{Y|*XkzRRc3<7NNF5jB0+PHE#4=JCnrR4Sd>H*rQ{0}l;lLqs~;mY zrV5|@G1L@%UWDcq&yYGol1X80sL6?%n#toVCQ3;Sk`bP%2|`nn5rl+@qB=#$h-gAi z9v`*GIXh_|Wl3spdzD$FC{)Q0Cd82;7y>jELAd`##`UriMf z>H|F?s+!Pul5Zy9a5rsmw7w|DsH!Rh|=gE?Mdr-awuquRb}+ z5Q=O$i0$7su>`! zuRE`cca)cVzvOwXUm-6~lZRX?@Pbik+WBY4Rrd|Yn*5XFiV%>;myi&VfB&wU+`o3# z^s7c+>(yD)-*4)bh$mObguhLg`Zb}+*My80?D`uRSkZzbtEIn#W&=^c-0j~8U+Kref_<0Fw>HA`ft^p^Uv{%x5w)B zr|!!9qwCMre*H&v_RJ8@>0fxDrr!Tn`~2U(p9A;KKMQqd{y8#uSR&`@zof?WulDu# zQS#;yoYP;2uK#x$@oW_L^w*v1&;IK~#@y3ickVxKF8hgl^Zzm3ng7R6ifF*O`rle( z*PpBX{D1V!S=_t+phMR`*F1W|#rt16bN{{BVAFA&n}2lZ`rF8e?$(^s-@rg;u0IT0 z#OGf9>(KjOQ(N!G9IStxdHzL;6>H{g;>?;-LODcKyHFuRr_l&*I+w7af}agD1NsaBlwB zq3i!Q*5+~X`P-Vh{$K6$|F$HPk({f49lHMiW@PO<(&RH^!;P0m##*0PyZVG{BN~i zf3{ocG?;_>*VOlKRJ;DIZ!P5D^#|Sg{L!hSEo?bg|2p*i)!Sj6!a1kE4t@XX!h7Fw z@BUZGftq^$w%V`1t$McCopbfCL+Afr5_WXwoc=m={r_|~Cr=LQUsKl~s{Q;^zOl%a zgZkIh=Z~sg|6-35N)GB@Q}@5BUH=w0q+I;|`I@T#YJdKu?ZZs&eg0jCzJDog-O{$) zn}2lY`>)c7^L03yq0fJ1ZmS>0x%o$j^cSC)>Bu?#b?E+k=NH`-oYP;2o`2i7%VYxQ^w**5Kdtw@ z;^O-+ojL!E_q#9UVEyaN{a?e;2HZRU(V_Wg(7T1bI9LBVwEjMphBxD!{yKF1ZT)ZI zR-Dschps>OBZkCtPJbP$|91Vhb>^J@IyC=>c6aK;IsJ9${3q_k<}RGmUx%LmG2dUp zJ^gj)^S_%{-0s7<`rqnWQ=h-6_WNJHKW+))oc=oW{SQGthHbc~zwSJLlJ>sqK+fr} zL;rtd_S3^YoYP;2K7SN^YBBdd|Eojuf1i#mCUUO+b?Ewois$UdLH%p|{>y&N7ktME z2|J=qj8KG)%3LlA6)X8lu|&jI4~3Rlx84*p$2`@sCO(=QwV}!LUDk{#NIdi7{ z{T0xg{DG3)$bMJv6tYX^tU=aXunQ=^Yl722v2NtBHX$LTFcJCD0 z-e}=^gdaSO``N6`8Px8Xx)$Z@oK}qdUfwu^^2YBeLj9lfco*{P=7aO!@GL@pWj8Q> zIr22}8{o7S`&;fp`4(+Hh2k!zV_tiscA~iWB8-cDus;53?4O-^5^Yy|tVOoq`7YEC z-!#m(aevI$W$12{e}UI&1hwmXUPRl= zPOL+CYoqBNTi}KnEu>ZhgMJVpcmpy2|X|Wejd+xFgsQq%tL1dS= zy@2AoO4g%x^~%#OtmX?x%6tQH1x{fcvSqxC!~saV$lCMX}3Kdy4x;WP`RIMK-tA614r?AGluL z|Bn4V1F*mJ$TsA+LyG%<)1nZyOM7ia{cad`48=EIzXY}Sj@^vx?HJt8btSl;%XnK6 z42cr)VDD;Vc@BlkSJ5be!|~izNIa(&P2v0w0&6?&Qo}1DQa7|V0~H!VShy=#v`+~ zpng5iK8o_i=3?D`&)tmLs(mHMcC=rH`kCGa_otUD?$3l3%TfL-FEGCDGseFU!Tldc z`cw0=S02`3ZW8wQ8iDI)jGbnDo8kQTdu~Mj=bGU>FLoE8w&yF{f5F5Otd||m?{*gB zsku1MR=35dKV9GBdBuvHKd5!)#i)fS&u(LUT+FpRjPiVxEW`OH;&ou}*b>O=rCEnn z77As^zgqt4kjr1i`efs|JWnMAOiB?wvy+4O-fo|^G@J&Krm1!M8m7Xs`!4T)nJR_5 zXBW2xp|B`Su{3>bOeu5H?T2{^Sl-{`^&0t(*vZQHdh0j}N( zmVFo#2j?gI7(Kh21)cWyezhlO9*pXD(#g#>87zqdjjr9838LNg&LsNHg9+J_d-czX zg;OuG8YLA6z^RcB8<-mB!ix6&ZaIjP!R(0D7Z;Zq@a0;`6Nf2zaQaKo=pCi;P+mT9 zMp=t=2!Bt+XQrpa&bbXQ-F_YoAB|koCb*@+g1sAWb@a{v!$!VAPew(<__}RgAGi?@ ztL`k0@Lwg<$A@J*PqsAxqz++H|*defLh=)7XUbL+10AYQh~GPFwsZ14T< z)x&q0u=>>XJKhHru&nRT*5;Se;QG)&)pYz=+{^X zZTQU6tX2^Wem2f9dem}g``Pqkh;0Ul2Q9FDS}+fadhAcC9k>QMm|59#n|_spg6ZrabcvR=o+qE5&2_FK;f{>DXq{fDdp&l9~nsD|Z$#qXYLc7I$9 zt)4eCwKk0V-{SQeXp51&%UausW=yR!^!YLC%CQP_J_H+!q8r~>3Vd!F5 zvie}aL|Gh|PZy_%TSb7I&+>=MH)TST4R-t6HHw88pB$xAK?*pSBo;e6Erd+NE-#|Y z;vm~)(t(9L5}>HT^V^WJ7@AHxKXB)$Sa{=KJoB;pG*VyQ(Kp76V9}uTh25Q%P;&kB z>je+hU=!KbAvI$q(RwN3l?pBIH~T8RM?>^AJbxZ0-QDQ%V~%PWNfl1GZNoux9k>J;^1&XEYPxY{M?-GZsGJv{o6UF%F(d*{N`pi43+_uZLW z=AeWg4?+)q@R7r}pQ!_|5>^0;5&@c~UrU+Q#mMQ~@8# z-@h?+Qo_WYu5VtKM*!b0FtB7!I+)h}e6YQ7CK$Jjw+gAPgueG`U#yoh6(R;Th~55j zI`EG1!*W|mpkj%k(TMB}5S>((*$bw?$mXI?9&_U1)YXlLLO#Vq!Q%v8vU?76JLbLR zok0XB4Teqa?W2SREk5u*or#6HuMB>&TRa)AxFuYy$4di;AN;48B+r3?*Iqup(sC*U zWw$?Svo#Lvo~|@+QJMu$+7EIV;Wz;r+y3zML`4$p3+VOW#@KXdT6o%b-o6N^*mF3z z@6K@OV{2(@V@CEn_(nt3t#J6=>!ROClksr8Rk_261GB;PaGp~iZ#jGz(DGdQtW=oV zWA?y3_GwV-uvv1MjT~lONhwnung+fZk?jVm)1kI}dAhoQhJZf#b=%L3)J=b_VJQIk(srN#*mXBt)! z*HH*&qb8f4Izx_QdBkD+@u86T(79mlr7-B;EXwxb$R+S+yWeJR97w?V#jW1UfYV)i}ROifllB zDzYcbaemd0GL$#8ZwkUqlNR7SfzfEcxjobHc|y-csNH*GB-&mQkdE*c-4|kfml9b; z^K_IaKQIsT+a*JOD*Fr+S8kJw@S<%pZ|Xdxz)HhwR1|7^4T(qjc08GfZHgSl zWrd}owx4n?vc2u1@cxQY@qW(X{T9uRM*ffd($Rh=U&HwgK#coUKOXnv&3qJp(>5B% z|Bm;&YQCmFnG%c_V}0@;FT(q4ui-l+0kxkF!{e$=ooEr-uG*u-`;kmV z`&T4mea?j8es*-tLjJN$P5pRbUZIiM>n@6Al$v*0-P@q*Jtm|X{bH!G48)=0v;E;v3T5Nt{R;i;X3!an~C;! z(g@d8Q2{>gJX@t9{OLH&d{vC=WU|*Zl;1gjG2&-%G8XGlhIR8gq?v!ZMqypl7+2N9 z{a1{PMR^m}WBmIycz$>kiThbXXmkVY-Sfc6w z-DuRWl5SXsx*s)pepTW;yKp@;ysjCqqu~h8%1%f9?H#VheiLw=CzNL5acr&`$B*%N z{CDF1e?C7C_d|v2+-`n4j&H8vdmHaJw6kV>?J&NBJfEPh3+~`0qkI?EM0aA_sDD2;?9M6XV`;#zlfg0uWvXP+nzzvDGKgaQL7upr;-^>@+ zt^1C-c>LN*k$;*2*5RS+T*z~x*FQ_@{olV^{%TcJ9J<-1?7F`IlJCm;-}elFMMIB{ z`EI=e#*Qqyc*u4fgx+5)?>$!lZO&(@+x!_01#@!mJN#x0kNWMr?>R~W{+$z>+?Xkb z>83ZDfBf@Lx3@OOn$$Tc0L9>s#uqZez+>s4J3h{%K`=P$eV6ghkh$IVy6rv!%6`kv z{d~{|a)0)C);&H1_9T^cr_K+=>)cng06y$G`%}s!>#<;3%iSiZTnvNTFQ{`dRtQ_V zU2kI4ivXAQ_Q!KW6T!%HTqirF7sNhKa(dQ!Jd`E5E?Lz)4n~weiH*;lN>ka47q=bnsIJEF38m_Vt+zOM?0a|DGQSN7k*ZKRGr8D!v=y z8D(4_;@jq3e%RL<%Kmtz@;es|ZdZ@k&B_b_c)8O!#;XqqFYL3rntT_2gSn54I57PwwMTKlGKU(x31vPrDubIed9rqvo<;Y@;GoFW0L#& zW*W@@L%nO*iez|t@$RJdJ_ID)HF@_qS_-PoYu+9T%7D2UHa9=z%HZSeHA9ocGB|E) z{B~9w0_=Z_tSGRU1hKX6?(wym2*+9-TXXYC7F_k5@PoOP09N$=>GtIvIbIJQ<4*H{4S#mxo>KID`25P7zHu>gGUpW77JAqc$2 z+}nL2LIk(-;_ueE7!G&g($Q{r{Gj%R_Y+>M7C_oXpF8%yCBdorqKBL1!(rm|tAALB zPJo`gl%c!AC&R&3D^|!iPK4;)EA|%cCE!%<4-c<(OMs5MH+0N>JQQAEvf6YZdji~B ze)^bM9Jy|6Zu#_GOF!sbR$gb#{E2Yo)s(2%E2E+Q+%~R`izb5EruG9rq=;c=o{#;z z=b=#a%kE7pTqlEvqMKveyFs7|XyRDZOb9RQKD+s#w-=ONz5da7ZZK?nRM4l^=Wr-A zzB}wx!HCnaz5eD z3EXC{{-FNyXVcuSW8lWif}F!WW1;xf=Z99~MuTCyTMmum9U!9B z`Q^mkNJu={x#_$vV<73&&f4Z5_|V`fzx7A*d~NW4ryi-b#{dkOU0yeh4|nF6^}o4K z1hb6mud{AB5cp&F^tg3Z2#3sD*L~SY1O|`OXTy;|IG!dFw!KQezv>)hCwUzTDu;`6 zR}==oFA2Bai(dHx&#+OoL! z8=igi$3QUZzj(!j;WD@rdf0tPxG&tdO}*qXEgbqjKDNDfpb*-2zkCV?1;N-UM^d&9 z6~de^rJWAuM8cRePu%(x`GD6=S%2xTlc9^lnKu?|72vqF|B#}eykOX>wO1Y%PK0-< zXO%E81P%l&xAeN?2Wt{FKsR zEId{=I=RrH0~k-RcKMj-4}755%i;2HtHj^#HfzTpo8 zJ_a4)hXuo1RrBGax(J}#7o)QUzx%>mwFBQK}+_!0r;yjjDRrudV`>HD_Z z--bhnctO;uWnw7XZdPm_AkMr`NstE{TW-m!snNUwQr@`+3bEmks`~x9o+`yhI9r z1`bxw8telODrcYf+asaiRhN^!O|#ldrYvBytintGNFCcD)W&7MT971kX$ZEAh!_`p20M=%223Q zs(sb=JVSI3aiFS}u%|jFdpg2u6KUSw-Xo|Bspt>SK&ckyxZg1R5B_M@|Nn?lyWjYa z?B{=BCu(nU=;$Jn2;%u6BAJp1p`&Cs-_p7Rw?pIZ9Rr%2I zRpmp+SCtPP&-o?3N#!M8A&V3%t6`0&$AW2TZJCy?0j6cf(`{xv-DbwqZ90x=={TmP zhrQ?{Ej$>M8Jl$r-(`{xv-KOK1mX2duI*w_X@pPLRPq&%z zbeoQ2S~`wt={Tlk#?x(PJl$r-(``DAY3VqorQ?{E8Be#F@pPLRPq*nfrlsSUmX2du zW<1?y#?x(PJl&?_n3j%XS~`wtnelX+8Be#F@pPMxV_G_nY3VqoWyaHOW<1?y#?x&& zj%n#QrlsSUmKjgCnelX+8Be$AIHslJn3j%XT4p@mX2#QPW<1@dAbhqInBnrm=4g@e4h!*MU+%Uk|tr^g8HupcK&0leiB4 zujs(}<-IOi-WBSJYJ0+${9HHDA)Bz_nGj8QwTQ;#Z(Ckj3>!T1tzl){gme#Khgq_a z-mFkSL5e+l4 zXy8hWD4c~64YOonV??>LFrs0WEKEk0TIHoRM%u7e7A^Q2Ml{Y~qz$uVVKSoK8H}`H zmMm{X`?Yh}@bzhOk<3`W{8OBN<0+MU5j8)nJE#)ukH z#u!mqXqb^j16N{1;Vg`3m?aAvBg&nH5e>6sVPixMDGMVSW@OR8l^9Vt3nLn4$->5n za%W*g!z@{tjGD7ooi?nMMGO9h5sfn#X~Qg8n2cz51|w~lB?}uPYDgJlL}j62MivcR zi4ldfFrs0WENqM@cNRu8%#wwT5jCVNjA)pVMFUr2MByxqXqY7n8zah{g%J(2WYK1n z!#IJ{%-&2`lZ63)Wu%R3F=E0jS+p5xyK6CG!Yo@F8)nJEWJJ3&7-_>S zS=bm+L(0O4h8bBja3w|*&ccX>S+cM(qTE>+(J)IEHb&HtvM{1yMivcRi4ldfFrs0W zENqM@cNRu8%#uaJNTh0j9<1rXSCZe$h(C7xPrh)YKJ`&4?H_z~RsUD7fL;N;0(u4X z3h0&sd3`ng)hviT|K);crM(!EuXT&PzPEY>^a|(|&?}%<04u;;4}0m?Lw#xJ70@f7 zS3s}8f1v`*^{}^oJ^U}M0zGBD0(u4X3g{JJu7^(g^-y0FdIj_f=oQc_@L#9^^Z(cU zyT@q^_4f<^3u{JCS+9Uz0lflTP=N9OYyRExNB;jBE@+_VpjSYzfL;N;0{?vqYNiJA8f%W{ Z7?mmce+H;8A6D?yJR`!6XcHrJ{2yvykXHZz literal 0 HcmV?d00001 From 227db28b468e9af868c0c4cc94a4e0cd9fcc6c55 Mon Sep 17 00:00:00 2001 From: flowerthrower Date: Tue, 17 Mar 2026 13:12:35 +0100 Subject: [PATCH 11/13] =?UTF-8?q?=F0=9F=8E=A8=20readme?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index bca6a753b..1485b2139 100644 --- a/README.md +++ b/README.md @@ -100,9 +100,7 @@ from mqt.predictor import qcompile from mqt.bench import get_benchmark, BenchmarkLevel # Get a benchmark circuit from MQT Bench -qc_uncompiled = get_benchmark( - benchmark="ghz", level=BenchmarkLevel.ALG, circuit_size=5 -) +qc_uncompiled = get_benchmark(benchmark="ghz", level=BenchmarkLevel.ALG, circuit_size=5) # Compile it using the MQT Predictor qc_compiled, compilation_information, quantum_device = qcompile( From 1a682631bb2291d76df0fe52d443617f71b860ee Mon Sep 17 00:00:00 2001 From: Zhou Shaobo Date: Tue, 17 Mar 2026 13:44:01 +0100 Subject: [PATCH 12/13] Adjust no effect penalty logic --- src/mqt/predictor/rl/predictorenv.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/mqt/predictor/rl/predictorenv.py b/src/mqt/predictor/rl/predictorenv.py index 52ccda125..b121d3191 100644 --- a/src/mqt/predictor/rl/predictorenv.py +++ b/src/mqt/predictor/rl/predictorenv.py @@ -279,13 +279,16 @@ def step(self, action: int) -> tuple[dict[str, Any], float, bool, bool, dict[Any else: new_val, new_kind = self.calculate_reward(mode="auto") delta_reward = new_val - self.prev_reward + reward_kind_changed = self.prev_reward_kind != new_kind - if self.prev_reward_kind != new_kind: + if reward_kind_changed: delta_reward = 0.0 reward_val = ( self.reward_scale * delta_reward if not isclose(delta_reward, 0.0, abs_tol=1e-12) + else 0.0 + if reward_kind_changed else self.no_effect_penalty ) self.prev_reward, self.prev_reward_kind = new_val, new_kind From 6e5e9b3a09272210fbcc6cccee53c1e103837a5e Mon Sep 17 00:00:00 2001 From: flowerthrower Date: Wed, 18 Mar 2026 11:57:08 +0100 Subject: [PATCH 13/13] =?UTF-8?q?=F0=9F=9A=A7=20lift=20bqskit=20restrictio?= =?UTF-8?q?ns?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/mqt/predictor/rl/actions.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/mqt/predictor/rl/actions.py b/src/mqt/predictor/rl/actions.py index d8a0a6d22..05888f7c1 100644 --- a/src/mqt/predictor/rl/actions.py +++ b/src/mqt/predictor/rl/actions.py @@ -375,9 +375,9 @@ def remove_action(name: str) -> None: circuit, optimization_level=1 if os.getenv("GITHUB_ACTIONS") == "true" else 2, synthesis_epsilon=1e-1 if os.getenv("GITHUB_ACTIONS") == "true" else 1e-8, - max_synthesis_size=2 if os.getenv("GITHUB_ACTIONS") == "true" else 3, + max_synthesis_size=3, seed=10, - num_workers=1 if os.getenv("GITHUB_ACTIONS") == "true" else -1, + num_workers=-1, ), ) ) @@ -542,9 +542,9 @@ def remove_action(name: str) -> None: with_mapping=True, optimization_level=1 if os.getenv("GITHUB_ACTIONS") == "true" else 2, synthesis_epsilon=1e-1 if os.getenv("GITHUB_ACTIONS") == "true" else 1e-8, - max_synthesis_size=2 if os.getenv("GITHUB_ACTIONS") == "true" else 3, + max_synthesis_size=3, seed=10, - num_workers=1 if os.getenv("GITHUB_ACTIONS") == "true" else -1, + num_workers=-1, ) ), ) @@ -572,9 +572,9 @@ def remove_action(name: str) -> None: model=MachineModel(bqskit_circuit.num_qudits, gate_set=get_bqskit_native_gates(device)), optimization_level=1 if os.getenv("GITHUB_ACTIONS") == "true" else 2, synthesis_epsilon=1e-1 if os.getenv("GITHUB_ACTIONS") == "true" else 1e-8, - max_synthesis_size=2 if os.getenv("GITHUB_ACTIONS") == "true" else 3, + max_synthesis_size=3, seed=10, - num_workers=1 if os.getenv("GITHUB_ACTIONS") == "true" else -1, + num_workers=-1, ) ), )