-
Notifications
You must be signed in to change notification settings - Fork 575
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
Ensure that qchem is imported lazily #1962
Conversation
Hello. You may have forgotten to update the changelog!
|
f"The {name} plugin requires PennyLane versions {plugin_device_class.pennylane_requires}, " | ||
f"however PennyLane version {__version__} is installed." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is because pylint was complaining
Thumbs up! |
Codecov Report
@@ Coverage Diff @@
## master #1962 +/- ##
==========================================
+ Coverage 96.90% 98.81% +1.91%
==========================================
Files 226 226
Lines 17346 17348 +2
==========================================
+ Hits 16809 17143 +334
+ Misses 537 205 -332
Continue to review full report at Codecov.
|
_qchem = None | ||
|
||
|
||
def __getattr__(name): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I performed VQE calculations in the following cases, everything seems to work as expected.
A. PennyLane-QChem is installed,
-
`from pennylane import qchem` works fine
-
`qml.qchem.excitations(2, 4)` without importing qchem works fine
B. PennyLane-QChem is not installed
-
`from pennylane import qchem`: does not complain
-
`qml.qchem.excitations(2, 4)` with/without importing qchem: asks for installing qchem
Thanks Soran for checking! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me, that is a nice addition.
By the way: Are you aware of https://github.com/mnmelo/lazy_import ? Just stumbled across it and it looks pretty amazing. |
Nice! I actually wasn't aware. Although it seems to be unmaintained for 4 years now... I imagine the ability to set module level (Although, its testing module looks quite nice) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me! 🎉 :) Just had some questions.
|
||
|
||
# add everything as long as it's not a module and not prefixed with _ | ||
_all = sorted( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How come we're sorting here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good question @antalszava.. I do not remember why I am sorting this.
if entry.name == "OpenFermion": | ||
_qchem = entry.load() | ||
|
||
if _qchem is None: | ||
raise ImportError( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems to check if OpenFermion was found as an entry. What if we have PennyLane-QChem installed, but OpenFermion uninstalled (e.g., first Qchem was installed, but then OpenFermion got manually uninstalled)? We'd get the ImportError
, however, it refers to QChem not Openfermion, correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh this is an historical accident 😆 The entry point for qchem
is named "OpenFermion"
, since we initially envisioned qchem as an openfermion plugin.
def __getattr__(name): | ||
"""Ensure that the qchem module is imported lazily""" | ||
if name == "qchem": | ||
global _qchem # pylint: disable=global-statement |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For my understanding: how come we have to define _qchem
as global here and not on line 322?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, _qchem
is an existing module level variable, but the way Python scope works is as follows:
a = 5
def f():
# No assignment; Python assumes
# a refers to the global variable a above.
print(a)
def g():
# a is assigned to within the function;
# Python assigns it with a scope *local*
# to the function, independent of the global
# a above.
a = 7
print(a)
If we wish g()
to assign value to the global variable a
above, we need to then explicitly state this using the global
keyword.
Context:
pennylane.qchem
is currently imported when PennyLane is imported, if it is available. If not,pennylane.qchem
instead points to a dummyNestedAttributeError
class, which raises an import error if or when the user attempts to accessqml.qchem
.Description of the Change: With Python 3.7, module level
__getattr__
and__dir__
special methods can now be defined. This allows us to modify this system, to ensure qchem is only imported when accessed.Benefits: Potential speed up in import time.
For example:
Possible Drawbacks: n/a
Related GitHub Issues: Closes #1961