diff --git a/news/12088.feature.rst b/news/12088.feature.rst new file mode 100644 index 00000000000..3b068547ad9 --- /dev/null +++ b/news/12088.feature.rst @@ -0,0 +1 @@ +New pip install option ``--executable=/path`` to set #! path in scripts. diff --git a/src/pip/_internal/commands/install.py b/src/pip/_internal/commands/install.py index 3c15ed4158c..4aecce67914 100644 --- a/src/pip/_internal/commands/install.py +++ b/src/pip/_internal/commands/install.py @@ -141,6 +141,14 @@ def add_options(self) -> None: "environment." ), ) + self.cmd_opts.add_option( + "--executable", + dest="executable_path", + default=None, + help=( + "Path to executable for #! lines in scripts." + ), + ) self.cmd_opts.add_option(cmdoptions.src()) @@ -452,6 +460,7 @@ def run(self, options: Values, args: List[str]) -> int: root=options.root_path, home=target_temp_dir_path, prefix=options.prefix_path, + executable=options.executable_path, warn_script_location=warn_script_location, use_user_site=options.use_user_site, pycompile=options.compile, diff --git a/src/pip/_internal/operations/install/wheel.py b/src/pip/_internal/operations/install/wheel.py index a8cd1330f0f..f3eebf53629 100644 --- a/src/pip/_internal/operations/install/wheel.py +++ b/src/pip/_internal/operations/install/wheel.py @@ -422,6 +422,9 @@ def _raise_for_invalid_entrypoint(specification: str) -> None: class PipScriptMaker(ScriptMaker): + def __init__(self, executable, *args, **kwargs): + super().__init__(*args, **kwargs) + self.executable = executable def make( self, specification: str, options: Optional[Dict[str, Any]] = None ) -> List[str]: @@ -434,6 +437,7 @@ def _install_wheel( wheel_zip: ZipFile, wheel_path: str, scheme: Scheme, + executable: Optional[str] = None, pycompile: bool = True, warn_script_location: bool = True, direct_url: Optional[DirectUrl] = None, @@ -624,7 +628,7 @@ def pyc_output_path(path: str) -> str: record_installed(pyc_record_path, pyc_path) logger.debug(stdout.getvalue()) - maker = PipScriptMaker(None, scheme.scripts) + maker = PipScriptMaker(executable, None, scheme.scripts) # Ensure old scripts are overwritten. # See https://github.com/pypa/pip/issues/1800 @@ -721,6 +725,7 @@ def install_wheel( wheel_path: str, scheme: Scheme, req_description: str, + executable: Optional[str] = None, pycompile: bool = True, warn_script_location: bool = True, direct_url: Optional[DirectUrl] = None, @@ -733,6 +738,7 @@ def install_wheel( wheel_zip=z, wheel_path=wheel_path, scheme=scheme, + executable=executable, pycompile=pycompile, warn_script_location=warn_script_location, direct_url=direct_url, diff --git a/src/pip/_internal/req/__init__.py b/src/pip/_internal/req/__init__.py index 16de903a44c..5bb3b924b26 100644 --- a/src/pip/_internal/req/__init__.py +++ b/src/pip/_internal/req/__init__.py @@ -40,6 +40,7 @@ def install_given_reqs( root: Optional[str], home: Optional[str], prefix: Optional[str], + executable: Optional[str], warn_script_location: bool, use_user_site: bool, pycompile: bool, @@ -74,6 +75,7 @@ def install_given_reqs( root=root, home=home, prefix=prefix, + executable=executable, warn_script_location=warn_script_location, use_user_site=use_user_site, pycompile=pycompile, diff --git a/src/pip/_internal/req/req_install.py b/src/pip/_internal/req/req_install.py index 1f479713a94..924adb8f43d 100644 --- a/src/pip/_internal/req/req_install.py +++ b/src/pip/_internal/req/req_install.py @@ -773,6 +773,7 @@ def install( root: Optional[str] = None, home: Optional[str] = None, prefix: Optional[str] = None, + executable: Optional[str] = None, warn_script_location: bool = True, use_user_site: bool = False, pycompile: bool = True, @@ -808,6 +809,7 @@ def install( self.name, self.local_file_path, scheme=scheme, + executable=executable, req_description=str(self.req), pycompile=pycompile, warn_script_location=warn_script_location,