diff --git a/python/scripts/mkvenv.py b/python/scripts/mkvenv.py index b4662d33e6..8ed6a35450 100644 --- a/python/scripts/mkvenv.py +++ b/python/scripts/mkvenv.py @@ -662,6 +662,7 @@ def pip_install( args: Sequence[str], online: bool = False, wheels_dir: Optional[Union[str, Path]] = None, + env: Optional[Dict[str, str]] = None, ) -> None: """ Use pip to install a package or package(s) as specified in @args. @@ -687,6 +688,7 @@ def pip_install( full_args += list(args) subprocess.run( full_args, + env=env, check=True, ) @@ -733,9 +735,14 @@ def _do_ensure( :param wheels_dir: If specified, search this path for packages. """ absent = [] + local_packages = [] present = [] canary = None for name, info in group.items(): + if "path" in info: + pkgpath = Path(__file__).parents[2].joinpath(info["path"]) + local_packages.append(str(pkgpath)) + continue constraint = _make_version_constraint(info, False) matcher = Matcher(name + constraint) print(f"mkvenv: checking for {matcher}", file=sys.stderr) @@ -770,15 +777,33 @@ def _do_ensure( print(f"mkvenv: installing {', '.join(absent)}", file=sys.stderr) try: pip_install(args=absent, online=online, wheels_dir=wheels_dir) - return None + absent = [] except subprocess.CalledProcessError: pass - return diagnose( - absent[0], - online, - wheels_dir, - canary, + if absent: + return diagnose( + absent[0], + online, + wheels_dir, + canary, + ) + + # Handle local packages separately and last so we can use different + # installation arguments (-e), and so that any dependencies that may + # be covered above will be handled according to the depfile + # specifications. + if local_packages: + print(f"mkvenv: installing {', '.join(local_packages)}", + file=sys.stderr) + env = dict(os.environ) + env['PIP_CONFIG_SETTINGS'] = "editable_mode=compat" + pip_install( + args=["--no-build-isolation", + "-e"] + local_packages, + online=online, + wheels_dir=wheels_dir, + env=env, ) return None