My code can use any Qt binding. I try to reduce the number of packages to install. For that, I'd like to check whether a package has already been installed and report it as the sole requirement. If nothing's installed, I pick the first item on the list.
# cat setup.py
from typing import NamedTuple
from setuptools import setup
class PackageRequirement(NamedTuple):
package_name: str
import_name: str
def is_package_importable(package_requirement: PackageRequirement) -> bool:
try:
__import__(package_requirement.import_name)
except ModuleNotFoundError:
return False
else:
return True
def required_package() -> str:
qt_list = [
PackageRequirement(package_name='PySide6', import_name='PySide6.QtCore'),
PackageRequirement(package_name='PyQt6', import_name='PyQt6.QtCore'),
PackageRequirement(package_name='PyQt5', import_name='PyQt5.QtCore'),
PackageRequirement(package_name='PySide2', import_name='PySide2.QtCore'),
]
for p in qt_list:
if is_package_importable(p):
return p.package_name
return qt_list[0].package_name
setup(install_requires=[required_package()])
The code resembles this answer. However, despite pip freeze
reports that I have PyQt5
installed in the venv
, and I can import it manually, the code reports the opposite and installs PySide6
.
I run the code in a venv
virtual environment as
pip install package_name.tar.gz
I've tried
from importlib.metadata import version, PackageNotFoundError
try:
version(package_requirement.package_name)
except PackageNotFoundError:
return False
else:
return True
instead of
try:
__import__(package_requirement.import_name)
except ModuleNotFoundError:
return False
else:
return True
with the same result. It looks like either the code ignores site-packages, or the access to them is somehow blocked.
Indeed, as soon as I prepend the code with
import site
site.main() # the line might be redundant
the packages are tested correctly.
By the way, are there any tricks to achieve the package selection more gracefully and in a wheel
package?
As far as I know, in order to install a dependency from source code or from sdist, pip first builds this dependency into a wheel, and this build step is made in an ephemeral isolated build environment. So this isolated build environment has its own site-packages
, and the other dependencies can not be imported.
What you could try is to deactivate the "build isolation" when installing that dependency. Try to take some time to understand the possible side effects, also maybe try to use this option only for that dependency and not for its dependencies.
python -m pip install --no-build-isolation --no-deps package_name.tar.gz