Repository: Qiskit/qiskit (Python)

Issue:
`Register.name_format` inaccessible as class property during deprecation
### Environment

- **Qiskit Terra version**: 0.23.0
- **Python version**: 3.10
- **Operating system**: macOS


### What is happening?

There used to be some class data `Register.name_format`, which is a regex for testing for valid OQ2 identifiers (ignoring keywords).  It's now deprecated as the naming restrictions on registers were relaxed in #9100, but the deprecation is done wrong - it's no longer usable as a class attribute, only an instance one.

### How can we reproduce the issue?

```python
from qiskit import ClassicalRegister

ClassicalRegister.name_format.match("valid_name")
```

gives

```
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-5-8200813a2299> in <module>
      1 from qiskit import ClassicalRegister
      2
----> 3 ClassicalRegister.name_format.match("valid_name")

AttributeError: 'property' object has no attribute 'match'
```

### What should happen?

In older Terras, `Register.name_format` was a `re.Pattern` accessible from the class.  It's not much use to need an _instance_ of `Register` to get the valid name formats to pass to its constructor.

### Any suggestions?

_No response_


Discussion:
Is adding `classmethod` to the property method sufficient or do we need to deprecate via a different mechanism? To be honest undeprecating it isn't terrible either, just carrying around a regex class variable isn't an issue in the grand scheme of weird legacy backwards compat things we have in tree
Yeah, you can just add `classmethod` on top of `property`.  Even if you couldn't, it'd be trivial to write a custom descriptor instead.



Patch:
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 <https://github.com/Qiskit/qiskit-terra/issues/9493>`__.


Test patch:
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"))