Repository: Qiskit/qiskit-terra (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_

Pull request:
Fix bad deprecation of Register.name_format

### Summary



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.

<!--
⚠️ If you do not respect this template, your pull request will be closed.
⚠️ Your pull request title should be short detailed and understandable for all.
⚠️ Also, please add a release note file using reno if the change needs to be
  documented in the release notes.
⚠️ If your pull request fixes an open issue, please link to the issue.

- [ ] I have added the tests to cover my changes.
- [ ] I have updated the documentation accordingly.
- [ ] I have read the CONTRIBUTING document.
-->


### Details and comments

Fix #9493



Patch:
diff --git a/qiskit/circuit/register.py b/qiskit/circuit/register.py
index 9e246a1fd..c8b7974e7 100644
--- a/qiskit/circuit/register.py
+++ b/qiskit/circuit/register.py
@@ -17,12 +17,24 @@ Base register reference object.
 """
 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 000000000..e9882f0d4
--- /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 35ddcb3b5..d083e311e 100644
--- a/test/python/circuit/test_register.py
+++ b/test/python/circuit/test_register.py
@@ -120,3 +120,15 @@ class TestRegisterClass(QiskitTestCase):
         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"))