A command line utility to display dependency tree of the installed Python packages
Go to file
Marc Abramowitz 32c30cb800 Switch from nose to pytest
Nicer output when asserts fail

Also more actively maintained and more flexible (e.g.: fixtures,
conftest.py)
2014-06-12 15:55:52 -07:00
tests Switch from nose to pytest 2014-06-12 15:55:52 -07:00
.gitignore Switch from nose to pytest 2014-06-12 15:55:52 -07:00
CHANGES.md Add Changelog 2014-05-11 16:27:38 +05:30
LICENSE Add LICENSE 2014-02-05 21:48:26 +05:30
README.rst Update README 2014-05-11 16:20:15 +05:30
pipdeptree.py Hack around a weird behaviour of pip 2014-05-11 15:55:30 +05:30
pytest.ini Switch from nose to pytest 2014-06-12 15:55:52 -07:00
setup.py Bump version to 0.3 2014-05-11 16:27:27 +05:30
tox.ini Switch from nose to pytest 2014-06-12 15:55:52 -07:00

README.rst

pipdeptree
==========

``pipdeptree`` is a command line utility for displaying the python
packages installed in an virtualenv in form of a dependency
tree. Since ``pip freeze`` shows all dependencies as a flat list,
finding out which are the top level packages and which packages do
they depend on requires some effort. It can also be tedious to resolve
conflicting dependencies because ``pip`` doesn't yet have true
dependency resolution (more on this later). This utility tries to
solve these problem.

To some extent, this tool is inspired by ``lein deps :tree`` command
of `Leiningen <http://leiningen.org/>`_.


Installation
------------

.. code-block:: bash

    $ pip install pipdeptree

.. note:: Needs to be installed inside every virtualenv

If you want to use ``pipdeptree`` to view dependency tree of packages
inside a virtualenv, then it needs to be installed inside that env
even if it's already installed globally.


Usage and examples
------------------

To give you a brief idea, here is the output of ``pipdeptree``
compared with ``pip freeze``:

.. code-block:: bash

    $ pip freeze
    Flask==0.10.1
    Flask-Script==0.6.6
    Jinja2==2.7.2
    -e git+git@github.com:naiquevin/lookupy.git@cdbe30c160e1c29802df75e145ea4ad903c05386#egg=Lookupy-master
    Mako==0.9.1
    MarkupSafe==0.18
    SQLAlchemy==0.9.1
    Werkzeug==0.9.4
    alembic==0.6.2
    argparse==1.2.1
    ipython==2.0.0
    itsdangerous==0.23
    psycopg2==2.5.2
    redis==2.9.1
    slugify==0.0.1
    wsgiref==0.1.2

And now see what ``pipdeptree`` outputs,

.. code-block:: bash

    $ pipdeptree
    Warning!!! Possible confusing dependencies found:
    * Mako==0.9.1 -> MarkupSafe [required: >=0.9.2, installed: 0.18]
      Jinja2==2.7.2 -> MarkupSafe [installed: 0.18]
    ------------------------------------------------------------------------
    Lookupy==0.1
    wsgiref==0.1.2
    argparse==1.2.1
    psycopg2==2.5.2
    Flask-Script==0.6.6
      - Flask [installed: 0.10.1]
        - Werkzeug [required: >=0.7, installed: 0.9.4]
        - Jinja2 [required: >=2.4, installed: 2.7.2]
          - MarkupSafe [installed: 0.18]
        - itsdangerous [required: >=0.21, installed: 0.23]
    alembic==0.6.2
      - SQLAlchemy [required: >=0.7.3, installed: 0.9.1]
      - Mako [installed: 0.9.1]
        - MarkupSafe [required: >=0.9.2, installed: 0.18]
    ipython==2.0.0
    slugify==0.0.1
    redis==2.9.1


What's with the warning about confusing dependencies?
-----------------------------------------------------

As seen in the above output, ``pipdeptree`` by default warns about
possible confusing dependencies. Any package that's specified as a
dependency of multiple packages with a different version is considered
as a possible confusing dependency. This is helpful because ``pip``
`doesn't have true dependency resolution
<https://github.com/pypa/pip/issues/988>`_ yet. The warning is printed
to stderr instead of stdout and it can be completely disabled by using
the ``--nowarn`` flag.


Using pipdeptree to write requirements.txt file
-----------------------------------------------

If you wish to track only the top level packages in your
``requirements.txt`` file, it's possible to do so using ``pipdeptree``
by grep-ing only the top-level lines from the output,

.. code-block:: bash

    $ pipdeptree | grep -P '^\w+'
    Lookupy==0.1
    wsgiref==0.1.2
    argparse==1.2.1
    psycopg2==2.5.2
    Flask-Script==0.6.6
    alembic==0.6.2
    ipython==2.0.0
    slugify==0.0.1
    redis==2.9.1

There is a problem here though. The output doesn't mention anything
about ``Lookupy`` being installed as an editable package (refer to the
output of ``pip freeze`` above) and information about it's source is
lost. To fix this, ``pipdeptree`` must be run with a ``-f`` or
``--freeze`` flag.

.. code-block:: bash

    $ pipdeptree -f --nowarn | grep -P '^[\w0-9\-=.]+'
    -e git+git@github.com:naiquevin/lookupy.git@cdbe30c160e1c29802df75e145ea4ad903c05386#egg=Lookupy-master
    wsgiref==0.1.2
    argparse==1.2.1
    psycopg2==2.5.2
    Flask-Script==0.6.6
    alembic==0.6.2
    ipython==2.0.0
    slugify==0.0.1
    redis==2.9.1

    $ pipdeptree -f --nowarn | grep -P '^[\w0-9\-=.]+' > requirements.txt


Usage
-----

.. code-block:: bash

    usage: pipdeptree.py [-h] [-f] [-a] [-l] [-w]

    Dependency tree of the installed python packages

    optional arguments:
      -h, --help        show this help message and exit
      -f, --freeze      Print names so as to write freeze files
      -a, --all         list all deps at top level
      -l, --local-only  If in a virtualenv that has global access donot show
                        globally installed packages
      -w, --nowarn      Inhibit warnings about possibly confusing packages


Known Issues
------------

One thing you might have noticed already is that ``flask`` is shown as
a dependency of ``flask-script``, which although correct, sounds a bit
odd. ``flask-script`` is being used here *because* we are using
``flask`` and not the other way around. Same with ``sqlalchemy`` and
``alembic``.  I haven't yet thought about a possible solution to this!
(May be if libs that are "extensions" could be distinguished from the
ones that are "dependencies". Suggestions are welcome.)


License
-------

MIT (See LICENSE)