Coder Social home page Coder Social logo

ddelange / pipgrip Goto Github PK

View Code? Open in Web Editor NEW
176.0 6.0 14.0 5.73 MB

Lightweight pip dependency resolver with deptree preview functionality based on the PubGrub algorithm

License: Other

Makefile 0.16% Python 99.84%
dependency-resolver pipdeptree python pypi wheels pip dephell dependency-resolution dependency-trees pubgrub

pipgrip's Introduction

pipgrip

build codecov pypi homebrew python downloads

pipgrip is a lightweight pip dependency resolver with deptree preview functionality based on the PubGrub algorithm, which is also used by poetry. For one or more PEP 508 dependency specifications, pipgrip recursively fetches/builds the Python wheels necessary for version solving, and optionally renders the full resulting dependency tree.

$ pipgrip --tree fastapi~=0.94

fastapi~=0.94 (0.95.1)
├── pydantic!=1.7,!=1.7.1,!=1.7.2,!=1.7.3,!=1.8,!=1.8.1,<2.0.0,>=1.6.2 (1.10.7)
│   └── typing-extensions>=4.2.0 (4.5.0)
└── starlette<0.27.0,>=0.26.1 (0.26.1)
    └── anyio<5,>=3.4.0 (3.6.2)
        ├── idna>=2.8 (3.4)
        └── sniffio>=1.1 (1.3.0)

pipgrip vs. poetry

poetry offers package management with dependency resolution, essentially replacing pip/setuptools. This means that poetry packages don't contain setup.py, and hence are not compatible with pip install -e: poetry projects would have to be converted to setuptools-based projects with e.g. dephell. To avoid such hassle, pipgrip only requires the selected package(s) + dependencies to be available to pip in the usual way.

pipgrip vs. pipdeptree

For offline usage, pipdeptree can inspect the current environment and show how the currently installed packages relate to each other. This however requires the packages to be pip-installed, and (despite warnings about e.g. cyclic dependencies) offers no form of dependency resolution since it's only based on the (single) package versions installed in the environment. Such shortcomings are avoided when using pipgrip, since packages don't need to be installed and all versions available to pip are considered.

Installation

This pure-Python, OS independent package is available on PyPI:

pip install pipgrip

Usage

This package can be used to:

  • Render an exhaustive dependency tree for any given pip-compatible package(s):
    • pipgrip --tree requests
  • Alleviate Python dependency hell by resolving the latest viable combination of required packages
  • Avoid bugs by running pipgrip as a stage in CI pipelines
  • Detect version conflicts for given constraints and give human readable feedback about it
  • Warn for cyclic dependencies in local projects [and install them anyway]:
    • pipgrip -v --tree . [--install -e]
  • Install complex packages without worries:
    • pipgrip --install aiobotocore[awscli]
  • Generate a lockfile with a complete working set of dependencies for reproducible installs:
    • pipgrip --lock aiobotocore[awscli] && pip install aiobotocore[awscli] --constraint ./pipgrip.lock
  • Combine dependency trees of multiple packages into one unified set of pinned packages:
    • pipgrip .[boto3] s3transfer==0.2.1 s3fs smart_open[s3]

See also known caveats.

Optionally, the environment variable PIPGRIP_ADDITIONAL_REQUIREMENTS can be populated with space/newline separated requirements, which will be appended to the requirements passed via CLI.

$ pipgrip --help

Usage: pipgrip [OPTIONS] [DEPENDENCIES]...

  pipgrip is a lightweight pip dependency resolver with deptree preview
  functionality based on the PubGrub algorithm, which is also used by poetry. For
  one or more PEP 508 dependency specifications, pipgrip recursively
  fetches/builds the Python wheels necessary for version solving, and optionally
  renders the full resulting dependency tree.

Options:
  --install                     Install full dependency tree after resolving.
  -e, --editable                Install a project in editable mode.
  --user                        Install to the Python user install directory for
                                your platform -- typically ~/.local/, or
                                %APPDATA%\Python on Windows.
  -r, --requirements-file FILE  Install from the given requirements file. This
                                option can be used multiple times.
  --lock                        Write out pins to './pipgrip.lock'.
  --pipe                        Output space-separated pins instead of newline-
                                separated pins.
  --json                        Output pins as JSON dict instead of newline-
                                separated pins. Combine with --tree for a detailed
                                nested JSON dependency tree.
  --sort                        Sort pins alphabetically before writing out. Can
                                be used bare, or in combination with --lock,
                                --pipe, --json, --tree-json, or --tree-json-exact.
  --tree                        Output human readable dependency tree (top-down).
                                Combine with --json for a detailed nested JSON
                                dependency tree. Use --tree-json instead for a
                                simplified JSON dependency tree (requirement
                                strings as keys, dependencies as values), or
                                --tree-json-exact for exact pins as keys.
  --tree-ascii                  Output human readable dependency tree with ASCII
                                tree markers.
  --reversed-tree               Output human readable dependency tree (bottom-up).
  --max-depth INTEGER           Maximum (JSON) tree rendering depth (default -1).
  --cache-dir DIRECTORY         Use a custom cache dir.
  --no-cache-dir                Disable pip cache for the wheels downloaded by
                                pipper. Overrides --cache-dir.
  --index-url TEXT              Base URL of the Python Package Index (default
                                https://pypi.org/simple).
  --extra-index-url TEXT        Extra URLs of package indexes to use in addition
                                to --index-url.
  --threads INTEGER             Maximum amount of threads to use for running
                                concurrent pip subprocesses.
  --pre                         Include pre-release and development versions. By
                                default, pip implicitly excludes pre-releases
                                (unless specified otherwise by PEP 440).
  -v, --verbose                 Control verbosity: -v will print cyclic
                                dependencies (WARNING), -vv will show solving
                                decisions (INFO), -vvv for development (DEBUG).
  -h, --help                    Show this message and exit.

Dependency trees

Exhaustive dependency trees without the need to install any packages (at most build some wheels).

$ pipgrip --tree pipgrip

pipgrip (0.10.6)
├── anytree>=2.4.1 (2.9.0)
│   └── six (1.16.0)
├── click>=7 (8.1.6)
├── packaging>=17 (23.1)
├── pip>=22.2 (23.2.1)
├── setuptools>=38.3 (68.0.0)
└── wheel (0.41.1)

For more details/further processing, combine --tree with --json for a detailed nested JSON dependency tree. See also --tree-ascii (no unicode tree markers), and --tree-json & --tree-json-exact (simplified JSON dependency trees).

Lockfile generation

Using the --lock option, resolved (pinned) dependencies are additionally written to ./pipgrip.lock.

$ pipgrip --tree --lock botocore==1.13.48 'boto3>=1.10,<1.10.50'

botocore==1.13.48 (1.13.48)
├── docutils<0.16,>=0.10 (0.15.2)
├── jmespath<1.0.0,>=0.7.1 (0.9.5)
├── python-dateutil<3.0.0,>=2.1 (2.8.1)
│   └── six>=1.5 (1.14.0)
└── urllib3<1.26,>=1.20 (1.25.8)
boto3<1.10.50,>=1.10 (1.10.48)
├── botocore<1.14.0,>=1.13.48 (1.13.48)
│   ├── docutils<0.16,>=0.10 (0.15.2)
│   ├── jmespath<1.0.0,>=0.7.1 (0.9.5)
│   ├── python-dateutil<3.0.0,>=2.1 (2.8.1)
│   │   └── six>=1.5 (1.14.0)
│   └── urllib3<1.26,>=1.20 (1.25.8)
├── jmespath<1.0.0,>=0.7.1 (0.9.5)
└── s3transfer<0.3.0,>=0.2.0 (0.2.1)
    └── botocore<2.0.0,>=1.12.36 (1.13.48)
        ├── docutils<0.16,>=0.10 (0.15.2)
        ├── jmespath<1.0.0,>=0.7.1 (0.9.5)
        ├── python-dateutil<3.0.0,>=2.1 (2.8.1)
        │   └── six>=1.5 (1.14.0)
        └── urllib3<1.26,>=1.20 (1.25.8)

$ cat ./pipgrip.lock

botocore==1.13.48
docutils==0.15.2
jmespath==0.9.5
python-dateutil==2.8.1
six==1.14.0
urllib3==1.25.8
boto3==1.10.48
s3transfer==0.2.1

NOTE: Since the selected botocore version is older than the one required by the recent versions of boto3, all boto3 versions will be checked for compatibility with botocore==1.13.48.

Version conflicts

If version conflicts exist for the given (ranges of) package version(s), a verbose explanation is raised.

$ pipgrip auto-sklearn~=0.6 dragnet==2.0.4

Error: Because dragnet (2.0.4) depends on scikit-learn (>=0.15.2,<0.21.0)
 and auto-sklearn (0.6.0) depends on scikit-learn (<0.22,>=0.21.0), dragnet (2.0.4) is incompatible with auto-sklearn (0.6.0).
And because no versions of auto-sklearn match >0.6.0,<1.0, dragnet (2.0.4) is incompatible with auto-sklearn (>=0.6.0,<1.0).
So, because root depends on both auto-sklearn (~=0.6) and dragnet (==2.0.4), version solving failed.

NOTE: If older versions of auto-sklearn are allowed, PubGrub will try all acceptable versions of auto-sklearn. In this case, auto-sklearn==0.5.2 requires scikit-learn (<0.20,>=0.19), making it compatible with dragnet==2.0.4.

Cyclic dependencies

If cyclic dependencies are found, it is noted in the resulting tree.

$ pipgrip --tree -v keras==2.2.2

WARNING: Cyclic dependency found: keras depends on keras-applications and vice versa.
WARNING: Cyclic dependency found: keras depends on keras-preprocessing and vice versa.
keras==2.2.2 (2.2.2)
├── h5py (2.10.0)
│   ├── numpy>=1.7 (1.18.1)
│   └── six (1.14.0)
├── keras-applications==1.0.4 (1.0.4)
│   ├── h5py (2.10.0)
│   │   ├── numpy>=1.7 (1.18.1)
│   │   └── six (1.14.0)
│   ├── keras>=2.1.6 (2.2.2, cyclic)
│   └── numpy>=1.9.1 (1.18.1)
├── keras-preprocessing==1.0.2 (1.0.2)
│   ├── keras>=2.1.6 (2.2.2, cyclic)
│   ├── numpy>=1.9.1 (1.18.1)
│   ├── scipy>=0.14 (1.4.1)
│   │   └── numpy>=1.13.3 (1.18.1)
│   └── six>=1.9.0 (1.14.0)
├── numpy>=1.9.1 (1.18.1)
├── pyyaml (5.3)
├── scipy>=0.14 (1.4.1)
│   └── numpy>=1.13.3 (1.18.1)
└── six>=1.9.0 (1.14.0)

Known caveats

  • PubGrub doesn't support version epochs, the main reason PyPA chose resolvelib over PubGrub for their new resolver.
  • Package names are canonicalised in wheel metadata, resulting in e.g. path.py -> path-py and keras_preprocessing -> keras-preprocessing in output.
  • VCS Support: combining VCS requirements with --editable, as well as the @ -e svn+ pattern are not supported.
  • Similar to setuptools' install_requires, omitting the projectname @ prefix is not supported neither for VCS requirements (like pip install git+https...), nor for PEP 440 direct references (like pip install https...).
  • Parsing requirements files (-r) does not support: custom file encodings, line continuations, global/per-requirement options
  • --reversed-tree isn't implemented yet.
  • Since pip install -r does not accept . as requirement, it is omitted from --lock output. So when installing local projects, either --pipe or --install should be used (the latter basically does pipgrip --lock . && pip install . --constraint ./pipgrip.lock).
  • Local paths are not supported (like pip install -e ../aiobotocore[boto3]), except for the current directory (like pipgrip --install -e .[boto3]).

Development

gitmoji pre-commit black

Run make help for options like installing for development, linting and testing.

See also


BSD 3-Clause License

Copyright (c) 2020 - 2024, ddelange, [email protected]

All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

  2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

  3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

SPDX-License-Identifier: BSD-3-Clause

pipgrip's People

Contributors

bchen1116 avatar cclauss avatar ddelange avatar dependabot[bot] avatar gruebel avatar kianmeng avatar kurtmckee avatar mdengler avatar suzil avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

pipgrip's Issues

pipgrep allennlp is slow

What you were trying to do (and why)

pipgrep allennlp takes > 10 mins.

What happened (including command output)

Command output

$ pipgrip -vvv <your-command>pipgrip -vv allennlp
INFO: fact: _root_ is root
INFO: derived: root
INFO: fact: root depends on allennlp (*)
INFO: selecting _root_ (0.0.0)
INFO: derived: allennlp (*)
INFO: discovering allennlp
INFO: fact: allennlp (2.10.1) depends on base58 (>=2.1.1)
INFO: fact: allennlp (2.10.1) depends on cached-path (>=1.1.3,<1.2.0)
INFO: fact: allennlp (2.10.1) depends on dill (>=0.3.4)
INFO: fact: allennlp (2.10.1) depends on fairscale (==0.4.6)
INFO: fact: allennlp (2.10.1) depends on filelock (>=3.3,<3.8)
INFO: fact: allennlp (2.10.1) depends on h5py (>=3.6.0)
INFO: fact: allennlp (2.10.1) depends on huggingface-hub (>=0.0.16)
INFO: fact: allennlp (2.10.1) depends on jsonnet (>=0.10.0)
INFO: fact: allennlp (2.10.1) depends on lmdb (>=1.2.1)
INFO: fact: allennlp (2.10.1) depends on more-itertools (>=8.12.0)
INFO: fact: allennlp (2.10.1) depends on nltk (>=3.6.5)
INFO: fact: allennlp (2.10.1) depends on numpy (>=1.21.4)
INFO: fact: allennlp (2.10.1) depends on protobuf (<4.0.0,>=3.12.0)
INFO: fact: allennlp (2.10.1) depends on pytest (>=6.2.5)
INFO: fact: allennlp (2.10.1) depends on requests (>=2.28)
INFO: fact: allennlp (2.10.1) depends on sacremoses (*)
INFO: fact: allennlp (2.10.1) depends on scikit-learn (>=1.0.1)
INFO: fact: allennlp (2.10.1) depends on scipy (>=1.7.3)
INFO: fact: allennlp (2.10.1) depends on sentencepiece (>=0.1.96)
INFO: fact: allennlp (2.10.1) depends on spacy (>=2.1.0,<3.4)
INFO: fact: allennlp (2.10.1) depends on tensorboardx (>=1.2)
INFO: fact: allennlp (2.10.1) depends on termcolor (==1.1.0)
INFO: fact: allennlp (2.10.1) depends on torch (<1.13.0,>=1.10.0)
INFO: fact: allennlp (2.10.1) depends on torchvision (<0.14.0,>=0.8.1)
INFO: fact: allennlp (2.10.1) depends on tqdm (>=4.62)
INFO: fact: allennlp (2.10.1) depends on traitlets (>5.1.1)
INFO: fact: allennlp (2.10.1) depends on transformers (<4.21,>=4.1)
INFO: fact: allennlp (2.10.1) depends on typer (>=0.4.1)
INFO: fact: allennlp (2.10.1) depends on wandb (>=0.10.0,<0.13.0)
INFO: selecting allennlp (2.10.1)
INFO: derived: wandb (>=0.10.0,<0.13.0)
INFO: derived: typer (>=0.4.1)
INFO: derived: transformers (<4.21,>=4.1)
INFO: derived: traitlets (>5.1.1)
INFO: derived: tqdm (>=4.62)
INFO: derived: torchvision (<0.14.0,>=0.8.1)
INFO: derived: torch (<1.13.0,>=1.10.0)
INFO: derived: termcolor (==1.1.0)
INFO: derived: tensorboardx (>=1.2)
INFO: derived: spacy (>=2.1.0,<3.4)
INFO: derived: sentencepiece (>=0.1.96)
INFO: derived: scipy (>=1.7.3)
INFO: derived: scikit-learn (>=1.0.1)
INFO: derived: sacremoses (*)
INFO: derived: requests (>=2.28)
INFO: derived: pytest (>=6.2.5)
INFO: derived: protobuf (<4.0.0,>=3.12.0)
INFO: derived: numpy (>=1.21.4)
INFO: derived: nltk (>=3.6.5)
INFO: derived: more-itertools (>=8.12.0)
INFO: derived: lmdb (>=1.2.1)
INFO: derived: jsonnet (>=0.10.0)
INFO: derived: huggingface-hub (>=0.0.16)
INFO: derived: h5py (>=3.6.0)
INFO: derived: filelock (>=3.3,<3.8)
INFO: derived: fairscale (==0.4.6)
INFO: derived: dill (>=0.3.4)
INFO: derived: cached-path (>=1.1.3,<1.2.0)
INFO: derived: base58 (>=2.1.1)
INFO: discovering wandb<0.13.0,>=0.10.0
INFO: discovering typer>=0.4.1
INFO: discovering transformers<4.21,>=4.1
INFO: discovering traitlets>5.1.1
INFO: discovering tqdm>=4.62
INFO: discovering torchvision<0.14.0,>=0.8.1
INFO: discovering torch<1.13.0,>=1.10.0
INFO: discovering termcolor==1.1.0
INFO: discovering tensorboardx>=1.2
INFO: discovering spacy<3.4,>=2.1.0
INFO: discovering sentencepiece>=0.1.96
INFO: discovering scipy>=1.7.3
INFO: discovering scikit-learn>=1.0.1
INFO: discovering sacremoses
INFO: discovering requests>=2.28
INFO: discovering pytest>=6.2.5
INFO: discovering protobuf<4.0.0,>=3.12.0
INFO: discovering numpy>=1.21.4
INFO: discovering nltk>=3.6.5
INFO: discovering more-itertools>=8.12.0
INFO: discovering lmdb>=1.2.1
INFO: discovering jsonnet>=0.10.0
INFO: discovering huggingface-hub>=0.0.16
INFO: discovering h5py>=3.6.0
INFO: discovering filelock<3.8,>=3.3
INFO: discovering fairscale==0.4.6
INFO: discovering dill>=0.3.4
INFO: discovering cached-path<1.2.0,>=1.1.3
INFO: discovering base58>=2.1.1
INFO: selecting termcolor (1.1.0)
INFO: selecting base58 (2.1.1)
INFO: fact: fairscale (0.4.6) depends on torch (>=1.8.0)
INFO: selecting fairscale (0.4.6)
INFO: selecting sentencepiece (0.1.98)
INFO: fact: h5py (3.8.0) depends on numpy (>=1.14.5)
INFO: selecting h5py (3.8.0)
INFO: selecting lmdb (1.4.1)
INFO: selecting dill (0.3.6)
INFO: fact: requests (2.29.0) depends on certifi (>=2017.4.17)
INFO: fact: requests (2.29.0) depends on charset-normalizer (<4,>=2)
INFO: fact: requests (2.29.0) depends on idna (<4,>=2.5)
INFO: fact: requests (2.29.0) depends on urllib3 (>=1.21.1,<1.27)
INFO: selecting requests (2.29.0)
INFO: derived: urllib3 (>=1.21.1,<1.27)
INFO: derived: idna (<4,>=2.5)
INFO: derived: charset-normalizer (<4,>=2)
INFO: derived: certifi (>=2017.4.17)
INFO: discovering urllib3<1.27,>=1.21.1
INFO: discovering idna<4,>=2.5
INFO: discovering charset-normalizer<4,>=2
INFO: discovering certifi>=2017.4.17
INFO: fact: cached-path (1.1.6) depends on boto3 (>=1.0,<2.0)
INFO: fact: cached-path (1.1.6) depends on filelock (>=3.4,<3.9)
INFO: fact: cached-path (1.1.6) depends on google-cloud-storage (<3.0,>=1.32.0)
INFO: fact: cached-path (1.1.6) depends on huggingface-hub (<0.11.0,>=0.8.1)
INFO: fact: cached-path (1.1.6) depends on requests (<3.0,>=2.0)
INFO: fact: cached-path (1.1.6) depends on rich (<13.0,>=12.1)
INFO: selecting cached-path (1.1.6)
INFO: derived: rich (<13.0,>=12.1)
INFO: derived: huggingface-hub (<0.11.0,>=0.8.1)
INFO: derived: google-cloud-storage (<3.0,>=1.32.0)
INFO: derived: filelock (>=3.4,<3.9)
INFO: derived: boto3 (>=1.0,<2.0)
INFO: discovering huggingface-hub==0.10.1
INFO: discovering rich<13.0,>=12.1
INFO: discovering google-cloud-storage<3.0,>=1.32.0
INFO: discovering boto3<2.0,>=1.0
INFO: selecting more-itertools (9.1.0)
INFO: fact: huggingface-hub (0.10.1) depends on filelock (*)
INFO: fact: huggingface-hub (0.10.1) depends on packaging (>=20.9)
INFO: fact: huggingface-hub (0.10.1) depends on pyyaml (>=5.1)
INFO: fact: huggingface-hub (0.10.1) depends on requests (*)
INFO: fact: huggingface-hub (0.10.1) depends on tqdm (*)
INFO: fact: huggingface-hub (0.10.1) depends on typing-extensions (>=3.7.4.3)
INFO: selecting huggingface-hub (0.10.1)
INFO: derived: typing-extensions (>=3.7.4.3)
INFO: derived: pyyaml (>=5.1)
INFO: derived: packaging (>=20.9)
INFO: discovering typing-extensions>=3.7.4.3
INFO: discovering pyyaml>=5.1
INFO: discovering packaging>=20.9
INFO: fact: typer (0.7.0) depends on click (<9.0.0,>=7.1.1)
INFO: selecting typer (0.7.0)
INFO: derived: click (<9.0.0,>=7.1.1)
INFO: discovering click<9.0.0,>=7.1.1
INFO: fact: torch (1.12.1) depends on typing-extensions (*)
INFO: selecting torch (1.12.1)
INFO: fact: nltk (3.8.1) depends on click (*)
INFO: fact: nltk (3.8.1) depends on joblib (*)
INFO: fact: nltk (3.8.1) depends on regex (>=2021.8.3)
INFO: fact: nltk (3.8.1) depends on tqdm (*)
INFO: selecting nltk (3.8.1)
INFO: derived: regex (>=2021.8.3)
INFO: derived: joblib (*)
INFO: discovering regex>=2021.8.3
INFO: discovering joblib
INFO: fact: torchvision (0.13.1) depends on numpy (*)
INFO: fact: torchvision (0.13.1) depends on pillow (>=5.3.0,<8.3.0 || >=8.4.0)
INFO: fact: torchvision (0.13.1) depends on requests (*)
INFO: fact: torchvision (0.13.1) depends on torch (*)
INFO: fact: torchvision (0.13.1) depends on typing-extensions (*)
INFO: selecting torchvision (0.13.1)
INFO: derived: pillow (>=5.3.0,<8.3.0 || >=8.4.0)
INFO: discovering pillow!=8.3.*,>=5.3.0
INFO: selecting filelock (3.7.1)
INFO: selecting packaging (23.1)
INFO: selecting pyyaml (6.0)
INFO: fact: scipy (1.10.1) depends on numpy (<1.27.0,>=1.19.5)
INFO: selecting scipy (1.10.1)
INFO: derived: numpy (<1.27.0,>=1.19.5)
INFO: fact: scikit-learn (1.2.2) depends on joblib (>=1.1.1)
INFO: fact: scikit-learn (1.2.2) depends on numpy (>=1.17.3)
INFO: fact: scikit-learn (1.2.2) depends on scipy (>=1.3.2)
INFO: fact: scikit-learn (1.2.2) depends on threadpoolctl (>=2.0.0)
INFO: selecting scikit-learn (1.2.2)
INFO: derived: threadpoolctl (>=2.0.0)
INFO: derived: joblib (>=1.1.1)
INFO: discovering threadpoolctl>=2.0.0
INFO: selecting joblib (1.2.0)
INFO: selecting threadpoolctl (3.1.0)
INFO: selecting tqdm (4.65.0)
INFO: selecting idna (3.4)
INFO: selecting click (8.1.3)
INFO: fact: rich (12.6.0) depends on commonmark (>=0.9.0,<0.10.0)
INFO: fact: rich (12.6.0) depends on pygments (<3.0.0,>=2.6.0)
INFO: selecting rich (12.6.0)
INFO: derived: pygments (<3.0.0,>=2.6.0)
INFO: derived: commonmark (>=0.9.0,<0.10.0)
INFO: discovering pygments<3.0.0,>=2.6.0
INFO: discovering commonmark<0.10.0,>=0.9.0
INFO: selecting commonmark (0.9.1)
INFO: selecting traitlets (5.9.0)
INFO: selecting typing-extensions (4.5.0)
INFO: fact: pytest (7.3.1) depends on exceptiongroup (>=1.0.0rc8)
INFO: fact: pytest (7.3.1) depends on iniconfig (*)
INFO: fact: pytest (7.3.1) depends on packaging (*)
INFO: fact: pytest (7.3.1) depends on pluggy (<2.0,>=0.12)
INFO: fact: pytest (7.3.1) depends on tomli (>=1.0.0)
INFO: selecting pytest (7.3.1)
INFO: derived: tomli (>=1.0.0)
INFO: derived: pluggy (<2.0,>=0.12)
INFO: derived: iniconfig (*)
INFO: derived: exceptiongroup (>=1.0.0rc8)
INFO: discovering tomli>=1.0.0
INFO: discovering pluggy<2.0,>=0.12
INFO: discovering iniconfig
INFO: discovering exceptiongroup>=1.0.0rc8
INFO: selecting pluggy (1.0.0)
INFO: selecting iniconfig (2.0.0)
INFO: selecting exceptiongroup (1.1.1)
INFO: selecting tomli (2.0.1)
INFO: selecting jsonnet (0.20.0)
INFO: fact: tensorboardx (2.6) depends on numpy (*)
INFO: fact: tensorboardx (2.6) depends on packaging (*)
INFO: fact: tensorboardx (2.6) depends on protobuf (<4,>=3.8.0)
INFO: selecting tensorboardx (2.6)
INFO: selecting numpy (1.24.3)
INFO: selecting charset-normalizer (3.1.0)
INFO: selecting pygments (2.15.1)
INFO: selecting regex (2023.3.23)
INFO: selecting pillow (9.5.0)
INFO: selecting certifi (2022.12.7)
INFO: fact: google-cloud-storage (2.8.0) depends on google-api-core (>=1.31.5,<2.0.0 || >2.3.0,<3.0.0dev)
INFO: fact: google-cloud-storage (2.8.0) depends on google-auth (<3.0dev,>=1.25.0)
INFO: fact: google-cloud-storage (2.8.0) depends on google-cloud-core (<3.0dev,>=2.3.0)
INFO: fact: google-cloud-storage (2.8.0) depends on google-resumable-media (>=2.3.2)
INFO: fact: google-cloud-storage (2.8.0) depends on requests (<3.0.0dev,>=2.18.0)
INFO: selecting google-cloud-storage (2.8.0)
INFO: derived: google-resumable-media (>=2.3.2)
INFO: derived: google-cloud-core (<3.0dev,>=2.3.0)
INFO: derived: google-auth (<3.0dev,>=1.25.0)
INFO: derived: google-api-core (>=1.31.5,<2.0.0 || >2.3.0,<3.0.0dev)
INFO: discovering google-resumable-media>=2.3.2
INFO: discovering google-cloud-core<3.0dev,>=2.3.0
INFO: discovering google-auth<3.0dev,>=1.25.0
INFO: discovering google-api-core!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.0,<3.0.0dev,>=1.31.5
INFO: fact: google-cloud-core (2.3.2) depends on google-api-core (>=1.31.6,<2.0.0 || >2.3.0,<3.0.0dev)
INFO: fact: google-cloud-core (2.3.2) depends on google-auth (<3.0dev,>=1.25.0)
INFO: selecting google-cloud-core (2.3.2)
INFO: derived: google-api-core (>=1.31.6,<2.0.0 || >2.3.0,<3.0.0dev)
INFO: fact: google-resumable-media (2.5.0) depends on google-crc32c (>=1.0,<2.0dev)
INFO: selecting google-resumable-media (2.5.0)
INFO: derived: google-crc32c (>=1.0,<2.0dev)
INFO: discovering google-crc32c<2.0dev,>=1.0
INFO: selecting google-crc32c (1.5.0)
INFO: fact: google-api-core (2.11.0) depends on google-auth (<3.0dev,>=2.14.1)
INFO: fact: google-api-core (2.11.0) depends on googleapis-common-protos (<2.0dev,>=1.56.2)
INFO: fact: google-api-core (2.11.0) depends on protobuf (>=3.19.5,<3.20.0 || >3.20.0,<3.20.1 || >3.20.1,<4.21.0 || >4.21.0,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<5.0.0dev)
INFO: fact: google-api-core (2.11.0) depends on requests (<3.0.0dev,>=2.18.0)
INFO: selecting google-api-core (2.11.0)
INFO: derived: protobuf (>=3.19.5,<3.20.0 || >3.20.0,<3.20.1 || >3.20.1,<4.21.0 || >4.21.0,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<5.0.0dev)
INFO: derived: googleapis-common-protos (<2.0dev,>=1.56.2)
INFO: derived: google-auth (<3.0dev,>=2.14.1)
INFO: discovering googleapis-common-protos<2.0dev,>=1.56.2
INFO: selecting protobuf (3.20.3)
INFO: fact: googleapis-common-protos (1.59.0) depends on protobuf (>=3.19.5,<3.20.0 || >3.20.0,<3.20.1 || >3.20.1,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<5.0.0dev)
INFO: selecting googleapis-common-protos (1.59.0)
INFO: fact: google-auth (2.17.3) depends on cachetools (>=2.0.0,<6.0)
INFO: fact: google-auth (2.17.3) depends on pyasn1-modules (>=0.2.1)
INFO: fact: google-auth (2.17.3) depends on rsa (<5,>=3.1.4)
INFO: fact: google-auth (2.17.3) depends on six (>=1.9.0)
INFO: selecting google-auth (2.17.3)
INFO: derived: six (>=1.9.0)
INFO: derived: rsa (<5,>=3.1.4)
INFO: derived: pyasn1-modules (>=0.2.1)
INFO: derived: cachetools (>=2.0.0,<6.0)
INFO: discovering six>=1.9.0
INFO: discovering rsa<5,>=3.1.4
INFO: discovering pyasn1-modules>=0.2.1
INFO: discovering cachetools<6.0,>=2.0.0
INFO: selecting six (1.16.0)
INFO: fact: pyasn1-modules (0.3.0) depends on pyasn1 (>=0.4.6,<0.6.0)
INFO: selecting pyasn1-modules (0.3.0)
INFO: derived: pyasn1 (>=0.4.6,<0.6.0)
INFO: discovering pyasn1<0.6.0,>=0.4.6
INFO: selecting pyasn1 (0.5.0)
INFO: selecting cachetools (5.3.0)
INFO: fact: rsa (4.9) depends on pyasn1 (>=0.1.3)
INFO: selecting rsa (4.9)
INFO: selecting urllib3 (1.26.15)
INFO: fact: sacremoses (0.0.53) depends on click (*)
INFO: fact: sacremoses (0.0.53) depends on joblib (*)
INFO: fact: sacremoses (0.0.53) depends on regex (*)
INFO: fact: sacremoses (0.0.53) depends on six (*)
INFO: fact: sacremoses (0.0.53) depends on tqdm (*)
INFO: selecting sacremoses (0.0.53)
INFO: fact: spacy (3.3.2) depends on blis (<0.8.0,>=0.4.0)
INFO: fact: spacy (3.3.2) depends on catalogue (>=2.0.6,<2.1.0)
INFO: fact: spacy (3.3.2) depends on cymem (>=2.0.2,<2.1.0)
INFO: fact: spacy (3.3.2) depends on jinja2 (*)
INFO: fact: spacy (3.3.2) depends on langcodes (<4.0.0,>=3.2.0)
INFO: fact: spacy (3.3.2) depends on murmurhash (<1.1.0,>=0.28.0)
INFO: fact: spacy (3.3.2) depends on numpy (>=1.15.0)
INFO: fact: spacy (3.3.2) depends on packaging (>=20.0)
INFO: fact: spacy (3.3.2) depends on pathy (>=0.3.5)
INFO: fact: spacy (3.3.2) depends on preshed (<3.1.0,>=3.0.2)
INFO: fact: spacy (3.3.2) depends on pydantic (>=1.7.4,<1.8 || >1.8,<1.8.1 || >1.8.1,<1.9.0)
INFO: fact: spacy (3.3.2) depends on requests (<3.0.0,>=2.13.0)
INFO: fact: spacy (3.3.2) depends on setuptools (*)
INFO: fact: spacy (3.3.2) depends on smart-open (<7.0.0,>=5.2.1)
INFO: fact: spacy (3.3.2) depends on spacy-legacy (<3.1.0,>=3.0.9)
INFO: fact: spacy (3.3.2) depends on spacy-loggers (>=1.0.0,<2.0.0)
INFO: fact: spacy (3.3.2) depends on srsly (<3.0.0,>=2.4.3)
INFO: fact: spacy (3.3.2) depends on thinc (>=8.0.14,<8.1.0)
INFO: fact: spacy (3.3.2) depends on tqdm (<5.0.0,>=4.38.0)
INFO: fact: spacy (3.3.2) depends on typer (<0.5.0,>=0.3.0)
INFO: fact: spacy (3.3.2) depends on wasabi (<1.1.0,>=0.9.1)
INFO: derived: not spacy (3.3.2)
INFO: discovering spacy==3.3.1
INFO: fact: spacy (3.3.1) depends on blis (<0.8.0,>=0.4.0)
INFO: fact: spacy (3.3.1) depends on catalogue (>=2.0.6,<2.1.0)
INFO: fact: spacy (3.3.1) depends on cymem (>=2.0.2,<2.1.0)
INFO: fact: spacy (3.3.1) depends on jinja2 (*)
INFO: fact: spacy (3.3.1) depends on langcodes (<4.0.0,>=3.2.0)
INFO: fact: spacy (3.3.1) depends on murmurhash (<1.1.0,>=0.28.0)
INFO: fact: spacy (3.3.1) depends on numpy (>=1.15.0)
INFO: fact: spacy (3.3.1) depends on packaging (>=20.0)
INFO: fact: spacy (3.3.1) depends on pathy (>=0.3.5)
INFO: fact: spacy (3.3.1) depends on preshed (<3.1.0,>=3.0.2)
INFO: fact: spacy (3.3.1) depends on pydantic (>=1.7.4,<1.8 || >1.8,<1.8.1 || >1.8.1,<1.9.0)
INFO: fact: spacy (3.3.1) depends on requests (<3.0.0,>=2.13.0)
INFO: fact: spacy (3.3.1) depends on setuptools (*)
INFO: fact: spacy (3.3.1) depends on spacy-legacy (<3.1.0,>=3.0.9)
INFO: fact: spacy (3.3.1) depends on spacy-loggers (>=1.0.0,<2.0.0)
INFO: fact: spacy (3.3.1) depends on srsly (<3.0.0,>=2.4.3)
INFO: fact: spacy (3.3.1) depends on thinc (>=8.0.14,<8.1.0)
INFO: fact: spacy (3.3.1) depends on tqdm (<5.0.0,>=4.38.0)
INFO: fact: spacy (3.3.1) depends on typer (<0.5.0,>=0.3.0)
INFO: fact: spacy (3.3.1) depends on wasabi (<1.1.0,>=0.9.1)
INFO: derived: not spacy (3.3.1)
INFO: discovering spacy==3.3.0
INFO: fact: spacy (3.3.0) depends on blis (<0.8.0,>=0.4.0)
INFO: fact: spacy (3.3.0) depends on catalogue (>=2.0.6,<2.1.0)
INFO: fact: spacy (3.3.0) depends on cymem (>=2.0.2,<2.1.0)
INFO: fact: spacy (3.3.0) depends on jinja2 (*)
INFO: fact: spacy (3.3.0) depends on langcodes (<4.0.0,>=3.2.0)
INFO: fact: spacy (3.3.0) depends on murmurhash (<1.1.0,>=0.28.0)
INFO: fact: spacy (3.3.0) depends on numpy (>=1.15.0)
INFO: fact: spacy (3.3.0) depends on packaging (>=20.0)
INFO: fact: spacy (3.3.0) depends on pathy (>=0.3.5)
INFO: fact: spacy (3.3.0) depends on preshed (<3.1.0,>=3.0.2)
INFO: fact: spacy (3.3.0) depends on pydantic (>=1.7.4,<1.8 || >1.8,<1.8.1 || >1.8.1,<1.9.0)
INFO: fact: spacy (3.3.0) depends on requests (<3.0.0,>=2.13.0)
INFO: fact: spacy (3.3.0) depends on setuptools (*)
INFO: fact: spacy (3.3.0) depends on spacy-legacy (<3.1.0,>=3.0.9)
INFO: fact: spacy (3.3.0) depends on spacy-loggers (>=1.0.0,<2.0.0)
INFO: fact: spacy (3.3.0) depends on srsly (<3.0.0,>=2.4.3)
INFO: fact: spacy (3.3.0) depends on thinc (>=8.0.14,<8.1.0)
INFO: fact: spacy (3.3.0) depends on tqdm (<5.0.0,>=4.38.0)
INFO: fact: spacy (3.3.0) depends on typer (<0.5.0,>=0.3.0)
INFO: fact: spacy (3.3.0) depends on wasabi (<1.1.0,>=0.9.1)
INFO: derived: not spacy (3.3.0)
INFO: discovering spacy==3.2.5
INFO: fact: spacy (3.2.5) depends on blis (<0.8.0,>=0.4.0)
INFO: fact: spacy (3.2.5) depends on catalogue (>=2.0.6,<2.1.0)
INFO: fact: spacy (3.2.5) depends on cymem (>=2.0.2,<2.1.0)
INFO: fact: spacy (3.2.5) depends on jinja2 (*)
INFO: fact: spacy (3.2.5) depends on langcodes (<4.0.0,>=3.2.0)
INFO: fact: spacy (3.2.5) depends on murmurhash (<1.1.0,>=0.28.0)
INFO: fact: spacy (3.2.5) depends on numpy (>=1.15.0)
INFO: fact: spacy (3.2.5) depends on packaging (>=20.0)
INFO: fact: spacy (3.2.5) depends on pathy (>=0.3.5)
INFO: fact: spacy (3.2.5) depends on preshed (<3.1.0,>=3.0.2)
INFO: fact: spacy (3.2.5) depends on pydantic (>=1.7.4,<1.8 || >1.8,<1.8.1 || >1.8.1,<1.9.0)
INFO: fact: spacy (3.2.5) depends on requests (<3.0.0,>=2.13.0)
INFO: fact: spacy (3.2.5) depends on setuptools (*)
INFO: fact: spacy (3.2.5) depends on smart-open (<7.0.0,>=5.2.1)
INFO: fact: spacy (3.2.5) depends on spacy-legacy (<3.1.0,>=3.0.8)
INFO: fact: spacy (3.2.5) depends on spacy-loggers (>=1.0.0,<2.0.0)
INFO: fact: spacy (3.2.5) depends on srsly (<3.0.0,>=2.4.1)
INFO: fact: spacy (3.2.5) depends on thinc (>=8.0.12,<8.1.0)
INFO: fact: spacy (3.2.5) depends on tqdm (<5.0.0,>=4.38.0)
INFO: fact: spacy (3.2.5) depends on typer (<0.5.0,>=0.3.0)
INFO: fact: spacy (3.2.5) depends on wasabi (<1.1.0,>=0.8.1)
INFO: derived: not spacy (3.2.5)
INFO: discovering spacy==3.2.4
INFO: fact: spacy (3.2.4) depends on blis (<0.8.0,>=0.4.0)
INFO: fact: spacy (3.2.4) depends on catalogue (>=2.0.6,<2.1.0)
INFO: fact: spacy (3.2.4) depends on click (<8.1.0)
INFO: fact: spacy (3.2.4) depends on cymem (>=2.0.2,<2.1.0)
INFO: fact: spacy (3.2.4) depends on jinja2 (*)
INFO: fact: spacy (3.2.4) depends on langcodes (<4.0.0,>=3.2.0)
INFO: fact: spacy (3.2.4) depends on murmurhash (<1.1.0,>=0.28.0)
INFO: fact: spacy (3.2.4) depends on numpy (>=1.15.0)
INFO: fact: spacy (3.2.4) depends on packaging (>=20.0)
INFO: fact: spacy (3.2.4) depends on pathy (>=0.3.5)
INFO: fact: spacy (3.2.4) depends on preshed (<3.1.0,>=3.0.2)
INFO: fact: spacy (3.2.4) depends on pydantic (>=1.7.4,<1.8 || >1.8,<1.8.1 || >1.8.1,<1.9.0)
INFO: fact: spacy (3.2.4) depends on requests (<3.0.0,>=2.13.0)
INFO: fact: spacy (3.2.4) depends on setuptools (*)
INFO: fact: spacy (3.2.4) depends on spacy-legacy (<3.1.0,>=3.0.8)
INFO: fact: spacy (3.2.4) depends on spacy-loggers (>=1.0.0,<2.0.0)
INFO: fact: spacy (3.2.4) depends on srsly (<3.0.0,>=2.4.1)
INFO: fact: spacy (3.2.4) depends on thinc (>=8.0.12,<8.1.0)
INFO: fact: spacy (3.2.4) depends on tqdm (<5.0.0,>=4.38.0)
INFO: fact: spacy (3.2.4) depends on typer (<0.5.0,>=0.3.0)
INFO: fact: spacy (3.2.4) depends on wasabi (<1.1.0,>=0.8.1)
INFO: derived: not spacy (3.2.4)
INFO: discovering spacy==3.2.3
INFO: fact: spacy (3.2.3) depends on blis (<0.8.0,>=0.4.0)
INFO: fact: spacy (3.2.3) depends on catalogue (>=2.0.6,<2.1.0)
INFO: fact: spacy (3.2.3) depends on cymem (>=2.0.2,<2.1.0)
INFO: fact: spacy (3.2.3) depends on jinja2 (*)
INFO: fact: spacy (3.2.3) depends on langcodes (<4.0.0,>=3.2.0)
INFO: fact: spacy (3.2.3) depends on murmurhash (<1.1.0,>=0.28.0)
INFO: fact: spacy (3.2.3) depends on numpy (>=1.15.0)
INFO: fact: spacy (3.2.3) depends on packaging (>=20.0)
INFO: fact: spacy (3.2.3) depends on pathy (>=0.3.5)
INFO: fact: spacy (3.2.3) depends on preshed (<3.1.0,>=3.0.2)
INFO: fact: spacy (3.2.3) depends on pydantic (>=1.7.4,<1.8 || >1.8,<1.8.1 || >1.8.1,<1.9.0)
INFO: fact: spacy (3.2.3) depends on requests (<3.0.0,>=2.13.0)
INFO: fact: spacy (3.2.3) depends on setuptools (*)
INFO: fact: spacy (3.2.3) depends on spacy-legacy (<3.1.0,>=3.0.8)
INFO: fact: spacy (3.2.3) depends on spacy-loggers (>=1.0.0,<2.0.0)
INFO: fact: spacy (3.2.3) depends on srsly (<3.0.0,>=2.4.1)
INFO: fact: spacy (3.2.3) depends on thinc (>=8.0.12,<8.1.0)
INFO: fact: spacy (3.2.3) depends on tqdm (<5.0.0,>=4.38.0)
INFO: fact: spacy (3.2.3) depends on typer (<0.5.0,>=0.3.0)
INFO: fact: spacy (3.2.3) depends on wasabi (<1.1.0,>=0.8.1)
INFO: derived: not spacy (3.2.3)
INFO: discovering spacy==3.2.2
INFO: fact: spacy (3.2.2) depends on blis (<0.8.0,>=0.4.0)
INFO: fact: spacy (3.2.2) depends on catalogue (>=2.0.6,<2.1.0)
INFO: fact: spacy (3.2.2) depends on cymem (>=2.0.2,<2.1.0)
INFO: fact: spacy (3.2.2) depends on jinja2 (*)
INFO: fact: spacy (3.2.2) depends on langcodes (<4.0.0,>=3.2.0)
INFO: fact: spacy (3.2.2) depends on murmurhash (<1.1.0,>=0.28.0)
INFO: fact: spacy (3.2.2) depends on numpy (>=1.15.0)
INFO: fact: spacy (3.2.2) depends on packaging (>=20.0)
INFO: fact: spacy (3.2.2) depends on pathy (>=0.3.5)
INFO: fact: spacy (3.2.2) depends on preshed (<3.1.0,>=3.0.2)
INFO: fact: spacy (3.2.2) depends on pydantic (>=1.7.4,<1.8 || >1.8,<1.8.1 || >1.8.1,<1.9.0)
INFO: fact: spacy (3.2.2) depends on requests (<3.0.0,>=2.13.0)
INFO: fact: spacy (3.2.2) depends on setuptools (*)
INFO: fact: spacy (3.2.2) depends on spacy-legacy (<3.1.0,>=3.0.8)
INFO: fact: spacy (3.2.2) depends on spacy-loggers (>=1.0.0,<2.0.0)
INFO: fact: spacy (3.2.2) depends on srsly (<3.0.0,>=2.4.1)
INFO: fact: spacy (3.2.2) depends on thinc (>=8.0.12,<8.1.0)
INFO: fact: spacy (3.2.2) depends on tqdm (<5.0.0,>=4.38.0)
INFO: fact: spacy (3.2.2) depends on typer (<0.5.0,>=0.3.0)
INFO: fact: spacy (3.2.2) depends on wasabi (<1.1.0,>=0.8.1)
INFO: derived: not spacy (3.2.2)
INFO: discovering spacy==3.2.1
...
<output here>

What you expected to happen

Resolved in < 1 min (pip-compile takes 16 secs).

Step-by-step reproduction instructions

pipgrip incompatible with twine 4

What you were trying to do (and why)

Install both pipgrip +twine 4.0 together.

What happened (including command output)

Given a requirements.dev.txt containing:

pipgrip~=0.10.5
twine~=4.0

pipgrip fails to resolve

Error:     Because no versions of twine match >4.0.0,<4.0.1 || >4.0.1,<4.0.2 || >4.0.2,<5.0
 and twine (4.0.0) depends on pkginfo (>=1.8.1), twine (>=4.0.0,<4.0.1 || >4.0.1,<4.0.2 || >4.0.2,<5.0) requires pkginfo (>=1.8.1).
(1) So, because twine (4.0.1) depends on both pkginfo (>=1.8.1) and pkginfo (>=1.8.1), twine (>=4.0.0,<5.0) requires pkginfo (>=1.8.1).

    Because no versions of pipgrip match >0.10.0,<0.10.1 || >0.10.1,<0.10.2 || >0.10.2,<0.10.3 || >0.10.3,<0.10.4 || >0.10.4,<0.10.5 || >0.10.5,<1.0
 and pipgrip (0.10.0) depends on pkginfo (>=1.4.2,<1.8), pipgrip (>=0.10.0,<0.10.1 || >0.10.1,<0.10.2 || >0.10.2,<0.10.3 || >0.10.3,<0.10.4 || >0.10.4,<0.10.5 || >0.10.5,<1.0) requires pkginfo (>=1.4.2,<1.8).
    And because pipgrip (0.10.1) depends on pkginfo (>=1.4.2,<1.8), pipgrip (>=0.10.0,<0.10.2 || >0.10.2,<0.10.3 || >0.10.3,<0.10.4 || >0.10.4,<0.10.5 || >0.10.5,<1.0) requires pkginfo (>=1.4.2,<1.8).
    And because pipgrip (0.10.2) depends on both pkginfo (>=1.4.2,<1.8) and pkginfo (>=1.4.2,<1.8), pipgrip (>=0.10.0,<0.10.4 || >0.10.4,<0.10.5 || >0.10.5,<1.0) requires pkginfo (>=1.4.2,<1.8).
    And because pipgrip (0.10.4) depends on both pkginfo (>=1.4.2,<1.8) and pkginfo (>=1.4.2,<1.8), pipgrip (>=0.10.0,<1.0) requires pkginfo (>=1.4.2,<1.8).
    And because twine (>=4.0.0,<5.0) requires pkginfo (>=1.8.1) (1), twine (>=4.0.0,<5.0) is incompatible with pipgrip (>=0.10.0,<1.0)
    And because .[dev,notebook] (0.0.0) depends on both pipgrip (~=0.10) and twine (~=4.0), . is forbidden.
    So, because no versions of . match <0.0.0 || >0.0.0
 and root depends on .[dev,notebook] (*), version solving failed.

What you expected to happen

pipgrip is compatible with twine 4.0

Is there any chance of discovering package dependencies without building wheels?

Description

I'm trying to understand python dependency management in general, and pipgrep's approach specifically. In particular, I'd like to understand if it is possible, at all, to determine dependencies for a package without ever having to build wheels.

For example, the result of running pipgrip to see the dependency tree of a package containing non-Python code differs depending on the version I want to analyze. For example,

pipgrip  --tree numpy==1.9.2

fails (clang compilation fails with a massive stacktrace), whereas

pipgrip --tree numpy==1.19.1

succeeds, which appears to be caused by the latter case (1.19.1) having a readily-available wheel in PyPi that matches my Python interpreter (version, abi, platform) [1] whereas the former (1.9.2) does not have a pre-built bdist wheel that matches my Python interpreter and, therefore, needs to be built from the sdist (which requires a ton of packages to be installed on my computer).

Now, my question is if it's strictly necessary for pipgrip to build wheels to determine dependencies?
Would it be possible to determine the tree of dependencies by only looking at sdist distributions (and hence, never having to build wheels)? I'm probably missing something in my understanding of python's dependency management so feel free to enlighten me! :)

