Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AttributeError: 'NoneType' object has no attribute 'excluded_of' on pip 20.3 #9180

Closed
rcjsuen opened this issue Nov 30, 2020 · 14 comments · Fixed by #9369
Closed

AttributeError: 'NoneType' object has no attribute 'excluded_of' on pip 20.3 #9180

rcjsuen opened this issue Nov 30, 2020 · 14 comments · Fixed by #9369
Assignees
Labels
type: bug A confirmed bug or unintended behavior
Milestone

Comments

@rcjsuen
Copy link

rcjsuen commented Nov 30, 2020

Environment

  • pip version: 20.3
  • Python version: 3.9.0
  • OS: Linux

This error has happened locally on my computer, in CircleCI, and in Docker.

Description
Some combination of dependencies seems to cause an AttributeError to be thrown.

ERROR: Exception:
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/site-packages/pip/_internal/cli/base_command.py", line 210, in _main
    status = self.run(options, args)
  File "/usr/local/lib/python3.9/site-packages/pip/_internal/cli/req_command.py", line 180, in wrapper
    return func(self, options, args)
  File "/usr/local/lib/python3.9/site-packages/pip/_internal/commands/install.py", line 318, in run
    requirement_set = resolver.resolve(
  File "/usr/local/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/resolver.py", line 121, in resolve
    self._result = resolver.resolve(
  File "/usr/local/lib/python3.9/site-packages/pip/_vendor/resolvelib/resolvers.py", line 445, in resolve
    state = resolution.resolve(requirements, max_rounds=max_rounds)
  File "/usr/local/lib/python3.9/site-packages/pip/_vendor/resolvelib/resolvers.py", line 344, in resolve
    success = self._backtrack()
  File "/usr/local/lib/python3.9/site-packages/pip/_vendor/resolvelib/resolvers.py", line 287, in _backtrack
    criterion = self.state.criteria[name].excluded_of([candidate])
AttributeError: 'NoneType' object has no attribute 'excluded_of'

Expected behavior
I would expect pip to complete (noting the dependency issue between redis-log-handler and redis) but at least not dying due to an exçeption.

How to Reproduce

  1. Create this Dockerfile.
FROM python:3.9.0
RUN pip install --upgrade pip
RUN pip install celery==5.0.2 kombu==5.0.2 "billiard<4.0,>=3.6.0" redis==3.5.3 redis-log-handler==0.0.1.dev32
  1. Run docker build .
  2. Alternatively, you can also just run pip install celery==5.0.2 kombu==5.0.2 "billiard<4.0,>=3.6.0" redis==3.5.3 redis-log-handler==0.0.1.dev32 in your virtual environment and you should be able to reproduce the error.

Output

$ docker build .
Sending build context to Docker daemon  7.122MB
Step 1/3 : FROM python:3.9.0
 ---> a3fe352c5377
Step 2/3 : RUN pip install --upgrade pip
 ---> Running in 1587f59e4cdd
Collecting pip
  Downloading pip-20.3-py2.py3-none-any.whl (1.5 MB)
Installing collected packages: pip
  Attempting uninstall: pip
    Found existing installation: pip 20.2.4
    Uninstalling pip-20.2.4:
      Successfully uninstalled pip-20.2.4
Successfully installed pip-20.3
Removing intermediate container 1587f59e4cdd
 ---> 81b286c9cca5
Step 3/3 : RUN pip install celery==5.0.2 kombu==5.0.2 "billiard<4.0,>=3.6.0" redis==3.5.3 redis-log-handler==0.0.1.dev32
 ---> Running in c6c759d04b82
Collecting billiard<4.0,>=3.6.0
  Downloading billiard-3.6.3.0-py3-none-any.whl (89 kB)
Collecting celery==5.0.2
  Downloading celery-5.0.2-py3-none-any.whl (392 kB)
Collecting kombu==5.0.2
  Downloading kombu-5.0.2-py2.py3-none-any.whl (180 kB)
Collecting redis==3.5.3
  Downloading redis-3.5.3-py2.py3-none-any.whl (72 kB)
Collecting redis-log-handler==0.0.1.dev32
  Downloading redis_log_handler-0.0.1.dev32-py2.py3-none-any.whl (5.1 kB)
INFO: pip is looking at multiple versions of redis to determine which version is compatible with other requirements. This could take a while.
INFO: pip is looking at multiple versions of kombu to determine which version is compatible with other requirements. This could take a while.
INFO: pip is looking at multiple versions of celery to determine which version is compatible with other requirements. This could take a while.
INFO: pip is looking at multiple versions of billiard to determine which version is compatible with other requirements. This could take a while.
Collecting billiard<4.0,>=3.6.0
  Downloading billiard-3.6.2.0-py3-none-any.whl (89 kB)
ERROR: Exception:
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/site-packages/pip/_internal/cli/base_command.py", line 210, in _main
    status = self.run(options, args)
  File "/usr/local/lib/python3.9/site-packages/pip/_internal/cli/req_command.py", line 180, in wrapper
    return func(self, options, args)
  File "/usr/local/lib/python3.9/site-packages/pip/_internal/commands/install.py", line 318, in run
    requirement_set = resolver.resolve(
  File "/usr/local/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/resolver.py", line 121, in resolve
    self._result = resolver.resolve(
  File "/usr/local/lib/python3.9/site-packages/pip/_vendor/resolvelib/resolvers.py", line 445, in resolve
    state = resolution.resolve(requirements, max_rounds=max_rounds)
  File "/usr/local/lib/python3.9/site-packages/pip/_vendor/resolvelib/resolvers.py", line 344, in resolve
    success = self._backtrack()
  File "/usr/local/lib/python3.9/site-packages/pip/_vendor/resolvelib/resolvers.py", line 287, in _backtrack
    criterion = self.state.criteria[name].excluded_of([candidate])
AttributeError: 'NoneType' object has no attribute 'excluded_of'
The command '/bin/sh -c pip install celery==5.0.2 kombu==5.0.2 "billiard<4.0,>=3.6.0" redis==3.5.3 redis-log-handler==0.0.1.dev32' returned a non-zero code: 2
@pradyunsg
Copy link
Member

@uranusjr ^

@pradyunsg pradyunsg added C: new resolver type: bug A confirmed bug or unintended behavior labels Nov 30, 2020
@pradyunsg pradyunsg modified the milestone: 20.3 Nov 30, 2020
@uranusjr
Copy link
Member

Thanks for the report! I am able to reproduce without kombu (i.e. celery==5.0.2 "billiard<4.0,>=3.6.0" redis==3.5.3 redis-log-handler==0.0.1.dev32).

@uranusjr uranusjr self-assigned this Nov 30, 2020
@uranusjr
Copy link
Member

(For maintainers) So the issue is in the new backtracking code:

incompatibilities_from_broken = [
    (k, v.incompatibilities)
    for k, v in broken_state.criteria.items()
]

# Snipped.

for k, incompatibilities in incompatibilities_from_broken:
    try:
        crit = self.state.criteria[k]
    except KeyError:
        continue
    self.state.criteria[k] = crit.excluded_of(incompatibilities)

excluded_of() returns None if the added incompatibilities would exhaut the criterion’s candidate set. I thought it’s impossible for this to happen here (since all incompatibilites applied here were also in effect in the broken state). This isn’t difficult to fix (just add a clause to trigger further backtracking when that happens), but I’m a bit worried since I am not sure why it’s possible.

@brainwane brainwane added this to the 20.3 milestone Nov 30, 2020
@pradyunsg pradyunsg modified the milestones: 20.3, 20.3.1 Nov 30, 2020
@pradyunsg
Copy link
Member

pradyunsg commented Nov 30, 2020

If I use the commit before the resolvelib update:

ERROR: Cannot install redis==3.5.3 and redis-log-handler 0.0.1.dev32 because these package versions have conflicting dependencies.

The conflict is caused by:
    The user requested redis==3.5.3
    redis-log-handler 0.0.1.dev32 depends on redis==3.0.1

To fix this you could try to:
1. loosen the range of package versions you've specified
2. remove package versions to allow pip attempt to solve the dependency conflict

ERROR: ResolutionImpossible: for help visit https://pip.pypa.io/en/latest/user_guide/#fixing-conflicting-dependencies

IIUC, the criterion being empty is what we should expect in this case? And I think we should be backtracking in that case?

@uranusjr
Copy link
Member

I was not expecting it to happen because at this point we are re-applying the incompatibilities from the broken state, but not the final incompatibility that broke the broken state. Those incompatibilities should therefore not break the new state either, since the broken state should not reach the point it is in in the first place if that’s the case. The newly-added incompatibility (which will be added later) should be the only one that may break the new state, if my reasoning is correct.

Assuming my reasoning in wrong, yes, we should bactrack in this case.

@pradyunsg
Copy link
Member

Maybe? I'm gonna step through a debugger for this.

@brainwane
Copy link
Contributor

@rcjsuen I just want to say: Hello and thank you for your bug report! I'm sorry you're having trouble right now. Thank you for sharing your report with us.

I'll mention here one useful troubleshooting and workaround tip from the documentation: If you need a temporary workaround, you can choose the old resolver behavior using the flag --use-deprecated=legacy-resolver. This will work until we release pip 21.0 (see Deprecation timeline).

(If you don't mind, please also tell us what could have happened differently so you could have tested and caught and reported this during the pip resolver beta period.)

@rcjsuen
Copy link
Author

rcjsuen commented Dec 2, 2020

@rcjsuen I just want to say: Hello and thank you for your bug report! I'm sorry you're having trouble right now. Thank you for sharing your report with us.

@brainwane No worries, happy to help.

I'll mention here one useful troubleshooting and workaround tip from the documentation: If you need a temporary workaround, you can choose the old resolver behavior using the flag --use-deprecated=legacy-resolver. This will work until we release pip 21.0 (see Deprecation timeline).

We worked around the issue by pinning our dependencies so that they do not cause a conflict. Thank you for suggesting this workaround though as I'm sure others reading this issue may get some use out of it.

(If you don't mind, please also tell us what could have happened differently so you could have tested and caught and reported this during the pip resolver beta period.)

Honestly, I don't think there was any way I could have caught this earlier. Our builds just run pip install --upgrade pip and I have no interest in installing a beta version of pip on my system so I don't think I would have caught this until the day 20.3 went live.

@ardila
Copy link

ardila commented Dec 2, 2020

I'm also running into this issue. I don't think pip should be crashing for any set of dependencies right? It should just error out. I expect many people will soon run into this issue as more base docker images including the new version of pip are pushed out. I will follow this issue to see what happens, but for now we are reverting to the old resolver as recommended here.

@uranusjr uranusjr changed the title AttributeError raised on pip 20.3 AttributeError: 'NoneType' object has no attribute 'excluded_of' on pip 20.3 Dec 3, 2020
@pradyunsg pradyunsg modified the milestones: 20.3.2, 20.3.3 Dec 9, 2020
@brainwane
Copy link
Contributor

Sorry this hasn't gotten fixed yet; we have it on the roadmap to fix in the bugfix release 20.3.3.

Honestly, I don't think there was any way I could have caught this earlier. Our builds just run pip install --upgrade pip and I have no interest in installing a beta version of pip on my system so I don't think I would have caught this until the day 20.3 went live.

In pip 20.2, a beta of the new resolver was available, opt-in, using the flag --use-feature=2020-resolver; was this something that could have helped you @rcjsuen ? (Perhaps you did not hear about it in time.) I want to know because we will probably roll out new features in the future and I want to make those rollouts as smooth and testable as possible.

@rcjsuen
Copy link
Author

rcjsuen commented Dec 9, 2020

In pip 20.2, a beta of the new resolver was available, opt-in, using the flag --use-feature=2020-resolver; was this something that could have helped you @rcjsuen ? (Perhaps you did not hear about it in time.)

@brainwane No, it would not have helped me because I have no interest in enabling a flag for a beta feature in our build pipeline.

I want to know because we will probably roll out new features in the future and I want to make those rollouts as smooth and testable as possible.

I think you certainly should offer such a flag so people can test new and upcoming features. You should be aware that it does not mean people will test said new features though. Everyone has their own priorities and I have to admit that testing beta features for pip is not high on my list.

@chriselion
Copy link

@brainwane

we have it on the roadmap to fix in the bugfix release 20.3.3

Did a fix for this make it into 20.3.3? I see that was released a few days ago.

@uranusjr
Copy link
Member

No, there was a critical bug in 20.3.2, and 20.3.3 was assigned as an emergency release to fix that instead. This will likely be in 20.3.4.

@chriselion
Copy link

OK, thanks for the update.

bors bot referenced this issue in duckinator/emanate Jan 31, 2021
215: Update pip to 21.0.1 r=duckinator a=pyup-bot


This PR updates [pip](https://pypi.org/project/pip) from **20.3.3** to **21.0.1**.



<details>
  <summary>Changelog</summary>
  
  
   ### 21.0.1
   ```
   ===================

Bug Fixes
---------

- commands: debug: Use packaging.version.parse to compare between versions. (`9461 &lt;https://github.com/pypa/pip/issues/9461&gt;`_)
- New resolver: Download and prepare a distribution only at the last possible
  moment to avoid unnecessary network access when the same version is already
  installed locally. (`9516 &lt;https://github.com/pypa/pip/issues/9516&gt;`_)

Vendored Libraries
------------------

- Upgrade packaging to 20.9
   ```
   
  
  
   ### 21.0
   ```
   =================

Deprecations and Removals
-------------------------

- Drop support for Python 2. (`6148 &lt;https://github.com/pypa/pip/issues/6148&gt;`_)
- Remove support for legacy wheel cache entries that were created with pip
  versions older than 20.0. (`7502 &lt;https://github.com/pypa/pip/issues/7502&gt;`_)
- Remove support for VCS pseudo URLs editable requirements. It was emitting
  deprecation warning since version 20.0. (`7554 &lt;https://github.com/pypa/pip/issues/7554&gt;`_)
- Modernise the codebase after Python 2. (`8802 &lt;https://github.com/pypa/pip/issues/8802&gt;`_)
- Drop support for Python 3.5. (`9189 &lt;https://github.com/pypa/pip/issues/9189&gt;`_)
- Remove the VCS export feature that was used only with editable VCS
  requirements and had correctness issues. (`9338 &lt;https://github.com/pypa/pip/issues/9338&gt;`_)

Features
--------

- Add ``--ignore-requires-python`` support to pip download. (`1884 &lt;https://github.com/pypa/pip/issues/1884&gt;`_)
- New resolver: Error message shown when a wheel contains inconsistent metadata
  is made more helpful by including both values from the file name and internal
  metadata. (`9186 &lt;https://github.com/pypa/pip/issues/9186&gt;`_)

Bug Fixes
---------

- Fix a regression that made ``pip wheel`` do a VCS export instead of a VCS clone
  for editable requirements. This broke VCS requirements that need the VCS
  information to build correctly. (`9273 &lt;https://github.com/pypa/pip/issues/9273&gt;`_)
- Fix ``pip download`` of editable VCS requirements that need VCS information
  to build correctly. (`9337 &lt;https://github.com/pypa/pip/issues/9337&gt;`_)

Vendored Libraries
------------------

- Upgrade msgpack to 1.0.2.
- Upgrade requests to 2.25.1.

Improved Documentation
----------------------

- Render the unreleased pip version change notes on the news page in docs. (`9172 &lt;https://github.com/pypa/pip/issues/9172&gt;`_)
- Fix broken email link in docs feedback banners. (`9343 &lt;https://github.com/pypa/pip/issues/9343&gt;`_)


.. note

    You should *NOT* be adding new change log entries to this file, this
    file is managed by towncrier. You *may* edit previous change logs to
    fix problems like typo corrections or such.

    To add a new change log entry, please see
        https://pip.pypa.io/en/latest/development/contributing/#news-entries

.. towncrier release notes start
   ```
   
  
  
   ### 20.3.4
   ```
   ===================

Features
--------

- ``pip wheel`` now verifies the built wheel contains valid metadata, and can be
  installed by a subsequent ``pip install``. This can be disabled with
  ``--no-verify``. (`9206 &lt;https://github.com/pypa/pip/issues/9206&gt;`_)
- Improve presentation of XMLRPC errors in pip search. (`9315 &lt;https://github.com/pypa/pip/issues/9315&gt;`_)

Bug Fixes
---------

- Fixed hanging VCS subprocess calls when the VCS outputs a large amount of data
  on stderr. Restored logging of VCS errors that was inadvertently removed in pip
  20.2. (`8876 &lt;https://github.com/pypa/pip/issues/8876&gt;`_)
- Fix error when an existing incompatibility is unable to be applied to a backtracked state. (`9180 &lt;https://github.com/pypa/pip/issues/9180&gt;`_)
- New resolver: Discard a faulty distribution, instead of quitting outright.
  This implementation is taken from 20.2.2, with a fix that always makes the
  resolver iterate through candidates from indexes lazily, to avoid downloading
  candidates we do not need. (`9203 &lt;https://github.com/pypa/pip/issues/9203&gt;`_)
- New resolver: Discard a source distribution if it fails to generate metadata,
  instead of quitting outright. This implementation is taken from 20.2.2, with a
  fix that always makes the resolver iterate through candidates from indexes
  lazily, to avoid downloading candidates we do not need. (`9246 &lt;https://github.com/pypa/pip/issues/9246&gt;`_)

Vendored Libraries
------------------

- Upgrade resolvelib to 0.5.4.
   ```
   
  
</details>


 

<details>
  <summary>Links</summary>
  
  - PyPI: https://pypi.org/project/pip
  - Changelog: https://pyup.io/changelogs/pip/
  - Homepage: https://pip.pypa.io/
</details>



Co-authored-by: pyup-bot <github-bot@pyup.io>
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Oct 5, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
type: bug A confirmed bug or unintended behavior
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants