Skip to content

Commit

Permalink
Merge branch 'main' into meow
Browse files Browse the repository at this point in the history
  • Loading branch information
mtreinish authored Feb 23, 2024
2 parents d470006 + 76d1d13 commit 35f1790
Show file tree
Hide file tree
Showing 44 changed files with 954 additions and 252 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
python-version: [3.8, 3.9, '3.10', '3.11']
python-version: [3.8, 3.9, '3.10', '3.11', '3.12']
os: [ "macOS-latest", "ubuntu-latest", "windows-latest" ]
env:
LOG_LEVEL: DEBUG
Expand Down
203 changes: 203 additions & 0 deletions DEPRECATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
# Deprecation Policy

Many users and other packages depend on this package. We must
make sure that whenever we make changes to the code, we give users ample time to
adjust without breaking code that they have already written.

Most importantly: *do not* change any interface that is public-facing unless we
absolutely have to. Adding things is ok, taking things away is annoying for
users but can be handled reasonably with plenty notice, but changing behavior
generally means users cannot write code that will work with two subsequent
versions of qiskit-ibm-runtime, which is not acceptable.

Beware that users will often be using functions, classes and methods that we,
the Qiskit developers, may consider internal or not widely used. Do not make
assumptions that "this is buried, so nobody will be using it"; if it is public,
it is subject to the policy. The only exceptions here are functions and modules
that are explicitly internal, *i.e.* those whose names begin with a leading
underscore (`_`).

The guiding principles are:

- we must not remove or change code without active warnings for at least three
months or two complete version cycles;

- there must always be a way to achieve valid goals that does not issue any
warnings;

- never assume that a function that isn't explicitly internal isn't in use;