[1] {'implementation_name': 'cpython', 'implementation_version': '3.8.2', 'os_name': 'posix', 'platform_machine': 'x86_64', 'platform_release': '5.4.0-42-generic', 'platform_system': 'Linux', 'platform_version': '#46-Ubuntu SMP Fri Jul 10 00:24:02 UTC 2020', 'python_full_version': '3.8.2', 'platform_python_implementation': 'CPython', 'python_version': '3.8', 'sys_platform': 'linux'}

Use case / motivation / context

Related Issues

jupyterlab-black fails to install (packages with hyphens in name cause problems?)

I noticed:

$ python --version
Python 3.7.7

$ python -m pip list | grep pipgrip
pipgrip              0.3.0

$ pipgrip --verbose --install jupyterlab-black
Traceback (most recent call last):
  File "/home/martin/.local/bin/pipgrip", line 10, in <module>
    sys.exit(main())
  File "/home/martin/.local/lib/python3.7/site-packages/click/core.py", line 829, in __call__
    return self.main(*args, **kwargs)
  File "/home/martin/.local/lib/python3.7/site-packages/click/core.py", line 782, in main
    rv = self.invoke(ctx)
  File "/home/martin/.local/lib/python3.7/site-packages/click/core.py", line 1066, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/home/martin/.local/lib/python3.7/site-packages/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "/home/martin/.local/lib/python3.7/site-packages/pipgrip/cli.py", line 296, in main
    source.root_dep(root_dependency)
  File "/home/martin/.local/lib/python3.7/site-packages/pipgrip/package_source.py", line 147, in root_dep
    self.discover_and_add(req.__str__())
  File "/home/martin/.local/lib/python3.7/site-packages/pipgrip/package_source.py", line 126, in discover_and_add
    package, self.index_url, self.extra_index_url, self.cache_dir, self.pre
  File "/home/martin/.local/lib/python3.7/site-packages/pipgrip/pipper.py", line 337, in discover_dependencies_and_versions
    req.__str__(), index_url, extra_index_url, pre, cache_dir
  File "/home/martin/.local/lib/python3.7/site-packages/pipgrip/pipper.py", line 269, in _download_wheel
    str({package: os.path.join(cache_dir, fname.lstrip(os.path.sep))})
UnboundLocalError: local variable 'fname' referenced before assignment

...and that the fname detection in pipper._download_wheel seems not to work for jupyter-black and other packages with hyphens in their name:

(Pdb) l
249                             )
250                             if package.startswith("."):
251                                 fname = all_wheels[0]
252                             else:
253                                 pkg = canonicalize_name(package)
254  ->                             for whl in all_wheels:
255                                     if pkg in whl:
256                                         fname = whl
257                                         break
258                             break
259                     else:

(Pdb) pkg
'jupyterlab-black'

(Pdb) all_wheels
['jupyterlab_black-0.2.1-py3-none-any.whl', 'jupyterlab_commands-0.2.2-py2.py3-none-any.whl', 'jupyterlab_latex-2.0.0-py3-none-any.whl', 'jupyterlab-2.1.5-py3-none-any.whl', 'notebook-6.0.3-py3-none-any.whl', 'jupyter-1.0.0-py2.py3-none-any.whl', 'ipysankeywidget-0.3.0-py2.py3-none-any.whl']

Emit Markers when Locking

Description

I'm investigating pipgrip for rye (astral-sh/rye#82) and one of the topics of interest is making portable lock files that retain the markers (eg: python_version < '3.7'). It does not seem like markers are supported currently and it would appear that pipgrip can only resolve against the current Python version. I did not look into it yet, but how much work would it be to make it possible to create lock files for multiple markers?

Use case / motivation

It would be nice to have a single lock file that is Python version or platform independent.

Implement VCS support

Description

$ pipgrip https://github.com/jonmatthis/freemocap
Error: 'https://github.com/jonmatthis/freemocap' looks like a path, and is not supported yet by pipgrip

Use case / motivation

I am too lazy to checkout and install everything. Just want to run pipgrip in isolated environment.

podman run --rm -it python:3 bash -c "pip3 install pipgrip && pipgrip https://github.com/jonmatthis/freemocap"

Instead I need to do this.

podman run --rm -it python:3 bash -c "pip3 install pipgrip && git clone https://github.com/jonmatthis/freemocap app && cd app && pipgrip --tree ."

And remember to cd, because pipgrip app won't work and will just show dependency tree from https://pypi.org/project/app/

Always getting "Failed to download wheel for pip" on Windows

On Windows 10 with Python 2.7.12 (and running from Git Bash) I'm always getting

$ pipgrip --tree pipgrip
Traceback (most recent call last):
  File "c:\python\lib\runpy.py", line 174, in _run_module_as_main
    "__main__", fname, loader, pkg_name)
  File "c:\python\lib\runpy.py", line 72, in _run_code
    exec code in run_globals
  File "C:\Python27\Scripts\pipgrip.exe\__main__.py", line 9, in <module>
  File "c:\python\lib\site-packages\click\core.py", line 722, in __call__
    return self.main(*args, **kwargs)
  File "c:\python\lib\site-packages\click\core.py", line 697, in main
    rv = self.invoke(ctx)
  File "c:\python\lib\site-packages\click\core.py", line 895, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "c:\python\lib\site-packages\click\core.py", line 535, in invoke
    return callback(*args, **kwargs)
  File "c:\python\lib\site-packages\pipgrip\cli.py", line 305, in main
    source.root_dep(root_dependency)
  File "c:\python\lib\site-packages\pipgrip\package_source.py", line 147, in root_dep
    self.discover_and_add(req.__str__())
  File "c:\python\lib\site-packages\pipgrip\package_source.py", line 126, in discover_and_add
    package, self.index_url, self.extra_index_url, self.cache_dir, self.pre
  File "c:\python\lib\site-packages\pipgrip\pipper.py", line 345, in discover_dependencies_and_versions
    req.__str__(), index_url, extra_index_url, pre, cache_dir
  File "c:\python\lib\site-packages\pipgrip\pipper.py", line 280, in _download_wheel
    raise RuntimeError("Failed to download wheel for {}".format(package))
RuntimeError: Failed to download wheel for pipgrip

I also tried with other Python packages, same thing. Any hint how to resolve that issue?

Add a more detailed --tree-json-full output option

What you were trying to do (and why)

Output the dependency tree in JSON format.

What happened (including command output)

Compare

$ pipgrip --tree-json pipgrip
{"pipgrip": {"anytree": {"six>=1.9.0": {}}, "click": {}, "enum34": {}, "packaging>=17": {"pyparsing>=2.0.2": {}, "six": {}}, "pip>=7.1.0": {}, "pkginfo>=1.4.2": {}, "setuptools>=38.3": {}, "typing": {}, "wheel": {}}}

to

$ pipgrip --tree-ascii pipgrip
pipgrip (0.5.0)
|-- anytree (2.8.0)
|   +-- six>=1.9.0 (1.15.0)
|-- click (7.1.2)
|-- enum34 (1.1.10)
|-- packaging>=17 (20.4)
|   |-- pyparsing>=2.0.2 (2.4.7)
|   +-- six (1.15.0)
|-- pip>=7.1.0 (20.1.1)
|-- pkginfo>=1.4.2 (1.5.0.1)
|-- setuptools>=38.3 (44.1.1)
|-- typing (3.7.4.3)
+-- wheel (0.34.2)

to see that e.g. the wheel version "0.34.2" is missing from JSON output while it's present in ASCII output.

What you expected to happen

Each JSON node probably should have two properties, version and dependencies, where version is the use version of the package itself, and dependencies a list of its dependencies (where each dependency is of the same type as the parent node).

--reversed-tree raises NotImplementedError

What you were trying to do (and why)

--reversed-tree raises NotImplementedError

What happened (including command output)

Command output

$ pipgrip -vvv --reversed-tree
....

Traceback (most recent call last):
  File "/Users/tekumara/.local/bin/pipgrip", line 8, in <module>
    sys.exit(main())
  File "/Users/tekumara/.local/pipx/venvs/pipgrip/lib/python3.10/site-packages/click/core.py", line 1157, in __call__
    return self.main(*args, **kwargs)
  File "/Users/tekumara/.local/pipx/venvs/pipgrip/lib/python3.10/site-packages/click/core.py", line 1078, in main
    rv = self.invoke(ctx)
  File "/Users/tekumara/.local/pipx/venvs/pipgrip/lib/python3.10/site-packages/click/core.py", line 1434, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/Users/tekumara/.local/pipx/venvs/pipgrip/lib/python3.10/site-packages/click/core.py", line 783, in invoke
    return __callback(*args, **kwargs)
  File "/Users/tekumara/.local/pipx/venvs/pipgrip/lib/python3.10/site-packages/pipgrip/cli.py", line 509, in main
    raise NotImplementedError()
NotImplementedError
<output here>

What you expected to happen

A tree with leaf nodes that are dependents rather than dependencies

Step-by-step reproduction instructions

Error when multiple extras are requested separately

I think there's also another related issue:

  • pipgrip -vv --tree ray[tune] → Successful
  • pipgrip -vv --tree ray[rllib] → Successful
  • pipgrip -vv --tree ray[tune,rllib] → Successful
  • pipgrip -vv --tree ray[tune] ray[rllib] → Fails
Command output

