Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Internally importing qiskit.providers.backend.Backend should not raise DeprecationWarning #12906

Merged
merged 9 commits into from
Aug 15, 2024

Conversation

1ucian0
Copy link
Member

@1ucian0 1ucian0 commented Aug 5, 2024

Fixes #12902

@1ucian0 1ucian0 requested review from nonhermitian, a team and jyu00 as code owners August 5, 2024 13:08
@qiskit-bot
Copy link
Collaborator

One or more of the following people are relevant to this code:

@1ucian0 1ucian0 added this to the 1.2.0 milestone Aug 5, 2024
Comment on lines 787 to 795

with warnings.catch_warnings():
warnings.filterwarnings(
"ignore",
category=DeprecationWarning,
message=r"qiskit\.providers\.models.+",
module="qiskit",
)
from qiskit.providers.backend import Backend
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fact that we're doing this means that the warning will not be firing correctly. If import qiskit.providers causes an import of qiskit.providers.models internally, then user code subsequently calling import qiskit.providers.models will not re-execute the module (since it'll already be in sys.modules), and therefore they'll not see the warning.

A correct fix to this should prevent the bad import from happening at all, unless the user specifically does the bad thing.

@coveralls
Copy link

coveralls commented Aug 5, 2024

Pull Request Test Coverage Report for Build 10406261159

Warning: This coverage report may be inaccurate.

This pull request's base commit is no longer the HEAD commit of its target branch. This means it includes changes from outside the original pull request, including, potentially, unrelated coverage changes.

Details

  • 95 of 189 (50.26%) changed or added relevant lines in 9 files are covered.
  • 66 unchanged lines in 8 files lost coverage.
  • Overall coverage decreased (-0.1%) to 89.574%

Changes Missing Coverage Covered Lines Changed/Added Lines %
qiskit/providers/fake_provider/generic_backend_v2.py 76 170 44.71%
Files with Coverage Reduction New Missed Lines %
crates/qasm2/src/expr.rs 1 94.02%
qiskit/transpiler/passes/synthesis/unitary_synthesis.py 2 88.39%
crates/qasm2/src/parse.rs 6 97.61%
qiskit/providers/models/jobstatus.py 7 0.0%
qiskit/synthesis/two_qubit/xx_decompose/decomposer.py 7 90.84%
crates/qasm2/src/lex.rs 8 91.48%
qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py 14 93.98%
crates/circuit/src/circuit_instruction.rs 21 90.95%
Totals Coverage Status
Change from base Build 10391255051: -0.1%
Covered Lines: 67586
Relevant Lines: 75453

💛 - Coveralls

@1ucian0 1ucian0 added stable backport potential The bug might be minimal and/or import enough to be port to stable Changelog: None Do not include in changelog labels Aug 6, 2024
@1ucian0
Copy link
Member Author

1ucian0 commented Aug 6, 2024

@jakelishman I took a different approach, but also not sure if it is the right one. Have a look and let me know.

@1ucian0
Copy link
Member Author

1ucian0 commented Aug 7, 2024

Extended the PR because import qiskit.providers.fake_provider had the same issue.

Copy link
Member

@jakelishman jakelishman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's good that you've been very specific with the warning filters, but in general, I don't think we should be using warnings.catch_warnings like this in library code. Seems like there's two cases we're currently using it:

  1. when we're calling deprecated functionality from a class that is itself deprecated
  2. when an eager import involves calling deprecated code

Imo, case 1 doesn't need suppression at all. The functionality is deprecated already; it's entirely expected that deprecated functions call other deprecated functions, and correctly configured stack levels in the warnings should mean that the deprecated code gets "blamed", not the user / downstream library. Using the filter makes the code slower to run, harder to read, and runs more risk of inadvertently suppressing a true warning, for (imo) no benefit - users won't see it, and downstream tests that need to test deprecated code paths should understand how to configure their test suite correctly to say "we expect to be blamed for this warning, and we understand that internal deprecation warnings will be issued from qiskit.providers.model" - it's a standard part of testing.

In case 2, in general, importing Qiskit should not use deprecated code at all - deprecated code should only run when specifically triggered by a user. If it's still necessary for us to run, it indicates we're not ready to be deprecating it. In rare cases where it remains necessary to exist in imports that don't directly touch deprecated code, we can use lazy attribute getters like module-level __getattr__ to only call the deprecated functionality if/when it's actually used by something.

Context-managers like catch_warnings are also inherently non-thread-safe, which means that any downstream libraries that use internal threading (like several of the primitives implementations) can cause breakages to the warning filters, such as permanent application of one of these catch filters, if we have them in library code.

Comment on lines 175 to 192
with warnings.catch_warnings():
# BackendV1 is deprecated along qiskit.providers.models.backendstatus.BackendStatus
# They both need to be removed at the same time
warnings.filterwarnings(
"ignore",
category=DeprecationWarning,
message=r"qiskit\.providers\.models.+",
module="qiskit",
)
from qiskit.providers.models.backendstatus import BackendStatus

return BackendStatus(
backend_name=self.name(),
backend_version="1",
operational=True,
pending_jobs=0,
status_msg="",
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I personally wouldn't put this warning catch in - it's expected that deprecated code will call other deprecated code, and the stacklevel of the BackendStatus warning should be set such that qiskit is "blamed" for the warning, which will mean it's suppressed for users by default (which is good - we want that). It would show up if all warnings are set to display, but that's expected behaviour.

Comment on lines 100 to 101
if typing.TYPE_CHECKING:
from qiskit.providers.models import PulseDefaults
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TYPE_CHECKING guards are conventionally put up at the top with the rest of the imports.

Copy link
Member

@jakelishman jakelishman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not fully convinced that it's a great idea for us to be switching our imports to the inner modules - I haven't had chance to check in full detail - but at this point in the release cycle, I'm happy to just do it and go ahead like this. The fix to the deprecation for GenericBackendV2 looks like the most important bit - we're now doing what we'd expect others to do, and defining "our own" calibration things, if that's something we're going to expose to users.

We ought to take a note to remove those fake calibrations from GenericBackendV2 in the future as well, if it's something we're generally dropping support for; GenericBackendV2 is supposed to the lowest common denominator backend support, so when pulse things are no longer considered part of that, we'll want to drop them there.

@jakelishman jakelishman added this pull request to the merge queue Aug 15, 2024
Merged via the queue into Qiskit:main with commit 713ab38 Aug 15, 2024
15 checks passed
mergify bot pushed a commit that referenced this pull request Aug 15, 2024
…ise `DeprecationWarning` (#12906)

* better module deprecation

* _pulse_library

* __getattr__

* copy qiskit.qobj.PulseQobjInstruction and qiskit.qobj.PulseLibraryItem for internal generic_backend_v2 usage

* lint

* Aer models

* skip

* more generic catch

* specific imports

(cherry picked from commit 713ab38)
github-merge-queue bot pushed a commit that referenced this pull request Aug 15, 2024
…ise `DeprecationWarning` (#12906) (#12965)

* better module deprecation

* _pulse_library

* __getattr__

* copy qiskit.qobj.PulseQobjInstruction and qiskit.qobj.PulseLibraryItem for internal generic_backend_v2 usage

* lint

* Aer models

* skip

* more generic catch

* specific imports

(cherry picked from commit 713ab38)

Co-authored-by: Luciano Bello <bel@zurich.ibm.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Changelog: None Do not include in changelog stable backport potential The bug might be minimal and/or import enough to be port to stable
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Importing BackendV2 results in a deprecation warning of qiskit.providers.models
4 participants