Skip to content

Instantly share code, notes, and snippets.

@kinow
Last active July 21, 2020 22:27
Show Gist options
  • Save kinow/27eb6f22743efa4fd05e798ef9be94ea to your computer and use it in GitHub Desktop.
Save kinow/27eb6f22743efa4fd05e798ef9be94ea to your computer and use it in GitHub Desktop.
Debugging conda install

Check out conda/conda, and create a venv. Activate it, and run pip install -e ..

Then create a file test.py with the following contents:

from conda.cli.main import main
main('install', '--dry-run', '--use-index-cache', 'cylc==8.0a2')

Now you should be able to debug it. The --use-index-cache is important to skip downloading the repository data every run.

URLs used:
- 'https://conda.anaconda.org/conda-forge/linux-64'
- 'https://conda.anaconda.org/conda-forge/noarch'

Debugging session

There are good comments in the code. And some interesting ones with hints where contributors could help.

image

p.s.: how to activate context.concurrent? It was false for me, and downloading repo data is quite slow...

The part of the code that we are interested, is the dependencies solver. More specifically, the part about deciding which version and which build to use. This comment hints that that is a possible location to start digging.

image

There are many for-loops, and when setting breakpoints it is important to set a condition like "cylc" in str(s) or "cylc-flow" in str(s), as otherwise you spend simply too long releasing the execution and inspecting variables repeatedly.

The logic appears to be:

  • For each cylc-flow package
  • Iterate it in order, ignoring python versions (i.e. conda-forge::cylc-flow-8.0a2-py38h32f6830_2 and conda-forge::cylc-flow-8.0a2-py38h32f6830_2 won't increase build index, and both evaluate to the same version_key in conda.resolve::generate_version_metrics)
  • If the build number changed, we increment the ib index
  • Keep a dictionary with the dist.full_name as key, and the ib as value

image

For cylc-flow, it is iterating all the versions, and the final dictionary contains eqb['conda-forge::cylc-flow-8.0a2-py37hc8dfbb8_0'] = 2 and eqb['conda-forge::cylc-flow-8.0a2-py38h32f6830_0'] = 2.

Possible Explanation 1 (?)

For Python 3.7 (version I am using) there are three builds.

  • cylc-flow-8.0a2-py37hc8dfbb8_0
  • cylc-flow-8.0a2-py37hc8dfbb8_1
  • cylc-flow-8.0a2-py37hc8dfbb8_2

However, the function conda.resolve::generate_version_metrics produces the following entries in the dictionary.

  • 'conda-forge::cylc-flow-8.0a2-py37hc8dfbb8_1': 1
  • 'conda-forge::cylc-flow-8.0a2-py37hc8dfbb8_0': 2

Looks like the version in the dictionary with the greatest build index is 'conda-forge::cylc-flow-8.0a2-py37hc8dfbb8_0': 2, which is not correct.

If Conda is really using this build index when choosing the version, that explains why it is using the first build we produced, instead of the third one.

Turns out this is the correct behavior. So no luck debugging conda install.

Logging

We cat get a lot more in the logs by editing conda.console.py, and adding the following:

    stdoutlogger = logging.getLogger('conda')
    stdoutlogger.setLevel(logging.DEBUG)
    stdoutlogger.addHandler(SysStdoutWriteHandler())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment