Make Q# imports in Python more intuitive for Python users
Is your feature request related to a problem? Please describe.
It can be unexpected behavior for Python users that import qsharp or qsharp.reload() injects Python objects into the local namespace.
import qsharp
qsharp.reload() # This searches for Q# programs in folder and loads into local namespace
from Microsoft.Quantum.Samples import TrotterEstimateEnergy
TrotterEstimateEnergy.simulate(...)
Describe the solution you'd like It would be great to have an experience like so:
import qsharp
estimate_energy = qsharp.load("Microsoft.Quantum.Samples.TrotterEstimateEnergy") # this searchers for Q# programs in folder and returns handle
result = estimate_energy.simulate(...)
Describe alternatives you've considered No alternatives considered
Additional context Notes from @cgranade :
that already kind of exists in terms of the QSharpCallable object. If we want to extend the existing qsharp.get_operations() to wrap in QSharpCallable, and to allow looking up by qualified name similar to our meta_loader hooks, I agree that could be useful. I just don't want to also drop the import hooks for users that find those useful.
Thanks for opening this, @guenp! If I could offer a couple quick points of clarification about the current API, the qsharp.reload() in your first snippet is not actually needed today — as documented in https://github.com/microsoft/iqsharp/issues/440, the only place where that comes up is when Q# source files depend on a package, but that package is not listed in a project file with <IQSharpLoadAutomatically> set to true. It's also not quite the case that import qsharp modifies the local namespace — no variables other than qsharp itself are added to either globals() or locals() until an explicit import statement is used to make Q# operations available in locals().
With respect to the proposal itself, I agree it would be useful, but I don't think that the existing behavior is unexpected for all Python users, so much as it's a case where different users have different expectations. In particular, the current mechanism uses standard built-in extensibility APIs provided by Python such as sys.meta_path, following the pattern of other language interop packages. From that perspective, I don't think we should retire or deprecate any existing functionality so much as expose it in an additional way, paralleling that Python itself has both the import keyword and the __import__ function.