Important(?) Details
- Windows 10, version 10.0.19045
- Python 3.12.2
- PyCharm 2024.1 (Professional Edition)
- GitBash 2.45.1.windows.1
The Setup
I’m trying to install pygraphviz
with my package in a virtual environment.
I’ve written a custom install
subclass to be used by setuptools
during package install.
"""Contents of custom_install.py"""
from os import getenv
from platform import system
import subprocess
import sys
from setuptools.command.install import install
class InstallPygraphviz(install):
"""Custom command to install pygraphviz package.
Reference:
https://pygraphviz.github.io/documentation/stable/install.html#windows
"""
def run(self):
python_exe = sys.executable
subprocess.check_call([python_exe, "-m", "ensurepip"])
pip_command = [python_exe, "-m", "pip", "install"]
if system() == "Windows":
graphviz_path = getenv("GRAPHVIZ_PATH")
if graphviz_path is None:
raise ValueError("GRAPHVIZ_PATH is not set")
include_path = f"{graphviz_path}/include"
lib_path = f"{graphviz_path}/lib"
pip_command.extend(
[
"--config-settings='--global-option=build_ext'",
f"--config-settings='--global-option=-I{include_path}'",
f"--config-settings='--global-option=-L{lib_path}'",
]
)
pip_command.append("pygraphviz")
subprocess.check_call(pip_command)
install.run(self)
Per this github issue, I learned I could use a pyproject.toml to set my config settings instead of setup.py.
[build-system]
requires = ["setuptools>=70.0.0", "setuptools-scm>=8.1.0"]
build-backend = "setuptools.build_meta"
[project]
name = "awesome"
requires-python = ">=3.12"
dynamic = ["version"]
[tool.setuptools.dynamic]
version = {attr = "awesome.__version__"}
[tool.setuptools.packages.find]
where = ["src"]
[tool.setuptools.cmdclass]
install = "awesome.custom_install.InstallPygraphviz"
This is my package layout:
pyproject.toml
+---src
+---awesome
| | custom_install.py
| | __init__.py
Recreating The Problem
-
I create and activate a virtual environment:
py -3.12 -m venv env
source env/Scripts/activate
-
I
cd
into the project directory and run the following command:pip install .
-
Errors
Processing c:usersa2644752adotest Installing build dependencies ... done Getting requirements to build wheel ... done Installing backend dependencies ... done Preparing metadata (pyproject.toml) ... done Building wheels for collected packages: awesome Building wheel for awesome (pyproject.toml) ... error error: subprocess-exited-with-error × Building wheel for awesome (pyproject.toml) did not run successfully. │ exit code: 1 ╰─> [66 lines of output] running bdist_wheel running build running build_py creating build creating buildlib creating buildlibawesome copying srcawesomecustom_install.py -> buildlibawesome copying srcawesome__init__.py -> buildlibawesome running egg_info writing srcawesome.egg-infoPKG-INFO writing dependency_links to srcawesome.egg-infodependency_links.txt writing top-level names to srcawesome.egg-infotop_level.txt ERROR setuptools_scm._file_finders.git listing git files failed - pretending there aren't any reading manifest file 'srcawesome.egg-infoSOURCES.txt' writing manifest file 'srcawesome.egg-infoSOURCES.txt' installing to buildbdist.win-amd64wheel running install Looking in links: c:UsersA2644752AppDataLocalTemptmpyagl6bqz Processing c:usersa2644752appdatalocaltemptmpyagl6bqzpip-24.0-py3-none-any.whl Installing collected packages: pip Successfully installed pip-24.0 C:UsersA2644752ADOtestenvScriptspython.exe: No module named pip Traceback (most recent call last): File "C:UsersA2644752ADOtestenvLibsite-packagespip_vendorpyproject_hooks_in_process_in_process.py", line 353, in <module> main() File "C:UsersA2644752ADOtestenvLibsite-packagespip_vendorpyproject_hooks_in_process_in_process.py", line 335, in main json_out['return_val'] = hook(**hook_input['kwargs']) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:UsersA2644752ADOtestenvLibsite-packagespip_vendorpyproject_hooks_in_process_in_process.py", line 251, in build_wheel return _build_backend().build_wheel(wheel_directory, config_settings, ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:UsersA2644752AppDataLocalTemppip-build-env-pbo1oi67overlayLibsite-packagessetuptoolsbuild_meta.py", line 410, in build_wheel return self._build_with_temp_dir( ^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:UsersA2644752AppDataLocalTemppip-build-env-pbo1oi67overlayLibsite-packagessetuptoolsbuild_meta.py", line 395, in _build_with_temp_dir self.run_setup() File "C:UsersA2644752AppDataLocalTemppip-build-env-pbo1oi67overlayLibsite-packagessetuptoolsbuild_meta.py", line 311, in run_setup exec(code, locals()) File "<string>", line 1, in <module> File "C:UsersA2644752AppDataLocalTemppip-build-env-pbo1oi67overlayLibsite-packagessetuptools__init__.py", line 103, in setup return distutils.core.setup(**attrs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:UsersA2644752AppDataLocalTemppip-build-env-pbo1oi67overlayLibsite-packagessetuptools_distutilscore.py", line 184, in setup return run_commands(dist) ^^^^^^^^^^^^^^^^^^ File "C:UsersA2644752AppDataLocalTemppip-build-env-pbo1oi67overlayLibsite-packagessetuptools_distutilscore.py", line 200, in run_commands dist.run_commands() File "C:UsersA2644752AppDataLocalTemppip-build-env-pbo1oi67overlayLibsite-packagessetuptools_distutilsdist.py", line 969, in run_commands self.run_command(cmd) File "C:UsersA2644752AppDataLocalTemppip-build-env-pbo1oi67overlayLibsite-packagessetuptoolsdist.py", line 968, in run_command super().run_command(command) File "C:UsersA2644752AppDataLocalTemppip-build-env-pbo1oi67overlayLibsite-packagessetuptools_distutilsdist.py", line 988, in run_command cmd_obj.run() File "C:UsersA2644752AppDataLocalTemppip-build-env-pbo1oi67normalLibsite-packageswheelbdist_wheel.py", line 403, in run self.run_command("install") File "C:UsersA2644752AppDataLocalTemppip-build-env-pbo1oi67overlayLibsite-packagessetuptools_distutilscmd.py", line 316, in run_command self.distribution.run_command(command) File "C:UsersA2644752AppDataLocalTemppip-build-env-pbo1oi67overlayLibsite-packagessetuptoolsdist.py", line 968, in run_command super().run_command(command) File "C:UsersA2644752AppDataLocalTemppip-build-env-pbo1oi67overlayLibsite-packagessetuptools_distutilsdist.py", line 988, in run_command cmd_obj.run() File "C:UsersA2644752ADOtestsrcawesomecustom_install.py", line 38, in run subprocess.check_call(pip_command) File "C:UsersA2644752AppDataLocalProgramsPythonPython312Libsubprocess.py", line 413, in check_call raise CalledProcessError(retcode, cmd) subprocess.CalledProcessError: Command '['C:\Users\A2644752\ADO\test\env\Scripts\python.exe', '-m', 'pip', 'install', "--config-settings='--global-option=build_ext'", "--config-settings='--global-option=-IC:\Users\A2644752\AppData\Local\Programs\Graphviz/include'", "--config-settings='--global-option=-LC:\Users\A2644752\AppData\Local\Programs\Graphviz/lib'", 'pygraphviz']' returned non-zero exit status 1. [end of output] note: This error originates from a subprocess, and is likely not a problem with pip. ERROR: Failed building wheel for awesome Failed to build awesome ERROR: Could not build wheels for awesome, which is required to install pyproject.toml-based projects
Looking through the traceback I found this:
C:UsersA2644752ADOtestenvScriptspython.exe: No module named pip
Not sure how that’s possible as I believe pip
comes with the virtual environment.
But to be sure, I run the following at the top of :method:InstallPygraphviz.run
:
def run(self):
python_exe = sys.executable
subprocess.check_call([python_exe, "-m", "ensurepip"])
...
This passes, as noted in the traceback just before it errors:
...
running install
Looking in links: c:UsersA2644752AppDataLocalTemptmpyagl6bqz
Processing c:usersa2644752appdatalocaltemptmpyagl6bqzpip-24.0-py3-none-any.whl
Installing collected packages: pip
Successfully installed pip-24.0
C:UsersA2644752ADOtestenvScriptspython.exe: No module named pip
...
I’m at a loss for what to do. Running the code in :method:InstallPygraphviz.run
in an interpreter works just fine, as does running the commands within the pip_command
in git-bash.
How do I tell subprocess
that pip
exists in the environment and it should use it?