- all deprecations, changes and removals are considered API changes, and can
only occur in minor releases not patch releases, per the [stable branch policy](https://github.com/Qiskit/qiskit/blob/main/MAINTAINING.md#stable-branch-policy).


## Removing a feature

When removing a feature (for example a class, function or function parameter),
we will follow this procedure:

- A deprecation warning must be issued prior to any removal. The warning
must indicate what the alternative path is, and the alternative path
must be in place when the warning is issued. When a feature is
deprecated, add a
release note with a `deprecations` section listing all deprecated paths,
their alternatives, and the reason for deprecation. [Update the tests to test the warnings](#testing-deprecated-functionality).

*Reason*: we need to give people time to swap over without breaking their
code as soon as they upgrade.

- Set a removal date for the old feature, and remove it (and the warnings) when
reached. This must be at least three months after the version with the
warnings was first released, and cannot be the minor version immediately
after the warnings. Add an `upgrade` release note that lists all the
removals. For example, if the alternative path was provided
and the warnings were added in `0.20.0`, the earliest version for removal
is `0.22.0`, even if `0.21.0` was released more than three months after
`0.20.0`.

**Note: These are _minimum_** requirements. For removal of significant or core features, give
users at least an extra minor version if not longer.**

*Reason*: there needs to be time for users to see these messages, and to give
them time to adjust. Not all users will update their version of qiskit-ibm-runtime
immediately, and some may skip minor versions.

When a feature is marked as deprecated it is slated for removal, but users
should still be able to rely on it to work correctly. We consider a feature
marked "deprecated" as frozen; we commit to maintaining it with critical bug
fixes until it is removed, but we won't merge new functionality to it.


## Changing behavior


Changing behavior without a removal is particularly difficult to manage, because
we need to have both options available for two versions, and be able to issue
warnings. For example, changing the type of the return value from a function
will almost invariably involve making an API break, which is frustrating for
users and makes it difficult for them to use this package.

The best solution here is often to make a new function, and then use [the procedures for removal](#removing-features) above.

If you absolutely must change the behavior of existing code (other than fixing
bugs), you will need to use your best judgment to apply the guiding principles
at the top of this document. The most appropriate warning for behavioral
changes is usually `FutureWarning`. Some possibilities for how to effect a
change:

- If you are changing the default behavior of a function, consider adding a
keyword argument to select between old and new behaviors. When it comes time,
you can issue a `FutureWarning` if the keyword argument is not given
(*e.g.* if it is `None`), saying that the new value will soon become the
default. You will need to go through the normal deprecation period for
removing this keyword argument after you have made the behavior change. This
will take at least six months to go through both cycles.

- If you need to change the return type of a function, consider adding a new
function that returns the new type, and then follow the procedures for
deprecating the old function.

- If you need to accept a new input that you cannot distinguish from an existing
possibility because of its type, consider letting it be passed by a different
keyword argument, or add a second function that only accepts the new form.



## Issuing deprecation warnings

The proper way to raise a deprecation warning is to use the `@deprecate_function` decorator, and
the `deprecate_arguments` and `issue_deprecation_msg` functions
from `qiskit_ibm_runtime.utils.deprecation`.
These will generate a standardized message and ensure an alternative path is specified.

Usually, you should set `remedy: str` with the format `"Instead, use ..."` so that
people know how to migrate. Read those functions' docstrings for additional arguments like
`version: str`.

If the functions in `qiskit_ibm_runtime.utils.deprecation` cannot handle your use case, consider improving
them. Otherwise, you can directly call the `warn` function
from the [warnings module in the Python standard library](https://docs.python.org/3/library/warnings.html),
using the category `DeprecationWarning`. For example:

```python
import warnings

def deprecated_function():
warnings.warn(
"The function qiskit.deprecated_function() is deprecated since "
"qiskit-ibm-runtime 0.14.0, and will be removed 3 months or more later. "
"Instead, you should use qiskit.other_function().",
category=DeprecationWarning,
stacklevel=2,
)
# ... the rest of the function ...

```

Make sure you include the version of the package that introduced the deprecation
warning (so maintainers can easily see when it is valid to remove it), and what
the alternative path is.

Take note of the `stacklevel` argument. This controls which function is
accused of being deprecated. Setting `stacklevel=1` means the
warning will blame the `warn` function itself, while `stacklevel=2` (the default) will
correctly blame the containing function. It is unusual to set this to anything
other than `2`, but can be useful if you use a helper function to issue the
same warning in multiple places.


## Testing deprecated functionality

Whenever you add deprecation warnings, you will need to update tests involving
the functionality. The test suite should fail otherwise, because of the new
warnings. We must continue to test deprecated functionality throughout the
deprecation period, to ensure that it still works.

To update the tests, you need to wrap each call of deprecated behavior in its
own assertion block. For subclasses of `unittest.TestCase` (which all Qiskit
test cases are), this is done by:


```python
class MyTestSuite(QiskitTestCase):
def test_deprecated_function(self):
with self.assertWarns(DeprecationWarning):
output = deprecated_function()
# ... do some things with output ...
self.assertEqual(output, expected)
```

## Documenting deprecations and breaking changes

It is important to warn the user when your breaking changes are coming.

Make sure to update the docstring of the function, so that it shows up in
API reference.

You can add a [Sphinx deprecated directive](https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html#directive-deprecated):


```python
def deprecated_function():
"""
Short description of the deprecated function.
.. deprecated:: 0.14.0
The function qiskit_ibm_runtime.deprecated_function() is deprecated since
qiskit_ibm_runtime 0.14.0, and will be removed 3 months or more later.
Instead, you should use qiskit_ibm_runtime.other_function().
<rest of the docstring>
"""
# ... the rest of the function ...
```


You should also document the deprecation in the changelog by using Reno. Explain the deprecation
and how to migrate.

In particular situations where a deprecation or change might be a major disruptor for users, a
*migration guide* might be needed. Please write these guides in Qiskit's documentation at
https://github.com/Qiskit/documentation/tree/main/docs/api/migration-guides. Once
the migration guide is written and published, deprecation
messages and documentation should link to it.
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
# The short X.Y version
version = ''
# The full version, including alpha/beta/rc tags
release = '0.19.1'
release = '0.20.1'

# -- General configuration ---------------------------------------------------

Expand Down
5 changes: 2 additions & 3 deletions docs/tutorials/Error-Suppression-and-Error-Mitigation.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -1953,10 +1953,9 @@
}
],
"source": [
"from qiskit.tools import jupyter\n",
"import qiskit\n",
"\n",
"%qiskit_version_table\n",
"%qiskit_copyright"
"qiskit.version.get_version_info()"
]
}
],
Expand Down
23 changes: 11 additions & 12 deletions docs/tutorials/how-to-getting-started-with-estimator.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
}
},
"source": [
"[Primitives](https://qiskit.org/ecosystem/ibm-runtime/primitives.html) are core functions that make it easier to build modular algorithms and applications. \n",
"[Primitives](https://docs.quantum.ibm.com/run/primitives) are core functions that make it easier to build modular algorithms and applications. \n",
"\n",
"The initial release of Qiskit Runtime includes two primitives:\n",
"\n",
Expand Down Expand Up @@ -115,7 +115,7 @@
}
},
"source": [
"For a basic expectation value calculation you will need at least one quantum circuit to prepare our system in a precise quantum state for study. Our examples all have circuits in them, but you can use Qiskit to create your own. To learn how to create circuits by using Qiskit, see the [Circuit basics tutorial](https://qiskit.org/documentation/tutorials/circuits/01_circuit_basics.html)."
"For a basic expectation value calculation you will need at least one quantum circuit to prepare our system in a precise quantum state for study. Our examples all have circuits in them, but you can use Qiskit to create your own. To learn how to create circuits by using Qiskit, see [the documentation](https://docs.quantum.ibm.com/build/circuit-construction)."
]
},
{
Expand Down Expand Up @@ -167,7 +167,7 @@
}
},
"source": [
"You will also need at least one observable to measure. Observables represent physical properties of a quantum system (such as energy or spin), and allow said properties to be measured (such as their expectation values) for a given state of our system. For simplicity, you can use the [SparsePauliOp class](https://qiskit.org/documentation/stubs/qiskit.quantum_info.SparsePauliOp.html#qiskit.quantum_info.SparsePauliOp) in Qiskit to define them, as illustrated in the following example."
"You will also need at least one observable to measure. Observables represent physical properties of a quantum system (such as energy or spin), and allow said properties to be measured (such as their expectation values) for a given state of our system. For simplicity, you can use the [SparsePauliOp class](https://docs.quantum.ibm.com/api/qiskit/qiskit.quantum_info.SparsePauliOp) in Qiskit to define them, as illustrated in the following example."
]
},
{
Expand Down Expand Up @@ -218,7 +218,7 @@
},
"source": [
"<!-- vale IBMQuantum.Spelling = NO -->\n",
"The next step is to create an instance of an `Estimator` class, which can be any of the subclasses that comply with the base specification. For simplicity, we will use Qiskit Terra's `qiskit.primitives.Estimator` class, based on the [Statevector construct](https://qiskit.org/documentation/stubs/qiskit.quantum_info.Statevector.html?highlight=statevector#qiskit.quantum_info.Statevector) (algebraic simulation).\n",
"The next step is to create an instance of an `Estimator` class, which can be any of the subclasses that comply with the base specification. For simplicity, we will use Qiskit Terra's `qiskit.primitives.Estimator` class, based on the [Statevector construct](https://docs.quantum.ibm.com/api/qiskit/qiskit.quantum_info.Statevector) (algebraic simulation).\n",
"<!-- vale IBMQuantum.Spelling = YES -->"
]
},
Expand Down Expand Up @@ -551,7 +551,7 @@
"source": [
"Since Qiskit Runtime `Estimator` is a managed service, you will first need to initialize your account. You can then select the simulator or real backend you want to use to calculate the expectation value.\n",
"\n",
"Follow the steps in the [getting started guide](https://qiskit.org/documentation/partners/qiskit_ibm_runtime/getting_started.html) if you don't already have an account set up."
"Follow the steps in the [set up documentation](https://docs.quantum.ibm.com/start/setup-channel) if you don't already have an account set up."
]
},
{
Expand Down Expand Up @@ -788,7 +788,7 @@
}
},
"source": [
"You can use the [Options](https://qiskit.org/documentation/partners/qiskit_ibm_runtime/stubs/qiskit_ibm_runtime.options.Options.html#qiskit_ibm_runtime.options.Options) class to specify different options."
"You can use the [Options](https://docs.quantum.ibm.com/api/qiskit-ibm-runtime/qiskit_ibm_runtime.options.Options) class to specify different options."
]
},
{
Expand Down Expand Up @@ -1044,7 +1044,7 @@
"\n",
"If you don't specify a timeout value, it is set to the initial job's maximum execution time and is the smaller of these values:\n",
"\n",
"- The system limit (see [What is the maximum execution time for a Qiskit Runtime job?](https://qiskit.org/documentation/partners/qiskit_ibm_runtime/faqs/max_execution_time.html)).\n",
"- The system limit (see [What is the maximum execution time for a Qiskit Runtime job?](https://docs.quantum.ibm.com/run/max-execution-time)).\n",
"- The `max_execution_time` defined by the program.\n",
"\n",
"After this time limit is reached, the session is permanently closed."
Expand Down Expand Up @@ -1366,9 +1366,9 @@
"id": "bf0fe74a",
"metadata": {},
"source": [
"You can find more details about the ``Estimator`` methods in the [Estimator API reference](https://qiskit.org/documentation/partners/qiskit_ibm_runtime/stubs/qiskit_ibm_runtime.Estimator.html#qiskit_ibm_runtime.Estimator).\n",
"You can find more details about the ``Estimator`` methods in the [Estimator API reference](https://docs.quantum.ibm.com/api/qiskit-ibm-runtime/qiskit_ibm_runtime.Estimator).\n",
"\n",
"And all the available options in the [Options API reference](https://qiskit.org/documentation/partners/qiskit_ibm_runtime/stubs/qiskit_ibm_runtime.options.Options.html#qiskit_ibm_runtime.options.Options)."
"And all the available options in the [Options API reference](https://docs.quantum.ibm.com/api/qiskit-ibm-runtime/qiskit_ibm_runtime.options.Options)."
]
},
{
Expand Down Expand Up @@ -1426,10 +1426,9 @@
}
],
"source": [
"from qiskit.tools.jupyter import *\n",
"import qiskit\n",
"\n",
"%qiskit_version_table\n",
"%qiskit_copyright"
"qiskit.version.get_version_info()"
]
}
],
Expand Down
19 changes: 9 additions & 10 deletions docs/tutorials/how-to-getting-started-with-sampler.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
}
},
"source": [
"[Primitives](https://qiskit.org/ecosystem/ibm-runtime/primitives.html) are core functions that make it easier to build modular algorithms and applications. \n",
"[Primitives](https://docs.quantum.ibm.com/run/primitives) are core functions that make it easier to build modular algorithms and applications. \n",
"\n",
"The initial release of Qiskit Runtime includes two primitives:\n",
"\n",
Expand Down Expand Up @@ -115,7 +115,7 @@
}
},
"source": [
"You will need at least one quantum circuit to prepare our system in a precise quantum state for study. Our examples all have circuits in them, but you can use Qiskit to create your own. To learn how to create circuits by using Qiskit, see the [Circuit basics tutorial](https://qiskit.org/documentation/tutorials/circuits/01_circuit_basics.html)."
"You will need at least one quantum circuit to prepare our system in a precise quantum state for study. Our examples all have circuits in them, but you can use Qiskit to create your own. To learn how to create circuits by using Qiskit, see the [circuit construction documentation](https://docs.quantum.ibm.com/build/circuit-construction)."
]
},
{
Expand Down Expand Up @@ -492,7 +492,7 @@
"source": [
"Since Qiskit Runtime `Sampler` is a managed service, you will first need to initialize your account. You can then select the simulator or real backend you want to use to calculate the expectation value.\n",
"\n",
"Follow the steps in the [getting started guide](https://qiskit.org/documentation/partners/qiskit_ibm_runtime/getting_started.html) if you don't already have an account set up."
"Follow the steps in the [setup guide](https://docs.quantum.ibm.com/start/setup-channel) if you don't already have an account set up."
]
},
{
Expand Down Expand Up @@ -719,7 +719,7 @@
}
},
"source": [
"You can use the [Options](https://qiskit.org/documentation/partners/qiskit_ibm_runtime/stubs/qiskit_ibm_runtime.options.Options.html#qiskit_ibm_runtime.options.Options) class to specify different options."
"You can use the [Options](https://docs.quantum.ibm.com/api/qiskit-ibm-runtime/qiskit_ibm_runtime.options.Options) class to specify different options."
]
},
{
Expand Down Expand Up @@ -973,7 +973,7 @@
"\n",
"If you don't specify a timeout value, it is set to the initial job's maximum execution time and is the smaller of these values:\n",
"\n",
"- The system limit (see [What is the maximum execution time for a Qiskit Runtime job?](https://qiskit.org/documentation/partners/qiskit_ibm_runtime/faqs/max_execution_time.html)).\n",
"- The system limit (see [What is the maximum execution time for a Qiskit Runtime job?](https://docs.quantum.ibm.com/run/max-execution-time)).\n",
"- The `max_execution_time` defined by the program.\n",
"\n",
"After this time limit is reached, the session is permanently closed."
Expand Down Expand Up @@ -1305,9 +1305,9 @@
"id": "e5827c27",
"metadata": {},
"source": [
"You can find more details about the ``Sampler`` methods in the [Sampler API reference](https://qiskit.org/documentation/partners/qiskit_ibm_runtime/stubs/qiskit_ibm_runtime.Sampler.html#qiskit_ibm_runtime.Sampler).\n",
"You can find more details about the ``Sampler`` methods in the [Sampler API reference](https://docs.quantum.ibm.com/api/qiskit-ibm-runtime/qiskit_ibm_runtime.Sampler).\n",
"\n",
"And all the available options in the [Options API reference](https://qiskit.org/documentation/partners/qiskit_ibm_runtime/stubs/qiskit_ibm_runtime.options.Options.html#qiskit_ibm_runtime.options.Options)."
"And all the available options in the [Options API reference](https://docs.quantum.ibm.com/api/qiskit-ibm-runtime/qiskit_ibm_runtime.options.Options)."
]
},
{
Expand Down Expand Up @@ -1365,10 +1365,9 @@
}
],
"source": [
"from qiskit.tools.jupyter import *\n",
"import qiskit\n",
"\n",
"%qiskit_version_table\n",
"%qiskit_copyright"
"qiskit.version.get_version_info()"
]
}
],
Expand Down
Loading

0 comments on commit 35f1790

Please sign in to comment.