← All tasks
pythonAzureAD/azure-activedirectory-library-for-python #61Not a task: not reproduced

Issues with requests != 2.12

envgap__AzureAD__azure-activedirectory-library-for-python-61

01 / FAILURE SIGNATURE

As reported upstream

pkg_resources.ContextualVersionConflict: (requests 2.12.3 (/path/to/lib/python2.7/site-packages/requests-2.12.3-py2.7.egg), Requirement.parse('requests!=2.12.*,>=2.0.0'), set(['adal']))
Not a benchmark task.
  • In a clean container the reported failure did not reproduce, or the known fix did not make the project run.

02 / ENVIRONMENT RECIPE

Base commit
20974f2c988a9150348def36a6c101d9b3be5615
Manifest
setup.py
Reproduce
Awaiting issue-specific recipe
Run under trace
Awaiting a meaningful runtime command

03 / ORIGINAL ISSUE TEXT

AzureAD/azure-activedirectory-library-for-python #61 · read the original issue
In #58 I see you added `requests != 2.12` to the requirements of `adal`. This is sadly not a workable restriction in practice due to the way pip currently does version dependency resolution. To illustrate, consider this simple Python package setup.py:



```python

from setuptools import setup, find_packages



version = '0.1'



setup(

    name='depfail',

    version=version,

    packages=find_packages(),

    entry_points={

        'console_scripts': [

            'run-me = depfail:fail',

        ]

    },

    install_requires=[

        'requests[security]',

        'adal',

    ],

)

```



We'll also have a `depfail/__init__.py` that looks like this:



```python

def fail():

    print("No failure!")

```



This package has two dependencies, `requests[security]` and `adal`. You might rationally think that pip would recursively look through dependencies to build a full set of requirements and then use something like a SAT solver to satisfy the constraints imposed on individual packages (and, of course, fail if it can't satisfy them). Unfortunately, that is not the case. In reality here's what your virtualenv will look like if you do `pip install .`:



```

adal (0.4.3)

cffi (1.9.1)

cryptography (1.6)

depfail (0.1)

enum34 (1.1.6)

idna (2.1)

ipaddress (1.0.17)

pip (9.0.1)

pyasn1 (0.1.9)

pycparser (2.17)

PyJWT (1.4.2)

pyOpenSSL (16.2.0)

python-dateutil (2.6.0)

requests (2.12.3)

setuptools (30.2.0)

six (1.10.0)

wheel (0.30.0a0)

```



As you can see, requests 2.12.3 is installed despite the explicit `!= 2.12`. Of course if we do a `python -c 'import depfail;depfail.fail()'` we get `No failure!`. So what's the problem?



Well, when you define a console_script it uses setuptools entry points to invoke your script. The installed script is available in your PATH and looks something like this:



```

# EASY-INSTALL-ENTRY-SCRIPT: 'depfail==0.1','console_scripts','run-me'

__requires__ = 'depfail==0.1'

import re

import sys

from pkg_resources import load_entry_point



if __name__ == '__main__':

    sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])

    sys.exit(

        load_entry_point('depfail==0.1', 'console_scripts', 'run-me')()

    )

```



`load_entry_point` is a bit more conscientious about whether or not dependencies are satisfied so it proceeds to check to see if adal's requirements are met and...



```

pkg_resources.ContextualVersionConflict: (requests 2.12.3 (/path/to/lib/python2.7/site-packages/requests-2.12.3-py2.7.egg), Requirement.parse('requests!=2.12.*,>=2.0.0'), set(['adal']))

```



This interaction means that `adal` can't effectively block requests 2.12 for users who have requests listed as a dependency that is processed before `adal` (a presumably common scenario). Additionally, this directive causes major breakage for users who invoke their application via console scripts (not an uncommon path).
Continue on GitHub ↗

04 / LABELS

Labels from the report text only; not yet run

No supported category has been assigned.

Label rules and the text that matched
[]