Closed pdhoolia closed 7 hours ago
To address the issue of improving support for Python 3.13's copy.replace
and object.__replace__
, we need to ensure that the CircuitInstruction
class, and potentially other similar classes, implement the __replace__
method. This will allow these classes to be compatible with the new copy protocol. Below are the suggested changes for each relevant file:
circuit_instruction.py
__replace__
Method:
replace
method in the CircuitInstruction
class.__replace__
method to mirror the behavior of the existing replace
method.class CircuitInstruction:
# existing code...
def replace(self, **changes):
# existing logic for replace...
pass
def __replace__(self, **changes):
return self.replace(**changes)
data_bin.py
DataBin
or similar classes have a replace
method, implement a __replace__
method.class DataBin:
# existing code...
def replace(self, **changes):
# existing logic for replace...
pass
def __replace__(self, **changes):
return self.replace(**changes)
circuit.py
and data.py
replace
method or are dataclass-like.__replace__
method similar to the above examples.immutable_utils.py
__replace__
method implementations.def apply_changes(obj, **changes):
# Utility function to apply changes immutably
return obj.__class__(**{**obj.__dict__, **changes})
__replace__
method works as expected, maintaining the immutability of the objects.__replace__
method and its usage.replace
method remains functional.By implementing these changes, you will align the Qiskit classes with Python 3.13's new copy.replace
protocol, enhancing interoperability and future-proofing the codebase.
What should we add?
We have some classes that act like immutable record types. These often define a custom
replace
method to allow constructing a new version of the class while making limited changes to a subset of fields. These classes tend now to be the ones defined in Rust space (CircuitInstruction
is a prime example, but there may be more).Python 3.13 formalised this idea into a part of the copy module / pickle protocol, with the user-facing copy.replace and the protocol-level object.replace. We should make sure that Qiskit objects that define a
replace
function with the same semantics expose the same behaviour as__replace__
to improve interoperability with later language features.At the time of writing, I'm only aware of
CircuitInstruction
that does this verbatim, but it's possible that we have other classes that are dataclass-like (for exampleDataBin
) that might want to begin supporting the behaviour.