From becc89326951dac2caafd5fd7fc4bf3ea4857b86 Mon Sep 17 00:00:00 2001 From: Jake Lishman Date: Tue, 31 Jan 2023 17:10:04 +0000 Subject: [PATCH] Fix bad deprecation of Register.name_format (#9494) * Fix bad deprecation of Register.name_format This inadvertantly made the class attribute accessible only from instances. It's no use for this to only be on instances, since you historically needed to validate against the regex to be sure the instance initialisation would succeed. * Use custom descriptor instead of classmethod/property The positive interaction between `classmethod` and `property` was apparently only added in Python 3.9. * Fixup release note Co-authored-by: Matthew Treinish --------- Co-authored-by: Matthew Treinish Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> (cherry picked from commit 06f5ac1e8d7cbf4dcd157c127911f83c1e43e6ae) --- qiskit/circuit/register.py | 28 ++++++++++--------- ...e-format-deprecation-61ad5b06d618bb29.yaml | 10 +++++++ test/python/circuit/test_register.py | 12 ++++++++ 3 files changed, 37 insertions(+), 13 deletions(-) create mode 100644 releasenotes/notes/fix-register-name-format-deprecation-61ad5b06d618bb29.yaml diff --git a/qiskit/circuit/register.py b/qiskit/circuit/register.py index 9e246a1fd1c1..c8b7974e7e91 100644 --- a/qiskit/circuit/register.py +++ b/qiskit/circuit/register.py @@ -17,12 +17,24 @@ """ import re import itertools +import warnings import numpy as np from qiskit.circuit.exceptions import CircuitError -# Over-specific import to avoid cyclic imports. -from qiskit.utils.deprecation import deprecate_function + +class _NameFormat: + REGEX = re.compile("[a-z][a-zA-Z0-9_]*") + + def __get__(self, obj, objtype=None): + warnings.warn( + "Register.name_format is deprecated as of Qiskit Terra 0.23, and will be removed in a" + " future release. There is no longer a restriction on the names of registers, so the" + " attribute has no meaning any more.", + DeprecationWarning, + stacklevel=2, + ) + return self.REGEX class Register: @@ -30,20 +42,10 @@ class Register: __slots__ = ["_name", "_size", "_bits", "_bit_indices", "_hash", "_repr"] - _name_format = re.compile("[a-z][a-zA-Z0-9_]*") - # In historical version of Terra, registers' name had to conform to the OpenQASM 2 specification # (see appendix A of https://arxiv.org/pdf/1707.03429v2.pdf), and this regex enforced it. That # restriction has been relaxed, so this is no longer necessary. - @property - @deprecate_function( - "Register.name_format is deprecated as of Qiskit Terra 0.23, and will be removed in a" - " future release. There is no longer a restriction on the names of registers, so the" - " attribute has no meaning any more." - ) - def name_format(self): - # pylint: disable=missing-function-docstring - return self._name_format + name_format = _NameFormat() # Counter for the number of instances in this class. instances_counter = itertools.count() diff --git a/releasenotes/notes/fix-register-name-format-deprecation-61ad5b06d618bb29.yaml b/releasenotes/notes/fix-register-name-format-deprecation-61ad5b06d618bb29.yaml new file mode 100644 index 000000000000..e9882f0d44fe --- /dev/null +++ b/releasenotes/notes/fix-register-name-format-deprecation-61ad5b06d618bb29.yaml @@ -0,0 +1,10 @@ +--- +fixes: + - | + Fixed a bad deprecation of :attr:`.Register.name_format` which had made the class attribute + available only from instances and not the class. When trying to send dynamic-circuits jobs to + hardware backends, this would frequently cause the error:: + + AttributeError: 'property' object has no attribute 'match' + + Fixed `#9493 `__. diff --git a/test/python/circuit/test_register.py b/test/python/circuit/test_register.py index 35ddcb3b5bc2..d083e311ecbd 100644 --- a/test/python/circuit/test_register.py +++ b/test/python/circuit/test_register.py @@ -120,3 +120,15 @@ def test_newstyle_register_eq(self, reg_type): bits_difftype = [difftype.bit_type() for _ in range(3)] reg_difftype = difftype(name="foo", bits=bits_difftype) self.assertNotEqual(reg_difftype, test_reg) + + @data(QuantumRegister, ClassicalRegister, AncillaRegister) + def test_register_name_format_deprecation(self, reg_type): + """Test that the `Register.name_format` class data can be accessed and triggers its + deprecation correctly.""" + # From instance: + reg_inst = reg_type(2) + with self.assertWarnsRegex(DeprecationWarning, "Register.name_format is deprecated"): + self.assertTrue(reg_inst.name_format.match("name")) + # From class: + with self.assertWarnsRegex(DeprecationWarning, "Register.name_format is deprecated"): + self.assertTrue(reg_type.name_format.match("name"))