{"payload":{"allShortcutsEnabled":false,"fileTree":{"":{"items":[{"name":".azure","path":".azure","contentType":"directory"},{"name":".binder","path":".binder","contentType":"directory"},{"name":".cargo","path":".cargo","contentType":"directory"},{"name":".github","path":".github","contentType":"directory"},{"name":"crates","path":"crates","contentType":"directory"},{"name":"docs","path":"docs","contentType":"directory"},{"name":"examples","path":"examples","contentType":"directory"},{"name":"qiskit","path":"qiskit","contentType":"directory"},{"name":"releasenotes","path":"releasenotes","contentType":"directory"},{"name":"test","path":"test","contentType":"directory"},{"name":"tools","path":"tools","contentType":"directory"},{"name":".editorconfig","path":".editorconfig","contentType":"file"},{"name":".git-blame-ignore-revs","path":".git-blame-ignore-revs","contentType":"file"},{"name":".gitignore","path":".gitignore","contentType":"file"},{"name":".local-spellings","path":".local-spellings","contentType":"file"},{"name":".mailmap","path":".mailmap","contentType":"file"},{"name":".mergify.yml","path":".mergify.yml","contentType":"file"},{"name":".stestr.conf","path":".stestr.conf","contentType":"file"},{"name":"CITATION.bib","path":"CITATION.bib","contentType":"file"},{"name":"CODE_OF_CONDUCT.md","path":"CODE_OF_CONDUCT.md","contentType":"file"},{"name":"CONTRIBUTING.md","path":"CONTRIBUTING.md","contentType":"file"},{"name":"Cargo.lock","path":"Cargo.lock","contentType":"file"},{"name":"Cargo.toml","path":"Cargo.toml","contentType":"file"},{"name":"DEPRECATION.md","path":"DEPRECATION.md","contentType":"file"},{"name":"LICENSE.txt","path":"LICENSE.txt","contentType":"file"},{"name":"MAINTAINING.md","path":"MAINTAINING.md","contentType":"file"},{"name":"MANIFEST.in","path":"MANIFEST.in","contentType":"file"},{"name":"Makefile","path":"Makefile","contentType":"file"},{"name":"README.md","path":"README.md","contentType":"file"},{"name":"SECURITY.md","path":"SECURITY.md","contentType":"file"},{"name":"asv.conf.json","path":"asv.conf.json","contentType":"file"},{"name":"azure-pipelines.yml","path":"azure-pipelines.yml","contentType":"file"},{"name":"constraints.txt","path":"constraints.txt","contentType":"file"},{"name":"pyproject.toml","path":"pyproject.toml","contentType":"file"},{"name":"qiskit_bot.yaml","path":"qiskit_bot.yaml","contentType":"file"},{"name":"requirements-dev.txt","path":"requirements-dev.txt","contentType":"file"},{"name":"requirements-optional.txt","path":"requirements-optional.txt","contentType":"file"},{"name":"requirements.txt","path":"requirements.txt","contentType":"file"},{"name":"rust-toolchain.toml","path":"rust-toolchain.toml","contentType":"file"},{"name":"setup.py","path":"setup.py","contentType":"file"},{"name":"tox.ini","path":"tox.ini","contentType":"file"}],"totalCount":41}},"fileTreeProcessingTime":4.050106,"foldersToFetch":[],"repo":{"id":83821669,"defaultBranch":"main","name":"qiskit","ownerLogin":"Qiskit","currentUserCanPush":false,"isFork":false,"isEmpty":false,"createdAt":"2017-03-03T17:02:42.000Z","ownerAvatar":"https://avatars.githubusercontent.com/u/30696987?v=4","public":true,"private":false,"isOrgOwned":true},"symbolsExpanded":false,"treeExpanded":true,"refInfo":{"name":"main","listCacheKey":"v0:1710846404.0","canEdit":false,"refType":"branch","currentOid":"43381ae1b159c01b55159d2dc1e8a65970b72746"},"path":"CONTRIBUTING.md","currentUser":null,"blob":{"rawLines":null,"stylingDirectives":null,"colorizedLines":null,"csv":null,"csvError":null,"dependabotInfo":{"showConfigurationBanner":false,"configFilePath":null,"networkDependabotPath":"/Qiskit/qiskit/network/updates","dismissConfigurationNoticePath":"/settings/dismiss-notice/dependabot_configuration_notice","configurationNoticeDismissed":null},"displayName":"CONTRIBUTING.md","displayUrl":"https://github.com/Qiskit/qiskit/blob/main/CONTRIBUTING.md?raw=true","headerInfo":{"blobSize":"36.8 KB","deleteTooltip":"You must be signed in to make or propose changes","editTooltip":"You must be signed in to make or propose changes","ghDesktopPath":"https://desktop.github.com","isGitLfs":false,"onBranch":true,"shortPath":"402bc91","siteNavLoginPath":"/login?return_to=https%3A%2F%2Fgithub.com%2FQiskit%2Fqiskit%2Fblob%2Fmain%2FCONTRIBUTING.md","isCSV":false,"isRichtext":true,"toc":[{"level":1,"text":"Contributing","anchor":"contributing","htmlText":"Contributing"},{"level":2,"text":"Contents","anchor":"contents","htmlText":"Contents"},{"level":2,"text":"Before you start","anchor":"before-you-start","htmlText":"Before you start"},{"level":2,"text":"Choose an issue to work on","anchor":"choose-an-issue-to-work-on","htmlText":"Choose an issue to work on"},{"level":2,"text":"Set up Python virtual development environment","anchor":"set-up-python-virtual-development-environment","htmlText":"Set up Python virtual development environment"},{"level":3,"text":"Set up a Python venv","anchor":"set-up-a-python-venv","htmlText":"Set up a Python venv"},{"level":3,"text":"Set up a Conda environment","anchor":"set-up-a-conda-environment","htmlText":"Set up a Conda environment"},{"level":2,"text":"Installing Qiskit from source","anchor":"installing-qiskit-from-source","htmlText":"Installing Qiskit from source"},{"level":2,"text":"Issues and pull requests","anchor":"issues-and-pull-requests","htmlText":"Issues and pull requests"},{"level":3,"text":"Pull request checklist","anchor":"pull-request-checklist","htmlText":"Pull request checklist"},{"level":3,"text":"Code Review","anchor":"code-review","htmlText":"Code Review"},{"level":2,"text":"Contributor Licensing Agreement","anchor":"contributor-licensing-agreement","htmlText":"Contributor Licensing Agreement"},{"level":2,"text":"Changelog generation","anchor":"changelog-generation","htmlText":"Changelog generation"},{"level":2,"text":"Release notes","anchor":"release-notes","htmlText":"Release notes"},{"level":3,"text":"Adding a new release note","anchor":"adding-a-new-release-note","htmlText":"Adding a new release note"},{"level":4,"text":"Linking to issues","anchor":"linking-to-issues","htmlText":"Linking to issues"},{"level":4,"text":"Generating the release notes","anchor":"generating-the-release-notes","htmlText":"Generating the release notes"},{"level":4,"text":"Building release notes locally","anchor":"building-release-notes-locally","htmlText":"Building release notes locally"},{"level":2,"text":"Testing","anchor":"testing","htmlText":"Testing"},{"level":5,"text":"STDOUT/STDERR and logging capture","anchor":"stdoutstderr-and-logging-capture","htmlText":"STDOUT/STDERR and logging capture"},{"level":5,"text":"Test Skip Options","anchor":"test-skip-options","htmlText":"Test Skip Options"},{"level":3,"text":"Snapshot Testing for Visualizations","anchor":"snapshot-testing-for-visualizations","htmlText":"Snapshot Testing for Visualizations"},{"level":2,"text":"Style and lint","anchor":"style-and-lint","htmlText":"Style and lint"},{"level":2,"text":"Building API docs locally","anchor":"building-api-docs-locally","htmlText":"Building API docs locally"},{"level":2,"text":"Development cycle","anchor":"development-cycle","htmlText":"Development cycle"},{"level":3,"text":"Branches","anchor":"branches","htmlText":"Branches"},{"level":3,"text":"Release cycle","anchor":"release-cycle","htmlText":"Release cycle"},{"level":2,"text":"Adding deprecation warnings","anchor":"adding-deprecation-warnings","htmlText":"Adding deprecation warnings"},{"level":2,"text":"Using dependencies","anchor":"using-dependencies","htmlText":"Using dependencies"},{"level":3,"text":"Adding a requirement","anchor":"adding-a-requirement","htmlText":"Adding a requirement"},{"level":3,"text":"Adding an optional dependency","anchor":"adding-an-optional-dependency","htmlText":"Adding an optional dependency"},{"level":3,"text":"Checking for optionals","anchor":"checking-for-optionals","htmlText":"Checking for optionals"},{"level":2,"text":"Dealing with the git blame ignore list","anchor":"dealing-with-the-git-blame-ignore-list","htmlText":"Dealing with the git blame ignore list"}],"lineInfo":{"truncatedLoc":"729","truncatedSloc":"564"},"mode":"file"},"image":false,"isCodeownersFile":null,"isPlain":false,"isValidLegacyIssueTemplate":false,"issueTemplate":null,"discussionTemplate":null,"language":"Markdown","languageID":222,"large":false,"planSupportInfo":{"repoIsFork":null,"repoOwnedByCurrentUser":null,"requestFullPath":"/Qiskit/qiskit/blob/main/CONTRIBUTING.md","showFreeOrgGatedFeatureMessage":null,"showPlanSupportBanner":null,"upgradeDataAttributes":null,"upgradePath":null},"publishBannersInfo":{"dismissActionNoticePath":"/settings/dismiss-notice/publish_action_from_dockerfile","releasePath":"/Qiskit/qiskit/releases/new?marketplace=true","showPublishActionBanner":false},"rawBlobUrl":"https://github.com/Qiskit/qiskit/raw/main/CONTRIBUTING.md","renderImageOrRaw":false,"richText":"

Contributing

\n

Qiskit is an open-source project committed to bringing quantum computing to\npeople of all backgrounds. This page describes how you can join the Qiskit\ncommunity in this goal.

\n

Contents

\n\n

Before you start

\n

If you are new to Qiskit contributing we recommend you do the following before diving into the code:

\n\n

Choose an issue to work on

\n

Qiskit uses the following labels to help non-maintainers find issues best suited to their interests and experience level:

\n\n

Set up Python virtual development environment

\n

Virtual environments are used for Qiskit development to isolate the development environment\nfrom system-wide packages. This way, we avoid inadvertently becoming dependent on a\nparticular system configuration. For developers, this also makes it easy to maintain multiple\nenvironments (e.g. one per supported Python version, for older versions of Qiskit, etc.).

\n

Set up a Python venv

\n

All Python versions supported by Qiskit include built-in virtual environment module\nvenv.

\n

Start by creating a new virtual environment with venv. The resulting\nenvironment will use the same version of Python that created it and will not inherit installed\nsystem-wide packages by default. The specified folder will be created and is used to hold the environment's\ninstallation. It can be placed anywhere. For more detail, see the official Python documentation,\nCreation of virtual environments.

\n
python3 -m venv ~/.venvs/qiskit-dev\n
\n

Activate the environment by invoking the appropriate activation script for your system, which can\nbe found within the environment folder. For example, for bash/zsh:

\n
source ~/.venvs/qiskit-dev/bin/activate\n
\n

Upgrade pip within the environment to ensure Qiskit dependencies installed in the subsequent sections\ncan be located for your system.

\n
pip install -U pip\n
\n
pip install -e .\n
\n

Set up a Conda environment

\n

For Conda users, a new environment can be created as follows.

\n
conda create -y -n QiskitDevenv python=3\nconda activate QiskitDevenv\n
\n
pip install -e .\n
\n

Installing Qiskit from source

\n

Qiskit is primarily written in Python but there are some core routines\nthat are written in the Rust programming\nlanguage to improve the runtime performance. For the released versions of\nqiskit we publish precompiled binaries on the\nPython Package Index for all the supported platforms\nwhich only requires a functional Python environment to install. However, when\nbuilding and installing from source you will need a rust compiler installed. You can do this very easily\nusing rustup: https://rustup.rs/ which provides a single tool to install and\nconfigure the latest version of the rust compiler.\nOther installation methods\nexist too. For Windows users, besides rustup, you will also need install\nthe Visual C++ build tools so that Rust can link against the system c/c++\nlibraries. You can see more details on this in the\nrustup documentation.

\n

If you use Rustup, it will automatically install the correct Rust version\ncurrently used by the project.

\n

Once you have a Rust compiler installed, you can rely on the normal Python\nbuild/install steps to install Qiskit. This means you just run\npip install . in your local git clone to build and install Qiskit.

\n

Do note that if you do use develop mode/editable install (via python setup.py develop or pip install -e .) the Rust extension will be built in debug mode\nwithout any optimizations enabled. This will result in poor runtime performance.\nIf you'd like to use an editable install with an optimized binary you can\nrun python setup.py build_rust --release --inplace after you install in\neditable mode to recompile the rust extensions in release mode.

\n

Note that in order to run python setup.py ... commands you need have build\ndependency packages installed in your environment, which are listed in the\npyproject.toml file under the [build-system] section.

\n

Issues and pull requests

\n

We use GitHub pull requests to accept\ncontributions.

\n

While not required, opening a new issue about the bug you're fixing or the\nfeature you're working on before you open a pull request is an important step\nin starting a discussion with the community about your work. The issue gives us\na place to talk about the idea and how we can work together to implement it in\nthe code. It also lets the community know what you're working on, and if you\nneed help, you can reference the issue when discussing it with other community\nand team members.

\n\n

If you've written some code but need help finishing it, want to get initial\nfeedback on it prior to finishing it, or want to share it and discuss prior\nto finishing the implementation, you can open a Draft pull request and prepend\nthe title with the [WIP] tag (for Work In Progress). This will indicate\nto reviewers that the code in the PR isn't in its final state and will change.\nIt also means that we will not merge the commit until it is finished. You or a\nreviewer can remove the [WIP] tag when the code is ready to be fully reviewed for merging.

\n

Before marking your Pull Request as \"ready for review\" make sure you have followed the\nPR Checklist below. PRs that adhere to this list are more likely to get reviewed and\nmerged in a timely manner.

\n

Pull request checklist

\n

When submitting a pull request and you feel it is ready for review,\nplease ensure that:

\n
    \n
  1. \n

    The code follows the code style of the project and successfully\npasses the CI tests. For convenience, you can execute tox locally,\nwhich will run these checks and report any issues.

    \n

    If your code fails the local style checks (specifically the black\ncode formatting check) you can use tox -eblack to automatically\nfix update the code formatting.

    \n
  2. \n
  3. \n

    The documentation has been updated accordingly. In particular, if a\nfunction or class has been modified during the PR, please update the\ndocstring accordingly.

    \n

    If your pull request is adding a new class, function, or module that is\nintended to be user facing ensure that you've also added those to a\ndocumentation autosummary index to include it in the api documentation.

    \n
  4. \n
  5. \n

    If it makes sense for your change that you have added new tests that\ncover the changes.

    \n
  6. \n
  7. \n

    Ensure that if your change has an end user facing impact (new feature,\ndeprecation, removal etc) that you have added a reno release note for that\nchange and that the PR is tagged for the changelog.

    \n
  8. \n
  9. \n

    All contributors have signed the CLA.

    \n
  10. \n
  11. \n

    The PR has a concise and explanatory title (e.g. Fixes Issue1234 is a bad title!).

    \n
  12. \n
  13. \n

    If the PR addresses an open issue the PR description includes the fixes #issue-number\nsyntax to link the PR to that issue (you must use the exact phrasing in order for GitHub\nto automatically close the issue when the PR merges)

    \n
  14. \n
\n

Code Review

\n

Code review is done in the open and is open to anyone. While only maintainers have\naccess to merge commits, community feedback on pull requests is extremely valuable.\nIt is also a good mechanism to learn about the code base.

\n

Response times may vary for your PR, it is not unusual to wait a few weeks for a maintainer\nto review your work, due to other internal commitments. If you have been waiting over a week\nfor a review on your PR feel free to tag the relevant maintainer in a comment to politely remind\nthem to review your work.

\n

Please be patient! Maintainers have a number of other priorities to focus on and so it may take\nsome time for your work to get reviewed and merged. PRs that are in a good shape (i.e. following the Pull request checklist)\nare easier for maintainers to review and more likely to get merged in a timely manner. Please also make\nsure to always be kind and respectful in your interactions with maintainers and other contributors, you can read\nthe Qiskit Code of Conduct.

\n

Contributor Licensing Agreement

\n

Before you can submit any code, all contributors must sign a\ncontributor license agreement (CLA). By signing a CLA, you're attesting\nthat you are the author of the contribution, and that you're freely\ncontributing it under the terms of the Apache-2.0 license.

\n

When you contribute to the Qiskit project with a new pull request,\na bot will evaluate whether you have signed the CLA. If required, the\nbot will comment on the pull request, including a link to accept the\nagreement. The individual CLA\ndocument is available for review as a PDF.

\n

Note: If your contribution is part of your employment or your contribution\nis the property of your employer, then you will more than likely need to sign a\ncorporate CLA too and\nemail it to us at qiskit@us.ibm.com.

\n

Changelog generation

\n

The changelog is automatically generated as part of the release process\nautomation. This works through a combination of the git log and the pull\nrequest. When a release is tagged and pushed to github the release automation\nbot looks at all commit messages from the git log for the release. It takes the\nPR numbers from the git log (assuming a squash merge) and checks if that PR had\na Changelog: label on it. If there is a label it will add the git commit\nmessage summary line from the git log for the release to the changelog.

\n

If there are multiple Changelog: tags on a PR the git commit message summary\nline from the git log will be used for each changelog category tagged.

\n

The current categories for each label are as follows:

\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
PR LabelChangelog Category
Changelog: DeprecationDeprecated
Changelog: New FeatureAdded
Changelog: API ChangeChanged
Changelog: RemovalRemoved
Changelog: BugfixFixed
\n

Release notes

\n

When making any end user facing changes in a contribution we have to make sure\nwe document that when we release a new version of qiskit. The expectation\nis that if your code contribution has user facing changes that you will write\nthe release documentation for these changes. This documentation must explain\nwhat was changed, why it was changed, and how users can either use or adapt\nto the change. The idea behind release documentation is that when a naive\nuser with limited internal knowledge of the project is upgrading from the\nprevious release to the new one, they should be able to read the release notes,\nunderstand if they need to update their program which uses qiskit, and how they\nwould go about doing that. It ideally should explain why they need to make\nthis change too, to provide the necessary context.

\n

To make sure we don't forget a release note or if the details of user facing\nchanges over a release cycle we require that all user facing changes include\ndocumentation at the same time as the code. To accomplish this we use the\nreno tool which enables a git based\nworkflow for writing and compiling release notes.

\n

Adding a new release note

\n

Making a new release note is quite straightforward. Ensure that you have reno\ninstalled with:

\n
pip install -U reno\n
\n

Once you have reno installed you can make a new release note by running in\nyour local repository checkout's root:

\n
reno new short-description-string\n
\n

where short-description-string is a brief string (with no spaces) that describes\nwhat's in the release note. This will become the prefix for the release note\nfile. Once that is run it will create a new yaml file in releasenotes/notes.\nThen open that yaml file in a text editor and write the release note. The basic\nstructure of a release note is restructured text in yaml lists under category\nkeys. You add individual items under each category and they will be grouped\nautomatically by release when the release notes are compiled. A single file\ncan have as many entries in it as needed, but to avoid potential conflicts\nyou'll want to create a new file for each pull request that has user facing\nchanges. When you open the newly created file it will be a full template of\nthe different categories with a description of a category as a single entry\nin each category. You'll want to delete all the sections you aren't using and\nupdate the contents for those you are. For example, the end result should\nlook something like:

\n
features:\n  - |\n    Introduced a new feature foo, that adds support for doing something to\n    :class:`.QuantumCircuit` objects. It can be used by using the foo function,\n    for example::\n\n      from qiskit import foo\n      from qiskit import QuantumCircuit\n      foo(QuantumCircuit())\n\n  - |\n    The :class:`.QuantumCircuit` class has a new method :meth:`~.QuantumCircuit.foo`. \n    This is the equivalent of calling the :func:`~qiskit.foo` to do something to your\n    :class:`.QuantumCircuit`. This is the equivalent of running :func:`~qiskit.foo` \n    on your circuit, but provides the convenience of running it natively on\n    an object. For example::\n\n      from qiskit import QuantumCircuit\n\n      circ = QuantumCircuit()\n      circ.foo()\n\ndeprecations:\n  - |\n    The ``qiskit.bar`` module has been deprecated and will be removed in a\n    future release. Its sole function, ``foobar()`` has been superseded by the\n    :func:`~qiskit.foo` function which provides similar functionality but with\n    more accurate results and better performance. You should update your\n    :func:`~qiskit.bar.foobar` calls to :func:`~qiskit.foo`.
\n

You can also look at other release notes for other examples.

\n

Note that you can use sphinx restructured text syntax.\nIn fact, you can use any restructured text feature in them (code sections, tables,\nenumerated lists, bulleted list, etc) to express what is being changed as\nneeded. In general you want the release notes to include as much detail as\nneeded so that users will understand what has changed, why it changed, and how\nthey'll have to update their code.

\n

After you've finished writing your release notes you'll want to add the note\nfile to your commit with git add and commit them to your PR branch to make\nsure they're included with the code in your PR.

\n

Linking to issues

\n

If you need to link to an issue or other github artifact as part of the release\nnote this should be done using an inline link with the text being the issue\nnumber. For example you would write a release note with a link to issue 12345\nas:

\n
fixes:\n  - |\n    Fixes a race condition in the function ``foo()``. Refer to\n    `#12345 <https://github.com/Qiskit/qiskit/issues/12345>` for more\n    details.
\n

Generating the release notes

\n

After release notes have been added, you can use reno to see what the full output\nof the release notes is. In general the output from reno that we'll get is a rst\n(ReStructuredText) file that can be compiled by\nsphinx. To generate the rst file you\nuse the reno report command. If you want to generate the full release\nnotes for all releases (since we started using reno during 0.9) you just run:

\n
reno report\n
\n

but you can also use the --version argument to view a single release (after\nit has been tagged:

\n
reno report --version 0.9.0\n
\n

At release time reno report is used to generate the release notes for the\nrelease and the output will be submitted as a pull request to the documentation\nrepository's release notes file

\n

Building release notes locally

\n

Building The release notes are part of the standard qiskit documentation\nbuilds. To check what the rendered html output of the release notes will look\nlike for the current state of the repo you can run: tox -edocs which will\nbuild all the documentation into docs/_build/html and the release notes in\nparticular will be located at docs/_build/html/release_notes.html

\n

Testing

\n

Once you've made a code change, it is important to verify that your change\ndoes not break any existing tests and that any new tests that you've added\nalso run successfully. Before you open a new pull request for your change,\nyou'll want to run the test suite locally.

\n

The easiest way to run the test suite is to use\ntox. You can install tox\nwith pip: pip install -U tox. Tox provides several advantages, but the\nbiggest one is that it builds an isolated virtualenv for running tests. This\nmeans it does not pollute your system python when running. Additionally, the\nenvironment that tox sets up matches the CI environment more closely and it\nruns the tests in parallel (resulting in much faster execution). To run tests\non all installed supported python versions and lint/style checks you can simply\nrun tox. Or if you just want to run the tests once run for a specific python\nversion: tox -epy310 (or replace py310 with the python version you want to use,\npy39 or py311).

\n

If you just want to run a subset of tests you can pass a selection regex to\nthe test runner. For example, if you want to run all tests that have \"dag\" in\nthe test id you can run: tox -epy310 -- dag. You can pass arguments directly to\nthe test runner after the bare --. To see all the options on test selection\nyou can refer to the stestr manual:\nhttps://stestr.readthedocs.io/en/stable/MANUAL.html#test-selection

\n

If you want to run a single test module, test class, or individual test method\nyou can do this faster with the -n/--no-discover option. For example:

\n

to run a module:

\n
tox -epy310 -- -n test.python.test_examples\n
\n

or to run the same module by path:

\n
tox -epy310 -- -n test/python/test_examples.py\n
\n

to run a class:

\n
tox -epy310 -- -n test.python.test_examples.TestPythonExamples\n
\n

to run a method:

\n
tox -epy310 -- -n test.python.test_examples.TestPythonExamples.test_all_examples\n
\n

Alternatively there is a makefile provided to run tests, however this\ndoes not perform any environment setup. It also doesn't run tests in\nparallel and doesn't provide an option to easily modify the tests run.\nFor executing the tests with the makefile, a make test target is available.\nThe execution of the tests (both via the make target and during manual\ninvocation) takes into account the LOG_LEVEL environment variable. If\npresent, a .log file will be created on the test directory with the\noutput of the log calls, which will also be printed to stdout. You can\nadjust the verbosity via the content of that variable, for example:

\n

Linux and Mac:

\n
$ cd out\nout$ LOG_LEVEL=\"DEBUG\" ARGS=\"-V\" make test\n
\n

Windows:

\n
$ cd out\nC:\\..\\out> set LOG_LEVEL=\"DEBUG\"\nC:\\..\\out> set ARGS=\"-V\"\nC:\\..\\out> make test\n
\n

For executing a simple python test manually, we don't need to change\nthe directory to out, just run this command:

\n

Linux and Mac:

\n
$ LOG_LEVEL=INFO python -m unittest test/python/circuit/test_circuit_operations.py\n
\n

Windows:

\n
C:\\..\\> set LOG_LEVEL=\"INFO\"\nC:\\..\\> python -m unittest test/python/circuit/test_circuit_operations.py\n
\n
STDOUT/STDERR and logging capture
\n

When running tests in parallel using stestr either via tox, the Makefile\n(make test_ci), or in CI we set the env variable\nQISKIT_TEST_CAPTURE_STREAMS which will capture any text written to stdout,\nstderr, and log messages and add them as attachments to the tests run so\noutput can be associated with the test case it originated from. However, if\nyou run tests with stestr outside of these mechanisms by default the streams\nare not captured. To enable stream capture just set the\nQISKIT_TEST_CAPTURE_STREAMS env variable to 1. If this environment\nvariable is set outside of running with stestr the streams (STDOUT, STDERR,\nand logging) will still be captured but not displayed in the test runners\noutput. If you are using the stdlib unittest runner a similar result can be\naccomplished by using the\n--buffer\noption (e.g. python -m unittest discover --buffer ./test/python).

\n
Test Skip Options
\n

How and which tests are executed is controlled by an environment\nvariable, QISKIT_TESTS:

\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
OptionDescriptionDefault
run_slowIt runs tests tagged as slow.False
\n

It is possible to provide more than one option separated with commas.

\n

Alternatively, the make test_ci target can be used instead of\nmake test in order to run in a setup that replicates the configuration\nwe used in our CI systems more closely.

\n

Snapshot Testing for Visualizations

\n

If you are working on code that makes changes to any matplotlib visualisations\nyou will need to check that your changes don't break any snapshot tests, and add\nnew tests where necessary. You can do this as follows:

\n
    \n
  1. \n

    Make sure you have pushed your latest changes to your remote branch.

    \n
  2. \n
  3. \n

    Go to link: https://mybinder.org/v2/gh/<github_user>/<repo>/<branch>?urlpath=apps/test/ipynb/mpl_tester.ipynb. For example, if your GitHub username is username, your forked repo has the same name the original, and your branch is my_awesome_new_feature, you should visit https://mybinder.org/v2/gh/username/qiskit/my_awesome_new_feature?urlpath=apps/test/ipynb/mpl_tester.ipynb.\nThis opens a Jupyter Notebook application running in the cloud that automatically runs\nthe snapshot tests (note this may take some time to finish loading).

    \n
  4. \n
  5. \n

    Each test result provides a set of 3 images (left: reference image, middle: your test result, right: differences). In the list of tests the passed tests are collapsed and failed tests are expanded. If a test fails, you will see a situation like this:

    \n\"Screenshot_2021-03-26_at_14\n
  6. \n
  7. \n

    Fix any broken tests. Working on code for one aspect of the visualisations\ncan sometimes result in minor changes elsewhere to spacing etc. In these cases\nyou just need to update the reference images as follows:

    \n
      \n
    • download the mismatched images (link at top of Jupyter Notebook output)
    • \n
    • unzip the folder
    • \n
    • copy and paste the new images into qiskit/test/ipynb/mpl/references,\nreplacing the existing reference images
    • \n
    • add, commit and push your changes, then restart the Jupyter Notebook app in your browser. The\ntests should now pass.
    • \n
    \n
  8. \n
  9. \n

    Add new snapshot tests covering your new features, extensions, or bugfixes.

    \n
      \n
    • add your new snapshot tests to test/ipynb/mpl/test_circuit_matplotlib_drawer.py\n, where you can also find existing tests to use as a guide.
    • \n
    • commit and push your changes, restart the Jupyter Notebook app in your browser.\nAs this is the first time you run your new tests there won't be any reference\nimages to compare to. Instead you should see an option in the list of tests\nto download the new images, like so:
    • \n
    \n \"Screenshot_2021-03-26_at_15\n
      \n
    • download the new images, then copy and paste into qiskit/test/ipynb/mpl/references
    • \n
    • add, commit and push your changes, restart the Jupyter Notebook app in your browser. The\nnew tests should now pass.
    • \n
    \n
  10. \n
\n

Note: If you have run test/ipynb/mpl_tester.ipynb locally it is possible some file metadata has changed, please do not commit and push changes to this file unless they were intentional.

\n

Style and lint

\n

Qiskit uses three tools for verify code formatting and lint checking. The\nfirst tool is black which is a code formatting\ntool that will automatically update the code formatting to a consistent style.\nThe second tool is pylint which is a code linter\nwhich does a deeper analysis of the Python code to find both style issues and\npotential bugs and other common issues in Python. The third tool is the linter\nruff, which has been recently\nintroduced into Qiskit on an experimental basis. Only a very small number\nof rules are enabled.

\n

You can check that your local modifications conform to the style rules by\nrunning tox -elint which will run black, ruff, and pylint to check the\nlocal code formatting and lint. If black returns a code formatting error you can\nrun tox -eblack to automatically update the code formatting to conform to the\nstyle. However, if ruff or pylint return any error you will have to fix\nthese issues by manually updating your code.

\n

Because pylint analysis can be slow, there is also a tox -elint-incr target,\nwhich runs black and ruff just as tox -elint does, but only applies\npylint to files which have changed from the source github. On rare occasions\nthis will miss some issues that would have been caught by checking the complete\nsource tree, but makes up for this by being much faster (and those rare\noversights will still be caught by the CI after you open a pull request).

\n

Because they are so fast, it is sometimes convenient to run the tools black and ruff separately\nrather than via tox. If you have installed the development packages in your python environment via\npip install -r requirements-dev.txt, then ruff and black will be available and can be run from\nthe command line. See tox.ini for how tox invokes them.

\n

Building API docs locally

\n

If you have made changes to the API documentation, you can run the command below\nto build documentation locally to review the html output.\nThe easiest and recommended way to build the documentation is to use tox:

\n
tox -edocs\n
\n

Once you run this command, the output will be located at docs/_build/html.\nThen, open up the file index.html in your browser.

\n

Sometimes Sphinx can get in a bad cache state. Run tox -e docs-clean\nto reset Sphinx's cache.

\n

Development cycle

\n

The development cycle for qiskit is all handled in the open using\nthe project boards in Github for project management. We use milestones\nin Github to track work for specific releases. The features or other changes\nthat we want to include in a release will be tagged and discussed in Github.\nAs we're preparing a new release we'll document what has changed since the\nprevious version in the release notes.

\n

Branches

\n\n

The main branch is used for development of the next version of qiskit.\nIt will be updated frequently and should not be considered stable. The API\ncan and will change on main as we introduce and refine new features.

\n\n

Release cycle

\n

In the lead up to a release there are a few things to keep in mind. Prior to\nthe release date there is a feature, removal, and deprecation proposal freeze\ndate. This date in each release cycle is the last day where a new PR adding a\nnew feature, removing something, or adding a new deprecation can be proposed (in\na ready for review state) for potential inclusion in the release. If a new\nPR is opened after this date it will not be considered for inclusion in that\nrelease. Note, that meeting these deadlines does not guarantee inclusion in a\nrelease: they are preconditions. You can refer to the milestone page for each\nrelease to see these dates for each release (for example for 0.21.0 the page is:\nhttps://github.com/Qiskit/qiskit/milestone/23).

\n

After the proposal freeze a release review period will begin, during this time\nrelease candidate PRs will be reviewed as we finalize the feature set and merge\nthe last PRs for the release. Following the review period a release candidate will be\ntagged and published. This release candidate is pre-release that enables users and\ndevelopers to test the release ahead of time. When the pre-release is tagged the release\nautomation will publish the pre-release to PyPI (but only get installed on user request),\ncreate the stable/* branch, and generate a pre-release changelog/release page. At\nthis point the main opens up for development of the next release. The stable/*\nbranches should only receive changes in the form of bug fixes at this point. If there\nis a need additional release candidates can be published from stable/* and when the\nrelease is ready a full release will be tagged and published from stable/*.

\n

Adding deprecation warnings

\n

The qiskit code is part of Qiskit and, therefore, the Qiskit Deprecation Policy fully applies here. Additionally, qiskit does not allow DeprecationWarnings in its testsuite. If you are deprecating code, you should add a test to use the new/non-deprecated method (most of the time based on the existing test of the deprecated method) and alter the existing test to check that the deprecated method still works as expected, using assertWarns. The assertWarns context will silence the deprecation warning while checking that it raises.

\n

For example, if Obj.method1 is being deprecated in favour of Obj.method2, the existing test (or tests) for method1 might look like this:

\n
def test_method1(self):\n   result = Obj.method1()\n   self.assertEqual(result, <expected>)
\n

Deprecating method1 means that Obj.method1() now raises a deprecation warning and the test will not pass. The existing test should be updated and a new test added for method2:

\n
def test_method1_deprecated(self):\n   with self.assertWarns(DeprecationWarning):\n       result = Obj.method1()\n   self.assertEqual(result, <expected>)\n\ndef test_method2(self):\n   result = Obj.method2()\n   self.assertEqual(result, <expected>)
\n

test_method1_deprecated can be removed after Obj.method1 is removed (following the Qiskit Deprecation Policy).

\n

Using dependencies

\n

We distinguish between \"requirements\" and \"optional dependencies\" in qiskit.\nA requirement is a package that is absolutely necessary for core functionality in qiskit, such as Numpy or Scipy.\nAn optional dependency is a package that is used for specialized functionality, which might not be needed by all users.\nIf a new feature has a new dependency, it is almost certainly optional.

\n

Adding a requirement

\n

Any new requirement must have broad system support; it needs to be supported on all the Python versions and operating systems that qiskit supports.\nIt also cannot impose many version restrictions on other packages.\nUsers often install qiskit into virtual environments with many different packages in, and we need to ensure that neither we, nor any of our requirements, conflict with their other packages.\nWhen adding a new requirement, you must add it to requirements.txt with as loose a constraint on the allowed versions as possible.

\n

Adding an optional dependency

\n

New features can also use optional dependencies, which might be used only in very limited parts of qiskit.\nThese are not required to use the rest of the package, and so should not be added to requirements.txt.\nInstead, if several optional dependencies are grouped together to provide one feature, you can consider adding an \"extra\" to the package metadata, such as the visualization extra that installs Matplotlib and Seaborn (amongst others).\nTo do this, modify the setup.py file, adding another entry in the extras_require keyword argument to setup() at the bottom of the file.\nYou do not need to be quite as accepting of all versions here, but it is still a good idea to be as permissive as you possibly can be.\nYou should also add a new \"tester\" to qiskit.utils.optionals, for use in the next section.

\n

Checking for optionals

\n

You cannot import an optional dependency at the top of a file, because if it is not installed, it will raise an error and qiskit will be unusable.\nWe also largely want to avoid importing packages until they are actually used; if we import a lot of packages during import qiskit, it becomes sluggish for the user if they have a large environment.\nInstead, you should use one of the \"lazy testers\" for optional dependencies, and import your optional dependency inside the function or class that uses it, as in the examples within that link.\nVery lightweight requirements can be imported at the tops of files, but even this should be limited; it's always ok to import numpy, but Scipy modules are relatively heavy, so only import them within functions that use them.

\n

Dealing with the git blame ignore list

\n

In the qiskit repository we maintain a list of commits for git blame\nto ignore. This is mostly commits that are code style changes that don't\nchange the functionality but just change the code formatting (for example,\nwhen we migrated to use black for code formatting). This file,\n.git-blame-ignore-revs just contains a list of commit SHA1s you can tell git\nto ignore when using the git blame command. This can be done one time\nwith something like

\n
git blame --ignore-revs-file .git-blame-ignore-revs qiskit/version.py\n\n
\n

from the root of the repository. If you'd like to enable this by default you\ncan update your local repository's configuration with:

\n
git config blame.ignoreRevsFile .git-blame-ignore-revs\n
\n

which will update your local repositories configuration to use the ignore list\nby default.

\n
","renderedFileInfo":null,"shortPath":null,"symbolsEnabled":true,"tabSize":8,"topBannersInfo":{"overridingGlobalFundingFile":false,"globalPreferredFundingPath":null,"showInvalidCitationWarning":false,"citationHelpUrl":"https://docs.github.com/github/creating-cloning-and-archiving-repositories/creating-a-repository-on-github/about-citation-files","actionsOnboardingTip":null},"truncated":false,"viewable":true,"workflowRedirectUrl":null,"symbols":{"timed_out":true,"not_analyzed":false,"symbols":[{"name":"Contributing","kind":"section_1","ident_start":2,"ident_end":14,"extent_start":0,"extent_end":37666,"fully_qualified_name":"Contributing","ident_utf16":{"start":{"line_number":0,"utf16_col":2},"end":{"line_number":0,"utf16_col":14}},"extent_utf16":{"start":{"line_number":0,"utf16_col":0},"end":{"line_number":729,"utf16_col":0}}},{"name":"Contents","kind":"section_2","ident_start":196,"ident_end":204,"extent_start":193,"extent_end":1257,"fully_qualified_name":"Contents","ident_utf16":{"start":{"line_number":7,"utf16_col":3},"end":{"line_number":7,"utf16_col":11}},"extent_utf16":{"start":{"line_number":7,"utf16_col":0},"end":{"line_number":30,"utf16_col":0}}},{"name":"Before you start","kind":"section_2","ident_start":1260,"ident_end":1276,"extent_start":1257,"extent_end":1703,"fully_qualified_name":"Before you start","ident_utf16":{"start":{"line_number":30,"utf16_col":3},"end":{"line_number":30,"utf16_col":19}},"extent_utf16":{"start":{"line_number":30,"utf16_col":0},"end":{"line_number":39,"utf16_col":0}}},{"name":"Choose an issue to work on","kind":"section_2","ident_start":1706,"ident_end":1732,"extent_start":1703,"extent_end":2801,"fully_qualified_name":"Choose an issue to work on","ident_utf16":{"start":{"line_number":39,"utf16_col":3},"end":{"line_number":39,"utf16_col":29}},"extent_utf16":{"start":{"line_number":39,"utf16_col":0},"end":{"line_number":47,"utf16_col":0}}},{"name":"Set up Python virtual development environment","kind":"section_2","ident_start":2804,"ident_end":2849,"extent_start":2801,"extent_end":4481,"fully_qualified_name":"Set up Python virtual development environment","ident_utf16":{"start":{"line_number":47,"utf16_col":3},"end":{"line_number":47,"utf16_col":48}},"extent_utf16":{"start":{"line_number":47,"utf16_col":0},"end":{"line_number":103,"utf16_col":0}}},{"name":"Set up a Python venv","kind":"section_3","ident_start":3218,"ident_end":3238,"extent_start":3214,"extent_end":4282,"fully_qualified_name":"Set up a Python venv","ident_utf16":{"start":{"line_number":56,"utf16_col":4},"end":{"line_number":56,"utf16_col":24}},"extent_utf16":{"start":{"line_number":56,"utf16_col":0},"end":{"line_number":90,"utf16_col":0}}},{"name":"Set up a Conda environment","kind":"section_3","ident_start":4286,"ident_end":4312,"extent_start":4282,"extent_end":4481,"fully_qualified_name":"Set up a Conda environment","ident_utf16":{"start":{"line_number":90,"utf16_col":4},"end":{"line_number":90,"utf16_col":30}},"extent_utf16":{"start":{"line_number":90,"utf16_col":0},"end":{"line_number":103,"utf16_col":0}}},{"name":"Installing Qiskit from source","kind":"section_2","ident_start":4484,"ident_end":4513,"extent_start":4481,"extent_end":6521,"fully_qualified_name":"Installing Qiskit from source","ident_utf16":{"start":{"line_number":103,"utf16_col":3},"end":{"line_number":103,"utf16_col":32}},"extent_utf16":{"start":{"line_number":103,"utf16_col":0},"end":{"line_number":138,"utf16_col":0}}},{"name":"Issues and pull requests","kind":"section_2","ident_start":6524,"ident_end":6548,"extent_start":6521,"extent_end":11584,"fully_qualified_name":"Issues and pull requests","ident_utf16":{"start":{"line_number":138,"utf16_col":3},"end":{"line_number":138,"utf16_col":27}},"extent_utf16":{"start":{"line_number":138,"utf16_col":0},"end":{"line_number":214,"utf16_col":0}}},{"name":"Pull request checklist","kind":"section_3","ident_start":8925,"ident_end":8947,"extent_start":8921,"extent_end":10472,"fully_qualified_name":"Pull request checklist","ident_utf16":{"start":{"line_number":166,"utf16_col":4},"end":{"line_number":166,"utf16_col":26}},"extent_utf16":{"start":{"line_number":166,"utf16_col":0},"end":{"line_number":196,"utf16_col":0}}},{"name":"Code Review","kind":"section_3","ident_start":10476,"ident_end":10487,"extent_start":10472,"extent_end":11584,"fully_qualified_name":"Code Review","ident_utf16":{"start":{"line_number":196,"utf16_col":4},"end":{"line_number":196,"utf16_col":15}},"extent_utf16":{"start":{"line_number":196,"utf16_col":0},"end":{"line_number":214,"utf16_col":0}}},{"name":"Contributor Licensing Agreement","kind":"section_2","ident_start":11587,"ident_end":11618,"extent_start":11584,"extent_end":12478,"fully_qualified_name":"Contributor Licensing Agreement","ident_utf16":{"start":{"line_number":214,"utf16_col":3},"end":{"line_number":214,"utf16_col":34}},"extent_utf16":{"start":{"line_number":214,"utf16_col":0},"end":{"line_number":232,"utf16_col":0}}},{"name":"Changelog generation","kind":"section_2","ident_start":12481,"ident_end":12501,"extent_start":12478,"extent_end":13577,"fully_qualified_name":"Changelog generation","ident_utf16":{"start":{"line_number":232,"utf16_col":3},"end":{"line_number":232,"utf16_col":23}},"extent_utf16":{"start":{"line_number":232,"utf16_col":0},"end":{"line_number":255,"utf16_col":0}}},{"name":"Release notes","kind":"section_2","ident_start":13580,"ident_end":13593,"extent_start":13577,"extent_end":19725,"fully_qualified_name":"Release notes","ident_utf16":{"start":{"line_number":255,"utf16_col":3},"end":{"line_number":255,"utf16_col":16}},"extent_utf16":{"start":{"line_number":255,"utf16_col":0},"end":{"line_number":391,"utf16_col":0}}},{"name":"Adding a new release note","kind":"section_3","ident_start":14776,"ident_end":14801,"extent_start":14772,"extent_end":19725,"fully_qualified_name":"Adding a new release note","ident_utf16":{"start":{"line_number":275,"utf16_col":4},"end":{"line_number":275,"utf16_col":29}},"extent_utf16":{"start":{"line_number":275,"utf16_col":0},"end":{"line_number":391,"utf16_col":0}}},{"name":"Linking to issues","kind":"section_4","ident_start":17994,"ident_end":18011,"extent_start":17989,"extent_end":18424,"fully_qualified_name":"Linking to issues","ident_utf16":{"start":{"line_number":347,"utf16_col":5},"end":{"line_number":347,"utf16_col":22}},"extent_utf16":{"start":{"line_number":347,"utf16_col":0},"end":{"line_number":362,"utf16_col":0}}},{"name":"Generating the release notes","kind":"section_4","ident_start":18429,"ident_end":18457,"extent_start":18424,"extent_end":19315,"fully_qualified_name":"Generating the release notes","ident_utf16":{"start":{"line_number":362,"utf16_col":5},"end":{"line_number":362,"utf16_col":33}},"extent_utf16":{"start":{"line_number":362,"utf16_col":0},"end":{"line_number":383,"utf16_col":0}}},{"name":"Building release notes locally","kind":"section_4","ident_start":19320,"ident_end":19350,"extent_start":19315,"extent_end":19725,"fully_qualified_name":"Building release notes locally","ident_utf16":{"start":{"line_number":383,"utf16_col":5},"end":{"line_number":383,"utf16_col":35}},"extent_utf16":{"start":{"line_number":383,"utf16_col":0},"end":{"line_number":391,"utf16_col":0}}},{"name":"Testing","kind":"section_2","ident_start":19728,"ident_end":19735,"extent_start":19725,"extent_end":27348,"fully_qualified_name":"Testing","ident_utf16":{"start":{"line_number":391,"utf16_col":3},"end":{"line_number":391,"utf16_col":10}},"extent_utf16":{"start":{"line_number":391,"utf16_col":0},"end":{"line_number":551,"utf16_col":0}}},{"name":"STDOUT/STDERR and logging capture","kind":"section_5","ident_start":22902,"ident_end":22935,"extent_start":22896,"extent_end":23905,"fully_qualified_name":"STDOUT/STDERR and logging capture","ident_utf16":{"start":{"line_number":481,"utf16_col":6},"end":{"line_number":481,"utf16_col":39}},"extent_utf16":{"start":{"line_number":481,"utf16_col":0},"end":{"line_number":498,"utf16_col":0}}},{"name":"Test Skip Options","kind":"section_5","ident_start":23911,"ident_end":23928,"extent_start":23905,"extent_end":24389,"fully_qualified_name":"Test Skip Options","ident_utf16":{"start":{"line_number":498,"utf16_col":6},"end":{"line_number":498,"utf16_col":23}},"extent_utf16":{"start":{"line_number":498,"utf16_col":0},"end":{"line_number":513,"utf16_col":0}}},{"name":"Snapshot Testing for Visualizations","kind":"section_3","ident_start":24393,"ident_end":24428,"extent_start":24389,"extent_end":27348,"fully_qualified_name":"Snapshot Testing for Visualizations","ident_utf16":{"start":{"line_number":513,"utf16_col":4},"end":{"line_number":513,"utf16_col":39}},"extent_utf16":{"start":{"line_number":513,"utf16_col":0},"end":{"line_number":551,"utf16_col":0}}},{"name":"Style and lint","kind":"section_2","ident_start":27351,"ident_end":27365,"extent_start":27348,"extent_end":29271,"fully_qualified_name":"Style and lint","ident_utf16":{"start":{"line_number":551,"utf16_col":3},"end":{"line_number":551,"utf16_col":17}},"extent_utf16":{"start":{"line_number":551,"utf16_col":0},"end":{"line_number":582,"utf16_col":0}}},{"name":"Building API docs locally","kind":"section_2","ident_start":29274,"ident_end":29299,"extent_start":29271,"extent_end":29810,"fully_qualified_name":"Building API docs locally","ident_utf16":{"start":{"line_number":582,"utf16_col":3},"end":{"line_number":582,"utf16_col":28}},"extent_utf16":{"start":{"line_number":582,"utf16_col":0},"end":{"line_number":598,"utf16_col":0}}},{"name":"Development cycle","kind":"section_2","ident_start":29813,"ident_end":29830,"extent_start":29810,"extent_end":32538,"fully_qualified_name":"Development cycle","ident_utf16":{"start":{"line_number":598,"utf16_col":3},"end":{"line_number":598,"utf16_col":20}},"extent_utf16":{"start":{"line_number":598,"utf16_col":0},"end":{"line_number":647,"utf16_col":0}}},{"name":"Branches","kind":"section_3","ident_start":30242,"ident_end":30250,"extent_start":30238,"extent_end":30841,"fully_qualified_name":"Branches","ident_utf16":{"start":{"line_number":607,"utf16_col":4},"end":{"line_number":607,"utf16_col":12}},"extent_utf16":{"start":{"line_number":607,"utf16_col":0},"end":{"line_number":622,"utf16_col":0}}},{"name":"Release cycle","kind":"section_3","ident_start":30845,"ident_end":30858,"extent_start":30841,"extent_end":32538,"fully_qualified_name":"Release cycle","ident_utf16":{"start":{"line_number":622,"utf16_col":4},"end":{"line_number":622,"utf16_col":17}},"extent_utf16":{"start":{"line_number":622,"utf16_col":0},"end":{"line_number":647,"utf16_col":0}}},{"name":"Adding deprecation warnings","kind":"section_2","ident_start":32541,"ident_end":32568,"extent_start":32538,"extent_end":34036,"fully_qualified_name":"Adding deprecation warnings","ident_utf16":{"start":{"line_number":647,"utf16_col":3},"end":{"line_number":647,"utf16_col":30}},"extent_utf16":{"start":{"line_number":647,"utf16_col":0},"end":{"line_number":674,"utf16_col":0}}},{"name":"Using dependencies","kind":"section_2","ident_start":34039,"ident_end":34057,"extent_start":34036,"extent_end":36803,"fully_qualified_name":"Using dependencies","ident_utf16":{"start":{"line_number":674,"utf16_col":3},"end":{"line_number":674,"utf16_col":21}},"extent_utf16":{"start":{"line_number":674,"utf16_col":0},"end":{"line_number":705,"utf16_col":0}}},{"name":"Adding a requirement","kind":"section_3","ident_start":34447,"ident_end":34467,"extent_start":34443,"extent_end":35028,"fully_qualified_name":"Adding a requirement","ident_utf16":{"start":{"line_number":681,"utf16_col":4},"end":{"line_number":681,"utf16_col":24}},"extent_utf16":{"start":{"line_number":681,"utf16_col":0},"end":{"line_number":688,"utf16_col":0}}},{"name":"Adding an optional dependency","kind":"section_3","ident_start":35032,"ident_end":35061,"extent_start":35028,"extent_end":35923,"fully_qualified_name":"Adding an optional dependency","ident_utf16":{"start":{"line_number":688,"utf16_col":4},"end":{"line_number":688,"utf16_col":33}},"extent_utf16":{"start":{"line_number":688,"utf16_col":0},"end":{"line_number":697,"utf16_col":0}}},{"name":"Checking for optionals","kind":"section_3","ident_start":35927,"ident_end":35949,"extent_start":35923,"extent_end":36803,"fully_qualified_name":"Checking for optionals","ident_utf16":{"start":{"line_number":697,"utf16_col":4},"end":{"line_number":697,"utf16_col":26}},"extent_utf16":{"start":{"line_number":697,"utf16_col":0},"end":{"line_number":705,"utf16_col":0}}},{"name":"Dealing with the git blame ignore list","kind":"section_2","ident_start":36806,"ident_end":36844,"extent_start":36803,"extent_end":37666,"fully_qualified_name":"Dealing with the git blame ignore list","ident_utf16":{"start":{"line_number":705,"utf16_col":3},"end":{"line_number":705,"utf16_col":41}},"extent_utf16":{"start":{"line_number":705,"utf16_col":0},"end":{"line_number":729,"utf16_col":0}}}]}},"copilotInfo":null,"copilotAccessAllowed":false,"csrf_tokens":{"/Qiskit/qiskit/branches":{"post":"kWQVhATcv-y2rr_2Try1AP8iZrHBh6UQ5sTmsb8upU49ZI5UClrcx60mNfd0HrxKAkWR3peP4YPhf8hbQWOcGQ"},"/repos/preferences":{"post":"dRc9G2CmabmopNHLjEHjYZz_mblBa9aGvogN0PhTywlX3S2criJfXltYfq4Rq8wv8_Q3BP0Xzt-SqZDqU8d1Mw"}}},"title":"qiskit/CONTRIBUTING.md at main ยท Qiskit/qiskit"}