Traceback (most recent call last):
  File "/home/vagrant/.local/bin/pipgrip", line 8, in <module>
    sys.exit(main())
  File "/usr/lib/python3/dist-packages/click/core.py", line 764, in __call__
    return self.main(*args, **kwargs)
  File "/usr/lib/python3/dist-packages/click/core.py", line 717, in main
    rv = self.invoke(ctx)
  File "/usr/lib/python3/dist-packages/click/core.py", line 956, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/usr/lib/python3/dist-packages/click/core.py", line 555, in invoke
    return callback(*args, **kwargs)
  File "/home/vagrant/.local/lib/python3.8/site-packages/pipgrip/cli.py", line 460, in main
    raise RuntimeError(
RuntimeError: Unexpected partial solution encountered, not all packages have decisions

Originally posted by @jdchn in #95 (comment)

Feature Request - Cater for preferred versions constraints

Hi,
pipgrip is a great library, but I can't see any feature to allow preferred versions to be specified. It is common that a particular version (or version range) of a library is preferred over others (Example reasons: compatibility with other software that uses it, free of particular bugs, etc.), Such a feature would be like specifying the dependencyManagament dependencies that Maven supports, where dependency version constraints can be specified. Allowing preferred versions to be specified independently to requirements.txt facilitates consistent version constraint specifications across multiple package builds.

Possible Details:
A requirements-constraints.txt file "dependency constrainer" could be optionally passed via the command line, which specifies the limited range or specific version(s) of packages that may be used - using the same version constraint syntax/semantics as requirements.txt. Let the requirements-constraints.txt dependency constraints be defined as X. Let the version constraints defined in requirements.txt be Y. The version constraint used by the dependency resolver for a given package Z from requirements.txt in Y would be:

  • If only Y contains a constraint for Z, use the constraint in Y
  • If Y and X contains a constraint for Z, use the intersection of Y and X. Raise an Exception if the intersection is empty.

Any plans to support such a feature (any time soon) ?

Thanks
Andrew

Fails to fetch deps for `numba==0.50.1`

What you were trying to do (and why)

See the dependency branch for numba (which is a dependency it self).

pipgrip -vvv --tree numba==0.50.1

Or in a clean container.

podman run --rm -it python:3 bash -c "pip3 install pipgrip && ls -la && pipgrip -vvv --tree numba==0.50.1"

What happened (including command output

ModuleNotFoundError: No module named 'numpy'.

Command output

$ pipgrip -vvv --tree numba==0.50.1

DEBUG: pip version: [21, 2, 4]
DEBUG: pipgrip version: 0.6.10
INFO: discovering numba==0.50.1
DEBUG: Downloading/building wheel for numba==0.50.1 into cache_dir /root/.cache/pip/wheels/pipgrip
DEBUG: ['/usr/local/bin/python', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--wheel-dir', '/root/.cache/pip/wheels/pipgrip', '--progress-bar=off', 'numba==0.50.1']
ERROR: Collecting numba==0.50.1
  Downloading numba-0.50.1.tar.gz (2.0 MB)
Building wheels for collected packages: numba
  Building wheel for numba (setup.py): started
  Building wheel for numba (setup.py): finished with status 'error'
  ERROR: Command errored out with exit status 1:
   command: /usr/local/bin/python -u -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-wheel-d69jbhr7/numba_85cab453a57940c8bc4abf92d91bb9f1/setup.py'"'"'; __file__='"'"'/tmp/pip-wheel-d69jbhr7/numba_85cab453a57940c8bc4abf92d91bb9f1/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' bdist_wheel -d /tmp/pip-wheel-gj3k3z69
       cwd: /tmp/pip-wheel-d69jbhr7/numba_85cab453a57940c8bc4abf92d91bb9f1/
  Complete output (7 lines):
  Traceback (most recent call last):
    File "<string>", line 1, in <module>
    File "/tmp/pip-wheel-d69jbhr7/numba_85cab453a57940c8bc4abf92d91bb9f1/setup.py", line 358, in <module>
      metadata['ext_modules'] = get_ext_modules()
    File "/tmp/pip-wheel-d69jbhr7/numba_85cab453a57940c8bc4abf92d91bb9f1/setup.py", line 94, in get_ext_modules
      import numpy.distutils.misc_util as np_misc
  ModuleNotFoundError: No module named 'numpy'
  ----------------------------------------
  ERROR: Failed building wheel for numba
  Running setup.py clean for numba
  ERROR: Command errored out with exit status 1:
   command: /usr/local/bin/python -u -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-wheel-d69jbhr7/numba_85cab453a57940c8bc4abf92d91bb9f1/setup.py'"'"'; __file__='"'"'/tmp/pip-wheel-d69jbhr7/numba_85cab453a57940c8bc4abf92d91bb9f1/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' clean --all
       cwd: /tmp/pip-wheel-d69jbhr7/numba_85cab453a57940c8bc4abf92d91bb9f1
  Complete output (7 lines):
  Traceback (most recent call last):
    File "<string>", line 1, in <module>
    File "/tmp/pip-wheel-d69jbhr7/numba_85cab453a57940c8bc4abf92d91bb9f1/setup.py", line 358, in <module>
      metadata['ext_modules'] = get_ext_modules()
    File "/tmp/pip-wheel-d69jbhr7/numba_85cab453a57940c8bc4abf92d91bb9f1/setup.py", line 94, in get_ext_modules
      import numpy.distutils.misc_util as np_misc
  ModuleNotFoundError: No module named 'numpy'
  ----------------------------------------
  ERROR: Failed cleaning build dir for numba
Failed to build numba
ERROR: Failed to build one or more wheels

Error: Command '['/usr/local/bin/python', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--wheel-dir', '/root/.cache/pip/wheels/pipgrip', '--progress-bar=off', 'numba==0.50.1']' returned non-zero exit status 1.

What you expected to happen

Fetch numpy with other dependencies and show the tree.

have to repeatedly invoke, different "failed to download wheel" each time

What you were trying to do (and why)

determine package dependencies using a test case

pipgrip --tree pipgrip

What happened (including command output)

each time it was invoked, it gave a traceback about "failed to download wheel" with one of the dependencies, but then the next time it would proceed to the next dependency. after all dependencies were downloaded, it worked. so for example with pipgrip, it would say in turn:

RuntimeError: Failed to download wheel for pkginfo>=1.4.2
RuntimeError: Failed to download wheel for packaging>=17
RuntimeError: Failed to download wheel for click>=7
RuntimeError: Failed to download wheel for anytree
RuntimeError: Failed to download wheel for pyparsing>=2.0.2
RuntimeError: Failed to download wheel for six>=1.9.0

then it finally succeeded:

 $ pipgrip --tree pipgrip
pipgrip (0.6.8)
├── anytree (2.8.0)
│   └── six>=1.9.0 (1.16.0)
├── click>=7 (8.0.0)
├── packaging>=17 (20.9)
│   └── pyparsing>=2.0.2 (2.4.7)
├── pip>=7.1.0 (21.1.1)
├── pkginfo>=1.4.2 (1.7.0)
├── setuptools>=38.3 (56.2.0)
└── wheel (0.36.2)

(there might have been one or more that was missed above because it had scrolled off my screen, I think it was every dependency)

I did manage to capture the one with -vvv for setuptools:

 $ pipgrip -vvv --tree pipgrip
DEBUG: Environment: {'implementation_name': 'cpython', 'implementation_version': '3.9.5', 'os_name': 'posix', 'platform_machine': 'x86_64', 'platform_release': '5.6.0-1055-oem', 'platform_system': 'Linux', 'platform_version': '#59-Ubuntu SMP Fri Apr 16 08:43:28 UTC 2021', 'python_full_version': '3.9.5', 'platform_python_implementation': 'CPython', 'python_version': '3.9', 'sys_platform': 'linux'}
DEBUG: Pip version: [21, 1, 1]
DEBUG: Downloading/building wheel for pipgrip
DEBUG: ['/opt/python-3.9.5/bin/python3.9', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--wheel-dir', '/home/scott/.cache/pip/wheels/pipgrip', '--progress-bar=off', 'pipgrip']
DEBUG: {'pipgrip': '/home/scott/.cache/pip/wheels/pipgrip/pipgrip-0.6.8-py2.py3-none-any.whl'}
DEBUG: Searching metadata in /home/scott/.cache/pip/wheels/pipgrip/pipgrip-0.6.8-py2.py3-none-any.whl
DEBUG: dropped conditional dep enum34 ; python_version == "2.7"
DEBUG: dropped conditional dep typing ; python_version == "2.7"
DEBUG: Finding possible versions for pipgrip
DEBUG: ['/opt/python-3.9.5/bin/python3.9', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--progress-bar=off', 'pipgrip==42.42.post424242']
DEBUG: {'pipgrip': ['0.0.1', '0.0.2', '0.0.3', '0.1.0', '0.2.0', '0.2.1', '0.2.2', '0.3.0', '0.3.1', '0.4.0', '0.4.1', '0.4.2', '0.5.0', '0.5.1', '0.6.0', '0.6.1', '0.6.2', '0.6.3', '0.6.4', '0.6.5', '0.6.6', '0.6.7', '0.6.8']}
INFO: fact: _root_ is root
INFO: derived: root
INFO: fact: root depends on pipgrip (*)
INFO: selecting . (0.0.0)
INFO: derived: pipgrip (*)
INFO: fact: pipgrip (0.6.8) depends on anytree (*)
INFO: fact: pipgrip (0.6.8) depends on click (>=7)
INFO: fact: pipgrip (0.6.8) depends on packaging (>=17)
INFO: fact: pipgrip (0.6.8) depends on pip (>=7.1.0)
INFO: fact: pipgrip (0.6.8) depends on pkginfo (>=1.4.2)
INFO: fact: pipgrip (0.6.8) depends on setuptools (>=38.3)
INFO: fact: pipgrip (0.6.8) depends on wheel (*)
INFO: selecting pipgrip (0.6.8)
INFO: derived: wheel (*)
INFO: derived: setuptools (>=38.3)
INFO: derived: pkginfo (>=1.4.2)
INFO: derived: pip (>=7.1.0)
INFO: derived: packaging (>=17)
INFO: derived: click (>=7)
INFO: derived: anytree (*)
DEBUG: Downloading/building wheel for wheel
DEBUG: ['/opt/python-3.9.5/bin/python3.9', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--wheel-dir', '/home/scott/.cache/pip/wheels/pipgrip', '--progress-bar=off', 'wheel']
DEBUG: {'wheel': '/home/scott/.cache/pip/wheels/pipgrip/wheel-0.36.2-py2.py3-none-any.whl'}
DEBUG: Searching metadata in /home/scott/.cache/pip/wheels/pipgrip/wheel-0.36.2-py2.py3-none-any.whl
DEBUG: dropped conditional dep pytest (>=3.0.0) ; extra == 'test'
DEBUG: dropped conditional dep pytest-cov ; extra == 'test'
DEBUG: Finding possible versions for wheel
DEBUG: ['/opt/python-3.9.5/bin/python3.9', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--progress-bar=off', 'wheel==42.42.post424242']
DEBUG: {'wheel': ['0.1', '0.2', '0.3', '0.4', '0.4.1', '0.4.2', '0.5', '0.6', '0.7', '0.8', '0.9', '0.9.1', '0.9.2', '0.9.3', '0.9.4', '0.9.5', '0.9.6', '0.9.7', '0.10.0', '0.10.1', '0.10.2', '0.10.3', '0.11.0', '0.12.0', '0.13.0', '0.14.0', '0.15.0', '0.16.0', '0.17.0', '0.18.0', '0.19.0', '0.21.0', '0.22.0', '0.23.0', '0.24.0', '0.25.0', '0.26.0', '0.27.0', '0.28.0', '0.29.0', '0.30.0', '0.31.0', '0.31.1', '0.32.0', '0.32.1', '0.32.2', '0.32.3', '0.33.0', '0.33.1', '0.33.4', '0.33.5', '0.33.6', '0.34.0', '0.34.1', '0.34.2', '0.35.0', '0.35.1', '0.36.0', '0.36.1', '0.36.2']}
DEBUG: Downloading/building wheel for setuptools>=38.3
DEBUG: ['/opt/python-3.9.5/bin/python3.9', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--wheel-dir', '/home/scott/.cache/pip/wheels/pipgrip', '--progress-bar=off', 'setuptools>=38.3']
DEBUG: {'setuptools>=38.3': '/home/scott/.cache/pip/wheels/pipgrip/setuptools-56.2.0-py3-none-any.whl'}
DEBUG: Searching metadata in /home/scott/.cache/pip/wheels/pipgrip/setuptools-56.2.0-py3-none-any.whl
DEBUG: dropped conditional dep certifi (==2016.9.26) ; extra == 'certs'
DEBUG: dropped conditional dep sphinx ; extra == 'docs'
DEBUG: dropped conditional dep jaraco.packaging (>=8.2) ; extra == 'docs'
DEBUG: dropped conditional dep rst.linker (>=1.9) ; extra == 'docs'
DEBUG: dropped conditional dep pygments-github-lexers (==0.0.5) ; extra == 'docs'
DEBUG: dropped conditional dep sphinx-inline-tabs ; extra == 'docs'
DEBUG: dropped conditional dep wincertstore (==0.2) ; (sys_platform == "win32") and extra == 'ssl'
DEBUG: dropped conditional dep pytest (>=4.6) ; extra == 'testing'
DEBUG: dropped conditional dep pytest-checkdocs (>=2.4) ; extra == 'testing'
DEBUG: dropped conditional dep pytest-flake8 ; extra == 'testing'
DEBUG: dropped conditional dep pytest-cov ; extra == 'testing'
DEBUG: dropped conditional dep pytest-enabler (>=1.0.1) ; extra == 'testing'
DEBUG: dropped conditional dep mock ; extra == 'testing'
DEBUG: dropped conditional dep flake8-2020 ; extra == 'testing'
DEBUG: dropped conditional dep virtualenv (>=13.0.0) ; extra == 'testing'
DEBUG: dropped conditional dep pytest-virtualenv (>=1.2.7) ; extra == 'testing'
DEBUG: dropped conditional dep wheel ; extra == 'testing'
DEBUG: dropped conditional dep paver ; extra == 'testing'
DEBUG: dropped conditional dep pip (>=19.1) ; extra == 'testing'
DEBUG: dropped conditional dep jaraco.envs ; extra == 'testing'
DEBUG: dropped conditional dep pytest-xdist ; extra == 'testing'
DEBUG: dropped conditional dep sphinx ; extra == 'testing'
DEBUG: dropped conditional dep jaraco.path (>=3.2.0) ; extra == 'testing'
DEBUG: dropped conditional dep pytest-black (>=0.3.7) ; (platform_python_implementation != "PyPy" and python_version < "3.10") and extra == 'testing'
DEBUG: dropped conditional dep pytest-mypy ; (platform_python_implementation != "PyPy" and python_version < "3.10") and extra == 'testing'
DEBUG: Finding possible versions for setuptools
DEBUG: ['/opt/python-3.9.5/bin/python3.9', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--progress-bar=off', 'setuptools==42.42.post424242']
DEBUG: {'setuptools': ['0.7.2', '0.7.3', '0.7.4', '0.7.5', '0.7.6', '0.7.7', '0.7.8', '0.8', '0.9', '0.9.1', '0.9.2', '0.9.3', '0.9.4', '0.9.5', '0.9.6', '0.9.7', '0.9.8', '1.0', '1.1', '1.1.1', '1.1.2', '1.1.3', '1.1.4', '1.1.5', '1.1.6', '1.1.7', '1.2', '1.3', '1.3.1', '1.3.2', '1.4', '1.4.1', '1.4.2', '2.0', '2.0.1', '2.0.2', '2.1', '2.1.1', '2.1.2', '2.2', '3.0', '3.0.1', '3.0.2', '3.1', '3.2', '3.3', '3.4', '3.4.1', '3.4.2', '3.4.3', '3.4.4', '3.5', '3.5.1', '3.5.2', '3.6', '3.7', '3.7.1', '3.8', '3.8.1', '4.0', '4.0.1', '5.0', '5.0.1', '5.0.2', '5.1', '5.2', '5.3', '5.4', '5.4.1', '5.4.2', '5.5', '5.5.1', '5.6', '5.7', '5.8', '6.0.1', '6.0.2', '6.1', '7.0', '8.0', '8.0.1', '8.0.2', '8.0.3', '8.0.4', '8.1', '8.2', '8.2.1', '8.3', '9.0', '9.0.1', '9.1', '10.0', '10.0.1', '10.1', '10.2', '10.2.1', '11.0', '11.1', '11.2', '11.3', '11.3.1', '12.0', '12.0.1', '12.0.2', '12.0.3', '12.0.4', '12.0.5', '12.1', '12.2', '12.3', '12.4', '13.0.1', '13.0.2', '14.0', '14.1', '14.1.1', '14.2', '14.3', '14.3.1', '15.0', '15.1', '15.2', '16.0', '17.0', '17.1', '17.1.1', '18.0', '18.0.1', '18.1', '18.2', '18.3', '18.3.1', '18.3.2', '18.4', '18.5', '18.6', '18.6.1', '18.7', '18.7.1', '18.8', '18.8.1', '19.0', '19.1', '19.1.1', '19.2', '19.3', '19.4', '19.4.1', '19.5', '19.6', '19.6.1', '19.6.2', '19.7', '20.0', '20.1', '20.1.1', '20.2.2', '20.3', '20.3.1', '20.4', '20.6.6', '20.6.7', '20.6.8', '20.7.0', '20.8.0', '20.8.1', '20.9.0', '20.10.1', '21.0.0', '21.1.0', '21.2.0', '21.2.1', '21.2.2', '22.0.0', '22.0.1', '22.0.2', '22.0.4', '22.0.5', '23.0.0', '23.1.0', '23.2.0', '23.2.1', '24.0.0', '24.0.1', '24.0.2', '24.0.3', '24.1.0', '24.1.1', '24.2.0', '24.2.1', '24.3.0', '24.3.1', '25.0.0', '25.0.1', '25.0.2', '25.1.0', '25.1.1', '25.1.2', '25.1.3', '25.1.4', '25.1.5', '25.1.6', '25.2.0', '25.3.0', '25.4.0', '26.0.0', '26.1.0', '26.1.1', '27.0.0', '27.1.0', '27.1.2', '27.2.0', '27.3.0', '27.3.1', '28.0.0', '28.1.0', '28.2.0', '28.3.0', '28.4.0', '28.5.0', '28.6.0', '28.6.1', '28.7.0', '28.7.1', '28.8.0', '28.8.1', '29.0.0', '29.0.1', '30.0.0', '30.1.0', '30.2.0', '30.2.1', '30.3.0', '30.4.0', '31.0.0', '31.0.1', '32.0.0', '32.1.0', '32.1.1', '32.1.2', '32.1.3', '32.2.0', '32.3.0', '32.3.1', '33.1.0', '33.1.1', '34.0.0', '34.0.1', '34.0.2', '34.0.3', '34.1.0', '34.1.1', '34.2.0', '34.3.0', '34.3.1', '34.3.2', '34.3.3', '34.4.0', '34.4.1', '35.0.0', '35.0.1', '35.0.2', '36.0.1', '36.1.0', '36.1.1', '36.2.0', '36.2.1', '36.2.2', '36.2.3', '36.2.4', '36.2.5', '36.2.6', '36.2.7', '36.3.0', '36.4.0', '36.5.0', '36.6.0', '36.6.1', '36.7.0', '36.7.1', '36.7.2', '36.8.0', '37.0.0', '38.0.0', '38.1.0', '38.2.0', '38.2.1', '38.2.3', '38.2.4', '38.2.5', '38.3.0', '38.4.0', '38.4.1', '38.5.0', '38.5.1', '38.5.2', '38.6.0', '38.6.1', '38.7.0', '39.0.0', '39.0.1', '39.1.0', '39.2.0', '40.0.0', '40.1.0', '40.1.1', '40.2.0', '40.3.0', '40.4.0', '40.4.1', '40.4.2', '40.4.3', '40.5.0', '40.6.0', '40.6.1', '40.6.2', '40.6.3', '40.7.0', '40.7.1', '40.7.2', '40.7.3', '40.8.0', '40.9.0', '41.0.0', '41.0.1', '41.1.0', '41.2.0', '41.3.0', '41.4.0', '41.5.0', '41.5.1', '41.6.0', '42.0.0', '42.0.1', '42.0.2', '43.0.0', '44.0.0', '44.1.0', '44.1.1', '45.0.0', '45.1.0', '45.2.0', '45.3.0', '46.0.0', '46.1.0', '46.1.1', '46.1.2', '46.1.3', '46.2.0', '46.3.0', '46.3.1', '46.4.0', '47.0.0', '47.1.0', '47.1.1', '47.2.0', '47.3.0', '47.3.1', '47.3.2', '48.0.0', '49.0.0', '49.0.1', '49.1.0', '49.1.1', '49.1.2', '49.1.3', '49.2.0', '49.2.1', '49.3.0', '49.3.1', '49.3.2', '49.4.0', '49.5.0', '49.6.0', '50.0.0', '50.0.1', '50.0.2', '50.0.3', '50.1.0', '50.2.0', '50.3.0', '50.3.1', '50.3.2', '51.0.0', '51.1.0', '51.1.1', '51.1.2', '51.2.0', '51.3.0', '51.3.1', '51.3.2', '51.3.3', '52.0.0', '53.0.0', '53.1.0', '54.0.0', '54.1.0', '54.1.1', '54.1.2', '54.1.3', '54.2.0', '56.0.0', '56.1.0', '56.2.0']}
DEBUG: Downloading/building wheel for pkginfo>=1.4.2
DEBUG: ['/opt/python-3.9.5/bin/python3.9', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--wheel-dir', '/home/scott/.cache/pip/wheels/pipgrip', '--progress-bar=off', 'pkginfo>=1.4.2']
ERROR: Failed to extract wheel filename from pip stdout:
Collecting pkginfo>=1.4.2
  Using cached pkginfo-1.7.0-py2.py3-none-any.whl (25 kB)
Saved ./.cache/pip/wheels/pipgrip/pkginfo-1.7.0-py2.py3-none-any.whl
Traceback (most recent call last):
  File "/home/scott/.local/bin/pipgrip", line 8, in <module>
    sys.exit(main())
  File "/home/scott/.local/lib/python3.9/site-packages/click/core.py", line 1134, in __call__
    return self.main(*args, **kwargs)
  File "/home/scott/.local/lib/python3.9/site-packages/click/core.py", line 1059, in main
    rv = self.invoke(ctx)
  File "/home/scott/.local/lib/python3.9/site-packages/click/core.py", line 1401, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/home/scott/.local/lib/python3.9/site-packages/click/core.py", line 767, in invoke
    return __callback(*args, **kwargs)
  File "/home/scott/.local/lib/python3.9/site-packages/pipgrip/cli.py", line 426, in main
    solution = solver.solve()
  File "/home/scott/.local/lib/python3.9/site-packages/pipgrip/libs/mixology/version_solver.py", line 69, in solve
    if not self._run():
  File "/home/scott/.local/lib/python3.9/site-packages/pipgrip/libs/mixology/version_solver.py", line 85, in _run
    next_package = self._choose_package_version()
  File "/home/scott/.local/lib/python3.9/site-packages/pipgrip/libs/mixology/version_solver.py", line 349, in _choose_package_version
    term = self._next_term_to_try()
  File "/home/scott/.local/lib/python3.9/site-packages/pipgrip/libs/mixology/version_solver.py", line 337, in _next_term_to_try
    term = min(*unsatisfied, key=_get_min)
  File "/home/scott/.local/lib/python3.9/site-packages/pipgrip/libs/mixology/version_solver.py", line 324, in _get_min
    versions = self._source.versions_for(
  File "/home/scott/.local/lib/python3.9/site-packages/pipgrip/libs/mixology/package_source.py", line 77, in versions_for
    return self._versions_for(package, constraint)
  File "/home/scott/.local/lib/python3.9/site-packages/pipgrip/package_source.py", line 167, in _versions_for
    self.discover_and_add(package.req.__str__())
  File "/home/scott/.local/lib/python3.9/site-packages/pipgrip/package_source.py", line 129, in discover_and_add
    to_create = discover_dependencies_and_versions(
  File "/home/scott/.local/lib/python3.9/site-packages/pipgrip/pipper.py", line 395, in discover_dependencies_and_versions
    wheel_fname = _download_wheel(
  File "/home/scott/.local/lib/python3.9/site-packages/pipgrip/pipper.py", line 331, in _download_wheel
    raise RuntimeError("Failed to download wheel for {}".format(package))
RuntimeError: Failed to download wheel for pkginfo>=1.4.2

this is just ubuntu 20 with a compiled python-3.9.5, and --user install of pipgrip-0.6.8. there would have been no other system libraries installed, only the ones that came with python:

 $ pip3 freeze --all 
anytree==2.8.0
click==8.0.0
packaging==20.9
pip==21.1.1
pipgrip==0.6.8
pkginfo==1.7.0
pyparsing==2.4.7
setuptools==56.0.0
six==1.16.0
wheel==0.36.2

Show partial tree on errors

Need pipgrip to render partial tree when installation fails with errors.

Use case / motivation

I need to see who pulls in broken dependency when CI jobs fail.

Related Issues

The discussion started here #52 (comment)

And the solution I used was to pipe requirements.txt line by line until pipgrip fails.

cat requirements.txt | xargs -n 1 pipgrip --tree -v

However, for this failure the dependencies are specified as .[test_all] in tox.ini and configured dynamically in setup.py.

The cat also won't work well for deeper levels in hierarchy.

Are environment markers aka conditional requirements supported?

Description

My requirements.txt file has this line.

fastavro==0.21.24; python_version < '3.8'

I'm in a py38 environment using latest pipgrip 0.6.12. When I run pipgrip -vv --tree -r requirements.txt, I get the error

INFO: discovering fastavro==0.21.24; python_version < "3.8"
ERROR: Failed to extract wheel filename from pip stdout:
Looking in indexes: https://artifactory.spotify.net/artifactory/api/pypi/pypi/simple/
Ignoring fastavro: markers 'python_version < "3.8"' don't match your environment
Traceback (most recent call last):
  File "/Users/dxia/src/ghe.spotify.net/kubeflow-platform/spotify-kubeflow/.tox/reqs-dryrun/bin/pipgrip", line 8, in <module>
    sys.exit(main())
  File "/Users/dxia/src/ghe.spotify.net/kubeflow-platform/spotify-kubeflow/.tox/reqs-dryrun/lib/python3.8/site-packages/click/core.py", line 1128, in __call__
    return self.main(*args, **kwargs)
  File "/Users/dxia/src/ghe.spotify.net/kubeflow-platform/spotify-kubeflow/.tox/reqs-dryrun/lib/python3.8/site-packages/click/core.py", line 1053, in main
    rv = self.invoke(ctx)
  File "/Users/dxia/src/ghe.spotify.net/kubeflow-platform/spotify-kubeflow/.tox/reqs-dryrun/lib/python3.8/site-packages/click/core.py", line 1395, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/Users/dxia/src/ghe.spotify.net/kubeflow-platform/spotify-kubeflow/.tox/reqs-dryrun/lib/python3.8/site-packages/click/core.py", line 754, in invoke
    return __callback(*args, **kwargs)
  File "/Users/dxia/src/ghe.spotify.net/kubeflow-platform/spotify-kubeflow/.tox/reqs-dryrun/lib/python3.8/site-packages/pipgrip/cli.py", line 420, in main
    source.root_dep(root_dependency)
  File "/Users/dxia/src/ghe.spotify.net/kubeflow-platform/spotify-kubeflow/.tox/reqs-dryrun/lib/python3.8/site-packages/pipgrip/package_source.py", line 154, in root_dep
    self.discover_and_add(req.__str__())
  File "/Users/dxia/src/ghe.spotify.net/kubeflow-platform/spotify-kubeflow/.tox/reqs-dryrun/lib/python3.8/site-packages/pipgrip/package_source.py", line 129, in discover_and_add
    to_create = discover_dependencies_and_versions(
  File "/Users/dxia/src/ghe.spotify.net/kubeflow-platform/spotify-kubeflow/.tox/reqs-dryrun/lib/python3.8/site-packages/pipgrip/pipper.py", line 407, in discover_dependencies_and_versions
    wheel_fname = _download_wheel(
  File "/Users/dxia/src/ghe.spotify.net/kubeflow-platform/spotify-kubeflow/.tox/reqs-dryrun/lib/python3.8/site-packages/pipgrip/pipper.py", line 342, in _download_wheel
    raise RuntimeError("Failed to download/build wheel for {}".format(package))
RuntimeError: Failed to download/build wheel for fastavro==0.21.24; python_version < "3.8"

Output has Ignoring fastavro: markers 'python_version < "3.8"' don't match your environment but then tries to download the wheel. I expect pipgrip to completely ignore fastavro in this environment.

Use case / motivation / context

Pipgrip should support pip environment markers for a more accurate result.

Related Issues

Error

Hi,

Am I doing something wrong?

pipgrip --tree requests -vvv

DEBUG: pip version: [23, 2, 1]
DEBUG: pipgrip version: 0.10.6
INFO: fact: _root_ is root
INFO: derived: root
DEBUG: unsatisfied: [<Term root>]
INFO: fact: root depends on requests (*)
INFO: selecting _root_ (0.0.0)
INFO: derived: requests (*)
DEBUG: unsatisfied: [<Term requests (*)>]
INFO: discovering requests
DEBUG: Getting report for requests (with fallback cache_dir ~\AppData\Local\pip\cache\wheels\pipgrip)
DEBUG: ['~\\mambaforge\\envs\\AIPlayground310\\python.exe', '-m', 'pip', 'install', '-qq', '--no-deps', '--ignore-installed', '--disable-pip-version-check', '--dry-run', '--no-deps', '--cache-dir', '~\AppData\\Local\\pip\\cache\\wheels\\pipgrip', '--report', '-', 'requests']```
`Traceback (most recent call last):
  File "~\mambaforge\envs\AIPlayground310\lib\runpy.py", line 196, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "~\mambaforge\envs\AIPlayground310\lib\runpy.py", line 86, in _run_code
    exec(code, run_globals)
  File "~\mambaforge\envs\AIPlayground310\Scripts\pipgrip.exe\__main__.py", line 7, in <module>
  File "~\mambaforge\envs\AIPlayground310\lib\site-packages\click\core.py", line 1157, in __call__
    return self.main(*args, **kwargs)
  File "~\mambaforge\envs\AIPlayground310\lib\site-packages\click\core.py", line 1078, in main
    rv = self.invoke(ctx)
  File "~\mambaforge\envs\AIPlayground310\lib\site-packages\click\core.py", line 1434, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "~\mambaforge\envs\AIPlayground310\lib\site-packages\click\core.py", line 783, in invoke
    return __callback(*args, **kwargs)
  File "~\mambaforge\envs\AIPlayground310\lib\site-packages\pipgrip\cli.py", line 440, in main
    solution = solver.solve()
  File "~\mambaforge\envs\AIPlayground310\lib\site-packages\pipgrip\libs\mixology\version_solver.py", line 74, in solve
    if not self._run():
  File "~\mambaforge\envs\AIPlayground310\lib\site-packages\pipgrip\libs\mixology\version_solver.py", line 90, in _run
    next_package = self._choose_package_version()
  File "~\mambaforge\envs\AIPlayground310\lib\site-packages\pipgrip\libs\mixology\version_solver.py", line 363, in _choose_package_version
    versions = self._source.versions_for(term.package, term.constraint.constraint)
  File "~\mambaforge\envs\AIPlayground310\lib\site-packages\pipgrip\libs\mixology\package_source.py", line 77, in versions_for
    return self._versions_for(package, constraint)
  File "~\mambaforge\envs\AIPlayground310\lib\site-packages\pipgrip\package_source.py", line 185, in _versions_for
    self.discover_and_add(package.req.__str__())
  File "~\mambaforge\envs\AIPlayground310\lib\site-packages\pipgrip\package_source.py", line 146, in discover_and_add
    to_create = discover_dependencies_and_versions(
  File "~\mambaforge\envs\AIPlayground310\lib\site-packages\pipgrip\pipper.py", line 478, in discover_dependencies_and_versions
    report = _get_package_report(
  File "~\mambaforge\envs\AIPlayground310\lib\site-packages\pipgrip\pipper.py", line 297, in _get_package_report
    out = stream_bash_command(args)
  File "~\mambaforge\envs\AIPlayground310\lib\site-packages\pipgrip\pipper.py", line 95, in stream_bash_command
    out += check_io()
  File "~\mambaforge\envs\AIPlayground310\lib\site-packages\pipgrip\pipper.py", line 83, in check_io
    line = process.stdout.readline().decode("utf-8")
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x92 in position 494: invalid start byte

ERROR: Failed building wheel for duplicity

Hi there! I've got another bug report from pipgrip on Homebrew.

What you were trying to do (and why)

Find recursive dependencies for duplicity

What happened (including command output)

Failed when collecting duplicity==0.8.14

Command output

$ pipgrip --no-cache-dir duplicity==0.8.14 -vvv
DEBUG: Environment: {'implementation_name': 'cpython', 'implementation_version': '3.8.5', 'os_name': 'posix', 'platform_machine': 'x86_64', 'platform_release': '19.6.0', 'platform_system': 'Darwin', 'platform_version': 'Darwin Kernel Version 19.6.0: Sun Jul  5 00:43:10 PDT 2020; root:xnu-6153.141.1~9/RELEASE_X86_64', 'python_full_version': '3.8.5', 'platform_python_implementation': 'CPython', 'python_version': '3.8', 'sys_platform': 'darwin'}
DEBUG: Pip version: [20, 1, 1]
DEBUG: Downloading/building wheel for duplicity==0.8.14
DEBUG: ['/Users/rylanpolster/Desktop/venv/bin/python', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--wheel-dir', '/var/folders/lx/jw48rn1j0235pst2sg8qlgp00000gp/T/tmpubpcq7wz', '--index-url', 'https://pypi.org/simple', '--trusted-host', 'pypi.org', '--progress-bar=off', 'duplicity==0.8.14']
ERROR: Collecting duplicity==0.8.14
  Using cached duplicity-0.8.14.tar.gz (1.5 MB)
Building wheels for collected packages: duplicity
  Building wheel for duplicity (setup.py): started
  Building wheel for duplicity (setup.py): finished with status 'error'
  ERROR: Command errored out with exit status 1:
   command: /Users/rylanpolster/Desktop/venv/bin/python -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/private/var/folders/lx/jw48rn1j0235pst2sg8qlgp00000gp/T/pip-wheel-10ckpxot/duplicity/setup.py'"'"'; __file__='"'"'/private/var/folders/lx/jw48rn1j0235pst2sg8qlgp00000gp/T/pip-wheel-10ckpxot/duplicity/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' bdist_wheel -d /private/var/folders/lx/jw48rn1j0235pst2sg8qlgp00000gp/T/pip-wheel-ktmuur69
       cwd: /private/var/folders/lx/jw48rn1j0235pst2sg8qlgp00000gp/T/pip-wheel-10ckpxot/duplicity/
  Complete output (189 lines):
  Unable to get SCM version: defaulting to 0.8.14
  running bdist_wheel
  running build
  running build_py
  creating build
  creating build/lib.macosx-10.15-x86_64-3.8
  creating build/lib.macosx-10.15-x86_64-3.8/duplicity
  copying duplicity/tempdir.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity
  copying duplicity/dup_threading.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity
  copying duplicity/backend.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity
  copying duplicity/config.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity
  copying duplicity/manifest.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity
  copying duplicity/log.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity
  copying duplicity/util.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity
  copying duplicity/globmatch.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity
  copying duplicity/__init__.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity
  copying duplicity/diffdir.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity
  copying duplicity/commandline.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity
  copying duplicity/librsync.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity
  copying duplicity/dup_time.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity
  copying duplicity/gpg.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity
  copying duplicity/file_naming.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity
  copying duplicity/dup_main.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity
  copying duplicity/asyncscheduler.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity
  copying duplicity/gpginterface.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity
  copying duplicity/robust.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity
  copying duplicity/dup_collections.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity
  copying duplicity/statistics.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity
  copying duplicity/patchdir.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity
  copying duplicity/errors.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity
  copying duplicity/selection.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity
  copying duplicity/progress.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity
  copying duplicity/dup_temp.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity
  copying duplicity/tarfile.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity
  copying duplicity/lazy.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity
  copying duplicity/filechunkio.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity
  copying duplicity/path.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity
  copying duplicity/cached_ops.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity
  creating build/lib.macosx-10.15-x86_64-3.8/duplicity/backends
  copying duplicity/backends/megabackend.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity/backends
  copying duplicity/backends/pydrivebackend.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity/backends
  copying duplicity/backends/imapbackend.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity/backends
  copying duplicity/backends/ssh_pexpect_backend.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity/backends
  copying duplicity/backends/par2backend.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity/backends
  copying duplicity/backends/multibackend.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity/backends
  copying duplicity/backends/s3_boto_backend.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity/backends
  copying duplicity/backends/swiftbackend.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity/backends
  copying duplicity/backends/tahoebackend.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity/backends
  copying duplicity/backends/giobackend.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity/backends
  copying duplicity/backends/_boto_multi.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity/backends
  copying duplicity/backends/localbackend.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity/backends
  copying duplicity/backends/adbackend.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity/backends
  copying duplicity/backends/sxbackend.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity/backends
  copying duplicity/backends/pcabackend.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity/backends
  copying duplicity/backends/rclonebackend.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity/backends
  copying duplicity/backends/_cf_pyrax.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity/backends
  copying duplicity/backends/megav2backend.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity/backends
  copying duplicity/backends/__init__.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity/backends
  copying duplicity/backends/mediafirebackend.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity/backends
  copying duplicity/backends/jottacloudbackend.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity/backends
  copying duplicity/backends/ncftpbackend.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity/backends
  copying duplicity/backends/gdocsbackend.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity/backends
  copying duplicity/backends/cfbackend.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity/backends
  copying duplicity/backends/_cf_cloudfiles.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity/backends
  copying duplicity/backends/_boto_single.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity/backends
  copying duplicity/backends/ssh_paramiko_backend.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity/backends
  copying duplicity/backends/hsibackend.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity/backends
  copying duplicity/backends/onedrivebackend.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity/backends
  copying duplicity/backends/hubicbackend.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity/backends
  copying duplicity/backends/dpbxbackend.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity/backends
  copying duplicity/backends/s3_boto3_backend.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity/backends
  copying duplicity/backends/b2backend.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity/backends
  copying duplicity/backends/azurebackend.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity/backends
  copying duplicity/backends/rsyncbackend.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity/backends
  copying duplicity/backends/lftpbackend.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity/backends
  copying duplicity/backends/webdavbackend.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity/backends
  creating build/lib.macosx-10.15-x86_64-3.8/duplicity/backends/pyrax_identity
  copying duplicity/backends/pyrax_identity/__init__.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity/backends/pyrax_identity
  copying duplicity/backends/pyrax_identity/hubic.py -> build/lib.macosx-10.15-x86_64-3.8/duplicity/backends/pyrax_identity
  creating build/lib.macosx-10.15-x86_64-3.8/testing
  copying testing/conftest.py -> build/lib.macosx-10.15-x86_64-3.8/testing
  copying testing/fix_unadorned_strings.py -> build/lib.macosx-10.15-x86_64-3.8/testing
  copying testing/find_unadorned_strings.py -> build/lib.macosx-10.15-x86_64-3.8/testing
  copying testing/test_code.py -> build/lib.macosx-10.15-x86_64-3.8/testing
  copying testing/__init__.py -> build/lib.macosx-10.15-x86_64-3.8/testing
  creating build/lib.macosx-10.15-x86_64-3.8/testing/functional
  copying testing/functional/test_verify.py -> build/lib.macosx-10.15-x86_64-3.8/testing/functional
  copying testing/functional/test_cleanup.py -> build/lib.macosx-10.15-x86_64-3.8/testing/functional
  copying testing/functional/__init__.py -> build/lib.macosx-10.15-x86_64-3.8/testing/functional
  copying testing/functional/test_selection.py -> build/lib.macosx-10.15-x86_64-3.8/testing/functional
  copying testing/functional/test_log.py -> build/lib.macosx-10.15-x86_64-3.8/testing/functional
  copying testing/functional/test_final.py -> build/lib.macosx-10.15-x86_64-3.8/testing/functional
  copying testing/functional/test_badupload.py -> build/lib.macosx-10.15-x86_64-3.8/testing/functional
  copying testing/functional/test_restart.py -> build/lib.macosx-10.15-x86_64-3.8/testing/functional
  copying testing/functional/test_replicate.py -> build/lib.macosx-10.15-x86_64-3.8/testing/functional
  copying testing/functional/test_rdiffdir.py -> build/lib.macosx-10.15-x86_64-3.8/testing/functional
  creating build/lib.macosx-10.15-x86_64-3.8/testing/overrides
  copying testing/overrides/gettext.py -> build/lib.macosx-10.15-x86_64-3.8/testing/overrides
  copying testing/overrides/__init__.py -> build/lib.macosx-10.15-x86_64-3.8/testing/overrides
  creating build/lib.macosx-10.15-x86_64-3.8/testing/unit
  copying testing/unit/test_backend.py -> build/lib.macosx-10.15-x86_64-3.8/testing/unit
  copying testing/unit/test_statistics.py -> build/lib.macosx-10.15-x86_64-3.8/testing/unit
  copying testing/unit/test_tempdir.py -> build/lib.macosx-10.15-x86_64-3.8/testing/unit
  copying testing/unit/test_dup_time.py -> build/lib.macosx-10.15-x86_64-3.8/testing/unit
  copying testing/unit/test_diffdir.py -> build/lib.macosx-10.15-x86_64-3.8/testing/unit
  copying testing/unit/test_gpginterface.py -> build/lib.macosx-10.15-x86_64-3.8/testing/unit
  copying testing/unit/__init__.py -> build/lib.macosx-10.15-x86_64-3.8/testing/unit
  copying testing/unit/test_selection.py -> build/lib.macosx-10.15-x86_64-3.8/testing/unit
  copying testing/unit/test_manifest.py -> build/lib.macosx-10.15-x86_64-3.8/testing/unit
  copying testing/unit/test_util.py -> build/lib.macosx-10.15-x86_64-3.8/testing/unit
  copying testing/unit/test_backend_instance.py -> build/lib.macosx-10.15-x86_64-3.8/testing/unit
  copying testing/unit/test_patchdir.py -> build/lib.macosx-10.15-x86_64-3.8/testing/unit
  copying testing/unit/test_dup_temp.py -> build/lib.macosx-10.15-x86_64-3.8/testing/unit
  copying testing/unit/test_gpg.py -> build/lib.macosx-10.15-x86_64-3.8/testing/unit
  copying testing/unit/test_file_naming.py -> build/lib.macosx-10.15-x86_64-3.8/testing/unit
  copying testing/unit/test_path.py -> build/lib.macosx-10.15-x86_64-3.8/testing/unit
  copying testing/unit/test_collections.py -> build/lib.macosx-10.15-x86_64-3.8/testing/unit
  copying testing/unit/test_lazy.py -> build/lib.macosx-10.15-x86_64-3.8/testing/unit
  copying testing/unit/test_globmatch.py -> build/lib.macosx-10.15-x86_64-3.8/testing/unit
  copying testing/unit/test_tarfile.py -> build/lib.macosx-10.15-x86_64-3.8/testing/unit
  running egg_info
  writing duplicity.egg-info/PKG-INFO
  writing dependency_links to duplicity.egg-info/dependency_links.txt
  writing requirements to duplicity.egg-info/requires.txt
  writing top-level names to duplicity.egg-info/top_level.txt
  reading manifest file 'duplicity.egg-info/SOURCES.txt'
  writing manifest file 'duplicity.egg-info/SOURCES.txt'
  copying duplicity/_librsyncmodule.c -> build/lib.macosx-10.15-x86_64-3.8/duplicity
  copying duplicity/backends/README -> build/lib.macosx-10.15-x86_64-3.8/duplicity/backends
  copying testing/run-tests -> build/lib.macosx-10.15-x86_64-3.8/testing
  copying testing/testfiles.tar.gz -> build/lib.macosx-10.15-x86_64-3.8/testing
  creating build/lib.macosx-10.15-x86_64-3.8/testing/docker
  copying testing/docker/.env -> build/lib.macosx-10.15-x86_64-3.8/testing/docker
  copying testing/docker/build-duplicity_test.sh -> build/lib.macosx-10.15-x86_64-3.8/testing/docker
  copying testing/docker/docker-compose.yml -> build/lib.macosx-10.15-x86_64-3.8/testing/docker
  copying testing/docker/id_rsa -> build/lib.macosx-10.15-x86_64-3.8/testing/docker
  copying testing/docker/id_rsa.pub -> build/lib.macosx-10.15-x86_64-3.8/testing/docker
  copying testing/docker/setup.sh -> build/lib.macosx-10.15-x86_64-3.8/testing/docker
  copying testing/docker/teardown.sh -> build/lib.macosx-10.15-x86_64-3.8/testing/docker
  creating build/lib.macosx-10.15-x86_64-3.8/testing/docker/duplicity_test
  copying testing/docker/duplicity_test/Dockerfile-18.04 -> build/lib.macosx-10.15-x86_64-3.8/testing/docker/duplicity_test
  copying testing/docker/duplicity_test/Dockerfile-18.10 -> build/lib.macosx-10.15-x86_64-3.8/testing/docker/duplicity_test
  copying testing/docker/duplicity_test/Dockerfile-19.04 -> build/lib.macosx-10.15-x86_64-3.8/testing/docker/duplicity_test
  copying testing/docker/duplicity_test/Dockerfile-19.10 -> build/lib.macosx-10.15-x86_64-3.8/testing/docker/duplicity_test
  copying testing/docker/duplicity_test/Dockerfile-20.04 -> build/lib.macosx-10.15-x86_64-3.8/testing/docker/duplicity_test
  creating build/lib.macosx-10.15-x86_64-3.8/testing/docker/ftp_server
  copying testing/docker/ftp_server/Dockerfile -> build/lib.macosx-10.15-x86_64-3.8/testing/docker/ftp_server
  copying testing/docker/ftp_server/pureftpd.passwd -> build/lib.macosx-10.15-x86_64-3.8/testing/docker/ftp_server
  creating build/lib.macosx-10.15-x86_64-3.8/testing/docker/ssh_server
  copying testing/docker/ssh_server/Dockerfile -> build/lib.macosx-10.15-x86_64-3.8/testing/docker/ssh_server
  creating build/lib.macosx-10.15-x86_64-3.8/testing/gnupg
  copying testing/gnupg/README -> build/lib.macosx-10.15-x86_64-3.8/testing/gnupg
  copying testing/gnupg/gpg-agent.conf -> build/lib.macosx-10.15-x86_64-3.8/testing/gnupg
  copying testing/gnupg/gpg.conf -> build/lib.macosx-10.15-x86_64-3.8/testing/gnupg
  copying testing/gnupg/pubring.gpg -> build/lib.macosx-10.15-x86_64-3.8/testing/gnupg
  copying testing/gnupg/secring.gpg -> build/lib.macosx-10.15-x86_64-3.8/testing/gnupg
  copying testing/gnupg/trustdb.gpg -> build/lib.macosx-10.15-x86_64-3.8/testing/gnupg
  creating build/lib.macosx-10.15-x86_64-3.8/testing/manual
  copying testing/manual/__init__.py -> build/lib.macosx-10.15-x86_64-3.8/testing/manual
  copying testing/manual/auto-ctrl-c-test.sh -> build/lib.macosx-10.15-x86_64-3.8/testing/manual
  copying testing/manual/backendtest.py -> build/lib.macosx-10.15-x86_64-3.8/testing/manual
  copying testing/manual/bug1526557.sh -> build/lib.macosx-10.15-x86_64-3.8/testing/manual
  copying testing/manual/bug1846678.sh -> build/lib.macosx-10.15-x86_64-3.8/testing/manual
  copying testing/manual/bug1860200.sh -> build/lib.macosx-10.15-x86_64-3.8/testing/manual
  copying testing/manual/manual-ctrl-c-test.sh -> build/lib.macosx-10.15-x86_64-3.8/testing/manual
  copying testing/manual/multibackend.json -> build/lib.macosx-10.15-x86_64-3.8/testing/manual
  copying testing/manual/multibackend.sh -> build/lib.macosx-10.15-x86_64-3.8/testing/manual
  copying testing/manual/rootfiles.tar.gz -> build/lib.macosx-10.15-x86_64-3.8/testing/manual
  copying testing/manual/roottest.py -> build/lib.macosx-10.15-x86_64-3.8/testing/manual
  copying testing/manual/run-coverage.sh -> build/lib.macosx-10.15-x86_64-3.8/testing/manual
  copying testing/manual/stdin_test.sh -> build/lib.macosx-10.15-x86_64-3.8/testing/manual
  copying testing/manual/test_config.py.tmpl -> build/lib.macosx-10.15-x86_64-3.8/testing/manual
  creating build/lib.macosx-10.15-x86_64-3.8/testing/overrides/bin
  copying testing/overrides/bin/hsi -> build/lib.macosx-10.15-x86_64-3.8/testing/overrides/bin
  copying testing/overrides/bin/lftp -> build/lib.macosx-10.15-x86_64-3.8/testing/overrides/bin
  copying testing/overrides/bin/ncftpget -> build/lib.macosx-10.15-x86_64-3.8/testing/overrides/bin
  copying testing/overrides/bin/ncftpls -> build/lib.macosx-10.15-x86_64-3.8/testing/overrides/bin
  copying testing/overrides/bin/ncftpput -> build/lib.macosx-10.15-x86_64-3.8/testing/overrides/bin
  copying testing/overrides/bin/tahoe -> build/lib.macosx-10.15-x86_64-3.8/testing/overrides/bin
  running build_ext
  building 'duplicity._librsync' extension
  creating build/temp.macosx-10.15-x86_64-3.8
  creating build/temp.macosx-10.15-x86_64-3.8/duplicity
  clang -Wno-unused-result -Wsign-compare -Wunreachable-code -fno-common -dynamic -DNDEBUG -g -fwrapv -O3 -Wall -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk -I/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include -I/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/System/Library/Frameworks/Tk.framework/Versions/8.5/Headers -I/usr/local/include -I/usr/local/opt/[email protected]/include -I/usr/local/opt/sqlite/include -I/Users/rylanpolster/Desktop/venv/include -I/usr/local/opt/[email protected]/Frameworks/Python.framework/Versions/3.8/include/python3.8 -c duplicity/_librsyncmodule.c -o build/temp.macosx-10.15-x86_64-3.8/duplicity/_librsyncmodule.o
  duplicity/_librsyncmodule.c:28:10: fatal error: 'librsync.h' file not found
  #include <librsync.h>
           ^~~~~~~~~~~~
  1 error generated.
  error: command 'clang' failed with exit status 1
  ----------------------------------------
  ERROR: Failed building wheel for duplicity
  Running setup.py clean for duplicity
Failed to build duplicity
ERROR: Failed to build one or more wheels

Error: Command '['/Users/rylanpolster/Desktop/venv/bin/python', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--wheel-dir', '/var/folders/lx/jw48rn1j0235pst2sg8qlgp00000gp/T/tmpubpcq7wz', '--index-url', 'https://pypi.org/simple', '--trusted-host', 'pypi.org', '--progress-bar=off', 'duplicity==0.8.14']' returned non-zero exit status 1.
<output here>

What you expected to happen

Show recursive dependencies for duplicity

Step-by-step reproduction instructions

pipgrip duplicity==0.8.14 -vvv

Note: I initially encountered this when using Homebrew's pipgrip but I have confirmed that the issue is present pipgrip from PyPI as well. The logs I posted above are from running pipgrip from PyPI in a virtual environment.

When running from Homebrew pipgrip the issue appears to be the same (librsync.h is not found) but with gcc instead of clang in the message. I can provide the output from running Homebrew's pipgrip as well if that would be helpful.

Pip 20.3.1 breaks pipgrip 0.6.1, ok with pip 20.2.4

What is failing

 pip --version
pip 20.3.1 

# Using the example from the help page:

(pipgrip-test) andrewv@bridge4:~/pydev$ pipgrip -vvv --tree --lock botocore==1.13.48 'boto3>=1.10,<1.10.50'
DEBUG: Environment: {'implementation_name': 'cpython', 'implementation_version': '3.6.8', 'os_name': 'posix', 'platform_machine': 'x86_64', 'platform_release': '4.15.0-112-generic', 'platform_system': 'Linux', 'platform_version': '#113-Ubuntu SMP Thu Jul 9 23:41:39 UTC 2020', 'python_full_version': '3.6.8', 'platform_python_implementation': 'CPython', 'python_version': '3.6', 'sys_platform': 'linux'}
DEBUG: Pip version: [20, 3, 1]
DEBUG: Downloading/building wheel for botocore==1.13.48
DEBUG: ['/home/andrewv/pyvenv/ubuntu/pipgrip-test/bin/python', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--wheel-dir', '/home/andrewv/.cache/pip/wheels/pipgrip', '--index-url', 'https://pypi.org/simple', '--trusted-host', 'pypi.org', '--progress-bar=off', 'botocore==1.13.48']
DEBUG: {'botocore==1.13.48': '/home/andrewv/.cache/pip/wheels/pipgrip/botocore-1.13.48-py2.py3-none-any.whl'}
DEBUG: Searching metadata in /home/andrewv/.cache/pip/wheels/pipgrip/botocore-1.13.48-py2.py3-none-any.whl
DEBUG: dropped conditional dep python-dateutil>=2.1,<2.7.0; python_version=="2.6"
DEBUG: included conditional dep python-dateutil>=2.1,<3.0.0; python_version>="2.7"
DEBUG: dropped conditional dep ordereddict==1.1; python_version=="2.6"
DEBUG: dropped conditional dep simplejson==3.3.0; python_version=="2.6"
DEBUG: dropped conditional dep urllib3>=1.20,<1.23; python_version=="3.3"
DEBUG: dropped conditional dep urllib3>=1.20,<1.24; python_version=="2.6"
DEBUG: dropped conditional dep urllib3>=1.20,<1.26; python_version=="2.7"
DEBUG: included conditional dep urllib3>=1.20,<1.26; python_version>="3.4"
DEBUG: Finding possible versions for botocore
DEBUG: ['/home/andrewv/pyvenv/ubuntu/pipgrip-test/bin/python', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--index-url', 'https://pypi.org/simple', '--trusted-host', 'pypi.org', '--progress-bar=off', 'botocore==rubbish']
Traceback (most recent call last):
  File "/home/andrewv/pyvenv/ubuntu/pipgrip-test/bin/pipgrip", line 8, in <module>
    sys.exit(main())
  File "/home/andrewv/pyvenv/ubuntu/pipgrip-test/lib/python3.6/site-packages/click/core.py", line 829, in __call__
    return self.main(*args, **kwargs)
  File "/home/andrewv/pyvenv/ubuntu/pipgrip-test/lib/python3.6/site-packages/click/core.py", line 782, in main
    rv = self.invoke(ctx)
  File "/home/andrewv/pyvenv/ubuntu/pipgrip-test/lib/python3.6/site-packages/click/core.py", line 1066, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/home/andrewv/pyvenv/ubuntu/pipgrip-test/lib/python3.6/site-packages/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "/home/andrewv/pyvenv/ubuntu/pipgrip-test/lib/python3.6/site-packages/pipgrip/cli.py", line 416, in main
    source.root_dep(root_dependency)
  File "/home/andrewv/pyvenv/ubuntu/pipgrip-test/lib/python3.6/site-packages/pipgrip/package_source.py", line 147, in root_dep
    self.discover_and_add(req.__str__())
  File "/home/andrewv/pyvenv/ubuntu/pipgrip-test/lib/python3.6/site-packages/pipgrip/package_source.py", line 126, in discover_and_add
    package, self.index_url, self.extra_index_url, self.cache_dir, self.pre
  File "/home/andrewv/pyvenv/ubuntu/pipgrip-test/lib/python3.6/site-packages/pipgrip/pipper.py", line 384, in discover_dependencies_and_versions
    if req.key != "."
  File "/home/andrewv/pyvenv/ubuntu/pipgrip-test/lib/python3.6/site-packages/pipgrip/pipper.py", line 212, in _get_available_versions
    all_versions = line.split("from versions: ", 1)[1].rstrip(")").split(", ")
IndexError: list index out of range

What you expected to happen

See below

Step-by-step reproduction instructions

# Works ok with pip 20.2.4

pip install pip==20.2.4
...
      Successfully uninstalled pip-20.3.1
Successfully installed pip-20.2.4

 DEBUG: Environment: {'implementation_name': 'cpython', 'implementation_version': '3.6.8', 'os_name': 'posix', 'platform_machine': 'x86_64', 'platform_release': '4.15.0-112-generic', 'platform_system': 'Linux', 'platform_version': '#113-Ubuntu SMP Thu Jul 9 23:41:39 UTC 2020', 'python_full_version': '3.6.8', 'platform_python_implementation': 'CPython', 'python_version': '3.6', 'sys_platform': 'linux'}
DEBUG: Pip version: [20, 2, 4]
DEBUG: Downloading/building wheel for botocore==1.13.48
DEBUG: ['/home/andrewv/pyvenv/ubuntu/pipgrip-test/bin/python', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--wheel-dir', '/home/andrewv/.cache/pip/wheels/pipgrip', '--index-url', 'https://pypi.org/simple', '--trusted-host', 'pypi.org', '--progress-bar=off', 'botocore==1.13.48']
DEBUG: {'botocore==1.13.48': '/home/andrewv/.cache/pip/wheels/pipgrip/botocore-1.13.48-py2.py3-none-any.whl'}
DEBUG: Searching metadata in /home/andrewv/.cache/pip/wheels/pipgrip/botocore-1.13.48-py2.py3-none-any.whl
DEBUG: dropped conditional dep python-dateutil>=2.1,<2.7.0; python_version=="2.6"
DEBUG: included conditional dep python-dateutil>=2.1,<3.0.0; python_version>="2.7"
DEBUG: dropped conditional dep ordereddict==1.1; python_version=="2.6"
DEBUG: dropped conditional dep simplejson==3.3.0; python_version=="2.6"
DEBUG: dropped conditional dep urllib3>=1.20,<1.23; python_version=="3.3"
DEBUG: dropped conditional dep urllib3>=1.20,<1.24; python_version=="2.6"
DEBUG: dropped conditional dep urllib3>=1.20,<1.26; python_version=="2.7"
DEBUG: included conditional dep urllib3>=1.20,<1.26; python_version>="3.4"
DEBUG: Finding possible versions for botocore
DEBUG: ['/home/andrewv/pyvenv/ubuntu/pipgrip-test/bin/python', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--index-url', 'https://pypi.org/simple', '--trusted-host', 'pypi.org', '--progress-bar=off', 'botocore==rubbish']
DEBUG: {'botocore': ['0.4.1', '0.4.2', '0.5.0', '0.5.1', '0.5.2', '0.5.3', '0.5.4', '0.6.0', '0.7.0', '0.8.0', '0.8.1', '0.8.2', '0.8.3', '0.9.0', '0.9.1', '0.9.2', '0.10.0', '0.11.0', '0.12.0', '0.13.0', '0.13.1', '0.14.0', '0.15.0', '0.15.1', '0.16.0', '0.17.0', '0.18.0', '0.19.0', '0.20.0', '0.21.0', '0.22.0', '0.23.0', '0.24.0', '0.25.0', '0.26.0', '0.27.0', '0.28.0', '0.29.0', '0.30.0', '0.31.0', '0.32.0', '0.33.0', '0.34.0', '0.35.0', '0.36.0', '0.37.0', '0.38.0', '0.39.0', '0.40.0', '0.41.0', '0.42.0', '0.43.0', '0.44.0', '0.45.0', '0.46.0', '0.47.0', '0.48.0', '0.49.0', '0.50.0', '0.51.0', '0.52.0', '0.53.0', '0.54.0', '0.55.0', '0.56.0', '0.57.0', '0.58.0', '0.59.0', '0.60.0', '0.61.0', '0.62.0', '0.63.0', '0.64.0', '0.65.0', '0.66.0', '0.67.0', '0.68.0', '0.69.0', '0.70.0', '0.71.0', '0.72.0', '0.73.0', '0.74.0', '0.75.0', '0.76.0', '0.77.0', '0.78.0', '0.79.0', '0.80.0', '0.81.0', '0.82.0', '0.83.0', '0.84.0', '0.85.0', '0.86.0', '0.87.0', '0.88.0', '0.89.0', '0.90.0', '0.91.0', '0.92.0', '0.93.0', '0.94.0', '0.95.0', '0.96.0', '0.97.0', '0.98.0', '0.99.0', '0.100.0', '0.101.0', '0.102.0', '0.103.0', '0.104.0', '0.105.0', '0.106.0', '0.107.0', '0.108.0', '0.109.0', '1.0.0', '1.0.1', '1.1.0', '1.1.1', '1.1.2', '1.1.3', '1.1.4', '1.1.5', '1.1.6', '1.1.7', '1.1.8', '1.1.9', '1.1.10', '1.1.11', '1.1.12', '1.2.0', '1.2.1', '1.2.2', '1.2.3', '1.2.4', '1.2.5', '1.2.6', '1.2.7', '1.2.8', '1.2.9', '1.2.10', '1.2.11', '1.3.0', '1.3.1', '1.3.2', '1.3.3', '1.3.4', '1.3.5', '1.3.6', '1.3.7', '1.3.8', '1.3.9', '1.3.10', '1.3.11', '1.3.12', '1.3.13', '1.3.14', '1.3.15', '1.3.16', '1.3.17', '1.3.18', '1.3.19', '1.3.20', '1.3.21', '1.3.22', '1.3.23', '1.3.24', '1.3.25', '1.3.26', '1.3.27', '1.3.28', '1.3.29', '1.3.30', '1.4.0', '1.4.1', '1.4.2', '1.4.3', '1.4.4', '1.4.5', '1.4.6', '1.4.7', '1.4.8', '1.4.9', '1.4.10', '1.4.11', '1.4.12', '1.4.13', '1.4.14', '1.4.15', '1.4.16', '1.4.17', '1.4.18', '1.4.19', '1.4.20', '1.4.21', '1.4.22', '1.4.23', '1.4.24', '1.4.25', '1.4.26', '1.4.27', '1.4.28', '1.4.29', '1.4.30', '1.4.31', '1.4.32', '1.4.33', '1.4.34', '1.4.35', '1.4.36', '1.4.37', '1.4.38', '1.4.39', '1.4.40', '1.4.41', '1.4.42', '1.4.43', '1.4.44', '1.4.46', '1.4.47', '1.4.48', '1.4.49', '1.4.50', '1.4.51', '1.4.52', '1.4.53', '1.4.54', '1.4.55', '1.4.56', '1.4.57', '1.4.58', '1.4.59', '1.4.60', '1.4.61', '1.4.62', '1.4.63', '1.4.64', '1.4.65', '1.4.66', '1.4.67', '1.4.68', '1.4.69', '1.4.70', '1.4.71', '1.4.72', '1.4.73', '1.4.74', '1.4.75', '1.4.76', '1.4.77', '1.4.78', '1.4.79', '1.4.80', '1.4.81', '1.4.82', '1.4.83', '1.4.84', '1.4.85', '1.4.86', '1.4.87', '1.4.88', '1.4.89', '1.4.90', '1.4.91', '1.4.92', '1.4.93', '1.5.0', '1.5.1', '1.5.2', '1.5.3', '1.5.4', '1.5.5', '1.5.6', '1.5.7', '1.5.8', '1.5.9', '1.5.10', '1.5.11', '1.5.12', '1.5.13', '1.5.14', '1.5.15', '1.5.16', '1.5.17', '1.5.18', '1.5.19', '1.5.20', '1.5.21', '1.5.22', '1.5.23', '1.5.24', '1.5.25', '1.5.26', '1.5.27', '1.5.28', '1.5.29', '1.5.30', '1.5.31', '1.5.32', '1.5.33', '1.5.34', '1.5.35', '1.5.36', '1.5.37', '1.5.38', '1.5.39', '1.5.40', '1.5.41', '1.5.42', '1.5.43', '1.5.44', '1.5.45', '1.5.46', '1.5.47', '1.5.48', '1.5.49', '1.5.50', '1.5.51', '1.5.52', '1.5.53', '1.5.54', '1.5.55', '1.5.56', '1.5.57', '1.5.58', '1.5.59', '1.5.60', '1.5.61', '1.5.62', '1.5.63', '1.5.64', '1.5.65', '1.5.66', '1.5.67', '1.5.68', '1.5.69', '1.5.70', '1.5.71', '1.5.72', '1.5.73', '1.5.74', '1.5.75', '1.5.76', '1.5.77', '1.5.78', '1.5.79', '1.5.80', '1.5.81', '1.5.82', '1.5.83', '1.5.84', '1.5.85', '1.5.86', '1.5.87', '1.5.88', '1.5.89', '1.5.90', '1.5.91', '1.5.92', '1.5.93', '1.5.94', '1.5.95', '1.6.0', '1.6.1', '1.6.2', '1.6.3', '1.6.4', '1.6.5', '1.6.6', '1.6.7', '1.6.8', '1.7.0', '1.7.1', '1.7.2', '1.7.3', '1.7.4', '1.7.5', '1.7.6', '1.7.7', '1.7.8', '1.7.9', '1.7.10', '1.7.11', '1.7.12', '1.7.13', '1.7.14', '1.7.15', '1.7.16', '1.7.17', '1.7.18', '1.7.19', '1.7.20', '1.7.21', '1.7.22', '1.7.23', '1.7.24', '1.7.25', '1.7.26', '1.7.27', '1.7.28', '1.7.29', '1.7.30', '1.7.31', '1.7.32', '1.7.33', '1.7.34', '1.7.35', '1.7.36', '1.7.37', '1.7.38', '1.7.39', '1.7.40', '1.7.41', '1.7.42', '1.7.43', '1.7.44', '1.7.45', '1.7.46', '1.7.47', '1.7.48', '1.8.0', '1.8.1', '1.8.2', '1.8.3', '1.8.4', '1.8.5', '1.8.6', '1.8.7', '1.8.8', '1.8.9', '1.8.10', '1.8.11', '1.8.12', '1.8.13', '1.8.14', '1.8.15', '1.8.16', '1.8.17', '1.8.18', '1.8.19', '1.8.20', '1.8.21', '1.8.22', '1.8.23', '1.8.24', '1.8.25', '1.8.26', '1.8.27', '1.8.28', '1.8.29', '1.8.30', '1.8.31', '1.8.32', '1.8.33', '1.8.34', '1.8.35', '1.8.36', '1.8.37', '1.8.38', '1.8.39', '1.8.40', '1.8.41', '1.8.42', '1.8.43', '1.8.44', '1.8.45', '1.8.46', '1.8.47', '1.8.48', '1.8.49', '1.8.50', '1.9.0', '1.9.1', '1.9.2', '1.9.3', '1.9.4', '1.9.5', '1.9.6', '1.9.7', '1.9.8', '1.9.9', '1.9.10', '1.9.11', '1.9.12', '1.9.13', '1.9.14', '1.9.15', '1.9.16', '1.9.17', '1.9.18', '1.9.19', '1.9.20', '1.9.21', '1.9.22', '1.9.23', '1.10.0', '1.10.1', '1.10.2', '1.10.3', '1.10.4', '1.10.5', '1.10.6', '1.10.7', '1.10.8', '1.10.9', '1.10.10', '1.10.11', '1.10.12', '1.10.13', '1.10.14', '1.10.15', '1.10.16', '1.10.17', '1.10.18', '1.10.19', '1.10.20', '1.10.21', '1.10.22', '1.10.23', '1.10.24', '1.10.25', '1.10.26', '1.10.27', '1.10.28', '1.10.29', '1.10.30', '1.10.31', '1.10.32', '1.10.33', '1.10.34', '1.10.35', '1.10.36', '1.10.37', '1.10.38', '1.10.39', '1.10.40', '1.10.41', '1.10.42', '1.10.43', '1.10.44', '1.10.45', '1.10.46', '1.10.47', '1.10.48', '1.10.49', '1.10.50', '1.10.51', '1.10.52', '1.10.53', '1.10.54', '1.10.55', '1.10.56', '1.10.57', '1.10.58', '1.10.59', '1.10.60', '1.10.61', '1.10.62', '1.10.63', '1.10.64', '1.10.65', '1.10.66', '1.10.67', '1.10.68', '1.10.69', '1.10.70', '1.10.71', '1.10.72', '1.10.73', '1.10.74', '1.10.75', '1.10.76', '1.10.77', '1.10.78', '1.10.79', '1.10.80', '1.10.81', '1.10.82', '1.10.83', '1.10.84', '1.11.0', '1.11.1', '1.11.2', '1.11.3', '1.11.4', '1.11.5', '1.11.6', '1.11.7', '1.11.8', '1.11.9', '1.12.0', '1.12.1', '1.12.2', '1.12.3', '1.12.4', '1.12.5', '1.12.6', '1.12.7', '1.12.8', '1.12.9', '1.12.10', '1.12.11', '1.12.12', '1.12.13', '1.12.14', '1.12.15', '1.12.16', '1.12.17', '1.12.18', '1.12.19', '1.12.20', '1.12.21', '1.12.22', '1.12.23', '1.12.24', '1.12.25', '1.12.26', '1.12.27', '1.12.28', '1.12.29', '1.12.30', '1.12.31', '1.12.32', '1.12.33', '1.12.34', '1.12.35', '1.12.36', '1.12.37', '1.12.38', '1.12.39', '1.12.40', '1.12.41', '1.12.42', '1.12.43', '1.12.44', '1.12.45', '1.12.46', '1.12.47', '1.12.48', '1.12.49', '1.12.50', '1.12.51', '1.12.52', '1.12.53', '1.12.54', '1.12.55', '1.12.56', '1.12.57', '1.12.58', '1.12.59', '1.12.60', '1.12.61', '1.12.62', '1.12.63', '1.12.64', '1.12.65', '1.12.66', '1.12.67', '1.12.68', '1.12.69', '1.12.70', '1.12.71', '1.12.72', '1.12.73', '1.12.74', '1.12.75', '1.12.76', '1.12.77', '1.12.78', '1.12.79', '1.12.80', '1.12.81', '1.12.82', '1.12.83', '1.12.84', '1.12.85', '1.12.86', '1.12.87', '1.12.88', '1.12.89', '1.12.90', '1.12.91', '1.12.92', '1.12.93', '1.12.94', '1.12.95', '1.12.96', '1.12.97', '1.12.98', '1.12.99', '1.12.100', '1.12.101', '1.12.102', '1.12.103', '1.12.104', '1.12.105', '1.12.106', '1.12.107', '1.12.108', '1.12.109', '1.12.110', '1.12.111', '1.12.112', '1.12.113', '1.12.114', '1.12.115', '1.12.116', '1.12.117', '1.12.118', '1.12.119', '1.12.120', '1.12.121', '1.12.122', '1.12.123', '1.12.124', '1.12.125', '1.12.126', '1.12.127', '1.12.128', '1.12.129', '1.12.130', '1.12.131', '1.12.132', '1.12.133', '1.12.134', '1.12.135', '1.12.136', '1.12.137', '1.12.138', '1.12.139', '1.12.140', '1.12.141', '1.12.142', '1.12.143', '1.12.144', '1.12.145', '1.12.146', '1.12.147', '1.12.148', '1.12.149', '1.12.150', '1.12.151', '1.12.152', '1.12.153', '1.12.154', '1.12.155', '1.12.156', '1.12.157', '1.12.158', '1.12.159', '1.12.160', '1.12.161', '1.12.162', '1.12.163', '1.12.164', '1.12.165', '1.12.166', '1.12.167', '1.12.168', '1.12.169', '1.12.170', '1.12.171', '1.12.172', '1.12.173', '1.12.174', '1.12.175', '1.12.176', '1.12.177', '1.12.178', '1.12.179', '1.12.180', '1.12.181', '1.12.182', '1.12.183', '1.12.184', '1.12.185', '1.12.186', '1.12.187', '1.12.188', '1.12.189', '1.12.190', '1.12.191', '1.12.192', '1.12.193', '1.12.194', '1.12.195', '1.12.196', '1.12.197', '1.12.198', '1.12.199', '1.12.200', '1.12.201', '1.12.202', '1.12.203', '1.12.204', '1.12.205', '1.12.206', '1.12.207', '1.12.208', '1.12.209', '1.12.210', '1.12.211', '1.12.212', '1.12.213', '1.12.214', '1.12.215', '1.12.216', '1.12.217', '1.12.218', '1.12.219', '1.12.220', '1.12.221', '1.12.222', '1.12.223', '1.12.224', '1.12.225', '1.12.226', '1.12.227', '1.12.228', '1.12.229', '1.12.230', '1.12.231', '1.12.232', '1.12.233', '1.12.234', '1.12.235', '1.12.236', '1.12.237', '1.12.238', '1.12.239', '1.12.240', '1.12.241', '1.12.242', '1.12.243', '1.12.244', '1.12.245', '1.12.246', '1.12.247', '1.12.248', '1.12.249', '1.12.250', '1.12.251', '1.12.252', '1.12.253', '1.13.0', '1.13.1', '1.13.2', '1.13.3', '1.13.4', '1.13.5', '1.13.6', '1.13.7', '1.13.8', '1.13.9', '1.13.10', '1.13.11', '1.13.12', '1.13.13', '1.13.14', '1.13.15', '1.13.16', '1.13.17', '1.13.18', '1.13.19', '1.13.20', '1.13.21', '1.13.22', '1.13.23', '1.13.24', '1.13.25', '1.13.26', '1.13.27', '1.13.28', '1.13.29', '1.13.30', '1.13.31', '1.13.32', '1.13.33', '1.13.34', '1.13.35', '1.13.36', '1.13.37', '1.13.38', '1.13.39', '1.13.40', '1.13.41', '1.13.42', '1.13.43', '1.13.44', '1.13.45', '1.13.46', '1.13.47', '1.13.48', '1.13.49', '1.13.50', '1.14.0', '1.14.1', '1.14.2', '1.14.3', '1.14.4', '1.14.5', '1.14.6', '1.14.7', '1.14.8', '1.14.9', '1.14.10', '1.14.11', '1.14.12', '1.14.13', '1.14.14', '1.14.15', '1.14.16', '1.14.17', '1.15.0', '1.15.1', '1.15.2', '1.15.3', '1.15.4', '1.15.5', '1.15.6', '1.15.7', '1.15.8', '1.15.9', '1.15.10', '1.15.11', '1.15.12', '1.15.13', '1.15.14', '1.15.15', '1.15.16', '1.15.17', '1.15.18', '1.15.19', '1.15.20', '1.15.21', '1.15.22', '1.15.23', '1.15.24', '1.15.25', '1.15.26', '1.15.27', '1.15.28', '1.15.29', '1.15.30', '1.15.31', '1.15.32', '1.15.33', '1.15.34', '1.15.35', '1.15.36', '1.15.37', '1.15.38', '1.15.39', '1.15.40', '1.15.41', '1.15.42', '1.15.43', '1.15.44', '1.15.45', '1.15.46', '1.15.47', '1.15.48', '1.15.49', '1.16.0', '1.16.1', '1.16.2', '1.16.3', '1.16.4', '1.16.5', '1.16.6', '1.16.7', '1.16.8', '1.16.9', '1.16.10', '1.16.11', '1.16.12', '1.16.13', '1.16.14', '1.16.15', '1.16.16', '1.16.17', '1.16.18', '1.16.19', '1.16.20', '1.16.21', '1.16.22', '1.16.23', '1.16.24', '1.16.25', '1.16.26', '1.17.0', '1.17.1', '1.17.2', '1.17.3', '1.17.4', '1.17.5', '1.17.6', '1.17.7', '1.17.8', '1.17.9', '1.17.10', '1.17.11', '1.17.12', '1.17.13', '1.17.14', '1.17.15', '1.17.16', '1.17.17', '1.17.18', '1.17.19', '1.17.20', '1.17.21', '1.17.22', '1.17.23', '1.17.24', '1.17.25', '1.17.26', '1.17.27', '1.17.28', '1.17.29', '1.17.30', '1.17.31', '1.17.32', '1.17.33', '1.17.34', '1.17.35', '1.17.36', '1.17.37', '1.17.38', '1.17.39', '1.17.40', '1.17.41', '1.17.42', '1.17.43', '1.17.44', '1.17.45', '1.17.46', '1.17.47', '1.17.48', '1.17.49', '1.17.50', '1.17.51', '1.17.52', '1.17.53', '1.17.54', '1.17.55', '1.17.56', '1.17.57', '1.17.58', '1.17.59', '1.17.60', '1.17.61', '1.17.62', '1.17.63', '1.18.0', '1.18.1', '1.18.2', '1.18.3', '1.18.4', '1.18.5', '1.18.6', '1.18.7', '1.18.8', '1.18.9', '1.18.10', '1.18.11', '1.18.12', '1.18.13', '1.18.14', '1.18.15', '1.18.16', '1.18.17', '1.18.18', '1.19.0', '1.19.1', '1.19.2', '1.19.3', '1.19.4', '1.19.5', '1.19.6', '1.19.7', '1.19.8', '1.19.9', '1.19.10', '1.19.11', '1.19.12', '1.19.13', '1.19.14', '1.19.15', '1.19.16', '1.19.17', '1.19.18', '1.19.19', '1.19.20', '1.19.21', '1.19.22', '1.19.23', '1.19.24', '1.19.25', '1.19.26', '1.19.27', '1.19.28', '1.19.29', '1.19.30', '1.19.31', '1.19.32', '1.19.33', '1.19.34']}
DEBUG: Downloading/building wheel for boto3<1.10.50,>=1.10
DEBUG: ['/home/andrewv/pyvenv/ubuntu/pipgrip-test/bin/python', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--wheel-dir', '/home/andrewv/.cache/pip/wheels/pipgrip', '--index-url', 'https://pypi.org/simple', '--trusted-host', 'pypi.org', '--progress-bar=off', 'boto3<1.10.50,>=1.10']
DEBUG: {'boto3<1.10.50,>=1.10': '/home/andrewv/.cache/pip/wheels/pipgrip/boto3-1.10.49-py2.py3-none-any.whl'}
DEBUG: Searching metadata in /home/andrewv/.cache/pip/wheels/pipgrip/boto3-1.10.49-py2.py3-none-any.whl
DEBUG: Finding possible versions for boto3
DEBUG: ['/home/andrewv/pyvenv/ubuntu/pipgrip-test/bin/python', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--index-url', 'https://pypi.org/simple', '--trusted-host', 'pypi.org', '--progress-bar=off', 'boto3==rubbish']
DEBUG: {'boto3': ['0.0.1', '0.0.2', '0.0.3', '0.0.4', '0.0.5', '0.0.6', '0.0.7', '0.0.8', '0.0.9', '0.0.10', '0.0.11', '0.0.12', '0.0.13', '0.0.14', '0.0.16', '0.0.17', '0.0.18', '0.0.19', '0.0.20', '0.0.21', '0.0.22', '1.0.0', '1.0.1', '1.1.0', '1.1.1', '1.1.2', '1.1.3', '1.1.4', '1.2.0', '1.2.1', '1.2.2', '1.2.3', '1.2.4', '1.2.5', '1.2.6', '1.3.0', '1.3.1', '1.4.0', '1.4.1', '1.4.2', '1.4.3', '1.4.4', '1.4.5', '1.4.6', '1.4.7', '1.4.8', '1.5.0', '1.5.1', '1.5.2', '1.5.3', '1.5.4', '1.5.5', '1.5.6', '1.5.7', '1.5.8', '1.5.9', '1.5.10', '1.5.11', '1.5.12', '1.5.13', '1.5.14', '1.5.15', '1.5.16', '1.5.17', '1.5.18', '1.5.19', '1.5.20', '1.5.21', '1.5.22', '1.5.23', '1.5.24', '1.5.25', '1.5.26', '1.5.27', '1.5.28', '1.5.29', '1.5.30', '1.5.31', '1.5.32', '1.5.33', '1.5.34', '1.5.35', '1.5.36', '1.6.0', '1.6.1', '1.6.2', '1.6.3', '1.6.4', '1.6.5', '1.6.6', '1.6.7', '1.6.8', '1.6.9', '1.6.10', '1.6.11', '1.6.12', '1.6.13', '1.6.14', '1.6.15', '1.6.16', '1.6.17', '1.6.18', '1.6.19', '1.6.20', '1.6.21', '1.6.22', '1.6.23', '1.7.0', '1.7.1', '1.7.2', '1.7.3', '1.7.4', '1.7.5', '1.7.6', '1.7.7', '1.7.8', '1.7.9', '1.7.10', '1.7.11', '1.7.12', '1.7.13', '1.7.14', '1.7.15', '1.7.16', '1.7.17', '1.7.18', '1.7.19', '1.7.20', '1.7.21', '1.7.22', '1.7.23', '1.7.24', '1.7.25', '1.7.26', '1.7.27', '1.7.28', '1.7.29', '1.7.30', '1.7.31', '1.7.32', '1.7.33', '1.7.34', '1.7.35', '1.7.36', '1.7.37', '1.7.38', '1.7.39', '1.7.40', '1.7.41', '1.7.42', '1.7.43', '1.7.44', '1.7.45', '1.7.46', '1.7.47', '1.7.48', '1.7.49', '1.7.50', '1.7.51', '1.7.52', '1.7.53', '1.7.54', '1.7.55', '1.7.56', '1.7.57', '1.7.58', '1.7.59', '1.7.60', '1.7.61', '1.7.62', '1.7.63', '1.7.64', '1.7.65', '1.7.66', '1.7.67', '1.7.68', '1.7.69', '1.7.70', '1.7.71', '1.7.72', '1.7.73', '1.7.74', '1.7.75', '1.7.76', '1.7.77', '1.7.78', '1.7.79', '1.7.80', '1.7.81', '1.7.82', '1.7.83', '1.7.84', '1.8.0', '1.8.1', '1.8.2', '1.8.3', '1.8.4', '1.8.5', '1.8.6', '1.8.7', '1.8.8', '1.8.9', '1.9.0', '1.9.1', '1.9.2', '1.9.3', '1.9.4', '1.9.5', '1.9.6', '1.9.7', '1.9.8', '1.9.9', '1.9.10', '1.9.11', '1.9.12', '1.9.13', '1.9.14', '1.9.15', '1.9.16', '1.9.17', '1.9.18', '1.9.19', '1.9.20', '1.9.21', '1.9.22', '1.9.23', '1.9.24', '1.9.25', '1.9.26', '1.9.27', '1.9.28', '1.9.29', '1.9.30', '1.9.31', '1.9.32', '1.9.33', '1.9.34', '1.9.35', '1.9.36', '1.9.37', '1.9.38', '1.9.39', '1.9.40', '1.9.41', '1.9.42', '1.9.43', '1.9.44', '1.9.45', '1.9.46', '1.9.47', '1.9.48', '1.9.49', '1.9.50', '1.9.51', '1.9.52', '1.9.53', '1.9.54', '1.9.55', '1.9.56', '1.9.57', '1.9.58', '1.9.59', '1.9.60', '1.9.61', '1.9.62', '1.9.63', '1.9.64', '1.9.65', '1.9.66', '1.9.67', '1.9.68', '1.9.69', '1.9.70', '1.9.71', '1.9.72', '1.9.73', '1.9.74', '1.9.75', '1.9.76', '1.9.77', '1.9.78', '1.9.79', '1.9.80', '1.9.81', '1.9.82', '1.9.83', '1.9.84', '1.9.85', '1.9.86', '1.9.87', '1.9.88', '1.9.89', '1.9.90', '1.9.91', '1.9.92', '1.9.93', '1.9.94', '1.9.95', '1.9.96', '1.9.97', '1.9.98', '1.9.99', '1.9.100', '1.9.101', '1.9.102', '1.9.103', '1.9.104', '1.9.105', '1.9.106', '1.9.107', '1.9.108', '1.9.109', '1.9.110', '1.9.111', '1.9.112', '1.9.113', '1.9.114', '1.9.115', '1.9.116', '1.9.117', '1.9.118', '1.9.119', '1.9.120', '1.9.121', '1.9.122', '1.9.123', '1.9.124', '1.9.125', '1.9.126', '1.9.127', '1.9.128', '1.9.129', '1.9.130', '1.9.131', '1.9.132', '1.9.133', '1.9.134', '1.9.135', '1.9.136', '1.9.137', '1.9.138', '1.9.139', '1.9.140', '1.9.141', '1.9.142', '1.9.143', '1.9.144', '1.9.145', '1.9.146', '1.9.147', '1.9.148', '1.9.149', '1.9.150', '1.9.151', '1.9.152', '1.9.153', '1.9.154', '1.9.155', '1.9.156', '1.9.157', '1.9.158', '1.9.159', '1.9.160', '1.9.161', '1.9.162', '1.9.163', '1.9.164', '1.9.165', '1.9.166', '1.9.167', '1.9.168', '1.9.169', '1.9.170', '1.9.171', '1.9.172', '1.9.173', '1.9.174', '1.9.175', '1.9.176', '1.9.177', '1.9.178', '1.9.179', '1.9.180', '1.9.181', '1.9.182', '1.9.183', '1.9.184', '1.9.185', '1.9.186', '1.9.187', '1.9.188', '1.9.189', '1.9.190', '1.9.191', '1.9.192', '1.9.193', '1.9.194', '1.9.195', '1.9.196', '1.9.197', '1.9.198', '1.9.199', '1.9.200', '1.9.201', '1.9.202', '1.9.203', '1.9.204', '1.9.205', '1.9.206', '1.9.207', '1.9.208', '1.9.209', '1.9.210', '1.9.211', '1.9.212', '1.9.213', '1.9.214', '1.9.215', '1.9.216', '1.9.217', '1.9.218', '1.9.219', '1.9.220', '1.9.221', '1.9.222', '1.9.223', '1.9.224', '1.9.225', '1.9.226', '1.9.227', '1.9.228', '1.9.229', '1.9.230', '1.9.231', '1.9.232', '1.9.233', '1.9.234', '1.9.235', '1.9.236', '1.9.237', '1.9.238', '1.9.239', '1.9.240', '1.9.241', '1.9.242', '1.9.243', '1.9.244', '1.9.245', '1.9.246', '1.9.247', '1.9.248', '1.9.249', '1.9.250', '1.9.251', '1.9.252', '1.9.253', '1.10.0', '1.10.1', '1.10.2', '1.10.3', '1.10.4', '1.10.5', '1.10.6', '1.10.7', '1.10.8', '1.10.9', '1.10.10', '1.10.11', '1.10.12', '1.10.13', '1.10.14', '1.10.15', '1.10.16', '1.10.17', '1.10.18', '1.10.19', '1.10.20', '1.10.21', '1.10.22', '1.10.23', '1.10.24', '1.10.25', '1.10.26', '1.10.27', '1.10.28', '1.10.29', '1.10.30', '1.10.31', '1.10.32', '1.10.33', '1.10.34', '1.10.35', '1.10.36', '1.10.37', '1.10.38', '1.10.39', '1.10.40', '1.10.41', '1.10.42', '1.10.43', '1.10.44', '1.10.45', '1.10.46', '1.10.47', '1.10.48', '1.10.49', '1.10.50', '1.11.0', '1.11.1', '1.11.2', '1.11.3', '1.11.4', '1.11.5', '1.11.6', '1.11.7', '1.11.8', '1.11.9', '1.11.10', '1.11.11', '1.11.12', '1.11.13', '1.11.14', '1.11.15', '1.11.16', '1.11.17', '1.12.0', '1.12.1', '1.12.2', '1.12.3', '1.12.4', '1.12.5', '1.12.6', '1.12.7', '1.12.8', '1.12.9', '1.12.10', '1.12.11', '1.12.12', '1.12.13', '1.12.14', '1.12.15', '1.12.16', '1.12.17', '1.12.18', '1.12.19', '1.12.20', '1.12.21', '1.12.22', '1.12.23', '1.12.24', '1.12.25', '1.12.26', '1.12.27', '1.12.28', '1.12.29', '1.12.30', '1.12.31', '1.12.32', '1.12.33', '1.12.34', '1.12.35', '1.12.36', '1.12.37', '1.12.38', '1.12.39', '1.12.40', '1.12.41', '1.12.42', '1.12.43', '1.12.44', '1.12.45', '1.12.46', '1.12.47', '1.12.48', '1.12.49', '1.13.0', '1.13.1', '1.13.2', '1.13.3', '1.13.4', '1.13.5', '1.13.6', '1.13.7', '1.13.8', '1.13.9', '1.13.10', '1.13.11', '1.13.12', '1.13.13', '1.13.14', '1.13.15', '1.13.16', '1.13.17', '1.13.18', '1.13.19', '1.13.20', '1.13.21', '1.13.22', '1.13.23', '1.13.24', '1.13.25', '1.13.26', '1.14.0', '1.14.1', '1.14.2', '1.14.3', '1.14.4', '1.14.5', '1.14.6', '1.14.7', '1.14.8', '1.14.9', '1.14.10', '1.14.11', '1.14.12', '1.14.13', '1.14.14', '1.14.15', '1.14.16', '1.14.17', '1.14.18', '1.14.19', '1.14.20', '1.14.21', '1.14.22', '1.14.23', '1.14.24', '1.14.25', '1.14.26', '1.14.27', '1.14.28', '1.14.29', '1.14.30', '1.14.31', '1.14.32', '1.14.33', '1.14.34', '1.14.35', '1.14.36', '1.14.37', '1.14.38', '1.14.39', '1.14.40', '1.14.41', '1.14.42', '1.14.43', '1.14.44', '1.14.45', '1.14.46', '1.14.47', '1.14.48', '1.14.49', '1.14.50', '1.14.51', '1.14.52', '1.14.53', '1.14.54', '1.14.55', '1.14.56', '1.14.57', '1.14.58', '1.14.59', '1.14.60', '1.14.61', '1.14.62', '1.14.63', '1.15.0', '1.15.1', '1.15.2', '1.15.3', '1.15.4', '1.15.5', '1.15.6', '1.15.7', '1.15.8', '1.15.9', '1.15.10', '1.15.11', '1.15.12', '1.15.13', '1.15.14', '1.15.15', '1.15.16', '1.15.17', '1.15.18', '1.16.0', '1.16.1', '1.16.2', '1.16.3', '1.16.4', '1.16.5', '1.16.6', '1.16.7', '1.16.8', '1.16.9', '1.16.10', '1.16.11', '1.16.12', '1.16.13', '1.16.14', '1.16.15', '1.16.16', '1.16.17', '1.16.18', '1.16.19', '1.16.20', '1.16.21', '1.16.22', '1.16.23', '1.16.24', '1.16.25', '1.16.26', '1.16.27', '1.16.28', '1.16.29', '1.16.30', '1.16.31', '1.16.32', '1.16.33', '1.16.34']}
INFO: fact: _root_ is root
INFO: derived: root
INFO: fact: root depends on botocore (==1.13.48)
INFO: fact: root depends on boto3 (>=1.10,<1.10.50)
INFO: selecting . (0.0.0)
INFO: derived: boto3 (>=1.10,<1.10.50)
INFO: derived: botocore (==1.13.48)
INFO: fact: botocore (1.13.48) depends on docutils (<0.16,>=0.10)
INFO: fact: botocore (1.13.48) depends on jmespath (<1.0.0,>=0.7.1)
INFO: fact: botocore (1.13.48) depends on python-dateutil (<3.0.0,>=2.1)
INFO: fact: botocore (1.13.48) depends on urllib3 (<1.26,>=1.20)
INFO: selecting botocore (1.13.48)
INFO: derived: urllib3 (<1.26,>=1.20)
INFO: derived: python-dateutil (<3.0.0,>=2.1)
INFO: derived: jmespath (<1.0.0,>=0.7.1)
INFO: derived: docutils (<0.16,>=0.10)
DEBUG: Downloading/building wheel for urllib3<1.26,>=1.20
DEBUG: ['/home/andrewv/pyvenv/ubuntu/pipgrip-test/bin/python', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--wheel-dir', '/home/andrewv/.cache/pip/wheels/pipgrip', '--index-url', 'https://pypi.org/simple', '--trusted-host', 'pypi.org', '--progress-bar=off', 'urllib3<1.26,>=1.20']
DEBUG: {'urllib3<1.26,>=1.20': '/home/andrewv/.cache/pip/wheels/pipgrip/urllib3-1.25.11-py2.py3-none-any.whl'}
DEBUG: Searching metadata in /home/andrewv/.cache/pip/wheels/pipgrip/urllib3-1.25.11-py2.py3-none-any.whl
DEBUG: dropped conditional dep brotlipy (>=0.6.0) ; extra == 'brotli'
DEBUG: dropped conditional dep pyOpenSSL (>=0.14) ; extra == 'secure'
DEBUG: dropped conditional dep cryptography (>=1.3.4) ; extra == 'secure'
DEBUG: dropped conditional dep idna (>=2.0.0) ; extra == 'secure'
DEBUG: dropped conditional dep certifi ; extra == 'secure'
DEBUG: dropped conditional dep ipaddress ; (python_version == "2.7") and extra == 'secure'
DEBUG: dropped conditional dep PySocks (!=1.5.7,<2.0,>=1.5.6) ; extra == 'socks'
DEBUG: Finding possible versions for urllib3
DEBUG: ['/home/andrewv/pyvenv/ubuntu/pipgrip-test/bin/python', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--index-url', 'https://pypi.org/simple', '--trusted-host', 'pypi.org', '--progress-bar=off', 'urllib3==rubbish']
DEBUG: {'urllib3': ['0.3', '1.0', '1.0.1', '1.0.2', '1.1', '1.2', '1.2.1', '1.2.2', '1.3', '1.4', '1.5', '1.6', '1.7', '1.7.1', '1.8', '1.8.2', '1.8.3', '1.9', '1.9.1', '1.10', '1.10.1', '1.10.2', '1.10.3', '1.10.4', '1.11', '1.12', '1.13', '1.13.1', '1.14', '1.15', '1.15.1', '1.16', '1.17', '1.18', '1.18.1', '1.19', '1.19.1', '1.20', '1.21', '1.21.1', '1.22', '1.23', '1.24', '1.24.1', '1.24.2', '1.24.3', '1.25', '1.25.1', '1.25.2', '1.25.3', '1.25.4', '1.25.5', '1.25.6', '1.25.7', '1.25.8', '1.25.9', '1.25.10', '1.25.11', '1.26.0', '1.26.1', '1.26.2']}
DEBUG: Downloading/building wheel for python-dateutil<3.0.0,>=2.1
DEBUG: ['/home/andrewv/pyvenv/ubuntu/pipgrip-test/bin/python', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--wheel-dir', '/home/andrewv/.cache/pip/wheels/pipgrip', '--index-url', 'https://pypi.org/simple', '--trusted-host', 'pypi.org', '--progress-bar=off', 'python-dateutil<3.0.0,>=2.1']
DEBUG: {'python-dateutil<3.0.0,>=2.1': '/home/andrewv/.cache/pip/wheels/pipgrip/python_dateutil-2.8.1-py2.py3-none-any.whl'}
DEBUG: Searching metadata in /home/andrewv/.cache/pip/wheels/pipgrip/python_dateutil-2.8.1-py2.py3-none-any.whl
DEBUG: Finding possible versions for python-dateutil
DEBUG: ['/home/andrewv/pyvenv/ubuntu/pipgrip-test/bin/python', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--index-url', 'https://pypi.org/simple', '--trusted-host', 'pypi.org', '--progress-bar=off', 'python-dateutil==rubbish']
DEBUG: {'python-dateutil': ['1.4', '1.4.1', '1.5', '2.1', '2.2', '2.3', '2.4.0', '2.4.1', '2.4.2', '2.5.0', '2.5.1', '2.5.2', '2.5.3', '2.6.0', '2.6.1', '2.7.0', '2.7.1', '2.7.2', '2.7.3', '2.7.4', '2.7.5', '2.8.0', '2.8.1']}
DEBUG: Downloading/building wheel for jmespath<1.0.0,>=0.7.1
DEBUG: ['/home/andrewv/pyvenv/ubuntu/pipgrip-test/bin/python', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--wheel-dir', '/home/andrewv/.cache/pip/wheels/pipgrip', '--index-url', 'https://pypi.org/simple', '--trusted-host', 'pypi.org', '--progress-bar=off', 'jmespath<1.0.0,>=0.7.1']
DEBUG: {'jmespath<1.0.0,>=0.7.1': '/home/andrewv/.cache/pip/wheels/pipgrip/jmespath-0.10.0-py2.py3-none-any.whl'}
DEBUG: Searching metadata in /home/andrewv/.cache/pip/wheels/pipgrip/jmespath-0.10.0-py2.py3-none-any.whl
DEBUG: Finding possible versions for jmespath
DEBUG: ['/home/andrewv/pyvenv/ubuntu/pipgrip-test/bin/python', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--index-url', 'https://pypi.org/simple', '--trusted-host', 'pypi.org', '--progress-bar=off', 'jmespath==rubbish']
DEBUG: {'jmespath': ['0.0.1', '0.0.2', '0.0.3', '0.1.0', '0.2.0', '0.2.1', '0.3.0', '0.3.1', '0.4.0', '0.4.1', '0.5.0', '0.6.0', '0.6.1', '0.6.2', '0.7.0', '0.7.1', '0.8.0', '0.9.0', '0.9.1', '0.9.2', '0.9.3', '0.9.4', '0.9.5', '0.10.0']}
DEBUG: Downloading/building wheel for docutils<0.16,>=0.10
DEBUG: ['/home/andrewv/pyvenv/ubuntu/pipgrip-test/bin/python', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--wheel-dir', '/home/andrewv/.cache/pip/wheels/pipgrip', '--index-url', 'https://pypi.org/simple', '--trusted-host', 'pypi.org', '--progress-bar=off', 'docutils<0.16,>=0.10']
DEBUG: {'docutils<0.16,>=0.10': '/home/andrewv/.cache/pip/wheels/pipgrip/docutils-0.15.2-py3-none-any.whl'}
DEBUG: Searching metadata in /home/andrewv/.cache/pip/wheels/pipgrip/docutils-0.15.2-py3-none-any.whl
DEBUG: Finding possible versions for docutils
DEBUG: ['/home/andrewv/pyvenv/ubuntu/pipgrip-test/bin/python', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--index-url', 'https://pypi.org/simple', '--trusted-host', 'pypi.org', '--progress-bar=off', 'docutils==rubbish']
DEBUG: {'docutils': ['0.3', '0.3.5', '0.3.7', '0.3.9', '0.4', '0.5', '0.6', '0.7', '0.8', '0.8.1', '0.9', '0.9.1', '0.10', '0.11', '0.12', '0.13.1', '0.14', '0.15', '0.15.2', '0.16']}
INFO: selecting docutils (0.15.2)
INFO: selecting jmespath (0.10.0)
INFO: fact: python-dateutil (2.8.1) depends on six (>=1.5)
INFO: selecting python-dateutil (2.8.1)
INFO: derived: six (>=1.5)
DEBUG: Downloading/building wheel for six>=1.5
DEBUG: ['/home/andrewv/pyvenv/ubuntu/pipgrip-test/bin/python', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--wheel-dir', '/home/andrewv/.cache/pip/wheels/pipgrip', '--index-url', 'https://pypi.org/simple', '--trusted-host', 'pypi.org', '--progress-bar=off', 'six>=1.5']
DEBUG: {'six>=1.5': '/home/andrewv/.cache/pip/wheels/pipgrip/six-1.15.0-py2.py3-none-any.whl'}
DEBUG: Searching metadata in /home/andrewv/.cache/pip/wheels/pipgrip/six-1.15.0-py2.py3-none-any.whl
DEBUG: Finding possible versions for six
DEBUG: ['/home/andrewv/pyvenv/ubuntu/pipgrip-test/bin/python', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--index-url', 'https://pypi.org/simple', '--trusted-host', 'pypi.org', '--progress-bar=off', 'six==rubbish']
DEBUG: {'six': ['0.9.0', '0.9.1', '0.9.2', '1.0.0', '1.1.0', '1.2.0', '1.3.0', '1.4.0', '1.4.1', '1.5.0', '1.5.1', '1.5.2', '1.6.0', '1.6.1', '1.7.0', '1.7.1', '1.7.2', '1.7.3', '1.8.0', '1.9.0', '1.10.0', '1.11.0', '1.12.0', '1.13.0', '1.14.0', '1.15.0']}
INFO: selecting six (1.15.0)
INFO: selecting urllib3 (1.25.11)
INFO: fact: boto3 (1.10.49) depends on botocore (>=1.13.49,<1.14.0)
INFO: fact: boto3 (1.10.49) depends on jmespath (<1.0.0,>=0.7.1)
INFO: fact: boto3 (1.10.49) depends on s3transfer (>=0.2.0,<0.3.0)
INFO: derived: not boto3 (1.10.49)
DEBUG: Downloading/building wheel for boto3==1.10.48
DEBUG: ['/home/andrewv/pyvenv/ubuntu/pipgrip-test/bin/python', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--wheel-dir', '/home/andrewv/.cache/pip/wheels/pipgrip', '--index-url', 'https://pypi.org/simple', '--trusted-host', 'pypi.org', '--progress-bar=off', 'boto3==1.10.48']
DEBUG: {'boto3==1.10.48': '/home/andrewv/.cache/pip/wheels/pipgrip/boto3-1.10.48-py2.py3-none-any.whl'}
DEBUG: Searching metadata in /home/andrewv/.cache/pip/wheels/pipgrip/boto3-1.10.48-py2.py3-none-any.whl
DEBUG: Finding possible versions for boto3
DEBUG: ['/home/andrewv/pyvenv/ubuntu/pipgrip-test/bin/python', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--index-url', 'https://pypi.org/simple', '--trusted-host', 'pypi.org', '--progress-bar=off', 'boto3==rubbish']
DEBUG: {'boto3': ['0.0.1', '0.0.2', '0.0.3', '0.0.4', '0.0.5', '0.0.6', '0.0.7', '0.0.8', '0.0.9', '0.0.10', '0.0.11', '0.0.12', '0.0.13', '0.0.14', '0.0.16', '0.0.17', '0.0.18', '0.0.19', '0.0.20', '0.0.21', '0.0.22', '1.0.0', '1.0.1', '1.1.0', '1.1.1', '1.1.2', '1.1.3', '1.1.4', '1.2.0', '1.2.1', '1.2.2', '1.2.3', '1.2.4', '1.2.5', '1.2.6', '1.3.0', '1.3.1', '1.4.0', '1.4.1', '1.4.2', '1.4.3', '1.4.4', '1.4.5', '1.4.6', '1.4.7', '1.4.8', '1.5.0', '1.5.1', '1.5.2', '1.5.3', '1.5.4', '1.5.5', '1.5.6', '1.5.7', '1.5.8', '1.5.9', '1.5.10', '1.5.11', '1.5.12', '1.5.13', '1.5.14', '1.5.15', '1.5.16', '1.5.17', '1.5.18', '1.5.19', '1.5.20', '1.5.21', '1.5.22', '1.5.23', '1.5.24', '1.5.25', '1.5.26', '1.5.27', '1.5.28', '1.5.29', '1.5.30', '1.5.31', '1.5.32', '1.5.33', '1.5.34', '1.5.35', '1.5.36', '1.6.0', '1.6.1', '1.6.2', '1.6.3', '1.6.4', '1.6.5', '1.6.6', '1.6.7', '1.6.8', '1.6.9', '1.6.10', '1.6.11', '1.6.12', '1.6.13', '1.6.14', '1.6.15', '1.6.16', '1.6.17', '1.6.18', '1.6.19', '1.6.20', '1.6.21', '1.6.22', '1.6.23', '1.7.0', '1.7.1', '1.7.2', '1.7.3', '1.7.4', '1.7.5', '1.7.6', '1.7.7', '1.7.8', '1.7.9', '1.7.10', '1.7.11', '1.7.12', '1.7.13', '1.7.14', '1.7.15', '1.7.16', '1.7.17', '1.7.18', '1.7.19', '1.7.20', '1.7.21', '1.7.22', '1.7.23', '1.7.24', '1.7.25', '1.7.26', '1.7.27', '1.7.28', '1.7.29', '1.7.30', '1.7.31', '1.7.32', '1.7.33', '1.7.34', '1.7.35', '1.7.36', '1.7.37', '1.7.38', '1.7.39', '1.7.40', '1.7.41', '1.7.42', '1.7.43', '1.7.44', '1.7.45', '1.7.46', '1.7.47', '1.7.48', '1.7.49', '1.7.50', '1.7.51', '1.7.52', '1.7.53', '1.7.54', '1.7.55', '1.7.56', '1.7.57', '1.7.58', '1.7.59', '1.7.60', '1.7.61', '1.7.62', '1.7.63', '1.7.64', '1.7.65', '1.7.66', '1.7.67', '1.7.68', '1.7.69', '1.7.70', '1.7.71', '1.7.72', '1.7.73', '1.7.74', '1.7.75', '1.7.76', '1.7.77', '1.7.78', '1.7.79', '1.7.80', '1.7.81', '1.7.82', '1.7.83', '1.7.84', '1.8.0', '1.8.1', '1.8.2', '1.8.3', '1.8.4', '1.8.5', '1.8.6', '1.8.7', '1.8.8', '1.8.9', '1.9.0', '1.9.1', '1.9.2', '1.9.3', '1.9.4', '1.9.5', '1.9.6', '1.9.7', '1.9.8', '1.9.9', '1.9.10', '1.9.11', '1.9.12', '1.9.13', '1.9.14', '1.9.15', '1.9.16', '1.9.17', '1.9.18', '1.9.19', '1.9.20', '1.9.21', '1.9.22', '1.9.23', '1.9.24', '1.9.25', '1.9.26', '1.9.27', '1.9.28', '1.9.29', '1.9.30', '1.9.31', '1.9.32', '1.9.33', '1.9.34', '1.9.35', '1.9.36', '1.9.37', '1.9.38', '1.9.39', '1.9.40', '1.9.41', '1.9.42', '1.9.43', '1.9.44', '1.9.45', '1.9.46', '1.9.47', '1.9.48', '1.9.49', '1.9.50', '1.9.51', '1.9.52', '1.9.53', '1.9.54', '1.9.55', '1.9.56', '1.9.57', '1.9.58', '1.9.59', '1.9.60', '1.9.61', '1.9.62', '1.9.63', '1.9.64', '1.9.65', '1.9.66', '1.9.67', '1.9.68', '1.9.69', '1.9.70', '1.9.71', '1.9.72', '1.9.73', '1.9.74', '1.9.75', '1.9.76', '1.9.77', '1.9.78', '1.9.79', '1.9.80', '1.9.81', '1.9.82', '1.9.83', '1.9.84', '1.9.85', '1.9.86', '1.9.87', '1.9.88', '1.9.89', '1.9.90', '1.9.91', '1.9.92', '1.9.93', '1.9.94', '1.9.95', '1.9.96', '1.9.97', '1.9.98', '1.9.99', '1.9.100', '1.9.101', '1.9.102', '1.9.103', '1.9.104', '1.9.105', '1.9.106', '1.9.107', '1.9.108', '1.9.109', '1.9.110', '1.9.111', '1.9.112', '1.9.113', '1.9.114', '1.9.115', '1.9.116', '1.9.117', '1.9.118', '1.9.119', '1.9.120', '1.9.121', '1.9.122', '1.9.123', '1.9.124', '1.9.125', '1.9.126', '1.9.127', '1.9.128', '1.9.129', '1.9.130', '1.9.131', '1.9.132', '1.9.133', '1.9.134', '1.9.135', '1.9.136', '1.9.137', '1.9.138', '1.9.139', '1.9.140', '1.9.141', '1.9.142', '1.9.143', '1.9.144', '1.9.145', '1.9.146', '1.9.147', '1.9.148', '1.9.149', '1.9.150', '1.9.151', '1.9.152', '1.9.153', '1.9.154', '1.9.155', '1.9.156', '1.9.157', '1.9.158', '1.9.159', '1.9.160', '1.9.161', '1.9.162', '1.9.163', '1.9.164', '1.9.165', '1.9.166', '1.9.167', '1.9.168', '1.9.169', '1.9.170', '1.9.171', '1.9.172', '1.9.173', '1.9.174', '1.9.175', '1.9.176', '1.9.177', '1.9.178', '1.9.179', '1.9.180', '1.9.181', '1.9.182', '1.9.183', '1.9.184', '1.9.185', '1.9.186', '1.9.187', '1.9.188', '1.9.189', '1.9.190', '1.9.191', '1.9.192', '1.9.193', '1.9.194', '1.9.195', '1.9.196', '1.9.197', '1.9.198', '1.9.199', '1.9.200', '1.9.201', '1.9.202', '1.9.203', '1.9.204', '1.9.205', '1.9.206', '1.9.207', '1.9.208', '1.9.209', '1.9.210', '1.9.211', '1.9.212', '1.9.213', '1.9.214', '1.9.215', '1.9.216', '1.9.217', '1.9.218', '1.9.219', '1.9.220', '1.9.221', '1.9.222', '1.9.223', '1.9.224', '1.9.225', '1.9.226', '1.9.227', '1.9.228', '1.9.229', '1.9.230', '1.9.231', '1.9.232', '1.9.233', '1.9.234', '1.9.235', '1.9.236', '1.9.237', '1.9.238', '1.9.239', '1.9.240', '1.9.241', '1.9.242', '1.9.243', '1.9.244', '1.9.245', '1.9.246', '1.9.247', '1.9.248', '1.9.249', '1.9.250', '1.9.251', '1.9.252', '1.9.253', '1.10.0', '1.10.1', '1.10.2', '1.10.3', '1.10.4', '1.10.5', '1.10.6', '1.10.7', '1.10.8', '1.10.9', '1.10.10', '1.10.11', '1.10.12', '1.10.13', '1.10.14', '1.10.15', '1.10.16', '1.10.17', '1.10.18', '1.10.19', '1.10.20', '1.10.21', '1.10.22', '1.10.23', '1.10.24', '1.10.25', '1.10.26', '1.10.27', '1.10.28', '1.10.29', '1.10.30', '1.10.31', '1.10.32', '1.10.33', '1.10.34', '1.10.35', '1.10.36', '1.10.37', '1.10.38', '1.10.39', '1.10.40', '1.10.41', '1.10.42', '1.10.43', '1.10.44', '1.10.45', '1.10.46', '1.10.47', '1.10.48', '1.10.49', '1.10.50', '1.11.0', '1.11.1', '1.11.2', '1.11.3', '1.11.4', '1.11.5', '1.11.6', '1.11.7', '1.11.8', '1.11.9', '1.11.10', '1.11.11', '1.11.12', '1.11.13', '1.11.14', '1.11.15', '1.11.16', '1.11.17', '1.12.0', '1.12.1', '1.12.2', '1.12.3', '1.12.4', '1.12.5', '1.12.6', '1.12.7', '1.12.8', '1.12.9', '1.12.10', '1.12.11', '1.12.12', '1.12.13', '1.12.14', '1.12.15', '1.12.16', '1.12.17', '1.12.18', '1.12.19', '1.12.20', '1.12.21', '1.12.22', '1.12.23', '1.12.24', '1.12.25', '1.12.26', '1.12.27', '1.12.28', '1.12.29', '1.12.30', '1.12.31', '1.12.32', '1.12.33', '1.12.34', '1.12.35', '1.12.36', '1.12.37', '1.12.38', '1.12.39', '1.12.40', '1.12.41', '1.12.42', '1.12.43', '1.12.44', '1.12.45', '1.12.46', '1.12.47', '1.12.48', '1.12.49', '1.13.0', '1.13.1', '1.13.2', '1.13.3', '1.13.4', '1.13.5', '1.13.6', '1.13.7', '1.13.8', '1.13.9', '1.13.10', '1.13.11', '1.13.12', '1.13.13', '1.13.14', '1.13.15', '1.13.16', '1.13.17', '1.13.18', '1.13.19', '1.13.20', '1.13.21', '1.13.22', '1.13.23', '1.13.24', '1.13.25', '1.13.26', '1.14.0', '1.14.1', '1.14.2', '1.14.3', '1.14.4', '1.14.5', '1.14.6', '1.14.7', '1.14.8', '1.14.9', '1.14.10', '1.14.11', '1.14.12', '1.14.13', '1.14.14', '1.14.15', '1.14.16', '1.14.17', '1.14.18', '1.14.19', '1.14.20', '1.14.21', '1.14.22', '1.14.23', '1.14.24', '1.14.25', '1.14.26', '1.14.27', '1.14.28', '1.14.29', '1.14.30', '1.14.31', '1.14.32', '1.14.33', '1.14.34', '1.14.35', '1.14.36', '1.14.37', '1.14.38', '1.14.39', '1.14.40', '1.14.41', '1.14.42', '1.14.43', '1.14.44', '1.14.45', '1.14.46', '1.14.47', '1.14.48', '1.14.49', '1.14.50', '1.14.51', '1.14.52', '1.14.53', '1.14.54', '1.14.55', '1.14.56', '1.14.57', '1.14.58', '1.14.59', '1.14.60', '1.14.61', '1.14.62', '1.14.63', '1.15.0', '1.15.1', '1.15.2', '1.15.3', '1.15.4', '1.15.5', '1.15.6', '1.15.7', '1.15.8', '1.15.9', '1.15.10', '1.15.11', '1.15.12', '1.15.13', '1.15.14', '1.15.15', '1.15.16', '1.15.17', '1.15.18', '1.16.0', '1.16.1', '1.16.2', '1.16.3', '1.16.4', '1.16.5', '1.16.6', '1.16.7', '1.16.8', '1.16.9', '1.16.10', '1.16.11', '1.16.12', '1.16.13', '1.16.14', '1.16.15', '1.16.16', '1.16.17', '1.16.18', '1.16.19', '1.16.20', '1.16.21', '1.16.22', '1.16.23', '1.16.24', '1.16.25', '1.16.26', '1.16.27', '1.16.28', '1.16.29', '1.16.30', '1.16.31', '1.16.32', '1.16.33', '1.16.34']}
INFO: fact: boto3 (1.10.48) depends on botocore (>=1.13.48,<1.14.0)
INFO: fact: boto3 (1.10.48) depends on jmespath (<1.0.0,>=0.7.1)
INFO: fact: boto3 (1.10.48) depends on s3transfer (>=0.2.0,<0.3.0)
INFO: selecting boto3 (1.10.48)
INFO: derived: s3transfer (>=0.2.0,<0.3.0)
DEBUG: Downloading/building wheel for s3transfer<0.3.0,>=0.2.0
DEBUG: ['/home/andrewv/pyvenv/ubuntu/pipgrip-test/bin/python', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--wheel-dir', '/home/andrewv/.cache/pip/wheels/pipgrip', '--index-url', 'https://pypi.org/simple', '--trusted-host', 'pypi.org', '--progress-bar=off', 's3transfer<0.3.0,>=0.2.0']
DEBUG: {'s3transfer<0.3.0,>=0.2.0': '/home/andrewv/.cache/pip/wheels/pipgrip/s3transfer-0.2.1-py2.py3-none-any.whl'}
DEBUG: Searching metadata in /home/andrewv/.cache/pip/wheels/pipgrip/s3transfer-0.2.1-py2.py3-none-any.whl
DEBUG: dropped conditional dep futures>=2.2.0,<4.0.0; python_version=="2.6" or python_version=="2.7"
DEBUG: Finding possible versions for s3transfer
DEBUG: ['/home/andrewv/pyvenv/ubuntu/pipgrip-test/bin/python', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--index-url', 'https://pypi.org/simple', '--trusted-host', 'pypi.org', '--progress-bar=off', 's3transfer==rubbish']
DEBUG: {'s3transfer': ['0.0.1', '0.1.0', '0.1.1', '0.1.2', '0.1.3', '0.1.4', '0.1.5', '0.1.6', '0.1.7', '0.1.8', '0.1.9', '0.1.10', '0.1.11', '0.1.12', '0.1.13', '0.2.0', '0.2.1', '0.3.0', '0.3.1', '0.3.2', '0.3.3']}
INFO: fact: s3transfer (0.2.1) depends on botocore (>=1.12.36,<2.0.0)
INFO: selecting s3transfer (0.2.1)
INFO: Version solving took 7.335 seconds.
INFO: Tried 1 solutions.
DEBUG: OrderedDict([(Package("botocore"), <Version 1.13.48>), (Package("docutils"), <Version 0.15.2>), (Package("jmespath"), <Version 0.10.0>), (Package("python-dateutil"), <Version 2.8.1>), (Package("six"), <Version 1.15.0>), (Package("urllib3"), <Version 1.25.11>), (Package("boto3"), <Version 1.10.48>), (Package("s3transfer"), <Version 0.2.1>)])
botocore==1.13.48 (1.13.48)
├── docutils<0.16,>=0.10 (0.15.2)
├── jmespath<1.0.0,>=0.7.1 (0.10.0)
├── python-dateutil<3.0.0,>=2.1 (2.8.1)
│   └── six>=1.5 (1.15.0)
└── urllib3<1.26,>=1.20 (1.25.11)
boto3<1.10.50,>=1.10 (1.10.48)
├── botocore<1.14.0,>=1.13.48 (1.13.48)
│   ├── docutils<0.16,>=0.10 (0.15.2)
│   ├── jmespath<1.0.0,>=0.7.1 (0.10.0)
│   ├── python-dateutil<3.0.0,>=2.1 (2.8.1)
│   │   └── six>=1.5 (1.15.0)
│   └── urllib3<1.26,>=1.20 (1.25.11)
├── jmespath<1.0.0,>=0.7.1 (0.10.0)
└── s3transfer<0.3.0,>=0.2.0 (0.2.1)
    └── botocore<2.0.0,>=1.12.36 (1.13.48)
        ├── docutils<0.16,>=0.10 (0.15.2)
        ├── jmespath<1.0.0,>=0.7.1 (0.10.0)
        ├── python-dateutil<3.0.0,>=2.1 (2.8.1)
        │   └── six>=1.5 (1.15.0)
        └── urllib3<1.26,>=1.20 (1.25.11)

I can pin at 20.2.4 as a workaround for now. I don't know if pip or pipgrip is the issue.

Thanks

pipgrip selects yanked verison

What you were trying to do (and why)

pipgrip prefect will select 2.82 which has been yanked.

What happened (including command output)

Command output

$ pipgrip prefect

prefect==2.82
aiosqlite==0.19.0
alembic==1.11.2
mako==1.2.4
markupsafe==2.1.3
sqlalchemy==1.4.49
typing-extensions==4.7.1
anyio==3.7.1
exceptiongroup==1.1.2
idna==3.4
sniffio==1.3.0
apprise==1.4.5
certifi==2023.7.22
click==8.1.6
markdown==3.4.4
pyyaml==6.0.1
requests==2.31.0
charset-normalizer==3.2.0
urllib3==2.0.4
requests-oauthlib==1.3.1
oauthlib==3.2.2
asgi-lifespan==2.1.0
asyncpg==0.28.0
cloudpickle==2.2.1
coolname==2.2.0
croniter==1.4.1
python-dateutil==2.8.2
six==1.16.0
cryptography==41.0.3
cffi==1.15.1
pycparser==2.21
dateparser==1.1.8
pytz==2023.3
regex==2023.8.8
tzlocal==5.0.1
docker==6.1.3
packaging==23.1
websocket-client==1.6.1
fastapi==0.101.0
pydantic==2.1.1
annotated-types==0.5.0
pydantic-core==2.4.0
starlette==0.27.0
fsspec==2023.6.0
griffe==0.32.3
colorama==0.4.6
httpx==0.24.1
h2==4.1.0
hpack==4.0.0
hyperframe==6.0.1
httpcore==0.17.3
h11==0.14.0
jinja2==3.1.2
jsonpatch==1.33
jsonpointer==2.4
jsonschema==4.19.0
attrs==23.1.0
jsonschema-specifications==2023.7.1
referencing==0.30.2
rpds-py==0.9.2
kubernetes==27.2.0
google-auth==2.17.3
cachetools==5.3.1
pyasn1-modules==0.3.0
pyasn1==0.5.0
rsa==4.9
orjson==3.9.4
pathspec==0.11.2
pendulum==2.1.2
pytzdata==2020.1
python-slugify==8.0.1
text-unidecode==1.3
readchar==4.0.5
setuptools==68.0.0
rich==13.5.2
markdown-it-py==3.0.0
mdurl==0.1.2
pygments==2.16.1
greenlet==2.0.2
toml==0.10.2
typer==0.9.0
uvicorn==0.23.2
websockets==11.0.3
$ pip install prefect==2.82
...
WARNING: The candidate selected for download or install is a yanked version: 'prefect' candidate (version 2.82 at https://files.pythonhosted.org/packages/16/e3/4ac0b6e214e4fb315d2032e176eaa33c175e29ff182fe48ac1cabccb30bc/prefect-2.82-py3-none-any.whl (from https://pypi.org/simple/prefect/) (requires-python:>=3.7))
Reason for being yanked: Version number was supposed to be "2.8.2"

What you expected to happen

Yanked versions are ignored

Step-by-step reproduction instructions

pipgrip==0.10.7

Support --tree rendering from requirements.txt

Description

pipgrip --tree -r requirements/base.txt doesn't render a tree. It starts to install packages (and fails, because some dependencies are faulty). It would be nice if it didn't try to install anything unless an explicit --install is given. Or at least show partial dependency tree for specific package before installing it.

Use case / motivation

I am trying to troubleshoot who adds a failing dependency which is not immediately present in requirements.txt.

Skip package versions when wheel fails to build

Description

Currently, when testing multiple versions of a package to find a version that satisfies some dependency constraints, if a single wheel for that package fails to build, it causes pipgrip to exit with a RuntimeError, even if there are more versions left to test. It would be preferable in some situations to just skip or ignore the version which fails to build, and continue trying the remaining versions of the package.

Use case / motivation

In DVC we have a dependency on knack and oss2. knack requires any jmespath, and oss2 requires aliyun-python-sdk-core-v3, which in turn requires jmespath<1.0.0.

The problem is that aliyun-python-sdk-core-v3==2.13.31 on pypi is broken, wheel builds for that version fail due to metadata issue:

$ python -m pip wheel --no-deps --disable-pip-version-check --wheel-dir /tmp/test-pipgrip aliyun-python-sdk-core-v3==2.13.31
Collecting aliyun-python-sdk-core-v3==2.13.31
  Using cached aliyun-python-sdk-core-v3-2.13.31.tar.gz (440 kB)
  Preparing metadata (setup.py) ... done
  WARNING: Generating metadata for package aliyun-python-sdk-core-v3 produced metadata for project name aliyun-python-sdk-core. Fix your #egg=aliyun-python-sdk-core-v3 fragments.
Discarding https://files.pythonhosted.org/packages/13/63/52c2fc00ce2334cef2051548215ae27878b187b819f01876539608752837/aliyun-python-sdk-core-v3-2.13.31.tar.gz#sha256=427f27f420d3d88577788f703e2ee1b2f804e9ce645a2e175dafe9c56d339b3c (from https://pypi.org/simple/aliyun-python-sdk-core-v3/): Requested aliyun-python-sdk-core from https://files.pythonhosted.org/packages/13/63/52c2fc00ce2334cef2051548215ae27878b187b819f01876539608752837/aliyun-python-sdk-core-v3-2.13.31.tar.gz#sha256=427f27f420d3d88577788f703e2ee1b2f804e9ce645a2e175dafe9c56d339b3c has inconsistent name: filename has 'aliyun-python-sdk-core-v3', but metadata has 'aliyun-python-sdk-core'
ERROR: Could not find a version that satisfies the requirement aliyun-python-sdk-core-v3==2.13.31 (from versions: 2.3.2, 2.3.3, 2.3.4, 2.3.5, 2.3.6, 2.3.7, 2.4.0, 2.4.1, 2.4.2, 2.4.3, 2.4.4, 2.5.0, 2.5.1, 2.5.2, 2.5.3, 2.5.4, 2.5.5, 2.7.2, 2.8.2, 2.8.3, 2.8.4, 2.8.5, 2.8.6, 2.8.7, 2.8.8, 2.8.9, 2.9.0, 2.9.1, 2.9.3, 2.9.4, 2.10.1, 2.11.0, 2.11.1, 2.11.4, 2.11.5, 2.12.1, 2.13.0, 2.13.3, 2.13.8, 2.13.9, 2.13.10, 2.13.11, 2.13.31, 2.13.32, 2.13.33)
ERROR: No matching distribution found for aliyun-python-sdk-core-v3==2.13.31

This is fixed in subsequent package versions, but for whatever reason the aliyun maintainers did not remove the 2.13.31 release from pypi.

In pipgrip, this build failure causes pipgrip to exit when trying to find a compatible match between jmespath and aliyun-python-sdk-core-v3:

$ pipgrip jmespath aliyun-python-sdk-core-v3 -vv
INFO: discovering jmespath
INFO: discovering aliyun-python-sdk-core-v3
INFO: fact: _root_ is root
INFO: derived: root
INFO: fact: root depends on jmespath (*)
INFO: fact: root depends on aliyun-python-sdk-core-v3 (*)
INFO: selecting _root_ (0.0.0)
INFO: derived: aliyun-python-sdk-core-v3 (*)
INFO: derived: jmespath (*)
INFO: selecting jmespath (1.0.0)
INFO: fact: aliyun-python-sdk-core-v3 (2.13.33) depends on cryptography (>=2.6.0)
INFO: fact: aliyun-python-sdk-core-v3 (2.13.33) depends on jmespath (<1.0.0,>=0.9.3)
INFO: derived: not aliyun-python-sdk-core-v3 (2.13.33)
INFO: discovering aliyun-python-sdk-core-v3==2.13.32
INFO: fact: aliyun-python-sdk-core-v3 (2.13.32) depends on cryptography (>=2.6.0)
INFO: fact: aliyun-python-sdk-core-v3 (2.13.32) depends on jmespath (<1.0.0,>=0.9.3)
INFO: derived: not aliyun-python-sdk-core-v3 (2.13.32)
INFO: discovering aliyun-python-sdk-core-v3==2.13.31
ERROR: Downloading/building wheel for aliyun-python-sdk-core-v3==2.13.31 failed with output:
Collecting aliyun-python-sdk-core-v3==2.13.31
  Using cached aliyun-python-sdk-core-v3-2.13.31.tar.gz (440 kB)
  Preparing metadata (setup.py): started
  Preparing metadata (setup.py): finished with status 'done'
  WARNING: Generating metadata for package aliyun-python-sdk-core-v3 produced metadata for project name aliyun-python-sdk-core. Fix your #egg=aliyun-python-sdk-core-v3 fragments.
...
ERROR: Could not find a version that satisfies the requirement aliyun-python-sdk-core-v3==2.13.31 (from versions: 2.3.2, 2.3.3, 2.3.4, 2.3.5, 2.3.6, 2.3.7, 2.4.0, 2.4.1, 2.4.2, 2.4.3, 2.4.4, 2.5.0, 2.5.1, 2.5.2, 2.5.3, 2.5.4, 2.5.5, 2.7.2, 2.8.2, 2.8.3, 2.8.4, 2.8.5, 2.8.6, 2.8.7, 2.8.8, 2.8.9, 2.9.0, 2.9.1, 2.9.3, 2.9.4, 2.10.1, 2.11.0, 2.11.1, 2.11.4, 2.11.5, 2.12.1, 2.13.0, 2.13.3, 2.13.8, 2.13.9, 2.13.10, 2.13.11, 2.13.31, 2.13.32, 2.13.33)
ERROR: No matching distribution found for aliyun-python-sdk-core-v3==2.13.31
Traceback (most recent call last):
  File "/opt/homebrew/Cellar/pipgrip/0.7.2/libexec/lib/python3.10/site-packages/pipgrip/pipper.py", line 258, in _download_wheel
    out = stream_bash_command(args)
  File "/opt/homebrew/Cellar/pipgrip/0.7.2/libexec/lib/python3.10/site-packages/pipgrip/pipper.py", line 91, in stream_bash_command
    raise subprocess.CalledProcessError(return_code, bash_command, output=out)
subprocess.CalledProcessError: Command '['/opt/homebrew/Cellar/pipgrip/0.7.2/libexec/bin/python3.10', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--wheel-dir', '/Users/pmrowla/Library/Caches/pip/wheels/pipgrip', '--progress-bar=off', 'aliyun-python-sdk-core-v3==2.13.31']' returned non-zero exit status 1.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/opt/homebrew/bin/pipgrip", line 33, in <module>
    sys.exit(load_entry_point('pipgrip==0.7.2', 'console_scripts', 'pipgrip')())
...
  File "/opt/homebrew/Cellar/pipgrip/0.7.2/libexec/lib/python3.10/site-packages/pipgrip/pipper.py", line 414, in discover_dependencies_and_versions
    wheel_fname = _download_wheel(
  File "/opt/homebrew/Cellar/pipgrip/0.7.2/libexec/lib/python3.10/site-packages/pipgrip/pipper.py", line 266, in _download_wheel
    raise RuntimeError("Failed to download/build wheel for {}".format(package))
RuntimeError: Failed to download/build wheel for aliyun-python-sdk-core-v3==2.13.31

If you manually exclude the offending version, pipgrip successfully iterates over the available aliyun-python-sdk-core-v3 releases and eventually finds a version that succeeds:

$ pipgrip jmespath "aliyun-python-sdk-core-v3!=2.13.31" -vv
INFO: discovering jmespath
INFO: discovering aliyun-python-sdk-core-v3!=2.13.31
INFO: fact: _root_ is root
INFO: derived: root
INFO: fact: root depends on jmespath (*)
INFO: fact: root depends on aliyun-python-sdk-core-v3 (<2.13.31 || >2.13.31)
INFO: selecting _root_ (0.0.0)
INFO: derived: aliyun-python-sdk-core-v3 (<2.13.31 || >2.13.31)
INFO: derived: jmespath (*)
INFO: selecting jmespath (1.0.0)
INFO: fact: aliyun-python-sdk-core-v3 (2.13.33) depends on cryptography (>=2.6.0)
INFO: fact: aliyun-python-sdk-core-v3 (2.13.33) depends on jmespath (>=0.9.3,<1.0.0)
INFO: derived: not aliyun-python-sdk-core-v3 (2.13.33)
INFO: discovering aliyun-python-sdk-core-v3==2.13.32
INFO: fact: aliyun-python-sdk-core-v3 (2.13.32) depends on cryptography (>=2.6.0)
INFO: fact: aliyun-python-sdk-core-v3 (2.13.32) depends on jmespath (>=0.9.3,<1.0.0)
INFO: derived: not aliyun-python-sdk-core-v3 (2.13.32)
INFO: discovering aliyun-python-sdk-core-v3==2.13.11
INFO: fact: aliyun-python-sdk-core-v3 (2.13.11) depends on jmespath (>=0.9.3,<1.0.0)
INFO: fact: aliyun-python-sdk-core-v3 (2.13.11) depends on pycryptodome (>=3.4.7)
INFO: derived: not aliyun-python-sdk-core-v3 (2.13.11)
INFO: discovering aliyun-python-sdk-core-v3==2.13.10
...
INFO: discovering aliyun-python-sdk-core-v3==2.11.5
INFO: fact: aliyun-python-sdk-core-v3 (2.11.5) depends on pycryptodome (>=3.4.7)
INFO: selecting aliyun-python-sdk-core-v3 (2.11.5)
INFO: derived: pycryptodome (>=3.4.7)
INFO: discovering pycryptodome>=3.4.7
INFO: selecting pycryptodome (3.14.1)
INFO: Version solving took 3.027 seconds.
INFO: Tried 1 solutions.
jmespath==1.0.0
aliyun-python-sdk-core-v3==2.11.5
pycryptodome==3.14.1

The end result is that in DVC, we cannot use any of homebrew's utilities for auto-updating brew recipes (since brew update-python-resources depends on pipgrip)

We can work around this by excluding the offending versions ourselves in DVC, but ideally pipgrip would just drop versions where the wheel fails to build and continue testing other versions (if any are available)

Related Issues

Subprocess error, looking for attrdict module but not finding it

What you were trying to do (and why)

Have pipgrip executed to find a package dependencies (it was actually run by homebrew, but I could reproduce it directly by myself after with a setup right from PyPI inside a venv)

What happened (including command output)

It crashed and raised an exception on this specific module (other modules didn't encounter issues).

Command output

$ pipgrip -vvv wxPython==4.2.0
DEBUG: environment: {'implementation_name': 'cpython', 'implementation_version': '3.10.5', 'os_name': 'posix', 'platform_machine': 'x86_64', 'platform_release': '5.18.12-arch1-1', 'platform_system': 'Linux', 'platform_version': '#1 SMP PREEMPT_DYNAMIC Fri, 15 Jul 2022 15:33:02 +0000', 'python_full_version': '3.10.5', 'platform_python_implementation': 'CPython', 'python_version': '3.10', 'sys_platform': 'linux'}
DEBUG: pip version: [22, 0, 4]
DEBUG: pipgrip version: 0.8.5
INFO: discovering wxpython==4.2.0
DEBUG: Downloading/building wheel for wxpython==4.2.0 into cache_dir /home/clement/.cache/pip/wheels/pipgrip
DEBUG: ['/tmp/test_pipgrip/.venv/bin/python', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--wheel-dir', '/home/clement/.cache/pip/wheels/pipgrip', '--progress-bar=off', 'wxpython==4.2.0']
ERROR: Downloading/building wheel for wxpython==4.2.0 failed with output:
Collecting wxpython==4.2.0
  Using cached wxPython-4.2.0.tar.gz (71.0 MB)
  Preparing metadata (setup.py): started
  Preparing metadata (setup.py): finished with status 'error'
  error: subprocess-exited-with-error

  × python setup.py egg_info did not run successfully.
  │ exit code: 1
  ╰─> [8 lines of output]
      Traceback (most recent call last):
        File "<string>", line 2, in <module>
        File "<pip-setuptools-caller>", line 34, in <module>
        File "/tmp/pip-wheel-f1dil03u/wxpython_d801786558cd4c0c93537ec795e53f1a/setup.py", line 27, in <module>
          from buildtools.config import Config, msg, opj, runcmd, canGetSOName, getSOName
        File "/tmp/pip-wheel-f1dil03u/wxpython_d801786558cd4c0c93537ec795e53f1a/buildtools/config.py", line 30, in <module>
          from attrdict import AttrDict
      ModuleNotFoundError: No module named 'attrdict'
      [end of output]

  note: This error originates from a subprocess, and is likely not a problem with pip.
error: metadata-generation-failed

× Encountered error while generating package metadata.
╰─> See above for output.

note: This is an issue with the package mentioned above, not pip.
hint: See above for details.
Traceback (most recent call last):
  File "/tmp/test_pipgrip/.venv/lib/python3.10/site-packages/pipgrip/pipper.py", line 258, in _download_wheel
    out = stream_bash_command(args)
  File "/tmp/test_pipgrip/.venv/lib/python3.10/site-packages/pipgrip/pipper.py", line 91, in stream_bash_command
    raise subprocess.CalledProcessError(return_code, bash_command, output=out)
subprocess.CalledProcessError: Command '['/tmp/test_pipgrip/.venv/bin/python', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--wheel-dir', '/home/clement/.cache/pip/wheels/pipgrip', '--progress-bar=off', 'wxpython==4.2.0']' returned non-zero exit status 1.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/tmp/test_pipgrip/.venv/bin/pipgrip", line 8, in <module>
    sys.exit(main())
  File "/tmp/test_pipgrip/.venv/lib/python3.10/site-packages/click/core.py", line 1130, in __call__
    return self.main(*args, **kwargs)
  File "/tmp/test_pipgrip/.venv/lib/python3.10/site-packages/click/core.py", line 1055, in main
    rv = self.invoke(ctx)
  File "/tmp/test_pipgrip/.venv/lib/python3.10/site-packages/click/core.py", line 1404, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/tmp/test_pipgrip/.venv/lib/python3.10/site-packages/click/core.py", line 760, in invoke
    return __callback(*args, **kwargs)
  File "/tmp/test_pipgrip/.venv/lib/python3.10/site-packages/pipgrip/cli.py", line 430, in main
    source.root_dep(root_dependency)
  File "/tmp/test_pipgrip/.venv/lib/python3.10/site-packages/pipgrip/package_source.py", line 160, in root_dep
    self.discover_and_add(req.__str__())
  File "/tmp/test_pipgrip/.venv/lib/python3.10/site-packages/pipgrip/package_source.py", line 133, in discover_and_add
    to_create = discover_dependencies_and_versions(
  File "/tmp/test_pipgrip/.venv/lib/python3.10/site-packages/pipgrip/pipper.py", line 414, in discover_dependencies_and_versions
    wheel_fname = _download_wheel(
  File "/tmp/test_pipgrip/.venv/lib/python3.10/site-packages/pipgrip/pipper.py", line 266, in _download_wheel
    raise RuntimeError("Failed to download/build wheel for {}".format(package))
RuntimeError: Failed to download/build wheel for wxpython==4.2.0

What you expected to happen

Don't get an exception and list correctly the dependencies

Step-by-step reproduction instructions

Just call pipgrip wxPython==4.2.0.

VCS requirement sometimes triggers panic

What you were trying to do (and why)

VCS requirement sometimes triggers a bug when building conflict message

# fine
pipgrip -vvv msrest==0.7.1 requests[socks]@git+https://github.com/psf/requests
# fine
pipgrip -vvv msrest==0.7.1 pypicloud[azure-blob] requests[socks]@git+https://github.com/psf/requests
# panic
pipgrip -vvv pypicloud[azure-blob]==1.3.8 requests[socks]@git+https://github.com/psf/[email protected]

What happened (including command output)

Command output

$ pipgrip -vvv pypicloud[azure-blob]==1.3.8 requests[socks]@git+https://github.com/psf/[email protected]
...
INFO: fact: no versions of pyramid match >2.0
INFO: conflict: no versions of pyramid match >2.0
INFO: ! pyramid (>2.0) is partially satisfied by not pyramid (2.0)
INFO: ! which is caused by "pyramid (2.0) depends on zope-interface (>=3.8.0)"
INFO: ! thus: pyramid (>=2.0) requires zope-interface (>=3.8.0)
Traceback (most recent call last):
  File "/usr/local/bin/pipgrip", line 33, in <module>
    sys.exit(load_entry_point('pipgrip', 'console_scripts', 'pipgrip')())
  File "/Users/ddelange/.pyenv/versions/3.8.10/envs/vv/lib/python3.8/site-packages/click/core.py", line 1130, in __call__
    return self.main(*args, **kwargs)
  File "/Users/ddelange/.pyenv/versions/3.8.10/envs/vv/lib/python3.8/site-packages/click/core.py", line 1055, in main
    rv = self.invoke(ctx)
  File "/Users/ddelange/.pyenv/versions/3.8.10/envs/vv/lib/python3.8/site-packages/click/core.py", line 1404, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/Users/ddelange/.pyenv/versions/3.8.10/envs/vv/lib/python3.8/site-packages/click/core.py", line 760, in invoke
    return __callback(*args, **kwargs)
  File "/Users/ddelange/git/pipgrip/src/pipgrip/cli.py", line 440, in main
    solution = solver.solve()
  File "/Users/ddelange/git/pipgrip/src/pipgrip/libs/mixology/version_solver.py", line 69, in solve
    if not self._run():
  File "/Users/ddelange/git/pipgrip/src/pipgrip/libs/mixology/version_solver.py", line 86, in _run
    self._propagate(next_package)
  File "/Users/ddelange/git/pipgrip/src/pipgrip/libs/mixology/version_solver.py", line 119, in _propagate
    root_cause = self._resolve_conflict(incompatibility)
  File "/Users/ddelange/git/pipgrip/src/pipgrip/libs/mixology/version_solver.py", line 219, in _resolve_conflict
    satisfier = self._solution.satisfier(term)
  File "/Users/ddelange/git/pipgrip/src/pipgrip/libs/mixology/partial_solution.py", line 203, in satisfier
    raise RuntimeError("[BUG] {} is not satisfied.".format(term))
RuntimeError: [BUG] not zope-interface (>=3.8.0) is not satisfied.

What you expected to happen

INFO: fact: msrest (0.7.1) depends on azure-core (>=1.24.0)
INFO: fact: msrest (0.7.1) depends on certifi (>=2017.4.17)
INFO: fact: msrest (0.7.1) depends on isodate (>=0.6.0)
INFO: fact: msrest (0.7.1) depends on requests-oauthlib (>=0.5.0)
INFO: fact: msrest (0.7.1) depends on requests (~=2.16)
INFO: conflict: msrest (0.7.1) depends on requests (~=2.16)
INFO: ! msrest (0.7.1) is satisfied by msrest (==0.7.1)
INFO: ! which is caused by "root depends on msrest (==0.7.1)"
INFO: ! thus: root requires requests (~=2.16)
INFO: ! not requests (~=2.16) is satisfied by requests[socks] (git+https://github.com/psf/requests)
INFO: ! which is caused by "root depends on requests[socks] (git+https://github.com/psf/requests)"
INFO: ! thus: version solving failed
Error: Because root depends on msrest (==0.7.1) which depends on requests (~=2.16), root requires requests (~=2.16).
So, because root depends on requests[socks] (git+https://github.com/psf/requests), version solving failed.

Step-by-step reproduction instructions

Use pre-releases according to PEP 440

It seems that pip does manage to install azure-cli==2.9.1 without needing --pre. Reading PEP 440 it's clear why:

Pre-releases of any kind, including developmental releases, are implicitly excluded from all version specifiers, unless they are already present on the system, explicitly requested by the user, or if the only available version that satisfies the version specifier is a pre-release.

By default, dependency resolution tools SHOULD:

  • accept already installed pre-releases for all version specifiers
  • accept remotely available pre-releases for version specifiers where there is no final or post release that satisfies the version specifier
  • exclude all other pre-releases from consideration

In this case, pipgrep should probably install 7.0.0rc1 as it applies to point 2 above (the pre-release being the only thing that satisfies the requirement).

Originally posted by @jonchang in Homebrew/brew#8059 (comment)

Error when package requires itself

What you were trying to do (and why)

Analyze the dependencies for a requirements.txt file containing jax.

The error can be isolated to the jax dependency etils[epath].

What happened (including command output)

Command output

$ pipgrip -vv --tree jax
INFO: discovering jax
INFO: fact: _root_ is root
INFO: derived: root
INFO: fact: root depends on jax (*)
INFO: selecting _root_ (0.0.0)
INFO: derived: jax (*)
INFO: fact: jax (0.3.16) depends on absl-py (*)
INFO: fact: jax (0.3.16) depends on etils[epath] (*)
INFO: fact: jax (0.3.16) depends on numpy (>=1.20)
INFO: fact: jax (0.3.16) depends on opt-einsum (*)
INFO: fact: jax (0.3.16) depends on scipy (>=1.5)
INFO: fact: jax (0.3.16) depends on typing-extensions (*)
INFO: selecting jax (0.3.16)
INFO: derived: typing-extensions (*)
INFO: derived: scipy (>=1.5)
INFO: derived: opt-einsum (*)
INFO: derived: numpy (>=1.20)
INFO: derived: etils[epath] (*)
INFO: derived: absl-py (*)
INFO: discovering typing-extensions
INFO: discovering scipy>=1.5
INFO: discovering opt-einsum
INFO: discovering numpy>=1.20
INFO: discovering etils[epath]
INFO: discovering absl-py
Traceback (most recent call last):
  File "/home/vagrant/.local/bin/pipgrip", line 8, in <module>
    sys.exit(main())
  File "/usr/lib/python3/dist-packages/click/core.py", line 764, in __call__
    return self.main(*args, **kwargs)
  File "/usr/lib/python3/dist-packages/click/core.py", line 717, in main
    rv = self.invoke(ctx)
  File "/usr/lib/python3/dist-packages/click/core.py", line 956, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/usr/lib/python3/dist-packages/click/core.py", line 555, in invoke
    return callback(*args, **kwargs)
  File "/home/vagrant/.local/lib/python3.8/site-packages/pipgrip/cli.py", line 434, in main
    solution = solver.solve()
  File "/home/vagrant/.local/lib/python3.8/site-packages/pipgrip/libs/mixology/version_solver.py", line 69, in solve
    if not self._run():
  File "/home/vagrant/.local/lib/python3.8/site-packages/pipgrip/libs/mixology/version_solver.py", line 85, in _run
    next_package = self._choose_package_version()
  File "/home/vagrant/.local/lib/python3.8/site-packages/pipgrip/libs/mixology/version_solver.py", line 363, in _choose_package_version
    for incompatibility in self._source.incompatibilities_for(
  File "/home/vagrant/.local/lib/python3.8/site-packages/pipgrip/libs/mixology/package_source.py", line 112, in incompatibilities_for
    incompatibility = Incompatibility(
  File "/home/vagrant/.local/lib/python3.8/site-packages/pipgrip/libs/mixology/incompatibility.py", line 61, in __init__
    assert by_ref[ref] is not None
AssertionError
$ pipgrip -vvv --tree etils[epath]
DEBUG: environment: {'implementation_name': 'cpython', 'implementation_version': '3.8.10', 'os_name': 'posix', 'platform_machine': 'x86_64', 'platform_release': '5.15.0-41-generic', 'platform_system': 'Linux', 'platform_version': '#44~20.04.1-Ubuntu SMP Fri Jun 24 13:27:29 UTC 2022', 'python_full_version': '3.8.10', 'platform_python_implementation': 'CPython', 'python_version': '3.8', 'sys_platform': 'linux'}
DEBUG: pip version: [20, 0, 2]
DEBUG: pipgrip version: 0.8.5
INFO: discovering etils[epath]
DEBUG: Downloading/building wheel for etils[epath] into cache_dir /home/vagrant/.cache/pip/wheels/pipgrip
DEBUG: ['/usr/bin/python3', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--wheel-dir', '/home/vagrant/.cache/pip/wheels/pipgrip', '--progress-bar=off', 'etils[epath]']
DEBUG: {'etils[epath]': '/home/vagrant/.cache/pip/wheels/pipgrip/etils-0.7.1-py3-none-any.whl'}
DEBUG: Searching metadata in /home/vagrant/.cache/pip/wheels/pipgrip/etils-0.7.1-py3-none-any.whl
DEBUG: dropped conditional dep etils[array-types] ; extra == "all"
DEBUG: dropped conditional dep etils[ecolab] ; extra == "all"
DEBUG: dropped conditional dep etils[edc] ; extra == "all"
DEBUG: dropped conditional dep etils[enp] ; extra == "all"
DEBUG: dropped conditional dep etils[epath] ; extra == "all"
DEBUG: dropped conditional dep etils[epy] ; extra == "all"
DEBUG: dropped conditional dep etils[etqdm] ; extra == "all"
DEBUG: dropped conditional dep etils[etree] ; extra == "all"
DEBUG: dropped conditional dep etils[etree-dm] ; extra == "all"
DEBUG: dropped conditional dep etils[etree-jax] ; extra == "all"
DEBUG: dropped conditional dep etils[etree-tf] ; extra == "all"
DEBUG: dropped conditional dep etils[enp] ; extra == "array-types"
DEBUG: dropped conditional dep pytest ; extra == "dev"
DEBUG: dropped conditional dep pytest-subtests ; extra == "dev"
DEBUG: dropped conditional dep pytest-xdist ; extra == "dev"
DEBUG: dropped conditional dep pylint>=2.6.0 ; extra == "dev"
DEBUG: dropped conditional dep yapf ; extra == "dev"
DEBUG: dropped conditional dep chex ; extra == "dev"
DEBUG: dropped conditional dep jupyter ; extra == "ecolab"
DEBUG: dropped conditional dep numpy ; extra == "ecolab"
DEBUG: dropped conditional dep mediapy ; extra == "ecolab"
DEBUG: dropped conditional dep etils[enp] ; extra == "ecolab"
DEBUG: dropped conditional dep etils[epy] ; extra == "ecolab"
DEBUG: dropped conditional dep etils[epy] ; extra == "edc"
DEBUG: dropped conditional dep numpy ; extra == "enp"
DEBUG: dropped conditional dep etils[epy] ; extra == "enp"
DEBUG: included conditional dep importlib_resources ; extra == "epath"
DEBUG: included conditional dep typing_extensions ; extra == "epath"
DEBUG: included conditional dep zipp ; extra == "epath"
DEBUG: included conditional dep etils[epy] ; extra == "epath"
DEBUG: dropped conditional dep typing_extensions ; extra == "epy"
DEBUG: dropped conditional dep absl-py ; extra == "etqdm"
DEBUG: dropped conditional dep tqdm ; extra == "etqdm"
DEBUG: dropped conditional dep etils[epy] ; extra == "etqdm"
DEBUG: dropped conditional dep etils[array_types] ; extra == "etree"
DEBUG: dropped conditional dep etils[epy] ; extra == "etree"
DEBUG: dropped conditional dep etils[enp] ; extra == "etree"
DEBUG: dropped conditional dep etils[etqdm] ; extra == "etree"
DEBUG: dropped conditional dep dm-tree ; extra == "etree-dm"
DEBUG: dropped conditional dep etils[etree] ; extra == "etree-dm"
DEBUG: dropped conditional dep jax[cpu] ; extra == "etree-jax"
DEBUG: dropped conditional dep etils[etree] ; extra == "etree-jax"
DEBUG: dropped conditional dep tf-nightly ; extra == "etree-tf"
DEBUG: dropped conditional dep etils[etree] ; extra == "etree-tf"
DEBUG: Finding possible versions for etils[epath]
DEBUG: ['/usr/bin/python3', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--progress-bar=off', 'etils[epath]==42.42.post424242']
DEBUG: {'etils[epath]': ['0.2.0', '0.3.0', '0.3.1', '0.3.2', '0.3.3', '0.4.0', '0.5.0', '0.5.1', '0.6.0', '0.7.0', '0.7.1']}
INFO: fact: _root_ is root
INFO: derived: root
INFO: fact: root depends on etils[epath] (*)
INFO: selecting _root_ (0.0.0)
INFO: derived: etils[epath] (*)
Traceback (most recent call last):
  File "/home/vagrant/.local/bin/pipgrip", line 8, in <module>
    sys.exit(main())
  File "/usr/lib/python3/dist-packages/click/core.py", line 764, in __call__
    return self.main(*args, **kwargs)
  File "/usr/lib/python3/dist-packages/click/core.py", line 717, in main
    rv = self.invoke(ctx)
  File "/usr/lib/python3/dist-packages/click/core.py", line 956, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/usr/lib/python3/dist-packages/click/core.py", line 555, in invoke
    return callback(*args, **kwargs)
  File "/home/vagrant/.local/lib/python3.8/site-packages/pipgrip/cli.py", line 434, in main
    solution = solver.solve()
  File "/home/vagrant/.local/lib/python3.8/site-packages/pipgrip/libs/mixology/version_solver.py", line 69, in solve
    if not self._run():
  File "/home/vagrant/.local/lib/python3.8/site-packages/pipgrip/libs/mixology/version_solver.py", line 85, in _run
    next_package = self._choose_package_version()
  File "/home/vagrant/.local/lib/python3.8/site-packages/pipgrip/libs/mixology/version_solver.py", line 363, in _choose_package_version
    for incompatibility in self._source.incompatibilities_for(
  File "/home/vagrant/.local/lib/python3.8/site-packages/pipgrip/libs/mixology/package_source.py", line 112, in incompatibilities_for
    incompatibility = Incompatibility(
  File "/home/vagrant/.local/lib/python3.8/site-packages/pipgrip/libs/mixology/incompatibility.py", line 61, in __init__
    assert by_ref[ref] is not None
AssertionError

What you expected to happen

Expected to see dependency tree for jax.

Step-by-step reproduction instructions

In an Ubuntu 20.04 or RHEL UBI 8 environment (VM or container) with Python 3.8...

  1. Install pipgrip.
  2. Run pipgrip -vv --tree etils[epath].

Installing pipgrip fails

What you were trying to do (and why)

I tried to pip install pipgrip on my Mac.

What happened (including command output)

Installation failed because of a permission error:

ERROR: Could not install packages due to an OSError: [Errno 13] Permission denied: '/usr/local/LICENSE'
Consider using the `--user` option or check the permissions.

What you expected to happen

This error should not occur, because LICENSE should not be copied into /usr/local. Instead, it should be available in the packages's site-packages directory. User-installing is just a workaround and doesn't fix the problem.

Step-by-step reproduction instructions

  1. Install Homebrew
  2. brew install python
  3. pip install pipgrip

Fails to discover dependencies of TensorFlow

What you were trying to do (and why)

I was trying to install a package that contains tensorflow as a dependency - this resulted in the error:

TypeError: 'NoneType' object is not iterable

The same behavior occurs when just resolving solo for TensorFlow pipgrip -vvv tensorflow

What happened (including command output)

Command output

$ pipgrip -vvv tensorflow

DEBUG: environment: {'implementation_name': 'cpython', 'implementation_version': '3.8.12', 'os_name': 'p
osix', 'platform_machine': 'x86_64', 'platform_release': '5.11.0-1023-gcp', 'platform_system': 'Linux', 
'platform_version': '#25~20.04.1-Ubuntu SMP Mon Nov 15 15:54:39 UTC 2021', 'python_full_version': '3.8.1
2', 'platform_python_implementation': 'CPython', 'python_version': '3.8', 'sys_platform': 'linux'}      
DEBUG: pip version: [21, 2, 4]                                                                          
DEBUG: pipgrip version: 0.6.10                                                                          
INFO: discovering tensorflow                                                                            
DEBUG: Downloading/building wheel for tensorflow into cache_dir /home/user/.cache/pip/wheels/pipgrip 
DEBUG: ['/home/user/miniconda3/envs/oocr-build-raw/bin/python', '-m', 'pip', 'wheel', '--no-deps', '-
-disable-pip-version-check', '--wheel-dir', '/home/user/.cache/pip/wheels/pipgrip', '--progress-bar=o
ff', 'tensorflow']                                                                                      
DEBUG: {'tensorflow': '/home/user/.cache/pip/wheels/pipgrip/tensorflow-2.7.0-cp38-cp38-manylinux2010_
x86_64.whl'}                                                                                            
DEBUG: Searching metadata in /home/user/.cache/pip/wheels/pipgrip/tensorflow-2.7.0-cp38-cp38-manylinu
x2010_x86_64.whl                                                                                        
DEBUG: Finding possible versions for tensorflow                                                         
DEBUG: ['/home/user/miniconda3/envs/oocr-build-raw/bin/python', '-m', 'pip', 'wheel', '--no-deps', '-
-disable-pip-version-check', '--progress-bar=off', 'tensorflow==42.42.post424242']                      
DEBUG: {'tensorflow': ['2.2.0', '2.2.1', '2.2.2', '2.2.3', '2.3.0', '2.3.1', '2.3.2', '2.3.3', '2.3.4', 
'2.4.0', '2.4.1', '2.4.2', '2.4.3', '2.4.4', '2.5.0', '2.5.1', '2.5.2', '2.6.0', '2.6.1', '2.6.2', '2.7.
0']}
INFO: fact: _root_ is root                                                                              
INFO: derived: root                                                                                     
INFO: fact: root depends on tensorflow (*)                                                              
INFO: selecting . (0.0.0)
INFO: derived: tensorflow (*)
INFO: discovering tensorflow==2.7.0
DEBUG: Downloading/building wheel for tensorflow==2.7.0 into cache_dir /home/user/.cache/pip/wheels/pipgrip
DEBUG: ['/home/user/miniconda3/envs/oocr-build-raw/bin/python', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--wheel-dir', '/home/user/.cache/pip/wheels/pipgrip', '--progress-bar=off', 'tensorflow==2.7.0']
DEBUG: {'tensorflow==2.7.0': '/home/user/.cache/pip/wheels/pipgrip/tensorflow-2.7.0-cp38-cp38-manylinux2010_x86_64.whl'}
DEBUG: Searching metadata in /home/user/.cache/pip/wheels/pipgrip/tensorflow-2.7.0-cp38-cp38-manylinux2010_x86_64.whl
Traceback (most recent call last):
  File "/home/user/miniconda3/envs/oocr-build-raw/bin/pipgrip", line 8, in <module>
    sys.exit(main())
  File "/home/user/miniconda3/envs/oocr-build-raw/lib/python3.8/site-packages/click/core.py", line 829, in __call__
    return self.main(*args, **kwargs)
  File "/home/user/miniconda3/envs/oocr-build-raw/lib/python3.8/site-packages/click/core.py", line 782, in main
    rv = self.invoke(ctx)
  File "/home/user/miniconda3/envs/oocr-build-raw/lib/python3.8/site-packages/click/core.py", line 1066, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/home/user/miniconda3/envs/oocr-build-raw/lib/python3.8/site-packages/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "/home/user/miniconda3/envs/oocr-build-raw/lib/python3.8/site-packages/pipgrip/cli.py", line 422, in main
    solution = solver.solve()
  File "/home/user/miniconda3/envs/oocr-build-raw/lib/python3.8/site-packages/pipgrip/libs/mixology/version_solver.py", line 69, in solve
    if not self._run():
  File "/home/user/miniconda3/envs/oocr-build-raw/lib/python3.8/site-packages/pipgrip/libs/mixology/version_solver.py", line 85, in _run
    next_package = self._choose_package_version()
  File "/home/user/miniconda3/envs/oocr-build-raw/lib/python3.8/site-packages/pipgrip/libs/mixology/version_solver.py", line 363, in _choose_package_version
    for incompatibility in self._source.incompatibilities_for(
  File "/home/user/miniconda3/envs/oocr-build-raw/lib/python3.8/site-packages/pipgrip/libs/mixology/package_source.py", line 106, in incompatibilities_for
    for dependency in dependencies:
TypeError: 'NoneType' object is not iterable

What you expected to happen

I would expect to see packages required to install TensorFlow.

Step-by-step reproduction instructions

Minimal setup to reproduce this error is to simply run pipgrip -vvv tensorflow

Cross-platform resolving?

Description

Hi, I'm on the hunt for a Python dependency resolver that can resolve deps for different values of sys_platform and platform_machine than the machine that resolver is run from.

For example:

  • From a machine with sys_platform = darwin and platform_machine = x86_64 be able to resolve deps for:
    • sys_platform = darwin, linux
    • platform_machine = x86_64, amd64

I was wondering if pipgrip is capable of this? If not could it be added? Or if you know of another resolver that can do this?

Use case / motivation / context

I would like to be able to freeze requirements that will be used on other machines that might have different OSs and chips.

Related Issues

Don't think there are any related issues?

Incorrect translation of negative constraints

Hi, I'm a maintainer of Homebrew. We're looking to use pipgrip as our dependency resolver to pin our Python packages to specific dependency trees. We've found that certain negative constraints such as in cryptography are not correctly translated during dependency resolution. In particular, cffi>=1.8,!=1.11.3 turns into cffi<1.11.3|>1.11.3,>=1.8, which I think due to some order of operations issues, pip gets confused and selects the broken 1.11.3 build anyway.

If I use the Python debugger and replace the bad constraint with the proper negative constraint cffi>=1.8,!=1.11.3, or specify this constraint on the command line, the build finishes fine.

Correct build (with extra constraint)
% pipgrip --no-cache-dir jrnl==2.4.4 'cffi>=1.8,!=1.11.3'
jrnl==2.4.4
ansiwrap==0.8.4
textwrap3==0.9.2
asteval==0.9.18
colorama==0.4.3
cryptography==2.9.2
cffi==1.14.0
pycparser==2.20
six==1.15.0
keyring==21.2.1
parsedatetime==2.6
passlib==1.7.2
python-dateutil==2.8.1
pytz==2020.1
pyxdg==0.26
pyyaml==5.3.1
tzlocal==2.1
Crashing build
% pipgrip --no-cache-dir jrnl==2.4.4 -vv         
INFO: fact: _root_ is root
INFO: derived: root
INFO: fact: root depends on jrnl (==2.4.4)
INFO: selecting . (0.0.0)
INFO: derived: jrnl (==2.4.4)
INFO: fact: jrnl (2.4.4) depends on ansiwrap (<0.9.0,>=0.8.4)
INFO: fact: jrnl (2.4.4) depends on asteval (>=0.9.14,<0.10.0)
INFO: fact: jrnl (2.4.4) depends on colorama (>=0.4.1,<0.5.0)
INFO: fact: jrnl (2.4.4) depends on cryptography (<3.0,>=2.7)
INFO: fact: jrnl (2.4.4) depends on keyring (<22.0,>19.0)
INFO: fact: jrnl (2.4.4) depends on parsedatetime (>=2.4,<3.0)
INFO: fact: jrnl (2.4.4) depends on passlib (<2.0,>=1.7)
INFO: fact: jrnl (2.4.4) depends on python-dateutil (<3.0,>=2.8)
INFO: fact: jrnl (2.4.4) depends on pytz (>=2019.1,<2021.0)
INFO: fact: jrnl (2.4.4) depends on pyxdg (<0.27.0,>=0.26.0)
INFO: fact: jrnl (2.4.4) depends on pyyaml (<6.0,>=5.1)
INFO: fact: jrnl (2.4.4) depends on tzlocal (<3.0,>1.5)
INFO: selecting jrnl (2.4.4)
INFO: derived: tzlocal (<3.0,>1.5)
INFO: derived: pyyaml (<6.0,>=5.1)
INFO: derived: pyxdg (<0.27.0,>=0.26.0)
INFO: derived: pytz (>=2019.1,<2021.0)
INFO: derived: python-dateutil (<3.0,>=2.8)
INFO: derived: passlib (<2.0,>=1.7)
INFO: derived: parsedatetime (>=2.4,<3.0)
INFO: derived: keyring (<22.0,>19.0)
INFO: derived: cryptography (<3.0,>=2.7)
INFO: derived: colorama (>=0.4.1,<0.5.0)
INFO: derived: asteval (>=0.9.14,<0.10.0)
INFO: derived: ansiwrap (<0.9.0,>=0.8.4)
INFO: selecting pyxdg (0.26)
INFO: fact: ansiwrap (0.8.4) depends on textwrap3 (>=0.9.2)
INFO: selecting ansiwrap (0.8.4)
INFO: derived: textwrap3 (>=0.9.2)
INFO: selecting textwrap3 (0.9.2)
INFO: fact: python-dateutil (2.8.1) depends on six (>=1.5)
INFO: selecting python-dateutil (2.8.1)
INFO: derived: six (>=1.5)
INFO: selecting passlib (1.7.2)
INFO: selecting parsedatetime (2.6)
INFO: selecting colorama (0.4.3)
INFO: fact: tzlocal (2.1) depends on pytz (*)
INFO: selecting tzlocal (2.1)
INFO: selecting pytz (2020.1)
INFO: selecting asteval (0.9.18)
INFO: fact: cryptography (2.9.2) depends on cffi (>=1.8,<1.11.3 || >1.11.3)
INFO: fact: cryptography (2.9.2) depends on six (>=1.4.1)
INFO: selecting cryptography (2.9.2)
INFO: derived: cffi (>=1.8,<1.11.3 || >1.11.3)
ERROR: Collecting cffi<1.11.3|>1.11.3,>=1.8
  Using cached cffi-1.11.3.tar.gz (436 kB)
Building wheels for collected packages: cffi
  Building wheel for cffi (setup.py): started
  Building wheel for cffi (setup.py): finished with status 'error'
  ERROR: Command errored out with exit status 1:
   command: /usr/local/Cellar/pipgrip/0.4.0/libexec/bin/python3.8 -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/private/var/folders/sy/w20_4b6s2ls83kqdtdtskd3r0000gn/T/pip-wheel-f6myglmi/cffi/setup.py'"'"'; __file__='"'"'/private/var/folders/sy/w20_4b6s2ls83kqdtdtskd3r0000gn/T/pip-wheel-f6myglmi/cffi/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' bdist_wheel -d /private/var/folders/sy/w20_4b6s2ls83kqdtdtskd3r0000gn/T/pip-wheel-vbizfeii
       cwd: /private/var/folders/sy/w20_4b6s2ls83kqdtdtskd3r0000gn/T/pip-wheel-f6myglmi/cffi/
  Complete output (62 lines):
  running bdist_wheel
  running build
  running build_py
  creating build
  creating build/lib.macosx-10.15-x86_64-3.8
  creating build/lib.macosx-10.15-x86_64-3.8/cffi
  copying cffi/backend_ctypes.py -> build/lib.macosx-10.15-x86_64-3.8/cffi
  copying cffi/error.py -> build/lib.macosx-10.15-x86_64-3.8/cffi
  copying cffi/setuptools_ext.py -> build/lib.macosx-10.15-x86_64-3.8/cffi
  copying cffi/__init__.py -> build/lib.macosx-10.15-x86_64-3.8/cffi
  copying cffi/cffi_opcode.py -> build/lib.macosx-10.15-x86_64-3.8/cffi
  copying cffi/vengine_gen.py -> build/lib.macosx-10.15-x86_64-3.8/cffi
  copying cffi/model.py -> build/lib.macosx-10.15-x86_64-3.8/cffi
  copying cffi/ffiplatform.py -> build/lib.macosx-10.15-x86_64-3.8/cffi
  copying cffi/api.py -> build/lib.macosx-10.15-x86_64-3.8/cffi
  copying cffi/vengine_cpy.py -> build/lib.macosx-10.15-x86_64-3.8/cffi
  copying cffi/commontypes.py -> build/lib.macosx-10.15-x86_64-3.8/cffi
  copying cffi/lock.py -> build/lib.macosx-10.15-x86_64-3.8/cffi
  copying cffi/recompiler.py -> build/lib.macosx-10.15-x86_64-3.8/cffi
  copying cffi/cparser.py -> build/lib.macosx-10.15-x86_64-3.8/cffi
  copying cffi/verifier.py -> build/lib.macosx-10.15-x86_64-3.8/cffi
  copying cffi/_cffi_include.h -> build/lib.macosx-10.15-x86_64-3.8/cffi
  copying cffi/parse_c_type.h -> build/lib.macosx-10.15-x86_64-3.8/cffi
  copying cffi/_embedding.h -> build/lib.macosx-10.15-x86_64-3.8/cffi
  copying cffi/_cffi_errors.h -> build/lib.macosx-10.15-x86_64-3.8/cffi
  running build_ext
  building '_cffi_backend' extension
  creating build/temp.macosx-10.15-x86_64-3.8
  creating build/temp.macosx-10.15-x86_64-3.8/c
  clang -Wno-unused-result -Wsign-compare -Wunreachable-code -fno-common -dynamic -DNDEBUG -g -fwrapv -O3 -Wall -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk -I/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include -I/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/System/Library/Frameworks/Tk.framework/Versions/8.5/Headers -DUSE__THREAD -DHAVE_SYNC_SYNCHRONIZE -I/usr/local/Cellar/libffi/3.3/include -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/ffi -I/usr/local/opt/[email protected]/Frameworks/Python.framework/Versions/3.8/include/python3.8 -c c/_cffi_backend.c -o build/temp.macosx-10.15-x86_64-3.8/c/_cffi_backend.o
  c/_cffi_backend.c:5827:9: warning: 'ffi_prep_closure' is deprecated [-Wdeprecated-declarations]
      if (ffi_prep_closure(closure, &cif_descr->cif,
          ^
  /usr/local/Cellar/libffi/3.3/include/ffi.h:341:18: note: 'ffi_prep_closure' has been explicitly marked deprecated here
    __attribute__((deprecated))
                   ^
  In file included from c/_cffi_backend.c:7286:
  In file included from c/cffi1_module.c:20:
  c/call_python.c:20:30: error: incomplete definition of type 'struct _is'
      builtins = tstate->interp->builtins;
                 ~~~~~~~~~~~~~~^
  /usr/local/opt/[email protected]/Frameworks/Python.framework/Versions/3.8/include/python3.8/pystate.h:20:8: note: forward declaration of 'struct _is'
  struct _is;
         ^
  In file included from c/_cffi_backend.c:7286:
  In file included from c/cffi1_module.c:20:
  c/call_python.c:160:39: error: incomplete definition of type 'struct _is'
      new1 = PyThreadState_GET()->interp->modules;
             ~~~~~~~~~~~~~~~~~~~~~~~~~~~^
  /usr/local/opt/[email protected]/Frameworks/Python.framework/Versions/3.8/include/python3.8/pystate.h:20:8: note: forward declaration of 'struct _is'
  struct _is;
         ^
  In file included from c/_cffi_backend.c:7286:
  In file included from c/cffi1_module.c:20:
  c/call_python.c:249:63: error: incomplete definition of type 'struct _is'
          if (externpy->reserved1 != PyThreadState_GET()->interp->modules) {
                                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~^
  /usr/local/opt/[email protected]/Frameworks/Python.framework/Versions/3.8/include/python3.8/pystate.h:20:8: note: forward declaration of 'struct _is'
  struct _is;
         ^
  1 warning and 3 errors generated.
  error: command 'clang' failed with exit status 1
  ----------------------------------------
  ERROR: Failed building wheel for cffi
  Running setup.py clean for cffi
Failed to build cffi
ERROR: Failed to build one or more wheels

Error: Command '['/usr/local/Cellar/pipgrip/0.4.0/libexec/bin/python3.8', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--wheel-dir', '/var/folders/sy/w20_4b6s2ls83kqdtdtskd3r0000gn/T/tmpxcz0ybav', '--index-url', 'https://pypi.org/simple', '--trusted-host', 'pypi.org', '--progress-bar=off', 'cffi<1.11.3|>1.11.3,>=1.8']' returned non-zero exit status 1.

Originally posted by @jonchang in Homebrew/homebrew-core#58626 (comment)

Proper rendering of requirements in tree

  • blabla[compress] not shown in tree
  • requirements markers:
├── raven-aiohttp==0.7.0 (0.7.0)
│   ├── aiohttp==3.5.4 (3.5.4)
│   │   ├── async-timeout==3.0.1 (3.0.1)
│   │   ├── attrs>=17.3.0 (19.3.0)
│   │   ├── chardet<4.0,>=2.0 (3.0.4)
│   │   ├── multidict==4.5.2 (4.5.2)
│   │   └── yarl==1.3.0 (1.3.0)
│   │       ├── idna>=2.0 (2.8)
│   │       └── multidict==4.5.2 (4.5.2)
│   └── raven>=5.4.0 (6.10.0)

is incorrect due to exact pin of aiohttp higher up in the tree it gets stored in the packages_metadata dict,

Fails to build wheel for gnureadline

What you were trying to do (and why)

Find recursive dependencies for dxpy

What happened (including command output)

Failed on gnureadline. It seems to build the readline library and then fails with a Failed to build gnureadline error

Command output

$ pipgrip -vvv dxpy

DEBUG: Environment: {'implementation_name': 'cpython', 'implementation_version': '3.8.5', 'os_name': 'posix', 'platform_machine': 'x86_64', 'platform_release': '19.6.0', 'platform_system': 'Darwin', 'platform_version': 'Darwin Kernel Version 19.6.0: Sun Jul  5 00:43:10 PDT 2020; root:xnu-6153.141.1~9/RELEASE_X86_64', 'python_full_version': '3.8.5', 'platform_python_implementation': 'CPython', 'python_version': '3.8', 'sys_platform': 'darwin'}
DEBUG: Pip version: [20, 1, 1]
DEBUG: Downloading/building wheel for dxpy
DEBUG: ['/usr/local/Cellar/pipgrip/0.5.1/libexec/bin/python3.8', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--wheel-dir', '/Users/rylanpolster/Library/Caches/pip/wheels/pipgrip', '--index-url', 'https://pypi.org/simple', '--trusted-host', 'pypi.org', '--progress-bar=off', 'dxpy']
DEBUG: {'dxpy': '/Users/rylanpolster/Library/Caches/pip/wheels/pipgrip/dxpy-0.298.1-py2.py3-none-any.whl'}
DEBUG: Searching metadata in /Users/rylanpolster/Library/Caches/pip/wheels/pipgrip/dxpy-0.298.1-py2.py3-none-any.whl
DEBUG: included conditional dep gnureadline (==6.3.8) ; sys_platform == "darwin"
DEBUG: dropped conditional dep xattr (==0.9.6) ; sys_platform == "linux2" or sys_platform == "linux"
DEBUG: Finding possible versions for dxpy
DEBUG: ['/usr/local/Cellar/pipgrip/0.5.1/libexec/bin/python3.8', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--index-url', 'https://pypi.org/simple', '--trusted-host', 'pypi.org', '--progress-bar=off', 'dxpy==rubbish']
DEBUG: {'dxpy': ['0.35.4', '0.38.1', '0.39.1', '0.41.2', '0.42.1', '0.43.2', '0.44.4', '0.45.1', '0.46.2', '0.47.3', '0.47.4', '0.47.5', '0.47.6', '0.48.2', '0.48.3', '0.49.1', '0.50.1', '0.51.1', '0.51.2', '0.52.2', '0.53.0', '0.54.0', '0.54.1', '0.54.2', '0.54.3', '0.55.4', '0.55.5', '0.55.6', '0.55.7', '0.56.1', '0.57.1', '0.58.1', '0.58.2', '0.58.4', '0.60.1', '0.61.1', '0.62.2', '0.62.3', '0.63.2', '0.63.3', '0.64.3', '0.65.0', '0.66.2', '0.66.3', '0.67.2', '0.68.1', '0.69.0', '0.70.1', '0.71.0', '0.72.0', '0.73.3', '0.74.0', '0.75.1', '0.76.0', '0.77.1', '0.78.2', '0.79.3', '0.80.1', '0.81.1', '0.82.1', '0.83.0', '0.84.1', '0.85.0', '0.86.1', '0.87.1', '0.88.0', '0.89.1', '0.90.0', '0.91.0', '0.92.1', '0.93.1', '0.94.2', '0.95.1', '0.96.1', '0.97.1', '0.98.3', '0.99.0', '0.99.1', '0.101.1', '0.101.2', '0.102.1', '0.103.2', '0.104.0', '0.105.2', '0.106.1', '0.107.1', '0.108.2', '0.109.2', '0.110.1', '0.111.3', '0.112.1', '0.113.1', '0.114.2', '0.115.2', '0.116.1', '0.117.1', '0.118.1', '0.119.0', '0.120.0', '0.121.1', '0.122.0', '0.123.2', '0.123.3', '0.124.1', '0.125.2', '0.126.1', '0.128.2', '0.129.0', '0.130.0', '0.131.0', '0.132.0', '0.133.0', '0.134.1', '0.135.3', '0.136.1', '0.137.2', '0.138.0', '0.139.0', '0.140.0', '0.141.1', '0.142.0', '0.143.1', '0.144.0', '0.145.1', '0.146.2', '0.147.0', '0.148.0', '0.149.1', '0.150.2', '0.151.0', '0.152.0', '0.153.0', '0.154.0', '0.155.1', '0.155.2', '0.156.2', '0.157.0', '0.157.1', '0.158.1', '0.159.1', '0.160.0', '0.161.0', '0.162.1', '0.163.0', '0.164.1', '0.164.2', '0.164.3', '0.164.4', '0.165.4', '0.166.1', '0.167.0', '0.168.0', '0.169.1', '0.170.1', '0.171.1', '0.172.0', '0.172.1', '0.173.0', '0.174.0', '0.175.1', '0.176.1', '0.177.4', '0.178.1', '0.179.0', '0.181.0', '0.182.1', '0.183.2', '0.184.1', '0.185.0', '0.186.1', '0.187.1', '0.188.3', '0.188.4', '0.189.2', '0.190.1', '0.191.0', '0.212.0', '0.213.1', '0.214.1', '0.215.0', '0.216.1', '0.217.0', '0.218.0', '0.219.0', '0.220.0', '0.221.0', '0.222.0', '0.223.0', '0.224.0', '0.225.0', '0.240.1', '0.242.0', '0.243.0', '0.244.0', '0.245.0', '0.246.0', '0.247.0', '0.248.0', '0.249.0', '0.250.1', '0.250.2', '0.250.3', '0.251.2', '0.252.0', '0.253.0', '0.254.0', '0.255.0', '0.257.2', '0.257.3', '0.258.2', '0.259.0', '0.260.0', '0.261.1', '0.262.0', '0.263.0', '0.264.0', '0.265.0', '0.266.1', '0.267.0', '0.267.1', '0.268.2', '0.269.2', '0.270.2', '0.271.0', '0.272.0', '0.273.0', '0.274.0', '0.275.0', '0.276.0', '0.277.0', '0.278.0', '0.279.0', '0.280.0', '0.281.0', '0.282.0', '0.283.0', '0.284.0', '0.285.0', '0.285.1', '0.286.1', '0.287.0', '0.288.0', '0.289.1', '0.290.1', '0.291.1', '0.292.0', '0.293.0', '0.294.0', '0.295.1', '0.296.0', '0.297.1', '0.298.1']}
INFO: fact: _root_ is root
INFO: derived: root
INFO: fact: root depends on dxpy (*)
INFO: selecting . (0.0.0)
INFO: derived: dxpy (*)
INFO: fact: dxpy (0.298.1) depends on argcomplete (>=1.9.4)
INFO: fact: dxpy (0.298.1) depends on beautifulsoup4 (==4.4.1)
INFO: fact: dxpy (0.298.1) depends on cryptography (>=2.3,<3.0)
INFO: fact: dxpy (0.298.1) depends on gnureadline (==6.3.8)
INFO: fact: dxpy (0.298.1) depends on psutil (>=3.3.0)
INFO: fact: dxpy (0.298.1) depends on python-dateutil (>=2.5)
INFO: fact: dxpy (0.298.1) depends on python-magic (==0.4.6)
INFO: fact: dxpy (0.298.1) depends on requests (<2.24.0,>=2.8.0)
INFO: fact: dxpy (0.298.1) depends on websocket-client (==0.53.0)
INFO: selecting dxpy (0.298.1)
INFO: derived: websocket-client (==0.53.0)
INFO: derived: requests (<2.24.0,>=2.8.0)
INFO: derived: python-magic (==0.4.6)
INFO: derived: python-dateutil (>=2.5)
INFO: derived: psutil (>=3.3.0)
INFO: derived: gnureadline (==6.3.8)
INFO: derived: cryptography (>=2.3,<3.0)
INFO: derived: beautifulsoup4 (==4.4.1)
INFO: derived: argcomplete (>=1.9.4)
DEBUG: Downloading/building wheel for websocket-client==0.53.0
DEBUG: ['/usr/local/Cellar/pipgrip/0.5.1/libexec/bin/python3.8', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--wheel-dir', '/Users/rylanpolster/Library/Caches/pip/wheels/pipgrip', '--index-url', 'https://pypi.org/simple', '--trusted-host', 'pypi.org', '--progress-bar=off', 'websocket-client==0.53.0']
DEBUG: {'websocket-client==0.53.0': '/Users/rylanpolster/Library/Caches/pip/wheels/pipgrip/websocket_client-0.53.0-py2.py3-none-any.whl'}
DEBUG: Searching metadata in /Users/rylanpolster/Library/Caches/pip/wheels/pipgrip/websocket_client-0.53.0-py2.py3-none-any.whl
DEBUG: Finding possible versions for websocket-client
DEBUG: ['/usr/local/Cellar/pipgrip/0.5.1/libexec/bin/python3.8', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--index-url', 'https://pypi.org/simple', '--trusted-host', 'pypi.org', '--progress-bar=off', 'websocket-client==rubbish']
DEBUG: {'websocket-client': ['0.3', '0.4', '0.4.1', '0.5.0', '0.5.1', '0.6.0', '0.7.0', '0.8.0', '0.9.0', '0.10.0', '0.11.0', '0.12.0', '0.13.0', '0.14.0', '0.14.1', '0.15.0', '0.16.0', '0.17.0', '0.18.0', '0.19.0', '0.20.0', '0.21.0', '0.22.0', '0.23.0', '0.24.0', '0.25.0', '0.26.0', '0.27.0', '0.28.0', '0.29.0', '0.30.0', '0.31.0', '0.32.0', '0.33.0', '0.34.0', '0.35.0', '0.36.0', '0.37.0', '0.39.0', '0.40.0', '0.42.0', '0.42.1', '0.43.0', '0.44.0', '0.45.0', '0.46.0', '0.47.0', '0.48.0', '0.49.0', '0.50.0', '0.51.0', '0.52.0', '0.53.0', '0.54.0', '0.55.0', '0.56.0', '0.57.0']}
DEBUG: Downloading/building wheel for requests<2.24.0,>=2.8.0
DEBUG: ['/usr/local/Cellar/pipgrip/0.5.1/libexec/bin/python3.8', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--wheel-dir', '/Users/rylanpolster/Library/Caches/pip/wheels/pipgrip', '--index-url', 'https://pypi.org/simple', '--trusted-host', 'pypi.org', '--progress-bar=off', 'requests<2.24.0,>=2.8.0']
DEBUG: {'requests<2.24.0,>=2.8.0': '/Users/rylanpolster/Library/Caches/pip/wheels/pipgrip/requests-2.23.0-py2.py3-none-any.whl'}
DEBUG: Searching metadata in /Users/rylanpolster/Library/Caches/pip/wheels/pipgrip/requests-2.23.0-py2.py3-none-any.whl
DEBUG: dropped conditional dep pyOpenSSL (>=0.14) ; extra == 'security'
DEBUG: dropped conditional dep cryptography (>=1.3.4) ; extra == 'security'
DEBUG: dropped conditional dep PySocks (!=1.5.7,>=1.5.6) ; extra == 'socks'
DEBUG: dropped conditional dep win-inet-pton ; (sys_platform == "win32" and python_version == "2.7") and extra == 'socks'
DEBUG: Finding possible versions for requests
DEBUG: ['/usr/local/Cellar/pipgrip/0.5.1/libexec/bin/python3.8', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--index-url', 'https://pypi.org/simple', '--trusted-host', 'pypi.org', '--progress-bar=off', 'requests==rubbish']
DEBUG: {'requests': ['0.2.0', '0.2.1', '0.2.2', '0.2.3', '0.2.4', '0.3.0', '0.3.1', '0.3.2', '0.3.3', '0.3.4', '0.4.0', '0.4.1', '0.5.0', '0.5.1', '0.6.0', '0.6.1', '0.6.2', '0.6.3', '0.6.4', '0.6.5', '0.6.6', '0.7.0', '0.7.1', '0.7.2', '0.7.3', '0.7.4', '0.7.5', '0.7.6', '0.8.0', '0.8.1', '0.8.2', '0.8.3', '0.8.4', '0.8.5', '0.8.6', '0.8.7', '0.8.8', '0.8.9', '0.9.0', '0.9.1', '0.9.2', '0.9.3', '0.10.0', '0.10.1', '0.10.2', '0.10.3', '0.10.4', '0.10.6', '0.10.7', '0.10.8', '0.11.1', '0.11.2', '0.12.0', '0.12.1', '0.13.0', '0.13.1', '0.13.2', '0.13.3', '0.13.4', '0.13.5', '0.13.6', '0.13.7', '0.13.8', '0.13.9', '0.14.0', '0.14.1', '0.14.2', '1.0.0', '1.0.1', '1.0.2', '1.0.3', '1.0.4', '1.1.0', '1.2.0', '1.2.1', '1.2.2', '1.2.3', '2.0.0', '2.0.1', '2.1.0', '2.2.0', '2.2.1', '2.3.0', '2.4.0', '2.4.1', '2.4.2', '2.4.3', '2.5.0', '2.5.1', '2.5.2', '2.5.3', '2.6.0', '2.6.1', '2.6.2', '2.7.0', '2.8.0', '2.8.1', '2.9.0', '2.9.1', '2.9.2', '2.10.0', '2.11.0', '2.11.1', '2.12.0', '2.12.1', '2.12.2', '2.12.3', '2.12.4', '2.12.5', '2.13.0', '2.14.0', '2.14.1', '2.14.2', '2.15.1', '2.16.0', '2.16.1', '2.16.2', '2.16.3', '2.16.4', '2.16.5', '2.17.0', '2.17.1', '2.17.2', '2.17.3', '2.18.0', '2.18.1', '2.18.2', '2.18.3', '2.18.4', '2.19.0', '2.19.1', '2.20.0', '2.20.1', '2.21.0', '2.22.0', '2.23.0', '2.24.0']}
DEBUG: Downloading/building wheel for python-magic==0.4.6
DEBUG: ['/usr/local/Cellar/pipgrip/0.5.1/libexec/bin/python3.8', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--wheel-dir', '/Users/rylanpolster/Library/Caches/pip/wheels/pipgrip', '--index-url', 'https://pypi.org/simple', '--trusted-host', 'pypi.org', '--progress-bar=off', 'python-magic==0.4.6']
DEBUG: {'python-magic==0.4.6': '/Users/rylanpolster/Library/Caches/pip/wheels/pipgrip/python_magic-0.4.6-py3-none-any.whl'}
DEBUG: Searching metadata in /Users/rylanpolster/Library/Caches/pip/wheels/pipgrip/python_magic-0.4.6-py3-none-any.whl
DEBUG: Finding possible versions for python-magic
DEBUG: ['/usr/local/Cellar/pipgrip/0.5.1/libexec/bin/python3.8', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--index-url', 'https://pypi.org/simple', '--trusted-host', 'pypi.org', '--progress-bar=off', 'python-magic==rubbish']
DEBUG: {'python-magic': ['0.2', '0.3', '0.3.1', '0.4.0', '0.4.2', '0.4.3', '0.4.5', '0.4.6', '0.4.7', '0.4.8', '0.4.9', '0.4.10', '0.4.11', '0.4.12', '0.4.13', '0.4.15', '0.4.17', '0.4.18']}
DEBUG: Downloading/building wheel for python-dateutil>=2.5
DEBUG: ['/usr/local/Cellar/pipgrip/0.5.1/libexec/bin/python3.8', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--wheel-dir', '/Users/rylanpolster/Library/Caches/pip/wheels/pipgrip', '--index-url', 'https://pypi.org/simple', '--trusted-host', 'pypi.org', '--progress-bar=off', 'python-dateutil>=2.5']
DEBUG: {'python-dateutil>=2.5': '/Users/rylanpolster/Library/Caches/pip/wheels/pipgrip/python_dateutil-2.8.1-py2.py3-none-any.whl'}
DEBUG: Searching metadata in /Users/rylanpolster/Library/Caches/pip/wheels/pipgrip/python_dateutil-2.8.1-py2.py3-none-any.whl
DEBUG: Finding possible versions for python-dateutil
DEBUG: ['/usr/local/Cellar/pipgrip/0.5.1/libexec/bin/python3.8', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--index-url', 'https://pypi.org/simple', '--trusted-host', 'pypi.org', '--progress-bar=off', 'python-dateutil==rubbish']
DEBUG: {'python-dateutil': ['1.4', '1.4.1', '1.5', '2.1', '2.2', '2.3', '2.4.0', '2.4.1', '2.4.2', '2.5.0', '2.5.1', '2.5.2', '2.5.3', '2.6.0', '2.6.1', '2.7.0', '2.7.1', '2.7.2', '2.7.3', '2.7.4', '2.7.5', '2.8.0', '2.8.1']}
DEBUG: Downloading/building wheel for psutil>=3.3.0
DEBUG: ['/usr/local/Cellar/pipgrip/0.5.1/libexec/bin/python3.8', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--wheel-dir', '/Users/rylanpolster/Library/Caches/pip/wheels/pipgrip', '--index-url', 'https://pypi.org/simple', '--trusted-host', 'pypi.org', '--progress-bar=off', 'psutil>=3.3.0']
DEBUG: {'psutil>=3.3.0': '/Users/rylanpolster/Library/Caches/pip/wheels/pipgrip/psutil-5.7.2-cp38-cp38-macosx_10_15_x86_64.whl'}
DEBUG: Searching metadata in /Users/rylanpolster/Library/Caches/pip/wheels/pipgrip/psutil-5.7.2-cp38-cp38-macosx_10_15_x86_64.whl
DEBUG: dropped conditional dep ipaddress ; (python_version < "3.0") and extra == 'test'
DEBUG: dropped conditional dep mock ; (python_version < "3.0") and extra == 'test'
DEBUG: dropped conditional dep unittest2 ; (python_version < "3.0") and extra == 'test'
DEBUG: dropped conditional dep enum34 ; (python_version <= "3.4") and extra == 'test'
DEBUG: dropped conditional dep pywin32 ; (sys_platform == "win32") and extra == 'test'
DEBUG: dropped conditional dep wmi ; (sys_platform == "win32") and extra == 'test'
DEBUG: Finding possible versions for psutil
DEBUG: ['/usr/local/Cellar/pipgrip/0.5.1/libexec/bin/python3.8', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--index-url', 'https://pypi.org/simple', '--trusted-host', 'pypi.org', '--progress-bar=off', 'psutil==rubbish']
DEBUG: {'psutil': ['0.1.1', '0.1.2', '0.1.3', '0.2.0', '0.2.1', '0.3.0', '0.4.0', '0.4.1', '0.5.0', '0.5.1', '0.6.0', '0.6.1', '0.7.0', '0.7.1', '1.0.0', '1.0.1', '1.1.0', '1.1.1', '1.1.2', '1.1.3', '1.2.0', '1.2.1', '2.0.0', '2.1.0', '2.1.1', '2.1.2', '2.1.3', '2.2.0', '2.2.1', '3.0.0', '3.0.1', '3.1.0', '3.1.1', '3.2.0', '3.2.1', '3.2.2', '3.3.0', '3.4.1', '3.4.2', '4.0.0', '4.1.0', '4.2.0', '4.3.0', '4.3.1', '4.4.0', '4.4.1', '4.4.2', '5.0.0', '5.0.1', '5.1.0', '5.1.1', '5.1.2', '5.1.3', '5.2.0', '5.2.1', '5.2.2', '5.3.0', '5.3.1', '5.4.0', '5.4.1', '5.4.2', '5.4.3', '5.4.4', '5.4.5', '5.4.6', '5.4.7', '5.4.8', '5.5.0', '5.5.1', '5.6.0', '5.6.1', '5.6.2', '5.6.3', '5.6.4', '5.6.5', '5.6.6', '5.6.7', '5.7.0', '5.7.1', '5.7.2']}
DEBUG: Downloading/building wheel for gnureadline==6.3.8
DEBUG: ['/usr/local/Cellar/pipgrip/0.5.1/libexec/bin/python3.8', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--wheel-dir', '/Users/rylanpolster/Library/Caches/pip/wheels/pipgrip', '--index-url', 'https://pypi.org/simple', '--trusted-host', 'pypi.org', '--progress-bar=off', 'gnureadline==6.3.8']
ERROR: Collecting gnureadline==6.3.8
  Using cached gnureadline-6.3.8.tar.gz (2.5 MB)
Building wheels for collected packages: gnureadline
  Building wheel for gnureadline (setup.py): started
  Building wheel for gnureadline (setup.py): finished with status 'error'
  ERROR: Command errored out with exit status 1:
   command: /usr/local/Cellar/pipgrip/0.5.1/libexec/bin/python3.8 -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/private/var/folders/lx/jw48rn1j0235pst2sg8qlgp00000gp/T/pip-wheel-geqsj3wu/gnureadline/setup.py'"'"'; __file__='"'"'/private/var/folders/lx/jw48rn1j0235pst2sg8qlgp00000gp/T/pip-wheel-geqsj3wu/gnureadline/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' bdist_wheel -d /private/var/folders/lx/jw48rn1j0235pst2sg8qlgp00000gp/T/pip-wheel-hjwoo35m
       cwd: /private/var/folders/lx/jw48rn1j0235pst2sg8qlgp00000gp/T/pip-wheel-geqsj3wu/gnureadline/
  Complete output (411 lines):
  
  ============ Building the readline library ============
  
  Using compiler cc on OS X
  Guessing actual compiler: Apple clang version 12.0.0 (clang-1200.0.26.2)
  Compiler supports architectures: x86_64
  x readline-6.3/
  x readline-6.3/doc/
  x readline-6.3/doc/Makefile.in
  x readline-6.3/doc/texinfo.tex
  x readline-6.3/doc/version.texi
  x readline-6.3/doc/fdl.texi
  x readline-6.3/doc/rlman.texi
  x readline-6.3/doc/rltech.texi
  x readline-6.3/doc/rluser.texi
  x readline-6.3/doc/rluserman.texi
  x readline-6.3/doc/history.texi
  x readline-6.3/doc/hstech.texi
  x readline-6.3/doc/hsuser.texi
  x readline-6.3/doc/readline.3
  x readline-6.3/doc/history.3
  x readline-6.3/doc/texi2dvi
  x readline-6.3/doc/texi2html
  x readline-6.3/doc/readline.ps
  x readline-6.3/doc/history.ps
  x readline-6.3/doc/rluserman.ps
  x readline-6.3/doc/readline.dvi
  x readline-6.3/doc/history.dvi
  x readline-6.3/doc/rluserman.dvi
  x readline-6.3/doc/readline.info
  x readline-6.3/doc/history.info
  x readline-6.3/doc/rluserman.info
  x readline-6.3/doc/readline.html
  x readline-6.3/doc/history.html
  x readline-6.3/doc/rluserman.html
  x readline-6.3/doc/readline.0
  x readline-6.3/doc/history.0
  x readline-6.3/doc/readline_3.ps
  x readline-6.3/doc/history_3.ps
  x readline-6.3/doc/history.pdf
  x readline-6.3/doc/readline.pdf
  x readline-6.3/doc/rluserman.pdf
  x readline-6.3/examples/
  x readline-6.3/examples/autoconf/
  x readline-6.3/examples/autoconf/BASH_CHECK_LIB_TERMCAP
  x readline-6.3/examples/autoconf/RL_LIB_READLINE_VERSION
  x readline-6.3/examples/autoconf/wi_LIB_READLINE
  x readline-6.3/examples/rlfe/
  x readline-6.3/examples/rlfe/ChangeLog
  x readline-6.3/examples/rlfe/Makefile.in
  x readline-6.3/examples/rlfe/README
  x readline-6.3/examples/rlfe/config.h.in
  x readline-6.3/examples/rlfe/configure
  x readline-6.3/examples/rlfe/configure.in
  x readline-6.3/examples/rlfe/extern.h
  x readline-6.3/examples/rlfe/os.h
  x readline-6.3/examples/rlfe/pty.c
  x readline-6.3/examples/rlfe/rlfe.c
  x readline-6.3/examples/rlfe/screen.h
  x readline-6.3/examples/Makefile.in
  x readline-6.3/examples/excallback.c
  x readline-6.3/examples/fileman.c
  x readline-6.3/examples/manexamp.c
  x readline-6.3/examples/readlinebuf.h
  x readline-6.3/examples/rl-fgets.c
  x readline-6.3/examples/rlcat.c
  x readline-6.3/examples/rlevent.c
  x readline-6.3/examples/rltest.c
  x readline-6.3/examples/rl-callbacktest.c
  x readline-6.3/examples/rl.c
  x readline-6.3/examples/rlptytest.c
  x readline-6.3/examples/rlversion.c
  x readline-6.3/examples/histexamp.c
  x readline-6.3/examples/hist_erasedups.c
  x readline-6.3/examples/hist_purgecmd.c
  x readline-6.3/examples/Inputrc
  x readline-6.3/examples/rlwrap-0.30.tar.gz
  x readline-6.3/support/
  x readline-6.3/support/config.guess
  x readline-6.3/support/config.rpath
  x readline-6.3/support/config.sub
  x readline-6.3/support/install.sh
  x readline-6.3/support/mkdirs
  x readline-6.3/support/mkdist
  x readline-6.3/support/mkinstalldirs
  x readline-6.3/support/shobj-conf
  x readline-6.3/support/shlib-install
  x readline-6.3/support/wcwidth.c
  x readline-6.3/shlib/
  x readline-6.3/shlib/Makefile.in
  x readline-6.3/COPYING
  x readline-6.3/README
  x readline-6.3/MANIFEST
  x readline-6.3/INSTALL
  x readline-6.3/CHANGELOG
  x readline-6.3/CHANGES
  x readline-6.3/NEWS
  x readline-6.3/USAGE
  x readline-6.3/aclocal.m4
  x readline-6.3/config.h.in
  x readline-6.3/configure
  x readline-6.3/configure.ac
  x readline-6.3/Makefile.in
  x readline-6.3/ansi_stdlib.h
  x readline-6.3/chardefs.h
  x readline-6.3/colors.h
  x readline-6.3/history.h
  x readline-6.3/histlib.h
  x readline-6.3/keymaps.h
  x readline-6.3/parse-colors.h
  x readline-6.3/rlconf.h
  x readline-6.3/posixdir.h
  x readline-6.3/posixjmp.h
  x readline-6.3/posixselect.h
  x readline-6.3/posixstat.h
  x readline-6.3/readline.h
  x readline-6.3/rldefs.h
  x readline-6.3/rlmbutil.h
  x readline-6.3/rlprivate.h
  x readline-6.3/rlshell.h
  x readline-6.3/rlstdc.h
  x readline-6.3/rltty.h
  x readline-6.3/rltypedefs.h
  x readline-6.3/rlwinsize.h
  x readline-6.3/tcap.h
  x readline-6.3/tilde.h
  x readline-6.3/xmalloc.h
  x readline-6.3/bind.c
  x readline-6.3/callback.c
  x readline-6.3/colors.c
  x readline-6.3/compat.c
  x readline-6.3/complete.c
  x readline-6.3/display.c
  x readline-6.3/emacs_keymap.c
  x readline-6.3/funmap.c
  x readline-6.3/input.c
  x readline-6.3/isearch.c
  x readline-6.3/keymaps.c
  x readline-6.3/kill.c
  x readline-6.3/macro.c
  x readline-6.3/mbutil.c
  x readline-6.3/misc.c
  x readline-6.3/nls.c
  x readline-6.3/parens.c
  x readline-6.3/parse-colors.c
  x readline-6.3/readline.c
  x readline-6.3/rltty.c
  x readline-6.3/savestring.c
  x readline-6.3/search.c
  x readline-6.3/shell.c
  x readline-6.3/signals.c
  x readline-6.3/terminal.c
  x readline-6.3/text.c
  x readline-6.3/tilde.c
  x readline-6.3/undo.c
  x readline-6.3/util.c
  x readline-6.3/vi_keymap.c
  x readline-6.3/vi_mode.c
  x readline-6.3/xfree.c
  x readline-6.3/xmalloc.c
  x readline-6.3/history.c
  x readline-6.3/histexpand.c
  x readline-6.3/histfile.c
  x readline-6.3/histsearch.c
  x readline-6.3/patchlevel
  patching file readline.c
  patching file patchlevel
  patching file readline.c
  patching file patchlevel
  patching file util.c
  patching file patchlevel
  patching file display.c
  patching file patchlevel
  patching file rltypedefs.h
  patching file patchlevel
  patching file display.c
  patching file patchlevel
  patching file input.c
  patching file patchlevel
  patching file misc.c
  patching file patchlevel
  checking build system type... x86_64-apple-darwin19.6.0
  checking host system type... x86_64-apple-darwin19.6.0
  
  Beginning configuration for readline-6.3 for x86_64-apple-darwin19.6.0
  
  checking whether make sets $(MAKE)... yes
  checking for gcc... cc
  checking whether the C compiler works... yes
  checking for C compiler default output file name... a.out
  checking for suffix of executables...
  checking whether we are cross compiling... no
  checking for suffix of object files... o
  checking whether we are using the GNU C compiler... yes
  checking whether cc accepts -g... yes
  checking for cc option to accept ISO C89... none needed
  checking how to run the C preprocessor... cc -E
  checking for grep that handles long lines and -e... /usr/bin/grep
  checking for egrep... /usr/bin/grep -E
  checking for ANSI C header files... yes
  checking for sys/types.h... yes
  checking for sys/stat.h... yes
  checking for stdlib.h... yes
  checking for string.h... yes
  checking for memory.h... yes
  checking for strings.h... yes
  checking for inttypes.h... yes
  checking for stdint.h... yes
  checking for unistd.h... yes
  checking minix/config.h usability... no
  checking minix/config.h presence... no
  checking for minix/config.h... no
  checking whether it is safe to define __EXTENSIONS__... yes
  checking whether cc needs -traditional... no
  checking for a BSD-compatible install... /usr/bin/install -c
  checking for ar... ar
  checking for ranlib... ranlib
  checking for an ANSI C-conforming const... yes
  checking for function prototypes... yes
  checking whether char is unsigned... no
  checking for working volatile... yes
  checking return type of signal handlers... void
  checking for size_t... yes
  checking for ssize_t... yes
  checking for ANSI C header files... (cached) yes
  checking whether stat file-mode macros are broken... no
  checking for dirent.h that defines DIR... yes
  checking for library containing opendir... none required
  checking for fcntl... yes
  checking for kill... yes
  checking for lstat... yes
  checking for memmove... yes
  checking for putenv... yes
  checking for select... yes
  checking for setenv... yes
  checking for setlocale... yes
  checking for strcasecmp... yes
  checking for strpbrk... yes
  checking for tcgetattr... yes
  checking for vsnprintf... yes
  checking for isascii... yes
  checking for isxdigit... yes
  checking for getpwent... yes
  checking for getpwnam... yes
  checking for getpwuid... yes
  checking for working strcoll... yes
  checking fcntl.h usability... yes
  checking fcntl.h presence... yes
  checking for fcntl.h... yes
  checking for unistd.h... (cached) yes
  checking for stdlib.h... (cached) yes
  checking varargs.h usability... no
  checking varargs.h presence... no
  checking for varargs.h... no
  checking stdarg.h usability... yes
  checking stdarg.h presence... yes
  checking for stdarg.h... yes
  checking stdbool.h usability... yes
  checking stdbool.h presence... yes
  checking for stdbool.h... yes
  checking for string.h... (cached) yes
  checking for strings.h... (cached) yes
  checking limits.h usability... yes
  checking limits.h presence... yes
  checking for limits.h... yes
  checking locale.h usability... yes
  checking locale.h presence... yes
  checking for locale.h... yes
  checking pwd.h usability... yes
  checking pwd.h presence... yes
  checking for pwd.h... yes
  checking for memory.h... (cached) yes
  checking termcap.h usability... yes
  checking termcap.h presence... yes
  checking for termcap.h... yes
  checking termios.h usability... yes
  checking termios.h presence... yes
  checking for termios.h... yes
  checking termio.h usability... no
  checking termio.h presence... no
  checking for termio.h... no
  checking sys/pte.h usability... no
  checking sys/pte.h presence... no
  checking for sys/pte.h... no
  checking sys/stream.h usability... no
  checking sys/stream.h presence... no
  checking for sys/stream.h... no
  checking sys/select.h usability... yes
  checking sys/select.h presence... yes
  checking for sys/select.h... yes
  checking sys/file.h usability... yes
  checking sys/file.h presence... yes
  checking for sys/file.h... yes
  checking for sys/ptem.h... no
  checking for special C compiler options needed for large files... no
  checking for _FILE_OFFSET_BITS value needed for large files... no
  checking for type of signal functions... posix
  checking if signal handlers must be reinstalled when invoked... yes
  checking for presence of POSIX-style sigsetjmp/siglongjmp... missing
  checking for lstat... yes
  checking whether or not strcoll and strcmp differ... no
  checking whether the ctype macros accept non-ascii characters... no
  checking whether getpw functions are declared in pwd.h... yes
  checking whether termios.h defines TIOCGWINSZ... yes
  checking for sig_atomic_t in signal.h... yes
  checking whether signal handlers are of type void... yes
  checking for TIOCSTAT in sys/ioctl.h... yes
  checking for FIONREAD in sys/ioctl.h... yes
  checking for speed_t in sys/types.h... no
  checking for struct winsize in sys/ioctl.h and termios.h... sys/ioctl.h
  checking for struct dirent.d_ino... yes
  checking for struct dirent.d_fileno... yes
  checking whether AUDIT_USER_TTY is declared... no
  checking for tgetent... no
  checking for tgetent in -ltermcap... yes
  checking which library has the termcap functions... using libtermcap
  checking wctype.h usability... yes
  checking wctype.h presence... yes
  checking for wctype.h... yes
  checking wchar.h usability... yes
  checking wchar.h presence... yes
  checking for wchar.h... yes
  checking langinfo.h usability... yes
  checking langinfo.h presence... yes
  checking for langinfo.h... yes
  checking for mbrlen... yes
  checking for mbscasecmp... no
  checking for mbscmp... no
  checking for mbsnrtowcs... yes
  checking for mbsrtowcs... yes
  checking for mbschr... no
  checking for wcrtomb... yes
  checking for wcscoll... yes
  checking for wcsdup... yes
  checking for wcwidth... yes
  checking for wctype... yes
  checking for wcswidth... yes
  checking whether mbrtowc and mbstate_t are properly declared... yes
  checking for iswlower... yes
  checking for iswupper... yes
  checking for towlower... yes
  checking for towupper... yes
  checking for iswctype... yes
  checking for nl_langinfo and CODESET... yes
  checking for wchar_t in wchar.h... yes
  checking for wctype_t in wctype.h... yes
  checking for wint_t in wctype.h... yes
  checking for wcwidth broken with unicode combining characters...
  checking configuration for building shared libraries... supported
  configure: creating ./config.status
  config.status: creating Makefile
  config.status: creating doc/Makefile
  config.status: creating examples/Makefile
  config.status: creating shlib/Makefile
  config.status: creating config.h
  config.status: executing default commands
  rm -f readline.o
  cc -c -DHAVE_CONFIG_H   -DNEED_EXTERN_PC -fPIC -I. -I. -DRL_LIBRARY_VERSION='"6.3"' -arch x86_64 readline.c
  rm -f vi_mode.o
  cc -c -DHAVE_CONFIG_H   -DNEED_EXTERN_PC -fPIC -I. -I. -DRL_LIBRARY_VERSION='"6.3"' -arch x86_64 vi_mode.c
  rm -f funmap.o
  cc -c -DHAVE_CONFIG_H   -DNEED_EXTERN_PC -fPIC -I. -I. -DRL_LIBRARY_VERSION='"6.3"' -arch x86_64 funmap.c
  rm -f keymaps.o
  cc -c -DHAVE_CONFIG_H   -DNEED_EXTERN_PC -fPIC -I. -I. -DRL_LIBRARY_VERSION='"6.3"' -arch x86_64 keymaps.c
  rm -f parens.o
  cc -c -DHAVE_CONFIG_H   -DNEED_EXTERN_PC -fPIC -I. -I. -DRL_LIBRARY_VERSION='"6.3"' -arch x86_64 parens.c
  rm -f search.o
  cc -c -DHAVE_CONFIG_H   -DNEED_EXTERN_PC -fPIC -I. -I. -DRL_LIBRARY_VERSION='"6.3"' -arch x86_64 search.c
  rm -f rltty.o
  cc -c -DHAVE_CONFIG_H   -DNEED_EXTERN_PC -fPIC -I. -I. -DRL_LIBRARY_VERSION='"6.3"' -arch x86_64 rltty.c
  rltty.c:83:7: error: implicit declaration of function 'ioctl' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
    if (ioctl (tty, TIOCGWINSZ, &w) == 0)
        ^
  rltty.c:720:3: error: implicit declaration of function 'ioctl' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
    ioctl (fildes, TIOCSTART, 0);
    ^
  rltty.c:759:3: error: implicit declaration of function 'ioctl' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
    ioctl (fildes, TIOCSTOP, 0);
    ^
  3 errors generated.
  make: *** [rltty.o] Error 1
  
  ============ Building the readline extension module ============
  
  running bdist_wheel
  running build
  running build_py
  creating build
  creating build/lib.macosx-10.15-x86_64-3.8
  copying readline.py -> build/lib.macosx-10.15-x86_64-3.8
  running egg_info
  writing gnureadline.egg-info/PKG-INFO
  writing dependency_links to gnureadline.egg-info/dependency_links.txt
  writing top-level names to gnureadline.egg-info/top_level.txt
  reading manifest file 'gnureadline.egg-info/SOURCES.txt'
  reading manifest template 'MANIFEST.in'
  writing manifest file 'gnureadline.egg-info/SOURCES.txt'
  running build_ext
  building 'gnureadline' extension
  creating build/temp.macosx-10.15-x86_64-3.8
  creating build/temp.macosx-10.15-x86_64-3.8/Modules
  creating build/temp.macosx-10.15-x86_64-3.8/Modules/3.x
  clang -Wno-unused-result -Wsign-compare -Wunreachable-code -fno-common -dynamic -DNDEBUG -g -fwrapv -O3 -Wall -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk -I/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include -I/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/System/Library/Frameworks/Tk.framework/Versions/8.5/Headers -DHAVE_RL_APPEND_HISTORY -DHAVE_RL_CALLBACK -DHAVE_RL_CATCH_SIGNAL -DHAVE_RL_COMPLETION_APPEND_CHARACTER -DHAVE_RL_COMPLETION_DISPLAY_MATCHES_HOOK -DHAVE_RL_COMPLETION_MATCHES -DHAVE_RL_COMPLETION_SUPPRESS_APPEND -DHAVE_RL_PRE_INPUT_HOOK -I. -I/usr/local/opt/[email protected]/Frameworks/Python.framework/Versions/3.8/include/python3.8 -c Modules/3.x/readline.c -o build/temp.macosx-10.15-x86_64-3.8/Modules/3.x/readline.o
  Modules/3.x/readline.c:962:19: warning: initializing 'char *' with an expression of type 'const char *' discards qualifiers [-Wincompatible-pointer-types-discards-qualifiers]
              char *s = _PyUnicode_AsString(r);
                    ^   ~~~~~~~~~~~~~~~~~~~~~~
  1 warning generated.
  clang -bundle -undefined dynamic_lookup -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk build/temp.macosx-10.15-x86_64-3.8/Modules/3.x/readline.o readline/libreadline.a readline/libhistory.a -lncurses -o build/lib.macosx-10.15-x86_64-3.8/gnureadline.cpython-38-darwin.so
  clang: error: no such file or directory: 'readline/libreadline.a'
  clang: error: no such file or directory: 'readline/libhistory.a'
  error: command 'clang' failed with exit status 1
  ----------------------------------------
  ERROR: Failed building wheel for gnureadline
  Running setup.py clean for gnureadline
Failed to build gnureadline
ERROR: Failed to build one or more wheels

Error: Command '['/usr/local/Cellar/pipgrip/0.5.1/libexec/bin/python3.8', '-m', 'pip', 'wheel', '--no-deps', '--disable-pip-version-check', '--wheel-dir', '/Users/rylanpolster/Library/Caches/pip/wheels/pipgrip', '--index-url', 'https://pypi.org/simple', '--trusted-host', 'pypi.org', '--progress-bar=off', 'gnureadline==6.3.8']' returned non-zero exit status 1.

What you expected to happen

Show recursive depndencies for dxpy

Step-by-step reproduction instructions

pipgrip dxpy

I've also tried this with no luck:

pipgrip dxpy --no-cache-dir

Let me know if there's any other information I can provide that would be helpful!

This is not a bug!!! i am unable to execute pipgrip.

I am on Ubuntu 20.04 LTS
Python 3.8.10
pip 20.0.2

Issuing pipgrip --help throws me command not found.
I have edited the .bashrc file by adding
export PATH=/usr/local:$PATH
And The path to site-packages file where pip modules are downloaded in my system.

But still getting the same output.

Please how can I run pipgrip need help.

--test flag or similar for when using test.pypi.org/simple

Description

Include a --test flag to first search https://test.pypi.org/simple/ for the specified packages before moving on to https://pypi.org/simple to gather the test packages requirements

Use case / motivation

Many users will be testing packages and trying to resolve dependency conflicts before publishing on pypi proper. Initially, I used pipgrip -v --tree --index-url https://test.pypi.org/simple/ foo which resulted in "ERROR: No matching distribution found for foo>5.1".

The solution was to run the command pipgrip -v --tree --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple foo.

If adding a --test flag is not viable, perhaps adding a short sentence to the help text of --extra-index-url specifying this use case could be beneficial. I would be happy to submit a pull request if you think this is worth doing.

Related Issues

No.


Great tool, thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.