From 0e696fbc001909660bc228b4bc1220d470aa6b87 Mon Sep 17 00:00:00 2001 From: Zack T Date: Wed, 24 Jan 2024 11:09:50 -0700 Subject: [PATCH 1/5] Add support for pip's --platform option --- locallibs/install.py | 15 +++++++++++++-- make_relocatable_python_framework.py | 10 +++++++++- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/locallibs/install.py b/locallibs/install.py index e381db1..fe93fa9 100644 --- a/locallibs/install.py +++ b/locallibs/install.py @@ -61,7 +61,7 @@ def upgrade_pip_install(framework_path, version): subprocess.check_call(cmd) -def install_requirements(requirements_file, framework_path, version): +def install_requirements(requirements_file, framework_path, version, pip_platform): """Use pip to install a Python pkg into framework_path""" python_path = os.path.join( framework_path, "Versions", version, "bin/python" + version @@ -69,10 +69,20 @@ def install_requirements(requirements_file, framework_path, version): headers_path = os.path.abspath(os.path.join( framework_path, "Versions", version, "include/python" + version )) + site_packages_path = os.path.join( + framework_path, "Versions", version, "lib/python" + version + + "/site-packages" + ) if not os.path.exists(python_path): print("No python at %s" % python_path, file=sys.stderr) return cmd = [python_path, "-s", "-m", "pip", "install", "-r", requirements_file] + + if pip_platform: + for platform in pip_platform: + cmd.append["--platform", platform] + cmd.append["--target==%s" % site_packages_path] + pip_env = os.environ pip_env["CPPFLAGS"] = "-I%s" % headers_path print("Installing modules from %s..." % requirements_file) @@ -85,6 +95,7 @@ def install_extras( requirements_file=None, upgrade_pip=False, without_pip=False, + pip_platform=None ): """install all extra pkgs into Python framework path""" print() @@ -111,6 +122,6 @@ def install_extras( upgrade_pip_install(framework_path, version) if requirements_file: print() - install_requirements(requirements_file, framework_path, version) + install_requirements(requirements_file, framework_path, version, pip_platform) else: print("Skipping all requirements, packages, etc due to without-pip specified") diff --git a/make_relocatable_python_framework.py b/make_relocatable_python_framework.py index fdca736..d8e6f30 100755 --- a/make_relocatable_python_framework.py +++ b/make_relocatable_python_framework.py @@ -78,6 +78,13 @@ def main(): action="store_true", help="Do not install pip." ) + parser.add_option( + "--pip-platform", + nargs=3, + help="Specify which platform the requirements should be downloaded for. " + "Default is to the platform of the running system. " + "Use this option multiple times to specify multiple platforms." + ) parser.set_defaults(unsign=True) options, _arguments = parser.parse_args() framework_path = get.FrameworkGetter( @@ -96,7 +103,8 @@ def main(): version=short_version, requirements_file=options.pip_requirements, upgrade_pip=options.upgrade_pip, - without_pip=options.without_pip + without_pip=options.without_pip, + pip_platform=options.pip_platform ) if fix_other_things(framework_path, short_version): print() From 5c3f7b08bdb8a83ca7b3729daf9a8e11fa6ea29f Mon Sep 17 00:00:00 2001 From: Zack T Date: Wed, 24 Jan 2024 23:45:36 -0700 Subject: [PATCH 2/5] Work around for using a `n` number of args in optparse --- locallibs/__init__.py | 44 ++++++++++++++++++++++++++++ make_relocatable_python_framework.py | 6 ++-- 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/locallibs/__init__.py b/locallibs/__init__.py index e69de29..473ff8b 100644 --- a/locallibs/__init__.py +++ b/locallibs/__init__.py @@ -0,0 +1,44 @@ +# encoding: utf-8 +# +# Copyright 2018 Greg Neagle. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Misc Helper Functions""" + +def vararg_callback(option, opt_str, value, parser): + """Optparse callback to support a variable number of arguments. + This is example 6 from the official docs: + https://docs.python.org/3/library/optparse.html#callback-example-6-variable-arguments + """ + + assert value is None + value = [] + + def floatable(str): + try: + float(str) + return True + except ValueError: + return False + + for arg in parser.rargs: + # stop on --foo like options + if arg[:2] == "--" and len(arg) > 2: + break + # stop on -a, but not on -3 or -3.0 + if arg[:1] == "-" and len(arg) > 1 and not floatable(arg): + break + value.append(arg) + + del parser.rargs[:len(value)] + setattr(parser.values, option.dest, value) diff --git a/make_relocatable_python_framework.py b/make_relocatable_python_framework.py index d8e6f30..cdce68a 100755 --- a/make_relocatable_python_framework.py +++ b/make_relocatable_python_framework.py @@ -20,7 +20,7 @@ import optparse -from locallibs import get +from locallibs import get, vararg_callback from locallibs.fix import fix_broken_signatures, fix_other_things from locallibs.install import install_extras from locallibs.relocatablizer import relocatablize @@ -79,8 +79,8 @@ def main(): help="Do not install pip." ) parser.add_option( - "--pip-platform", - nargs=3, + "--pip-platform", dest="pip_platform", + action="callback", callback=vararg_callback, help="Specify which platform the requirements should be downloaded for. " "Default is to the platform of the running system. " "Use this option multiple times to specify multiple platforms." From 7cfda89a401c2558717aed9c11c1adfbf251f4ab Mon Sep 17 00:00:00 2001 From: Zack T Date: Wed, 24 Jan 2024 23:46:18 -0700 Subject: [PATCH 3/5] Remove extra equals (`=`) --- locallibs/install.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locallibs/install.py b/locallibs/install.py index fe93fa9..073ab23 100644 --- a/locallibs/install.py +++ b/locallibs/install.py @@ -81,7 +81,7 @@ def install_requirements(requirements_file, framework_path, version, pip_platfor if pip_platform: for platform in pip_platform: cmd.append["--platform", platform] - cmd.append["--target==%s" % site_packages_path] + cmd.append["--target=%s" % site_packages_path] pip_env = os.environ pip_env["CPPFLAGS"] = "-I%s" % headers_path From b195fce3bdc429cd66b6b5efa3c342d13279b409 Mon Sep 17 00:00:00 2001 From: Zack T Date: Wed, 24 Jan 2024 23:47:59 -0700 Subject: [PATCH 4/5] Add support for pip's `--no-binary` & `--only-binary` --- locallibs/install.py | 41 ++++++++++++++++++++++++---- make_relocatable_python_framework.py | 22 ++++++++++++++- 2 files changed, 56 insertions(+), 7 deletions(-) diff --git a/locallibs/install.py b/locallibs/install.py index 073ab23..2bfc475 100644 --- a/locallibs/install.py +++ b/locallibs/install.py @@ -17,6 +17,7 @@ from __future__ import print_function +import itertools import os import subprocess import sys @@ -61,8 +62,28 @@ def upgrade_pip_install(framework_path, version): subprocess.check_call(cmd) -def install_requirements(requirements_file, framework_path, version, pip_platform): +def install_requirements( + requirements_file, framework_path, version, pip_platform, no_binary, only_binary): """Use pip to install a Python pkg into framework_path""" + + def multi_value_option(option, values, separator=None): + """Helper function supply the same option with multiple value + + Args: + option (str): the option name (e.g. --