From 55cc49a8d38796a6a30b313df3eccd9c393ecbf6 Mon Sep 17 00:00:00 2001 From: safiyat Date: Wed, 18 Apr 2018 01:10:00 +0530 Subject: [PATCH 1/3] Fixed issues caused due to upgrade of pip to v10.0.0 which removed the deprecated `pip install --download` support. Among other changes, - Introduced a set of global variables named `pip_version`, `pip_download_command` and `pip_no_binary_command`. The variables `pip_download_command` and `pip_no_binary_command` are version dependent. - Now we are importing the `main()` method from `pip` (for pip<10.0.0) or from `pip._internal` (for pip>=10.0.0) as `pip_main`. - Introduced a new flag `has_pip` (pretty much like `has_wheel`) as a global flag to denote the presence of pip. - The help messages printed by the pip2pi parser now dynamically prints options for pip download and no-binary features based on installed pip version. --- libpip2pi/commands.py | 76 ++++++++++++++++++++++++++++--------------- 1 file changed, 50 insertions(+), 26 deletions(-) diff --git a/libpip2pi/commands.py b/libpip2pi/commands.py index 3079b50..81461de 100644 --- a/libpip2pi/commands.py +++ b/libpip2pi/commands.py @@ -19,10 +19,42 @@ except ImportError: has_wheel = False + +def try_int(x): + try: + return int(x) + except ValueError: + return x + + try: - import pip + pip_pkg_info = pkg_resources.get_distribution('pip') + pip_version = tuple(try_int(x) for x in pip_pkg_info.version.split(".")) + has_pip = True except ImportError: - pip = None + pip_version = None + has_pip = False + pip_download_command = '' + pip_no_binary_command = '' + + +if pip_version: + if pip_version >= (10, 0, 0): + from pip._internal import main as pip_main + pip_download_command = 'download --dest' + pip_no_binary_command = '--no-binary=:all:' + elif pip_version >= (8, 0, 0): + from pip import main as pip_main + pip_download_command = 'download --dest' + pip_no_binary_command = '--no-binary=:all:' + elif pip_version >= (7, 0, 0): + from pip import main as pip_main + pip_download_command = 'install --download' + pip_no_binary_command = '--no-binary=:all:' + else: + from pip import main as pip_main + pip_download_command = 'install --download' + pip_no_binary_command = '--no-use-wheel' class PipError(Exception): pass @@ -130,18 +162,9 @@ def file_to_package(file, basedir=None): return (to_safe_name(split[0]), to_safe_rest(split[1])) -def try_int(x): - try: - return int(x) - except ValueError: - return x - -def pip_get_version(): - pip_dist = pkg_resources.get_distribution("pip") - return tuple(try_int(x) for x in pip_dist.version.split(".")) def pip_run_command(pip_args): - if pip is None: + if not has_pip: print("===== WARNING =====") print("Cannot `import pip` - falling back to the pip executable.") print("This will be deprecated in a future release.") @@ -151,11 +174,10 @@ def pip_run_command(pip_args): check_call(["pip"] + pip_args) return - version = pip_get_version() - if version < (1, 1): + if pip_version < (1, 1): raise RuntimeError("pip >= 1.1 required, but %s is installed" - %(version, )) - res = pip.main(pip_args) + %(pip_version, )) + res = pip_main(pip_args) if res != 0: raise PipError("pip failed with status %s while running: %s" %(res, pip_args)) @@ -381,7 +403,7 @@ def pip2tgz(argv=sys.argv): description=dedent(""" Where PACKAGES are any names accepted by pip (ex, `foo`, `foo==1.2`, `-r requirements.txt`), and [PIP_OPTIONS] can be any - options accepted by `pip install -d`. + options accepted by `pip %s`. pip2tgz will download all packages required to install PACKAGES and save them to sanely-named tarballs or wheel files in OUTPUT_DIRECTORY. @@ -390,10 +412,10 @@ def pip2tgz(argv=sys.argv): $ pip2tgz /var/www/packages/ -r requirements.txt foo==1.2 baz/ $ pip2tgz /var/www/packages/ \\ - --no-use-wheel \\ + %s \\ --index-url https://example.com/simple \\ bar==3.1 - """)) + """ % (pip_download_command, pip_no_binary_command))) option, argv = parser.parse_args(argv) if len(argv) < 3: @@ -410,7 +432,10 @@ def pip2tgz(argv=sys.argv): pkg_file_set = lambda: set(globall(full_glob_paths)) old_pkgs = pkg_file_set() - pip_run_command(['install', '-d', outdir] + argv[2:]) + if pip_version >= (8, 0, 0): + pip_run_command(pip_download_command.split() + [outdir] + argv[2:]) + else: + pip_run_command(pip_download_command.split() + [outdir] + argv[2:]) os.chdir(outdir) new_pkgs = pkg_file_set() - old_pkgs @@ -436,7 +461,6 @@ def handle_new_wheels(outdir, new_wheels): if not new_wheels: return 0 - pip_version = pip_get_version() if pip_version >= (1, 5, 3): return 0 @@ -485,8 +509,8 @@ def pip2pi(argv=sys.argv): package index will be built locally and rsync will be used to copy it to the remote host. - PIP_OPTIONS can be any options accepted by `pip install -d`, like - `--index-url` or `--no-use-wheel`. + PIP_OPTIONS can be any options accepted by `pip %s`, like + `--index-url` or `%s`. For example, to create a remote index: @@ -499,13 +523,13 @@ def pip2pi(argv=sys.argv): To pass arguments to pip: $ pip2pi ~/Sites/packages/ \\ - --no-use-wheel \\ + %s \\ --index-url https://example.com/simple \\ -r requirements-base.txt \\ -r requirements-dev.txt \\ bar==3.1 - """)) + """ % (pip_download_command, pip_no_binary_command, pip_no_binary_command))) parser.add_index_options() option, argv = parser.parse_args(argv) @@ -530,7 +554,7 @@ def pip2pi(argv=sys.argv): return res if option.get_source: subcmd_argv_source = subcmd_argv[:] - subcmd_argv_source.insert(2, '--no-use-wheel') + subcmd_argv_source.insert(2, pip_no_binary_command) res = pip2tgz(subcmd_argv_source) if res: print("pip2tgz returned an error; aborting.") From 957ff8342882d0d14aa5701f30a9fa25ce97603f Mon Sep 17 00:00:00 2001 From: Sam Garrett Date: Wed, 25 Apr 2018 18:27:46 -0400 Subject: [PATCH 2/3] get travis tests to run green --- .travis.yml | 18 +++++++++++++----- tox.ini | 2 +- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4dc2d48..61797e6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,9 +1,17 @@ language: python -python: 2.7 -env: - - TOX_ENV=py33 - - TOX_ENV=py27 - - TOX_ENV=pypy +sudo: false +cache: pip + +matrix: + include: + - python: 2.7 + env: TOX_ENV=py27 + - python: 3.3 + env: TOX_ENV=py33 + - python: 3.5 + env: TOX_ENV=py35 + - python: pypy + env: TOX_ENV=pypy install: - pip install tox==2.0.2 script: diff --git a/tox.ini b/tox.ini index 5ebbba0..b2698cc 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py{27,35}-pip{6,7,8} +envlist = py{27,33,35}-pip{6,7,8}, pypy [testenv] deps = From 0972eaf513d18dd016f16f4c496d9ba6f52d9af2 Mon Sep 17 00:00:00 2001 From: Md Safiyat Reza Date: Fri, 9 Nov 2018 13:23:51 +0530 Subject: [PATCH 3/3] Removing 'PIP_REQ_TRACKER' from the environment variables before execution of each pip command. When populated by one `pip_main` call, the variable remains in the environment properties for all subsequent calls, wreaking havoc since the directory is subsequently deleted. Should be removed once fixed in `pip`, but will remain until then. Also removed testing for py33 as pip 18.1 demands 3.4. --- .travis.yml | 4 ++-- libpip2pi/commands.py | 4 ++++ tox.ini | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 61797e6..bf15f21 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,8 +6,8 @@ matrix: include: - python: 2.7 env: TOX_ENV=py27 - - python: 3.3 - env: TOX_ENV=py33 + - python: 3.4 + env: TOX_ENV=py34 - python: 3.5 env: TOX_ENV=py35 - python: pypy diff --git a/libpip2pi/commands.py b/libpip2pi/commands.py index 81461de..28c0769 100644 --- a/libpip2pi/commands.py +++ b/libpip2pi/commands.py @@ -177,6 +177,10 @@ def pip_run_command(pip_args): if pip_version < (1, 1): raise RuntimeError("pip >= 1.1 required, but %s is installed" %(pip_version, )) + # TODO: Remove this once + # pip._internal.req.req_tracker.RequirementTracker.cleanup() does it + # already. + os.environ.pop('PIP_REQ_TRACKER', None) res = pip_main(pip_args) if res != 0: raise PipError("pip failed with status %s while running: %s" diff --git a/tox.ini b/tox.ini index b2698cc..a4af9c5 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py{27,33,35}-pip{6,7,8}, pypy +envlist = py{27,34,35}-pip{6,7,8}, pypy [testenv] deps =