Git Product home page Git Product logo

pipdeptree's Introduction

pipdeptree

PyPI Supported Python versions Downloads check pre-commit.ci status

pipdeptree is a command line utility for displaying the installed python packages in form of a dependency tree. It works for packages installed globally on a machine as well as in a virtualenv. 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's also tedious to resolve conflicting dependencies that could have been installed because older version of pip didn't have true dependency resolution1. pipdeptree can help here by identifying conflicting dependencies installed in the environment.

To some extent, pipdeptree is inspired by the lein deps :tree command of Leiningen.

Installation

pip install pipdeptree

Running in virtualenvs

New in ver. 2.0.0

If you want to run pipdeptree in the context of a particular virtualenv, you can specify the --python option. Note that this capability has been recently added in version 2.0.0.

Alternatively, you may also install pipdeptree inside the virtualenv and then run it from there.

As of version 2.21.0, you may also pass --python auto, where it will attempt to detect your virtual environment and grab the interpreter from there. It will fail if it is unable to detect one.

Usage and examples

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

$ pip freeze
Flask==0.10.1
itsdangerous==0.24
Jinja2==2.11.2
-e [email protected]:naiquevin/lookupy.git@cdbe30c160e1c29802df75e145ea4ad903c05386#egg=Lookupy
MarkupSafe==0.22
pipdeptree @ file:///private/tmp/pipdeptree-2.0.0b1-py3-none-any.whl
Werkzeug==0.11.2

And now see what pipdeptree outputs,

$ pipdeptree
Warning!!! Possibly conflicting dependencies found:
* Jinja2==2.11.2
 - MarkupSafe [required: >=0.23, installed: 0.22]
------------------------------------------------------------------------
Flask==0.10.1
  - itsdangerous [required: >=0.21, installed: 0.24]
  - Jinja2 [required: >=2.4, installed: 2.11.2]
    - MarkupSafe [required: >=0.23, installed: 0.22]
  - Werkzeug [required: >=0.7, installed: 0.11.2]
Lookupy==0.1
pipdeptree==2.0.0b1
  - pip [required: >=6.0.0, installed: 20.1.1]
setuptools==47.1.1
wheel==0.34.2

Is it possible to find out why a particular package is installed?

New in ver. 0.5.0

Yes, there's a --reverse (or simply -r) flag for this. To find out which packages depend on a particular package(s), it can be combined with --packages option as follows:

$ pipdeptree --reverse --packages itsdangerous,MarkupSafe
Warning!!! Possibly conflicting dependencies found:
* Jinja2==2.11.2
 - MarkupSafe [required: >=0.23, installed: 0.22]
------------------------------------------------------------------------
itsdangerous==0.24
  - Flask==0.10.1 [requires: itsdangerous>=0.21]
MarkupSafe==0.22
  - Jinja2==2.11.2 [requires: MarkupSafe>=0.23]
    - Flask==0.10.1 [requires: Jinja2>=2.4]

What's with the warning about conflicting dependencies?

As seen in the above output, pipdeptree by default warns about possible conflicting dependencies. Any package that's specified as a dependency of multiple packages with different versions is considered as a conflicting dependency. Conflicting dependencies are possible if older version of pip<=20.2 (without the new resolver2) was ever used to install dependencies at some point. The warning is printed to stderr instead of stdout and it can be completely silenced by specifying the -w silence or --warn silence option. On the other hand, it can be made mode strict with --warn fail, in which case the command will not only print the warnings to stderr but also exit with a non-zero status code. This is useful if you want to fit this tool into your CI pipeline.

Note: The --warn option is added in version 0.6.0. If you are using an older version, use --nowarn flag to silence the warnings.

Warnings about circular dependencies

In case any of the packages have circular dependencies (eg. package A depends on package B and package B depends on package A), then pipdeptree will print warnings about that as well.

$ pipdeptree --exclude pip,pipdeptree,setuptools,wheel
Warning!!! Cyclic dependencies found:
- CircularDependencyA => CircularDependencyB => CircularDependencyA
- CircularDependencyB => CircularDependencyA => CircularDependencyB
------------------------------------------------------------------------
wsgiref==0.1.2
argparse==1.2.1

Similar to the warnings about conflicting dependencies, these too are printed to stderr and can be controlled using the --warn option.

In the above example, you can also see --exclude option which is the opposite of --packages ie. these packages will be excluded from the output.

Using pipdeptree to write requirements.txt file

If you wish to track only top level packages in your requirements.txt file, it's possible by grep-ing3. only the top-level lines from the output,

$ pipdeptree --warn silence | grep -E '^\w+'
Flask==0.10.1
gnureadline==8.0.0
Lookupy==0.1
pipdeptree==2.0.0b1
setuptools==47.1.1
wheel==0.34.2

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 its source is lost. To fix this, pipdeptree must be run with a -f or --freeze flag.

$ pipdeptree -f --warn silence | grep -E '^[a-zA-Z0-9\-]+'
Flask==0.10.1
gnureadline==8.0.0
-e [email protected]:naiquevin/lookupy.git@cdbe30c160e1c29802df75e145ea4ad903c05386#egg=Lookupy
pipdeptree @ file:///private/tmp/pipdeptree-2.0.0b1-py3-none-any.whl
setuptools==47.1.1
wheel==0.34.2

$ pipdeptree -f --warn silence | grep -E '^[a-zA-Z0-9\-]+' > requirements.txt

The freeze flag will not prefix child dependencies with hyphens, so you could dump the entire output of pipdeptree -f to the requirements.txt file thus making it human-friendly (due to indentations) as well as pip-friendly.

$ pipdeptree -f | tee locked-requirements.txt
Flask==0.10.1
  itsdangerous==0.24
  Jinja2==2.11.2
    MarkupSafe==0.23
  Werkzeug==0.11.2
gnureadline==8.0.0
-e [email protected]:naiquevin/lookupy.git@cdbe30c160e1c29802df75e145ea4ad903c05386#egg=Lookupy
pipdeptree @ file:///private/tmp/pipdeptree-2.0.0b1-py3-none-any.whl
  pip==20.1.1
setuptools==47.1.1
wheel==0.34.2

On confirming that there are no conflicting dependencies, you can even treat this as a "lock file" where all packages, including the transient dependencies will be pinned to their currently installed versions. Note that the locked-requirements.txt file could end up with duplicate entries. Although pip install wouldn't complain about that, you can avoid duplicate lines (at the cost of losing indentation) as follows,

$ pipdeptree -f | sed 's/ //g' | sort -u > locked-requirements.txt

Using pipdeptree with external tools

New in ver. 0.5.0

It's also possible to have pipdeptree output json representation of the dependency tree so that it may be used as input to other external tools.

$ pipdeptree --json

Note that --json will output a flat list of all packages with their immediate dependencies. This is not very useful in itself. To obtain nested json, use --json-tree

New in ver. 0.11.0

$ pipdeptree --json-tree

Visualizing the dependency graph

The dependency graph can also be visualized using GraphViz:

$ pipdeptree --graph-output dot > dependencies.dot
$ pipdeptree --graph-output pdf > dependencies.pdf
$ pipdeptree --graph-output png > dependencies.png
$ pipdeptree --graph-output svg > dependencies.svg

Note that graphviz is an optional dependency ie. required only if you want to use --graph-output. If the version of graphviz installed in the env is older than 0.18.1, then a warning will be displayed about upgrading graphviz. Support for older versions of graphviz will be dropped soon.

Since version 2.0.0b1, --package and --reverse flags are supported for all output formats ie. text, json, json-tree and graph.

In earlier versions, --json, --json-tree and --graph-output options override --package and --reverse.

Usage

% pipdeptree --help
usage: pipdeptree [-h] [-v] [-w [{silence,suppress,fail}]] [--python PYTHON] [-p P] [-e P] [-a] [-l | -u] [-f] [--encoding E] [-d D] [-r] [--license] [-j | --json-tree | --mermaid | --graph-output FMT]

Dependency tree of the installed python packages

options:
  -h, --help          show this help message and exit
  -v, --version       show program's version number and exit
  -w [{silence,suppress,fail}], --warn [{silence,suppress,fail}]
                      warning control: suppress will show warnings but return 0 whether or not they are present; silence will not show warnings at all and always return 0; fail will show warnings and return 1 if any are present (default:
                      suppress)

select:
  choose what to render

  --python PYTHON     Python interpreter to inspect (default: /usr/local/bin/python)
  -p P, --packages P  comma separated list of packages to show - wildcards are supported, like 'somepackage.*' (default: None)
  -e P, --exclude P   comma separated list of packages to not show - wildcards are supported, like 'somepackage.*'. (cannot combine with -p or -a) (default: None)
  -a, --all           list all deps at top level (default: False)
  -l, --local-only    if in a virtualenv that has global access do not show globally installed packages (default: False)
  -u, --user-only     only show installations in the user site dir (default: False)

render:
  choose how to render the dependency tree (by default will use text mode)

  -f, --freeze        print names so as to write freeze files (default: False)
  --encoding E        the encoding to use when writing to the output (default: utf-8)
  -d D, --depth D     limit the depth of the tree (text render only) (default: inf)
  -r, --reverse       render the dependency tree in the reverse fashion ie. the sub-dependencies are listed with the list of packages that need them under them (default: False)
  --license           list the license(s) of a package (text render only) (default: False)
  -j, --json          raw JSON - this will yield output that may be used by external tools (default: False)
  --json-tree         nested JSON - mimics the text format layout (default: False)
  --mermaid           https://mermaid.js.org flow diagram (default: False)
  --graph-output FMT  Graphviz rendering with the value being the graphviz output e.g.: dot, jpeg, pdf, png, svg (default: None)

Known issues

  1. pipdeptree relies on the internal API of pip. I fully understand that it's a bad idea but it mostly works! On rare occasions, it breaks when a new version of pip is out with backward incompatible changes in internal API. So beware if you are using this tool in environments in which pip version is unpinned, specially automation or CD/CI pipelines.

Limitations & Alternatives

pipdeptree merely looks at the installed packages in the current environment using pip, constructs the tree, then outputs it in the specified format. If you want to generate the dependency tree without installing the packages, then you need a dependency resolver. You might want to check alternatives such as pipgrip or poetry.

License

MIT (See LICENSE)

Footnotes

Footnotes

  1. pip version 20.3 has been released in Nov 2020 with the dependency resolver <https://blog.python.org/2020/11/pip-20-3-release-new-resolver.html>_

  2. pip version 20.3 has been released in Nov 2020 with the dependency resolver <https://blog.python.org/2020/11/pip-20-3-release-new-resolver.html>_

  3. If you are on windows (powershell) you can run pipdeptree --warn silence | Select-String -Pattern '^\w+' instead of grep

pipdeptree's People

Contributors

aidos avatar ajkerrigan avatar bh avatar borda avatar chsava avatar ciarancourtney avatar dependabot[bot] avatar dqkqd avatar dunedan avatar eli-b avatar f3flight avatar gaborbernat avatar garar avatar gschaffner avatar haikoschol avatar jensens avatar jmbowman avatar johnyf avatar jwodder avatar kdeldycke avatar kemzeb avatar msabramo avatar naiquevin avatar nikolas avatar pjw91 avatar pre-commit-ci[bot] avatar sschuberth avatar tomkins avatar tterrace avatar xiacunshun 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  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

pipdeptree's Issues

Minor improvements to output readability

A few suggestions:

  • (recursively) sort the output, instead of having the packages in a semi-random order
  • provide a switch that allows limiting the depth of dependencies (possibly using [...] as a marker for "deeper dependencies not shown here) or hiding the installed version.
  • provide a switch for listing packages that are not dependencies of other packages.

Nice work!

Limit to individual project directories

It would be nice if the dependency reporting could be limited to a specific project directory. Usually, I'm not interested in all dependencies of all packages, but only in the (transitive) dependencies of a specific project, ideally even before having installed any of the dependencies.

graphviz is not available, but necessary for the output option. Please install it.

When I try to run pipdeptree with output of png, svg or pdf, it tells me that Graphviz is not installed, but it appears to be already installed.

root@8bf322acc378:/edx/app/edxapp/edx-platform# pipdeptree --graph-output png > pipdeps.png
graphviz is not available, but necessary for the output option. Please install it.

root@8bf322acc378:/edx/app/edxapp/edx-platform# apt-get install graphviz
Reading package lists... Done
Building dependency tree
Reading state information... Done
graphviz is already the newest version (2.38.0-12ubuntu2.1).
0 upgraded, 0 newly installed, 0 to remove and 4 not upgraded.

root@8bf322acc378:/edx/app/edxapp/edx-platform# pipdeptree --graph-output png > pipdeps.png
graphviz is not available, but necessary for the output option. Please install it.

The reverse view should group all the packages that require a certain package together.

When using pipdeptree -l -r, it's confusing to see the same package listed multiple times in the (long) list of required packages. It can lead a user to incorrectly think a package is only required by one package, because they didn't notice the package is listed again elsewhere in the output.

Also, the same dependency is sometimes listed more than once. For example, I get:

six==1.10.0

  • protobuf==3.0.0b2.post2 [requires: six>=1.1.0]
    • gcloud==0.12.0 [requires: protobuf]
      six==1.10.0
  • protobuf==3.0.0b2.post2 [requires: six]
    • gcloud==0.12.0 [requires: protobuf]

And sometimes I also get seeming contradictory dependency listings (yes, I did use -r -l here too):

six==1.10.0

  • Paste==2.0.3 [requires: six>=1.3.0]
    • pysaml2==4.0.5 [requires: Paste]
      six==1.10.0
  • Paste==2.0.3 [requires: six>=1.5]
    • pysaml2==4.0.5 [requires: Paste]

Option to limit depth of the dependency tree shown

It would be nice to have an option -d N or --depth N to limit the depth of the tree shown either in direct dependencies or reverse.
This would also help to find packages left behind when other packages are removed (leaves).

Support user dir

It would be nice to support user directories as in pip install --user

* Edited

Python 3.3 and 3.4 traceback

Works fine on python 2.7.8 but on both 3.3.5 and 3.4.2 I get the following traceback:

Traceback (most recent call last):
  File "/Users/jp/.virtualenvs/python3.3/bin/pipdeptree", line 9, in <module>
    load_entry_point('pipdeptree==0.4.1', 'console_scripts', 'pipdeptree')()
  File "/Users/jp/.virtualenvs/python3.3/lib/python3.3/site-packages/pipdeptree.py", line 250, in main
    is_empty, cyclic = peek_into(cyclic_deps(pkgs, pkg_index))
  File "/Users/jp/.virtualenvs/python3.3/lib/python3.3/site-packages/pipdeptree.py", line 202, in peek_into
    a.next()
AttributeError: 'itertools._tee' object has no attribute 'next'

List all "root" packages, even ones without dependencies

Hey naiquevin,

In one of my virtual environments I have the cx_Oracle package installed. It requires no dependencies, and isn't a dependency of any other package. However, when running pipdeptree with either the -a or -r flags, this package isn't listed. Wouldn't it be useful for it to be listed?

What I want is a list of all my "root" packages, that is, packages which may or may not have dependencies, but aren't a dependency of any other package themselves. That way, I can simply output this list to my requirements.txt, making it shorter.

I'm willing to submit a PR at some point in the future if you have interest in this feature but lack the time to implement it yourself.

Thanks in advance!

pipdeptree cannot run with pip 10 as get_installed_distributions is gone

Running pipdeptree with no arguments with the recently released pip 10 results in this:

Traceback (most recent call last):
  File "/home/cdown/.pyenv/versions/3.6.3/bin/pipdeptree", line 11, in <module>
    sys.exit(main())
  File "/home/cdown/.pyenv/versions/3.6.3/lib/python3.6/site-packages/pipdeptree.py", line 550, in main
    pkgs = pip.get_installed_distributions(local_only=args.local_only,
AttributeError: module 'pip' has no attribute 'get_installed_distributions'

This seems an intentional API restructuring, see pypa/pip#5154.

Confusing Dependencies section should not display non-conflicting dependencies

For example:

* django-guardian==1.2.2 -> Django [installed: 1.6.5]
  djrill==1.0.0 -> Django [required: >=1.3, installed: 1.6.5]
  django-mptt==0.6.1 -> Django [required: >=1.4.2, installed: 1.6.5]
  django-cors-headers==0.12 -> Django [required: >=1.4, installed: 1.6.5]

All of them require Django above a certain version. Since none of those packages limit the Django version in use there is no conflict (Django 1.4.2 and above is required).

Infinite recursion error when packages have a circular dependency

If there is a circular dependency in your packages, then pipdeptree dies with an infinite recursion error.

One way to reproduce this:

$ virtualenv circular_deps_Zope2.venv
New python executable in circular_deps_Zope2.venv/bin/python
Installing setuptools, pip...done.

$ circular_deps_Zope2.venv/bin/pip install pipdeptree Zope2==2.13.19
...

$ circular_deps_Zope2.venv/bin/pipdeptree --all
Warning!!! Possible confusing dependencies found:
* Zope2==2.13.19 -> zope.browserpage [installed: 4.0.0]
  zope.viewlet==3.7.2 -> zope.browserpage [required: >=3.10.1, installed: 4.0.0]
* Products.OFSP==2.13.2 -> Zope2 [required: >=2.13.0a1, installed: 2.13.19]
  Products.BTreeFolder2==2.13.4 -> Zope2 [required: >=2.13.0a1, installed: 2.13.19]
  Products.StandardCacheManagers==2.13.0 -> Zope2 [required: >=2.13.0a1, installed: 2.13.19]
  Products.ZCatalog==3.0.2 -> Zope2 [installed: 2.13.19]
  Products.PythonScripts==2.13.2 -> Zope2 [required: >=2.13.0a1, installed: 2.13.19]
  Products.ExternalMethod==2.13.0 -> Zope2 [required: >=2.13.0a1, installed: 2.13.19]
  Products.ZCTextIndex==2.13.5 -> Zope2 [required: >=2.13.0dev, installed: 2.13.19]
  Products.MailHost==2.13.1 -> Zope2 [required: >=2.13.0a1, installed: 2.13.19]
* zope.testbrowser==4.0.4 -> pytz [required: >dev, installed: 2014.4]
  Zope2==2.13.19 -> pytz [installed: 2014.4]
  zope.i18n==3.8.0 -> pytz [installed: 2014.4]
  DateTime==4.0.1 -> pytz [installed: 2014.4]
* zope.filerepresentation==4.0.2 -> zope.interface [installed: 4.1.1]
  ZEO==4.0.0 -> zope.interface [installed: 4.1.1]
  zope.pagetemplate==4.0.4 -> zope.interface [installed: 4.1.1]
  zope.contentprovider==3.7.2 -> zope.interface [installed: 4.1.1]
  zope.component==4.2.1 -> zope.interface [required: >=4.1.0, installed: 4.1.1]
  zope.tal==4.0.0 -> zope.interface [installed: 4.1.1]
  persistent==4.0.8 -> zope.interface [installed: 4.1.1]
  zope.proxy==4.1.4 -> zope.interface [installed: 4.1.1]
  zope.configuration==4.0.3 -> zope.interface [installed: 4.1.1]
  zope.annotation==4.2.0 -> zope.interface [installed: 4.1.1]
  zope.testbrowser==4.0.4 -> zope.interface [installed: 4.1.1]
  zope.processlifetime==2.0.0 -> zope.interface [installed: 4.1.1]
  ZODB==4.0.0 -> zope.interface [installed: 4.1.1]
  zope.site==3.9.2 -> zope.interface [installed: 4.1.1]
  zope.sendmail==3.7.5 -> zope.interface [installed: 4.1.1]
  zope.ptresource==3.9.0 -> zope.interface [installed: 4.1.1]
  BTrees==4.0.8 -> zope.interface [installed: 4.1.1]
  Zope2==2.13.19 -> zope.interface [installed: 4.1.1]
  zope.browserpage==4.0.0 -> zope.interface [installed: 4.1.1]
  zope.exceptions==4.0.7 -> zope.interface [installed: 4.1.1]
  zope.browser==2.0.2 -> zope.interface [installed: 4.1.1]
  zope.viewlet==3.7.2 -> zope.interface [installed: 4.1.1]
  Products.ZCatalog==3.0.2 -> zope.interface [installed: 4.1.1]
  zope.publisher==3.13.4 -> zope.interface [installed: 4.1.1]
  zope.security==4.0.1 -> zope.interface [installed: 4.1.1]
  zExceptions==2.13.0 -> zope.interface [installed: 4.1.1]
  zope.schema==4.4.1 -> zope.interface [required: >=3.6.0, installed: 4.1.1]
  zope.tales==4.0.2 -> zope.interface [installed: 4.1.1]
  AccessControl==3.0.8 -> zope.interface [installed: 4.1.1]
  zope.size==4.0.1 -> zope.interface [installed: 4.1.1]
  Products.ZCTextIndex==2.13.5 -> zope.interface [installed: 4.1.1]
  zope.browsermenu==4.0.0 -> zope.interface [installed: 4.1.1]
  zope.location==4.0.3 -> zope.interface [required: >=4.0.2, installed: 4.1.1]
  Acquisition==4.0 -> zope.interface [installed: 4.1.1]
  DateTime==4.0.1 -> zope.interface [installed: 4.1.1]
  zope.lifecycleevent==4.0.3 -> zope.interface [installed: 4.1.1]
  zope.traversing==4.0.0 -> zope.interface [required: >=4.0.4, installed: 4.1.1]
  zope.browserresource==4.0.1 -> zope.interface [installed: 4.1.1]
  transaction==1.4.3 -> zope.interface [installed: 4.1.1]
  zope.testing==4.1.3 -> zope.interface [installed: 4.1.1]
  zope.container==4.0.0 -> zope.interface [installed: 4.1.1]
* zope.pagetemplate==4.0.4 -> zope.traversing [installed: 4.0.0]
  Zope2==2.13.19 -> zope.traversing [installed: 4.0.0]
  zope.browserpage==4.0.0 -> zope.traversing [installed: 4.0.0]
  zope.viewlet==3.7.2 -> zope.traversing [installed: 4.0.0]
  zope.browsermenu==4.0.0 -> zope.traversing [required: >3.7, installed: 4.0.0]
  zope.browserresource==4.0.1 -> zope.traversing [required: >3.7, installed: 4.0.0]
  zope.container==4.0.0 -> zope.traversing [required: >=4.0.0a1, installed: 4.0.0]
* Zope2==2.13.19 -> zope.contenttype [installed: 4.0.1]
  zope.publisher==3.13.4 -> zope.contenttype [required: >=3.5, installed: 4.0.1]
  zope.browserresource==4.0.1 -> zope.contenttype [required: >=4.0.1, installed: 4.0.1]
* ZEO==4.0.0 -> ZConfig [installed: 3.0.4]
  ZODB==4.0.0 -> ZConfig [installed: 3.0.4]
  Zope2==2.13.19 -> ZConfig [installed: 3.0.4]
  zdaemon==4.0.0 -> ZConfig [installed: 3.0.4]
  zLOG==2.12.0 -> ZConfig [required: >=2.9.2, installed: 3.0.4]
* zope.pagetemplate==4.0.4 -> zope.component [installed: 4.2.1]
  Products.StandardCacheManagers==2.13.0 -> zope.component [installed: 4.2.1]
  zope.contentprovider==3.7.2 -> zope.component [installed: 4.2.1]
  zope.annotation==4.2.0 -> zope.component [installed: 4.2.1]
  zope.site==3.9.2 -> zope.component [required: >=3.8.0, installed: 4.2.1]
  zope.sendmail==3.7.5 -> zope.component [required: >=3.8.0, installed: 4.2.1]
  Zope2==2.13.19 -> zope.component [installed: 4.2.1]
  zope.browserpage==4.0.0 -> zope.component [required: >=3.7, installed: 4.2.1]
  zope.viewlet==3.7.2 -> zope.component [installed: 4.2.1]
  zope.publisher==3.13.4 -> zope.component [installed: 4.2.1]
  zope.security==4.0.1 -> zope.component [installed: 4.2.1]
  AccessControl==3.0.8 -> zope.component [installed: 4.2.1]
  zope.i18n==3.8.0 -> zope.component [installed: 4.2.1]
  zope.browsermenu==4.0.0 -> zope.component [required: >=3.7, installed: 4.2.1]
  zope.traversing==4.0.0 -> zope.component [installed: 4.2.1]
  zope.browserresource==4.0.1 -> zope.component [required: >=3.8.0, installed: 4.2.1]
  zope.container==4.0.0 -> zope.component [installed: 4.2.1]
* Products.BTreeFolder2==2.13.4 -> zope.lifecycleevent [installed: 4.0.3]
  zope.site==3.9.2 -> zope.lifecycleevent [installed: 4.0.3]
  Zope2==2.13.19 -> zope.lifecycleevent [installed: 4.0.3]
  zope.container==4.0.0 -> zope.lifecycleevent [required: >=3.5.2, installed: 4.0.3]
* Products.OFSP==2.13.2 -> AccessControl [installed: 3.0.8]
  Products.BTreeFolder2==2.13.4 -> AccessControl [installed: 3.0.8]
  Products.StandardCacheManagers==2.13.0 -> AccessControl [installed: 3.0.8]
  Zope2==2.13.19 -> AccessControl [required: >=2.13.2, installed: 3.0.8]
  Products.ZCatalog==3.0.2 -> AccessControl [installed: 3.0.8]
  Products.PythonScripts==2.13.2 -> AccessControl [installed: 3.0.8]
  Products.ExternalMethod==2.13.0 -> AccessControl [installed: 3.0.8]
  DocumentTemplate==2.13.2 -> AccessControl [installed: 3.0.8]
  Products.ZCTextIndex==2.13.5 -> AccessControl [installed: 3.0.8]
* zope.contentprovider==3.7.2 -> zope.publisher [installed: 3.13.4]
  zope.ptresource==3.9.0 -> zope.publisher [installed: 3.13.4]
  Zope2==2.13.19 -> zope.publisher [installed: 3.13.4]
  zope.browserpage==4.0.0 -> zope.publisher [required: >=3.8, installed: 3.13.4]
  zope.viewlet==3.7.2 -> zope.publisher [installed: 3.13.4]
  zExceptions==2.13.0 -> zope.publisher [installed: 3.13.4]
  AccessControl==3.0.8 -> zope.publisher [installed: 3.13.4]
  zope.browsermenu==4.0.0 -> zope.publisher [installed: 3.13.4]
  zope.traversing==4.0.0 -> zope.publisher [installed: 3.13.4]
  zope.browserresource==4.0.1 -> zope.publisher [required: >=3.8, installed: 3.13.4]
  zope.container==4.0.0 -> zope.publisher [installed: 3.13.4]
* zope.annotation==4.2.0 -> BTrees [installed: 4.0.8]
  ZODB==4.0.0 -> BTrees [installed: 4.0.8]
  ZODB3==3.11.0 -> BTrees [required: >=4.0.0dev, installed: 4.0.8]
  zope.container==4.0.0 -> BTrees [installed: 4.0.8]
* zope.pagetemplate==4.0.4 -> zope.tales [installed: 4.0.2]
  zope.contentprovider==3.7.2 -> zope.tales [installed: 4.0.2]
  Zope2==2.13.19 -> zope.tales [required: >=3.5.0, installed: 4.0.2]
* ZEO==4.0.0 -> ZODB [required: >=4.0.0b2, installed: 4.0.0]
  ZODB3==3.11.0 -> ZODB [required: >=4.0.0dev, installed: 4.0.0]
* zope.filerepresentation==4.0.2 -> zope.schema [installed: 4.4.1]
  zope.contentprovider==3.7.2 -> zope.schema [installed: 4.4.1]
  zope.configuration==4.0.3 -> zope.schema [installed: 4.4.1]
  zope.testbrowser==4.0.4 -> zope.schema [installed: 4.4.1]
  zope.sendmail==3.7.5 -> zope.schema [installed: 4.4.1]
  Zope2==2.13.19 -> zope.schema [installed: 4.4.1]
  zope.browserpage==4.0.0 -> zope.schema [installed: 4.4.1]
  zope.viewlet==3.7.2 -> zope.schema [installed: 4.4.1]
  Products.ZCatalog==3.0.2 -> zope.schema [installed: 4.4.1]
  zope.security==4.0.1 -> zope.schema [installed: 4.4.1]
  AccessControl==3.0.8 -> zope.schema [installed: 4.4.1]
  zope.i18n==3.8.0 -> zope.schema [installed: 4.4.1]
  zope.browsermenu==4.0.0 -> zope.schema [installed: 4.4.1]
  zope.location==4.0.3 -> zope.schema [required: >=4.2.2, installed: 4.4.1]
  zope.browserresource==4.0.1 -> zope.schema [installed: 4.4.1]
  zope.container==4.0.0 -> zope.schema [installed: 4.4.1]
* zope.deferredimport==4.0.0 -> zope.proxy [installed: 4.1.4]
  zope.annotation==4.2.0 -> zope.proxy [installed: 4.1.4]
  Zope2==2.13.19 -> zope.proxy [installed: 4.1.4]
  zope.publisher==3.13.4 -> zope.proxy [installed: 4.1.4]
  zope.security==4.0.1 -> zope.proxy [required: >=4.1.0, installed: 4.1.4]
  zope.location==4.0.3 -> zope.proxy [required: >=4.0.1, installed: 4.1.4]
  zope.traversing==4.0.0 -> zope.proxy [installed: 4.1.4]
* zope.ptresource==3.9.0 -> zope.pagetemplate [installed: 4.0.4]
  Zope2==2.13.19 -> zope.pagetemplate [installed: 4.0.4]
  zope.browserpage==4.0.0 -> zope.pagetemplate [installed: 4.0.4]
  zope.browsermenu==4.0.0 -> zope.pagetemplate [required: >=3.5, installed: 4.0.4]
* ZEO==4.0.0 -> zdaemon [installed: 4.0.0]
  ZODB==4.0.0 -> zdaemon [required: >=4.0.0a1, installed: 4.0.0]
  Zope2==2.13.19 -> zdaemon [installed: 4.0.0]
* zope.contentprovider==3.7.2 -> zope.location [installed: 4.0.3]
  zope.annotation==4.2.0 -> zope.location [installed: 4.0.3]
  zope.site==3.9.2 -> zope.location [required: >=3.7.0, installed: 4.0.3]
  Zope2==2.13.19 -> zope.location [installed: 4.0.3]
  zope.viewlet==3.7.2 -> zope.location [installed: 4.0.3]
  zope.publisher==3.13.4 -> zope.location [installed: 4.0.3]
  zope.security==4.0.1 -> zope.location [installed: 4.0.3]
  zope.traversing==4.0.0 -> zope.location [required: >=3.7.0, installed: 4.0.3]
  zope.browserresource==4.0.1 -> zope.location [installed: 4.0.3]
  zope.container==4.0.0 -> zope.location [required: >=3.5.4, installed: 4.0.3]
* ZEO==4.0.0 -> persistent [installed: 4.0.8]
  ZODB==4.0.0 -> persistent [installed: 4.0.8]
  BTrees==4.0.8 -> persistent [installed: 4.0.8]
  ZODB3==3.11.0 -> persistent [required: >=4.0.0dev, installed: 4.0.8]
  zope.container==4.0.0 -> persistent [installed: 4.0.8]
* tempstorage==2.12.2 -> ZODB3 [required: >=3.9.0, installed: 3.11.0]
  Products.BTreeFolder2==2.13.4 -> ZODB3 [installed: 3.11.0]
  Zope2==2.13.19 -> ZODB3 [installed: 3.11.0]
  Products.ZCatalog==3.0.2 -> ZODB3 [installed: 3.11.0]
  Products.ExternalMethod==2.13.0 -> ZODB3 [installed: 3.11.0]
  AccessControl==3.0.8 -> ZODB3 [installed: 3.11.0]
  Products.ZCTextIndex==2.13.5 -> ZODB3 [installed: 3.11.0]
  Persistence==2.13.2 -> ZODB3 [installed: 3.11.0]
* Zope2==2.13.19 -> ExtensionClass [installed: 4.0]
  Products.ZCatalog==3.0.2 -> ExtensionClass [installed: 4.0]
  Products.ExternalMethod==2.13.0 -> ExtensionClass [installed: 4.0]
  DocumentTemplate==2.13.2 -> ExtensionClass [installed: 4.0]
  AccessControl==3.0.8 -> ExtensionClass [installed: 4.0]
  MultiMapping==2.13.0 -> ExtensionClass [installed: 4.0]
  Acquisition==4.0 -> ExtensionClass [required: >=4.0a1, installed: 4.0]
  Missing==3.0 -> ExtensionClass [required: >=4.1a1, installed: 4.0]
  Persistence==2.13.2 -> ExtensionClass [installed: 4.0]
  Record==3.0 -> ExtensionClass [required: >=4.1a1, installed: 4.0]
------------------------------------------------------------------------
Traceback (most recent call last):
  File "circular_deps_Zope2.venv/bin/pipdeptree", line 9, in <module>
    load_entry_point('pipdeptree==0.3', 'console_scripts', 'pipdeptree')()
  File "/Users/marca/dev/git-repos/pipdeptree/circular_deps_Zope2.venv/lib/python2.7/site-packages/pipdeptree.py", line 215, in main
    non_top_pkg_str=non_top_pkg_str)
  File "/Users/marca/dev/git-repos/pipdeptree/circular_deps_Zope2.venv/lib/python2.7/site-packages/pipdeptree.py", line 159, in render_tree
    lines = flatten([aux(p) for p in (pkgs if list_all else top)])
  File "/Users/marca/dev/git-repos/pipdeptree/circular_deps_Zope2.venv/lib/python2.7/site-packages/pipdeptree.py", line 156, in aux
    for d in pkg_deps]))
  File "/Users/marca/dev/git-repos/pipdeptree/circular_deps_Zope2.venv/lib/python2.7/site-packages/pipdeptree.py", line 156, in aux
    for d in pkg_deps]))
  File "/Users/marca/dev/git-repos/pipdeptree/circular_deps_Zope2.venv/lib/python2.7/site-packages/pipdeptree.py", line 156, in aux
    for d in pkg_deps]))
  File "/Users/marca/dev/git-repos/pipdeptree/circular_deps_Zope2.venv/lib/python2.7/site-packages/pipdeptree.py", line 156, in aux
    for d in pkg_deps]))
...
  File "/Users/marca/dev/git-repos/pipdeptree/circular_deps_Zope2.venv/lib/python2.7/site-packages/pipdeptree.py", line 156, in aux
    for d in pkg_deps]))
  File "/Users/marca/dev/git-repos/pipdeptree/circular_deps_Zope2.venv/lib/python2.7/site-packages/pipdeptree.py", line 146, in aux
    name = pkg.project_name if dist is None else non_top_pkg_str(pkg, dist)
  File "/Users/marca/dev/git-repos/pipdeptree/circular_deps_Zope2.venv/lib/python2.7/site-packages/pipdeptree.py", line 57, in non_top_pkg_name
    vers.append(('installed', pkg.version))
RuntimeError: maximum recursion depth exceeded

Same happens with git master:

$ circular_deps_Zope2.venv/bin/pip uninstall --yes pipdeptree
...

$ circular_deps_Zope2.venv/bin/pip install -e .
...

$ circular_deps_Zope2.venv/bin/pip freeze | grep pipdeptree
-e git+https://github.com/naiquevin/pipdeptree.git@53aa14377b416cac8d3c3f19defb1af7bf2faac3#egg=pipdeptree-origin/HEAD

$ circular_deps_Zope2.venv/bin/pipdeptree --nowarn --all
...
  File "/Users/marca/dev/git-repos/pipdeptree/pipdeptree.py", line 156, in aux
    for d in pkg_deps]))
  File "/Users/marca/dev/git-repos/pipdeptree/pipdeptree.py", line 156, in aux
    for d in pkg_deps]))
  File "/Users/marca/dev/git-repos/pipdeptree/pipdeptree.py", line 156, in aux
    for d in pkg_deps]))
  File "/Users/marca/dev/git-repos/pipdeptree/pipdeptree.py", line 156, in aux
    for d in pkg_deps]))
  File "/Users/marca/dev/git-repos/pipdeptree/pipdeptree.py", line 146, in aux
    name = pkg.project_name if dist is None else non_top_pkg_str(pkg, dist)
  File "/Users/marca/dev/git-repos/pipdeptree/pipdeptree.py", line 57, in non_top_pkg_name
    vers.append(('installed', pkg.version))
RuntimeError: maximum recursion depth exceeded

but not with my branch:

$ git checkout master_fix_infinite_recursion
Switched to branch 'master_fix_infinite_recursion'

$ circular_deps_Zope2.venv/bin/pip freeze | grep pipdeptree
-e git+https://github.com/naiquevin/pipdeptree.git@e38cfe503f6448679ab21214b78849ac7923fcba#egg=pipdeptree-master_fix_infinite_recursion

$ circular_deps_Zope2.venv/bin/pipdeptree --nowarn --all
...
# Circular dependency: Products.BTreeFolder2 2.13.4 => Zope2>=2.13.0a1 => Products.OFSP>=2.13.2 => Zope2>=2.13.0a1
# Circular dependency: Products.BTreeFolder2 2.13.4 => Zope2>=2.13.0a1 => Products.ZCatalog => Products.ZCTextIndex => Zope2>=2.13.0dev
# Circular dependency: Products.BTreeFolder2 2.13.4 => Zope2>=2.13.0a1 => Products.ZCatalog => Zope2
# Circular dependency: Products.BTreeFolder2 2.13.4 => Zope2>=2.13.0a1 => Products.ZCTextIndex => Zope2>=2.13.0dev
# Circular dependency: Products.BTreeFolder2 2.13.4 => Zope2>=2.13.0a1 => Products.BTreeFolder2
# Circular dependency: Products.BTreeFolder2 2.13.4 => Zope2>=2.13.0a1 => Products.ExternalMethod => Zope2>=2.13.0a1
# Circular dependency: Products.BTreeFolder2 2.13.4 => Zope2>=2.13.0a1 => Products.MailHost => Zope2>=2.13.0a1
# Circular dependency: Products.BTreeFolder2 2.13.4 => Zope2>=2.13.0a1 => Products.PythonScripts => Zope2>=2.13.0a1
# Circular dependency: Products.BTreeFolder2 2.13.4 => Zope2>=2.13.0a1 => Products.StandardCacheManagers => Zope2>=2.13.0a1
# Circular dependency: Products.ExternalMethod 2.13.0 => Zope2>=2.13.0a1 => Products.OFSP>=2.13.2 => Zope2>=2.13.0a1
# Circular dependency: Products.ExternalMethod 2.13.0 => Zope2>=2.13.0a1 => Products.ZCatalog => Products.ZCTextIndex => Zope2>=2.13.0dev
# Circular dependency: Products.ExternalMethod 2.13.0 => Zope2>=2.13.0a1 => Products.ZCatalog => Zope2
# Circular dependency: Products.ExternalMethod 2.13.0 => Zope2>=2.13.0a1 => Products.ZCTextIndex => Zope2>=2.13.0dev
# Circular dependency: Products.ExternalMethod 2.13.0 => Zope2>=2.13.0a1 => Products.BTreeFolder2 => Zope2>=2.13.0a1
# Circular dependency: Products.ExternalMethod 2.13.0 => Zope2>=2.13.0a1 => Products.ExternalMethod
# Circular dependency: Products.ExternalMethod 2.13.0 => Zope2>=2.13.0a1 => Products.MailHost => Zope2>=2.13.0a1
# Circular dependency: Products.ExternalMethod 2.13.0 => Zope2>=2.13.0a1 => Products.PythonScripts => Zope2>=2.13.0a1
# Circular dependency: Products.ExternalMethod 2.13.0 => Zope2>=2.13.0a1 => Products.StandardCacheManagers => Zope2>=2.13.0a1
...
    - zope.component [installed: 4.2.1]
      - setuptools
      - zope.interface [required: >=4.1.0, installed: 4.1.1]
        - setuptools
      - zope.event [installed: 4.0.3]
        - setuptools
ZopeUndo==4.0
  - setuptools

$ echo $?
0

Python 3.4.x issue

I'll make a PR for this issue.

Traceback (most recent call last):
  File "/home/bhe/.virtualenvs/mx-py34/bin/pipdeptree", line 9, in <module>
    load_entry_point('pipdeptree==0.4', 'console_scripts', 'pipdeptree')()
  File "/home/bhe/.virtualenvs/mx-py34/lib/python3.4/site-packages/pipdeptree.py", line 221, in main
    confusing = confusing_deps(req_map)
  File "/home/bhe/.virtualenvs/mx-py34/lib/python3.4/site-packages/pipdeptree.py", line 105, in confusing_deps
    for p, rs in req_map.iteritems():
AttributeError: 'dict' object has no attribute 'iteritems'

Python 3.4.1 (default, May 19 2014, 17:23:49)
[GCC 4.9.0 20140507 (prerelease)] on linux

pipdeptree believes that "setuptools" is an unknown dependency

e.g. after installing twine and pipdeptree in a fresh virtualenv:

$ python -mpipdeptree
Warning!!! Possibly conflicting dependencies found:
* twine==1.6.5
 - setuptools [required: >=0.7.0, installed: <unknown>] # A recent setuptools is available.
------------------------------------------------------------------------
twine==1.6.5
  - pkginfo [required: >=1.0, installed: 1.2.1]
  - requests [required: >=2.3.0, installed: 2.9.1]
  - requests-toolbelt [required: >=0.5.1, installed: 0.6.0]
    - requests [required: >=2.0.1,<=3.0.0, installed: 2.9.1]
  - setuptools [required: >=0.7.0]

No output for a virtualenv with a bunch of Zope packages

I was trying to create a state with circular dependencies using some Zope packages to reproduce the infinite recursion error that I mentioned in #10 -- I found this page, which mentioned that Products.OFSP==2.13.2 and Zope2==2.13.19 had circular dependencies.

Instead I found a state, where pipdeptree prints no package tree even though a ton of packages are installed.

$ pip install Products.OFSP==2.13.2 Zope2==2.13.19
$ pip freeze
AccessControl==3.0.8
Acquisition==4.0
BTrees==4.0.8
DateTime==4.0.1
DocumentTemplate==2.13.2
ExtensionClass==4.0
Missing==3.0
MultiMapping==2.13.0
Persistence==2.13.2
Products.BTreeFolder2==2.13.4
Products.ExternalMethod==2.13.0
Products.MIMETools==2.13.0
Products.MailHost==2.13.1
Products.OFSP==2.13.2
Products.PythonScripts==2.13.2
Products.StandardCacheManagers==2.13.0
Products.ZCTextIndex==2.13.5
Products.ZCatalog==3.0.2
Record==3.0
RestrictedPython==3.6.0
ZConfig==3.0.4
ZEO==4.0.0
ZODB==4.0.0
ZODB3==3.11.0
Zope2==2.13.19
ZopeUndo==4.0
docutils==0.11
initgroups==2.13.0
mechanize==0.2.5
persistent==4.0.8
pipdeptree==0.3
pytz==2014.4
six==1.7.2
tempstorage==2.12.2
transaction==1.4.3
wsgiref==0.1.2
zExceptions==2.13.0
zLOG==2.12.0
zc.lockfile==1.1.0
zdaemon==4.0.0
zope.annotation==4.2.0
zope.browser==2.0.2
zope.browsermenu==4.0.0
zope.browserpage==4.0.0
zope.browserresource==4.0.1
zope.component==4.2.1
zope.configuration==4.0.3
zope.container==4.0.0
zope.contentprovider==3.7.2
zope.contenttype==4.0.1
zope.deferredimport==4.0.0
zope.dottedname==4.0.1
zope.event==4.0.3
zope.exceptions==4.0.7
zope.filerepresentation==4.0.2
zope.i18n==3.8.0
zope.i18nmessageid==4.0.3
zope.interface==4.1.1
zope.lifecycleevent==4.0.3
zope.location==4.0.3
zope.pagetemplate==4.0.4
zope.processlifetime==2.0.0
zope.proxy==4.1.4
zope.ptresource==3.9.0
zope.publisher==3.13.4
zope.schema==4.4.1
zope.security==4.0.1
zope.sendmail==3.7.5
zope.sequencesort==4.0.1
zope.site==3.9.2
zope.size==4.0.1
zope.structuredtext==4.0.0
zope.tal==4.0.0
zope.tales==4.0.2
zope.testbrowser==4.0.4
zope.testing==4.1.3
zope.traversing==4.0.0
zope.viewlet==3.7.2
$ pipdeptree
Warning!!! Possible confusing dependencies found:
* Zope2==2.13.19 -> zope.browserpage [installed: 4.0.0]
  zope.viewlet==3.7.2 -> zope.browserpage [required: >=3.10.1, installed: 4.0.0]
* Products.PythonScripts==2.13.2 -> Zope2 [required: >=2.13.0a1, installed: 2.13.19]
  Products.ZCTextIndex==2.13.5 -> Zope2 [required: >=2.13.0dev, installed: 2.13.19]
  Products.OFSP==2.13.2 -> Zope2 [required: >=2.13.0a1, installed: 2.13.19]
  Products.MailHost==2.13.1 -> Zope2 [required: >=2.13.0a1, installed: 2.13.19]
  Products.StandardCacheManagers==2.13.0 -> Zope2 [required: >=2.13.0a1, installed: 2.13.19]
  Products.BTreeFolder2==2.13.4 -> Zope2 [required: >=2.13.0a1, installed: 2.13.19]
  Products.ZCatalog==3.0.2 -> Zope2 [installed: 2.13.19]
  Products.ExternalMethod==2.13.0 -> Zope2 [required: >=2.13.0a1, installed: 2.13.19]
* zope.browsermenu==4.0.0 -> zope.interface [installed: 4.1.1]
  zope.site==3.9.2 -> zope.interface [installed: 4.1.1]
  zope.publisher==3.13.4 -> zope.interface [installed: 4.1.1]
  zope.size==4.0.1 -> zope.interface [installed: 4.1.1]
  DateTime==4.0.1 -> zope.interface [installed: 4.1.1]
  zope.testbrowser==4.0.4 -> zope.interface [installed: 4.1.1]
  AccessControl==3.0.8 -> zope.interface [installed: 4.1.1]
  zope.container==4.0.0 -> zope.interface [installed: 4.1.1]
  zope.tales==4.0.2 -> zope.interface [installed: 4.1.1]
  zExceptions==2.13.0 -> zope.interface [installed: 4.1.1]
  Products.ZCTextIndex==2.13.5 -> zope.interface [installed: 4.1.1]
  Acquisition==4.0 -> zope.interface [installed: 4.1.1]
  persistent==4.0.8 -> zope.interface [installed: 4.1.1]
  zope.browserpage==4.0.0 -> zope.interface [installed: 4.1.1]
  zope.location==4.0.3 -> zope.interface [required: >=4.0.2, installed: 4.1.1]
  zope.filerepresentation==4.0.2 -> zope.interface [installed: 4.1.1]
  transaction==1.4.3 -> zope.interface [installed: 4.1.1]
  ZEO==4.0.0 -> zope.interface [installed: 4.1.1]
  zope.contentprovider==3.7.2 -> zope.interface [installed: 4.1.1]
  zope.lifecycleevent==4.0.3 -> zope.interface [installed: 4.1.1]
  Zope2==2.13.19 -> zope.interface [installed: 4.1.1]
  zope.browserresource==4.0.1 -> zope.interface [installed: 4.1.1]
  zope.security==4.0.1 -> zope.interface [installed: 4.1.1]
  zope.exceptions==4.0.7 -> zope.interface [installed: 4.1.1]
  Products.ZCatalog==3.0.2 -> zope.interface [installed: 4.1.1]
  zope.testing==4.1.3 -> zope.interface [installed: 4.1.1]
  BTrees==4.0.8 -> zope.interface [installed: 4.1.1]
  zope.annotation==4.2.0 -> zope.interface [installed: 4.1.1]
  zope.tal==4.0.0 -> zope.interface [installed: 4.1.1]
  zope.traversing==4.0.0 -> zope.interface [required: >=4.0.4, installed: 4.1.1]
  zope.component==4.2.1 -> zope.interface [required: >=4.1.0, installed: 4.1.1]
  zope.sendmail==3.7.5 -> zope.interface [installed: 4.1.1]
  zope.browser==2.0.2 -> zope.interface [installed: 4.1.1]
  ZODB==4.0.0 -> zope.interface [installed: 4.1.1]
  zope.pagetemplate==4.0.4 -> zope.interface [installed: 4.1.1]
  zope.ptresource==3.9.0 -> zope.interface [installed: 4.1.1]
  zope.configuration==4.0.3 -> zope.interface [installed: 4.1.1]
  zope.processlifetime==2.0.0 -> zope.interface [installed: 4.1.1]
  zope.proxy==4.1.4 -> zope.interface [installed: 4.1.1]
  zope.schema==4.4.1 -> zope.interface [required: >=3.6.0, installed: 4.1.1]
  zope.viewlet==3.7.2 -> zope.interface [installed: 4.1.1]
* zope.browsermenu==4.0.0 -> zope.traversing [required: >3.7, installed: 4.0.0]
  zope.container==4.0.0 -> zope.traversing [required: >=4.0.0a1, installed: 4.0.0]
  zope.browserpage==4.0.0 -> zope.traversing [installed: 4.0.0]
  Zope2==2.13.19 -> zope.traversing [installed: 4.0.0]
  zope.browserresource==4.0.1 -> zope.traversing [required: >3.7, installed: 4.0.0]
  zope.pagetemplate==4.0.4 -> zope.traversing [installed: 4.0.0]
  zope.viewlet==3.7.2 -> zope.traversing [installed: 4.0.0]
* zope.publisher==3.13.4 -> zope.contenttype [required: >=3.5, installed: 4.0.1]
  Zope2==2.13.19 -> zope.contenttype [installed: 4.0.1]
  zope.browserresource==4.0.1 -> zope.contenttype [required: >=4.0.1, installed: 4.0.1]
* zLOG==2.12.0 -> ZConfig [required: >=2.9.2, installed: 3.0.4]
  ZEO==4.0.0 -> ZConfig [installed: 3.0.4]
  Zope2==2.13.19 -> ZConfig [installed: 3.0.4]
  ZODB==4.0.0 -> ZConfig [installed: 3.0.4]
  zdaemon==4.0.0 -> ZConfig [installed: 3.0.4]
* ZODB3==3.11.0 -> ZODB [required: >=4.0.0dev, installed: 4.0.0]
  ZEO==4.0.0 -> ZODB [required: >=4.0.0b2, installed: 4.0.0]
* zope.site==3.9.2 -> zope.lifecycleevent [installed: 4.0.3]
  zope.container==4.0.0 -> zope.lifecycleevent [required: >=3.5.2, installed: 4.0.3]
  Products.BTreeFolder2==2.13.4 -> zope.lifecycleevent [installed: 4.0.3]
  Zope2==2.13.19 -> zope.lifecycleevent [installed: 4.0.3]
* zope.container==4.0.0 -> BTrees [installed: 4.0.8]
  ZODB3==3.11.0 -> BTrees [required: >=4.0.0dev, installed: 4.0.8]
  zope.annotation==4.2.0 -> BTrees [installed: 4.0.8]
  ZODB==4.0.0 -> BTrees [installed: 4.0.8]
* Products.PythonScripts==2.13.2 -> AccessControl [installed: 3.0.8]
  Products.ZCTextIndex==2.13.5 -> AccessControl [installed: 3.0.8]
  Products.OFSP==2.13.2 -> AccessControl [installed: 3.0.8]
  Products.StandardCacheManagers==2.13.0 -> AccessControl [installed: 3.0.8]
  Products.BTreeFolder2==2.13.4 -> AccessControl [installed: 3.0.8]
  Zope2==2.13.19 -> AccessControl [required: >=2.13.2, installed: 3.0.8]
  Products.ZCatalog==3.0.2 -> AccessControl [installed: 3.0.8]
  DocumentTemplate==2.13.2 -> AccessControl [installed: 3.0.8]
  Products.ExternalMethod==2.13.0 -> AccessControl [installed: 3.0.8]
* zope.browsermenu==4.0.0 -> zope.publisher [installed: 3.13.4]
  AccessControl==3.0.8 -> zope.publisher [installed: 3.13.4]
  zope.container==4.0.0 -> zope.publisher [installed: 3.13.4]
  zExceptions==2.13.0 -> zope.publisher [installed: 3.13.4]
  zope.browserpage==4.0.0 -> zope.publisher [required: >=3.8, installed: 3.13.4]
  zope.contentprovider==3.7.2 -> zope.publisher [installed: 3.13.4]
  Zope2==2.13.19 -> zope.publisher [installed: 3.13.4]
  zope.browserresource==4.0.1 -> zope.publisher [required: >=3.8, installed: 3.13.4]
  zope.traversing==4.0.0 -> zope.publisher [installed: 3.13.4]
  zope.ptresource==3.9.0 -> zope.publisher [installed: 3.13.4]
  zope.viewlet==3.7.2 -> zope.publisher [installed: 3.13.4]
* zope.contentprovider==3.7.2 -> zope.tales [installed: 4.0.2]
  Zope2==2.13.19 -> zope.tales [required: >=3.5.0, installed: 4.0.2]
  zope.pagetemplate==4.0.4 -> zope.tales [installed: 4.0.2]
* zope.container==4.0.0 -> persistent [installed: 4.0.8]
  ZODB3==3.11.0 -> persistent [required: >=4.0.0dev, installed: 4.0.8]
  ZEO==4.0.0 -> persistent [installed: 4.0.8]
  BTrees==4.0.8 -> persistent [installed: 4.0.8]
  ZODB==4.0.0 -> persistent [installed: 4.0.8]
* DateTime==4.0.1 -> pytz [installed: 2014.4]
  zope.testbrowser==4.0.4 -> pytz [required: >dev, installed: 2014.4]
  zope.i18n==3.8.0 -> pytz [installed: 2014.4]
  Zope2==2.13.19 -> pytz [installed: 2014.4]
* zope.browsermenu==4.0.0 -> zope.schema [installed: 4.4.1]
  zope.testbrowser==4.0.4 -> zope.schema [installed: 4.4.1]
  AccessControl==3.0.8 -> zope.schema [installed: 4.4.1]
  zope.i18n==3.8.0 -> zope.schema [installed: 4.4.1]
  zope.container==4.0.0 -> zope.schema [installed: 4.4.1]
  zope.browserpage==4.0.0 -> zope.schema [installed: 4.4.1]
  zope.location==4.0.3 -> zope.schema [required: >=4.2.2, installed: 4.4.1]
  zope.filerepresentation==4.0.2 -> zope.schema [installed: 4.4.1]
  zope.contentprovider==3.7.2 -> zope.schema [installed: 4.4.1]
  Zope2==2.13.19 -> zope.schema [installed: 4.4.1]
  zope.browserresource==4.0.1 -> zope.schema [installed: 4.4.1]
  zope.security==4.0.1 -> zope.schema [installed: 4.4.1]
  Products.ZCatalog==3.0.2 -> zope.schema [installed: 4.4.1]
  zope.sendmail==3.7.5 -> zope.schema [installed: 4.4.1]
  zope.configuration==4.0.3 -> zope.schema [installed: 4.4.1]
  zope.viewlet==3.7.2 -> zope.schema [installed: 4.4.1]
* AccessControl==3.0.8 -> ExtensionClass [installed: 4.0]
  Missing==3.0 -> ExtensionClass [required: >=4.1a1, installed: 4.0]
  Acquisition==4.0 -> ExtensionClass [required: >=4.0a1, installed: 4.0]
  Record==3.0 -> ExtensionClass [required: >=4.1a1, installed: 4.0]
  MultiMapping==2.13.0 -> ExtensionClass [installed: 4.0]
  Zope2==2.13.19 -> ExtensionClass [installed: 4.0]
  Products.ZCatalog==3.0.2 -> ExtensionClass [installed: 4.0]
  DocumentTemplate==2.13.2 -> ExtensionClass [installed: 4.0]
  Persistence==2.13.2 -> ExtensionClass [installed: 4.0]
  Products.ExternalMethod==2.13.0 -> ExtensionClass [installed: 4.0]
* zope.publisher==3.13.4 -> zope.proxy [installed: 4.1.4]
  zope.deferredimport==4.0.0 -> zope.proxy [installed: 4.1.4]
  zope.location==4.0.3 -> zope.proxy [required: >=4.0.1, installed: 4.1.4]
  Zope2==2.13.19 -> zope.proxy [installed: 4.1.4]
  zope.security==4.0.1 -> zope.proxy [required: >=4.1.0, installed: 4.1.4]
  zope.annotation==4.2.0 -> zope.proxy [installed: 4.1.4]
  zope.traversing==4.0.0 -> zope.proxy [installed: 4.1.4]
* zope.browsermenu==4.0.0 -> zope.component [required: >=3.7, installed: 4.2.1]
  zope.site==3.9.2 -> zope.component [required: >=3.8.0, installed: 4.2.1]
  zope.publisher==3.13.4 -> zope.component [installed: 4.2.1]
  AccessControl==3.0.8 -> zope.component [installed: 4.2.1]
  zope.i18n==3.8.0 -> zope.component [installed: 4.2.1]
  zope.container==4.0.0 -> zope.component [installed: 4.2.1]
  zope.browserpage==4.0.0 -> zope.component [required: >=3.7, installed: 4.2.1]
  Products.StandardCacheManagers==2.13.0 -> zope.component [installed: 4.2.1]
  zope.contentprovider==3.7.2 -> zope.component [installed: 4.2.1]
  Zope2==2.13.19 -> zope.component [installed: 4.2.1]
  zope.browserresource==4.0.1 -> zope.component [required: >=3.8.0, installed: 4.2.1]
  zope.security==4.0.1 -> zope.component [installed: 4.2.1]
  zope.annotation==4.2.0 -> zope.component [installed: 4.2.1]
  zope.traversing==4.0.0 -> zope.component [installed: 4.2.1]
  zope.sendmail==3.7.5 -> zope.component [required: >=3.8.0, installed: 4.2.1]
  zope.pagetemplate==4.0.4 -> zope.component [installed: 4.2.1]
  zope.viewlet==3.7.2 -> zope.component [installed: 4.2.1]
* zope.browsermenu==4.0.0 -> zope.pagetemplate [required: >=3.5, installed: 4.0.4]
  zope.browserpage==4.0.0 -> zope.pagetemplate [installed: 4.0.4]
  Zope2==2.13.19 -> zope.pagetemplate [installed: 4.0.4]
  zope.ptresource==3.9.0 -> zope.pagetemplate [installed: 4.0.4]
* ZEO==4.0.0 -> zdaemon [installed: 4.0.0]
  Zope2==2.13.19 -> zdaemon [installed: 4.0.0]
  ZODB==4.0.0 -> zdaemon [required: >=4.0.0a1, installed: 4.0.0]
* zope.site==3.9.2 -> zope.location [required: >=3.7.0, installed: 4.0.3]
  zope.publisher==3.13.4 -> zope.location [installed: 4.0.3]
  zope.container==4.0.0 -> zope.location [required: >=3.5.4, installed: 4.0.3]
  zope.contentprovider==3.7.2 -> zope.location [installed: 4.0.3]
  Zope2==2.13.19 -> zope.location [installed: 4.0.3]
  zope.browserresource==4.0.1 -> zope.location [installed: 4.0.3]
  zope.security==4.0.1 -> zope.location [installed: 4.0.3]
  zope.annotation==4.2.0 -> zope.location [installed: 4.0.3]
  zope.traversing==4.0.0 -> zope.location [required: >=3.7.0, installed: 4.0.3]
  zope.viewlet==3.7.2 -> zope.location [installed: 4.0.3]
* AccessControl==3.0.8 -> ZODB3 [installed: 3.11.0]
  tempstorage==2.12.2 -> ZODB3 [required: >=3.9.0, installed: 3.11.0]
  Products.ZCTextIndex==2.13.5 -> ZODB3 [installed: 3.11.0]
  Products.BTreeFolder2==2.13.4 -> ZODB3 [installed: 3.11.0]
  Zope2==2.13.19 -> ZODB3 [installed: 3.11.0]
  Products.ZCatalog==3.0.2 -> ZODB3 [installed: 3.11.0]
  Persistence==2.13.2 -> ZODB3 [installed: 3.11.0]
  Products.ExternalMethod==2.13.0 -> ZODB3 [installed: 3.11.0]
------------------------------------------------------------------------
wsgiref==0.1.2

Note that outputs a bunch of warnings, but the only thing it really lists is wsgiref.

Option for reverse mode

pipdeptree displays all packages with their dependencies. I would like to see all packages with their dependents, to answer the question “why is X installed”. What do you think?

Odd error on appveyor when calling pipdeptree

The full test is here, and the traceback is below:

Traceback (most recent call last):
  File "c:\python35\lib\runpy.py", line 183, in _run_module_as_main
    mod_name, mod_spec, code = _get_module_details(mod_name, _Error)
  File "c:\python35\lib\runpy.py", line 142, in _get_module_details
    return _get_module_details(pkg_main_name, error)
  File "c:\python35\lib\runpy.py", line 109, in _get_module_details
    __import__(pkg_name)
  File "c:\python35\lib\site-packages\pip\__init__.py", line 28, in <module>
    from pip.vcs import git, mercurial, subversion, bazaar  # noqa
  File "c:\python35\lib\site-packages\pip\vcs\subversion.py", line 9, in <module>
    from pip.index import Link
  File "c:\python35\lib\site-packages\pip\index.py", line 31, in <module>
    from pip.wheel import Wheel, wheel_ext
  File "c:\python35\lib\site-packages\pip\wheel.py", line 6, in <module>
    import compileall
  File "c:\python35\lib\compileall.py", line 20, in <module>
    from concurrent.futures import ProcessPoolExecutor
  File "c:\python35\lib\site-packages\concurrent\futures\__init__.py", line 8, in <module>
    from concurrent.futures._base import (FIRST_COMPLETED,
  File "c:\python35\lib\site-packages\concurrent\futures\_base.py", line 357
    raise type(self._exception), self._exception, self._traceback
                               ^
SyntaxError: invalid syntax
c:\python35\lib\site-packages\IPython\kernel\__init__.py:13: ShimWarning: The `IPython.kernel` package has been deprecated since IPython 4.0.You should import from ipykernel or jupyter_client instead.
  "You should import from ipykernel or jupyter_client instead.", ShimWarning)
Traceback (most recent call last):
  File "c:\python35\lib\runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "c:\python35\lib\runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "C:\Python35\Scripts\pipdeptree.exe\__main__.py", line 5, in <module>
  File "c:\python35\lib\site-packages\pipdeptree.py", line 16, in <module>
    import pip
  File "c:\python35\lib\site-packages\pip\__init__.py", line 28, in <module>
    from pip.vcs import git, mercurial, subversion, bazaar  # noqa
  File "c:\python35\lib\site-packages\pip\vcs\subversion.py", line 9, in <module>
    from pip.index import Link
  File "c:\python35\lib\site-packages\pip\index.py", line 31, in <module>
    from pip.wheel import Wheel, wheel_ext
  File "c:\python35\lib\site-packages\pip\wheel.py", line 6, in <module>
    import compileall
  File "c:\python35\lib\compileall.py", line 20, in <module>
    from concurrent.futures import ProcessPoolExecutor
  File "c:\python35\lib\site-packages\concurrent\futures\__init__.py", line 8, in <module>
    from concurrent.futures._base import (FIRST_COMPLETED,
  File "c:\python35\lib\site-packages\concurrent\futures\_base.py", line 357
    raise type(self._exception), self._exception, self._traceback
                               ^
SyntaxError: invalid synta

I'm not exactly sure what is going on, but an exception handler may need to be implemented.

Use filled node with different color for graph output

Use filled node with different color for graph output, make it's clean for top level package and it's dependencies.

Changes in dump_graphviz(tree, output_format='dot'):

    dependencies = set()
    for deps in tree.values():
        for dep in deps:
            dependencies.add(dep.project_name)
    graph = Digraph(format=output_format)
    for package, deps in tree.items():
        project_name = package.project_name
        label = '{0}\n{1}'.format(project_name, package.version)
        attrs = {'style': 'filled'}
        attrs['color'] = 'lightblue' if project_name in dependencies else 'green'
        graph.node(project_name, label=label, **attrs)

Listing packages by dependency?

Is there any built-in option to only list packages that have a specific dependency?

I want to upgrade my version of Django, so I'm trying to find which packages I have installed depend on Django so I can check them.

I see there's a --packages option, but this only filters by the top-level package, not dependency.

Support using with both Python2 and Python3 installed

I would like to execute pipdeptree on both my Python 2 and Python 3 installations. Currently this is not possible, since the script installed into /usr/bin/pipdeptree is "bound" to a specific python version using the #! hashbang at the top:

#!/usr/bin/python2

# -*- coding: utf-8 -*-
import re
import sys

from pipdeptree import main

if __name__ == '__main__':
    sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
    sys.exit(main())

I guess we can solve this by two ways:

  1. Rename the installed script to pipdeptree2 if it's installed using Python 2, and ln -s to pipdeptree. For Python 3 we'll have pipdeptree3. This will allow the user to keep the two versions.
  2. Put them somewhere else e.g. in the Python system directory tree and link them to /usr/bin/, so the user can soft link/alias the scripts as he wishes.
  3. Any other idea?

Add mode to run on requirements.txt

It would be really convenient to run on a requirements.txt file, because right now I'm hitting a compilation failure installing a library that isn't a direct depedency but a transient dependency, and I don't know what pulls it in. I'd like to bump the direct dependency so I'm on the latest version of the transient one

Case sensitivity issues

If I use this in a package:

install_requires=[ 'shapely==1.5.17.post1' ]

The package installs fine, but the pipdeptree graphviz output has an extra root node with Shapely.

Fixing my package to match the case for this library on pypi works around the issue (install_requires=[ 'Shapely==1.5.17.post1' ])

Changes in pip-10.0.0b2 break pipdeptree

pipdeptree is broken with pip-10.0.0b2.

$ pipdeptree -j
Traceback (most recent call last):
  File "/home/someone/venv/bin/pipdeptree", line 11, in <module>
    sys.exit(main())
  File "/home/someone/venv/lib/python2.7/site-packages/pipdeptree.py", line 550, in main
    pkgs = pip.get_installed_distributions(local_only=args.local_only,
AttributeError: 'module' object has no attribute 'get_installed_distributions'

I believe this is due to the following item in the change notes for pip:

Move all of pip's APIs into the pip._internal package, properly reflecting the fact that pip does not currently have any public APIs. (#4696, #4700)

KeyError: 'py'

When running pipdeptree on one of my virtualenvs, I get the following error

$ pipdeptree -a
Warning!!! Possible confusing dependencies found:
Traceback (most recent call last):
  File "/home/stefan/soco/SoCo/venv32/bin/pipdeptree", line 9, in <module>
    load_entry_point('pipdeptree==0.4.1', 'console_scripts', 'pipdeptree')()
  File "/home/stefan/soco/SoCo/venv32/lib/python3.2/site-packages/pipdeptree.py", line 245, in main
    req = non_top_pkg_name(d, pkg_index[d.key])
KeyError: 'py'

I can provide a copy of the virtualenv if required.

Inconsistent order of dependency requirements

I've come across an issue where the order of the required dependencies seems to be inconsistent, in that sometimes it is listed as:
package-name [required: <x,>=y, installed: z]

and other times as:
package-name [required: >=y,<x, installed: z]

Why is this an issue?

I realise the above two outputs are equivalent, though I personally like to check this requirements output into version control, to track requirements changes during development. I therefore only really want to see changes to the pipdeptree output (> file), if the dependencies actually change.

Steps to reproduce:

virtualenv 'pipdeptree_ve'
source 'pipdeptree_ve/bin/activate'
    pip3 install \
        'flake8' \
        'pipdeptree'

    # I'd expect the output of each of these commands to be the same/consistent
    pipdeptree
    pipdeptree
    pipdeptree
deactivate

Expected behaviour:

# i.e. for the output to be the same each time.
flake8==3.3.0
  - mccabe [required: <0.7.0,>=0.6.0, installed: 0.6.1]
  - pycodestyle [required: >=2.0.0,<2.4.0, installed: 2.3.1]
  - pyflakes [required: >=1.5.0,<1.6.0, installed: 1.5.0]
pipdeptree==0.10.1
  - pip [required: >=6.0.0, installed: 9.0.1]
setuptools==36.0.1
wheel==0.29.0
flake8==3.3.0
  - mccabe [required: <0.7.0,>=0.6.0, installed: 0.6.1]
  - pycodestyle [required: >=2.0.0,<2.4.0, installed: 2.3.1]
  - pyflakes [required: >=1.5.0,<1.6.0, installed: 1.5.0]
pipdeptree==0.10.1
  - pip [required: >=6.0.0, installed: 9.0.1]
setuptools==36.0.1
wheel==0.29.0
flake8==3.3.0
  - mccabe [required: <0.7.0,>=0.6.0, installed: 0.6.1]
  - pycodestyle [required: >=2.0.0,<2.4.0, installed: 2.3.1]
  - pyflakes [required: >=1.5.0,<1.6.0, installed: 1.5.0]
pipdeptree==0.10.1
  - pip [required: >=6.0.0, installed: 9.0.1]
setuptools==36.0.1
wheel==0.29.0

Actual behaviour:

# Output differs each time.
flake8==3.3.0
  - mccabe [required: <0.7.0,>=0.6.0, installed: 0.6.1]
  - pycodestyle [required: >=2.0.0,<2.4.0, installed: 2.3.1]
  - pyflakes [required: >=1.5.0,<1.6.0, installed: 1.5.0]
pipdeptree==0.10.1
  - pip [required: >=6.0.0, installed: 9.0.1]
setuptools==36.0.1
wheel==0.29.0
flake8==3.3.0
  - mccabe [required: >=0.6.0,<0.7.0, installed: 0.6.1]
  - pycodestyle [required: <2.4.0,>=2.0.0, installed: 2.3.1]
  - pyflakes [required: <1.6.0,>=1.5.0, installed: 1.5.0]
pipdeptree==0.10.1
  - pip [required: >=6.0.0, installed: 9.0.1]
setuptools==36.0.1
wheel==0.29.0
flake8==3.3.0
  - mccabe [required: >=0.6.0,<0.7.0, installed: 0.6.1]
  - pycodestyle [required: <2.4.0,>=2.0.0, installed: 2.3.1]
  - pyflakes [required: <1.6.0,>=1.5.0, installed: 1.5.0]
pipdeptree==0.10.1
  - pip [required: >=6.0.0, installed: 9.0.1]
setuptools==36.0.1
wheel==0.29.0

Environment:

  • Ubuntu 17.04 (Zesty Zapus)
  • Python 3.5.3
  • pip 9.0.1

The tests does not pass for the python3.2

Running the tox test against python3.2.6 on a Ubuntu 14.04.5 causes this error message and stacktrace:

actionid: py32
msg: getenv
cmdargs: ['/usr/bin/python', '-m', 'virtualenv', '--python', '/usr/bin/python3.2', 'py32']
env: {'LC_CTYPE': 'en_US.UTF-8', 'LESSOPEN': '| /usr/bin/lesspipe %s', 'SSH_CLIENT': '10.0.2.2 53993 22', 'LOGNAME': 'vagrant', 'USER': 'vagrant', 'PATH': '/home/vagrant/pipdeptree-dev/.tox/py32/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games', 'HOME': '/home/vagrant', 'PS1': '\\[\\e]0;\\u@\\h: \\w\\a\\]${debian_chroot:+($debian_chroot)}\\u@\\h:\\w\\$ ', 'MAKEFLAGS': '', 'LANG': 'en_US.UTF-8', 'TERM': 'xterm-256color', 'SHELL': '/bin/bash', 'SHLVL': '1', 'PIP_CONFIG_FILE': '/home/vagrant/pip.conf', 'PYTHONHASHSEED': '1850169160', 'MFLAGS': '', 'WORKON_HOME': '/home/vagrant/.virtualenvs', 'XDG_RUNTIME_DIR': '/run/user/1000', 'VIRTUAL_ENV': '/home/vagrant/pipdeptree-dev/.tox/py32', 'VIRTUALENVWRAPPER_WORKON_CD': '1', 'XDG_SESSION_ID': '3', '_': '/usr/bin/make', 'VIRTUALENVWRAPPER_PROJECT_FILENAME': '.project', 'LS_COLORS': 'rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lz=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.axa=00;36:*.oga=00;36:*.spx=00;36:*.xspf=00;36:', 'LESSCLOSE': '/usr/bin/lesspipe %s %s', 'VIRTUALENVWRAPPER_HOOK_DIR': '/home/vagrant/.virtualenvs', 'SSH_TTY': '/dev/pts/0', 'OLDPWD': '/home/vagrant', 'VIRTUALENVWRAPPER_SCRIPT': '/usr/local/bin/virtualenvwrapper.sh', 'MAKELEVEL': '1', 'PWD': '/home/vagrant/pipdeptree-dev', 'MAIL': '/var/mail/vagrant', 'SSH_CONNECTION': '10.0.2.2 53993 10.0.2.15 22'}
New python executable in /home/vagrant/pipdeptree-dev/.tox/py32/bin/python3.2
Also creating executable in /home/vagrant/pipdeptree-dev/.tox/py32/bin/python
Installing setuptools, pip, wheel...
  Complete output from command /home/vagrant/pipdep...x/py32/bin/python3.2 - setuptools pip wheel:
  Traceback (most recent call last):
  File "<stdin>", line 7, in <module>
  File "/usr/local/lib/python2.7/dist-packages/virtualenv_support/pip-9.0.1-py2.py3-none-any.whl/pip/__init__.py", line 21, in <module>
  File "/usr/local/lib/python2.7/dist-packages/virtualenv_support/pip-9.0.1-py2.py3-none-any.whl/pip/_vendor/requests/__init__.py", line 66, in <module>
  File "/usr/local/lib/python2.7/dist-packages/virtualenv_support/pip-9.0.1-py2.py3-none-any.whl/pip/_vendor/requests/models.py", line 856
    http_error_msg = u'%s Client Error: %s for url: %s' % (self.status_code, reason, self.url)
                                                      ^
SyntaxError: invalid syntax
----------------------------------------
...Installing setuptools, pip, wheel...done.
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/virtualenv.py", line 2328, in <module>
    main()
  File "/usr/local/lib/python2.7/dist-packages/virtualenv.py", line 713, in main
    symlink=options.symlink)
  File "/usr/local/lib/python2.7/dist-packages/virtualenv.py", line 945, in create_environment
    download=download,
  File "/usr/local/lib/python2.7/dist-packages/virtualenv.py", line 901, in install_wheel
    call_subprocess(cmd, show_stdout=False, extra_env=env, stdin=SCRIPT)
  File "/usr/local/lib/python2.7/dist-packages/virtualenv.py", line 797, in call_subprocess
    % (cmd_desc, proc.returncode))
OSError: Command /home/vagrant/pipdep...x/py32/bin/python3.2 - setuptools pip wheel failed with error code 1
Running virtualenv with interpreter /usr/bin/python3.2

I suspect this has to do with unicode literals not being supported in python3.2.x ( this feature is used by virutalenv)

--json produces flattened output (which looses dependency data)

fantastic tool - bu I noticed that json produces flattened output

a normal output may include:

  • artifactory [required: Any, installed: 0.1.17]
    - pathlib [required: Any, installed: 1.0.1]
    - python-dateutil [required: Any, installed: 2.6.1]
    • six [required: >=1.5, installed: 1.10.0]
      - requests [required: Any, installed: 2.18.4]
    • certifi [required: >=2017.4.17, installed: 2018.1.18]
    • chardet [required: >=3.0.2,<3.1.0, installed: 3.0.4]
    • idna [required: >=2.5,<2.7, installed: 2.6]
    • urllib3 [required: <1.23,>=1.21.1, installed: 1.22]
      but json format urllib3 appears as a first level node
      [
      ...
      {
      "dependencies": [],
      "package": {
      "installed_version": "1.22",
      "package_name": "urllib3",
      "key": "urllib3"
      }
      },
      ...]

but I wanted to prune the dependency tree based on "provided by container" dependencies
assuming, in this simplified example that 'requests' is 'provided' at runtime on the path

I wanted to prune the json tree so that urllib3 is not included

Not a big deal - I will use the text tree output for my pruning

combine --package with --graph-output

Dear Vineet and colleagues

Great idea and wonderful program!
It would helpful to be able to plot the graph of antecedents to a package or set of packages.

Thanks
Arthur

Possible bug: json output different to bare output

Hi guys, I think there is a weird difference between the json output and the bare output, I'm not sure though, but it looks like the trees generated are different.

I created a simple requirements to show an example:

$ cat requirements.txt 
flask
flake8
ipdb
ipython
pep8

It looks like the json output does not have any nested elements like the bare version. If you check the six package in the bare output it's nested very deep inside ipdb but in the json it is not nested, it's just a dependency of prompt-toolkit at top level.

This is the json output

[
    {
        "dependencies": [
            {
                "key": "wcwidth",
                "installed_version": "0.1.7",
                "package_name": "wcwidth",
                "required_version": null
            },
            {
                "key": "six",
                "installed_version": "1.11.0",
                "package_name": "six",
                "required_version": ">=1.9.0"
            }
        ],
        "package": {
            "key": "prompt-toolkit",
            "installed_version": "1.0.15",
            "package_name": "prompt-toolkit"
        }
    },
    {
        "dependencies": [
            {
                "key": "mccabe",
                "installed_version": "0.6.1",
                "package_name": "mccabe",
                "required_version": ">=0.6.0,<0.7.0"
            },
            {
                "key": "pycodestyle",
                "installed_version": "2.3.1",
                "package_name": "pycodestyle",
                "required_version": ">=2.0.0,<2.4.0"
            },
            {
                "key": "pyflakes",
                "installed_version": "1.5.0",
                "package_name": "pyflakes",
                "required_version": "<1.6.0,>=1.5.0"
            }
        ],
        "package": {
            "key": "flake8",
            "installed_version": "3.4.1",
            "package_name": "flake8"
        }
    },
    {
        "dependencies": [],
        "package": {
            "key": "ptyprocess",
            "installed_version": "0.5.2",
            "package_name": "ptyprocess"
        }
    },
    {
        "dependencies": [],
        "package": {
            "key": "wheel",
            "installed_version": "0.30.0",
            "package_name": "wheel"
        }
    },
    {
        "dependencies": [],
        "package": {
            "key": "six",
            "installed_version": "1.11.0",
            "package_name": "six"
        }
    },
    {
        "dependencies": [],
        "package": {
            "key": "setuptools",
            "installed_version": "36.4.0",
            "package_name": "setuptools"
        }
    },
    {
        "dependencies": [],
        "package": {
            "key": "pyflakes",
            "installed_version": "1.5.0",
            "package_name": "pyflakes"
        }
    },
    {
        "dependencies": [
            {
                "key": "jinja2",
                "installed_version": "2.9.6",
                "package_name": "Jinja2",
                "required_version": ">=2.4"
            },
            {
                "key": "click",
                "installed_version": "6.7",
                "package_name": "click",
                "required_version": ">=2.0"
            },
            {
                "key": "werkzeug",
                "installed_version": "0.12.2",
                "package_name": "Werkzeug",
                "required_version": ">=0.7"
            },
            {
                "key": "itsdangerous",
                "installed_version": "0.24",
                "package_name": "itsdangerous",
                "required_version": ">=0.21"
            }
        ],
        "package": {
            "key": "flask",
            "installed_version": "0.12.2",
            "package_name": "Flask"
        }
    },
    {
        "dependencies": [],
        "package": {
            "key": "pycodestyle",
            "installed_version": "2.3.1",
            "package_name": "pycodestyle"
        }
    },
    {
        "dependencies": [],
        "package": {
            "key": "ipython-genutils",
            "installed_version": "0.2.0",
            "package_name": "ipython-genutils"
        }
    },
    {
        "dependencies": [
            {
                "key": "decorator",
                "installed_version": "4.1.2",
                "package_name": "decorator",
                "required_version": null
            },
            {
                "key": "six",
                "installed_version": "1.11.0",
                "package_name": "six",
                "required_version": null
            },
            {
                "key": "ipython-genutils",
                "installed_version": "0.2.0",
                "package_name": "ipython-genutils",
                "required_version": null
            }
        ],
        "package": {
            "key": "traitlets",
            "installed_version": "4.3.2",
            "package_name": "traitlets"
        }
    },
    {
        "dependencies": [],
        "package": {
            "key": "itsdangerous",
            "installed_version": "0.24",
            "package_name": "itsdangerous"
        }
    },
    {
        "dependencies": [
            {
                "key": "parso",
                "installed_version": "0.1.0",
                "package_name": "parso",
                "required_version": "==0.1.0"
            }
        ],
        "package": {
            "key": "jedi",
            "installed_version": "0.11.0",
            "package_name": "jedi"
        }
    },
    {
        "dependencies": [
            {
                "key": "markupsafe",
                "installed_version": "1.0",
                "package_name": "MarkupSafe",
                "required_version": ">=0.23"
            }
        ],
        "package": {
            "key": "jinja2",
            "installed_version": "2.9.6",
            "package_name": "Jinja2"
        }
    },
    {
        "dependencies": [],
        "package": {
            "key": "werkzeug",
            "installed_version": "0.12.2",
            "package_name": "Werkzeug"
        }
    },
    {
        "dependencies": [],
        "package": {
            "key": "click",
            "installed_version": "6.7",
            "package_name": "click"
        }
    },
    {
        "dependencies": [
            {
                "key": "prompt-toolkit",
                "installed_version": "1.0.15",
                "package_name": "prompt-toolkit",
                "required_version": "<2.0.0,>=1.0.4"
            },
            {
                "key": "traitlets",
                "installed_version": "4.3.2",
                "package_name": "traitlets",
                "required_version": ">=4.2"
            },
            {
                "key": "pexpect",
                "installed_version": "4.2.1",
                "package_name": "pexpect",
                "required_version": null
            },
            {
                "key": "simplegeneric",
                "installed_version": "0.8.1",
                "package_name": "simplegeneric",
                "required_version": ">0.8"
            },
            {
                "key": "jedi",
                "installed_version": "0.11.0",
                "package_name": "jedi",
                "required_version": ">=0.10"
            },
            {
                "key": "pygments",
                "installed_version": "2.2.0",
                "package_name": "pygments",
                "required_version": null
            },
            {
                "key": "decorator",
                "installed_version": "4.1.2",
                "package_name": "decorator",
                "required_version": null
            },
            {
                "key": "setuptools",
                "installed_version": "36.4.0",
                "package_name": "setuptools",
                "required_version": ">=18.5"
            },
            {
                "key": "pickleshare",
                "installed_version": "0.7.4",
                "package_name": "pickleshare",
                "required_version": null
            }
        ],
        "package": {
            "key": "ipython",
            "installed_version": "6.2.1",
            "package_name": "ipython"
        }
    },
    {
        "dependencies": [
            {
                "key": "ptyprocess",
                "installed_version": "0.5.2",
                "package_name": "ptyprocess",
                "required_version": ">=0.5"
            }
        ],
        "package": {
            "key": "pexpect",
            "installed_version": "4.2.1",
            "package_name": "pexpect"
        }
    },
    {
        "dependencies": [
            {
                "key": "pip",
                "installed_version": "9.0.1",
                "package_name": "pip",
                "required_version": ">=6.0.0"
            }
        ],
        "package": {
            "key": "pipdeptree",
            "installed_version": "0.10.1",
            "package_name": "pipdeptree"
        }
    },
    {
        "dependencies": [],
        "package": {
            "key": "mccabe",
            "installed_version": "0.6.1",
            "package_name": "mccabe"
        }
    },
    {
        "dependencies": [],
        "package": {
            "key": "colorama",
            "installed_version": "0.3.9",
            "package_name": "colorama"
        }
    },
    {
        "dependencies": [],
        "package": {
            "key": "parso",
            "installed_version": "0.1.0",
            "package_name": "parso"
        }
    },
    {
        "dependencies": [],
        "package": {
            "key": "pickleshare",
            "installed_version": "0.7.4",
            "package_name": "pickleshare"
        }
    },
    {
        "dependencies": [],
        "package": {
            "key": "pep8",
            "installed_version": "1.7.0",
            "package_name": "pep8"
        }
    },
    {
        "dependencies": [],
        "package": {
            "key": "markupsafe",
            "installed_version": "1.0",
            "package_name": "MarkupSafe"
        }
    },
    {
        "dependencies": [],
        "package": {
            "key": "pym",
            "installed_version": "0.1.3",
            "package_name": "pym"
        }
    },
    {
        "dependencies": [],
        "package": {
            "key": "simplegeneric",
            "installed_version": "0.8.1",
            "package_name": "simplegeneric"
        }
    },
    {
        "dependencies": [],
        "package": {
            "key": "colors.py",
            "installed_version": "0.2.2",
            "package_name": "colors.py"
        }
    },
    {
        "dependencies": [],
        "package": {
            "key": "pygments",
            "installed_version": "2.2.0",
            "package_name": "Pygments"
        }
    },
    {
        "dependencies": [
            {
                "key": "setuptools",
                "installed_version": "36.4.0",
                "package_name": "setuptools",
                "required_version": null
            },
            {
                "key": "ipython",
                "installed_version": "6.2.1",
                "package_name": "ipython",
                "required_version": ">=0.10.2"
            }
        ],
        "package": {
            "key": "ipdb",
            "installed_version": "0.10.3",
            "package_name": "ipdb"
        }
    },
    {
        "dependencies": [],
        "package": {
            "key": "decorator",
            "installed_version": "4.1.2",
            "package_name": "decorator"
        }
    },
    {
        "dependencies": [],
        "package": {
            "key": "pip",
            "installed_version": "9.0.1",
            "package_name": "pip"
        }
    },
    {
        "dependencies": [],
        "package": {
            "key": "wcwidth",
            "installed_version": "0.1.7",
            "package_name": "wcwidth"
        }
    }
]
colorama==0.3.9
colors.py==0.2.2
flake8==3.4.1
  - mccabe [required: >=0.6.0,<0.7.0, installed: 0.6.1]
  - pycodestyle [required: <2.4.0,>=2.0.0, installed: 2.3.1]
  - pyflakes [required: <1.6.0,>=1.5.0, installed: 1.5.0]
Flask==0.12.2
  - click [required: >=2.0, installed: 6.7]
  - itsdangerous [required: >=0.21, installed: 0.24]
  - Jinja2 [required: >=2.4, installed: 2.9.6]
    - MarkupSafe [required: >=0.23, installed: 1.0]
  - Werkzeug [required: >=0.7, installed: 0.12.2]
ipdb==0.10.3
  - ipython [required: >=0.10.2, installed: 6.2.1]
    - decorator [required: Any, installed: 4.1.2]
    - jedi [required: >=0.10, installed: 0.11.0]
      - parso [required: ==0.1.0, installed: 0.1.0]
    - pexpect [required: Any, installed: 4.2.1]
      - ptyprocess [required: >=0.5, installed: 0.5.2]
    - pickleshare [required: Any, installed: 0.7.4]
    - prompt-toolkit [required: >=1.0.4,<2.0.0, installed: 1.0.15]
      - six [required: >=1.9.0, installed: 1.11.0]
      - wcwidth [required: Any, installed: 0.1.7]
    - pygments [required: Any, installed: 2.2.0]
    - setuptools [required: >=18.5, installed: 36.4.0]
    - simplegeneric [required: >0.8, installed: 0.8.1]
    - traitlets [required: >=4.2, installed: 4.3.2]
      - decorator [required: Any, installed: 4.1.2]
      - ipython-genutils [required: Any, installed: 0.2.0]
      - six [required: Any, installed: 1.11.0]
  - setuptools [required: Any, installed: 36.4.0]
pep8==1.7.0
pipdeptree==0.10.1
  - pip [required: >=6.0.0, installed: 9.0.1]
pym==0.1.3
wheel==0.30.0

--reverse not working anymore in 0.10.0 ?

Hi there,

I just upgraded from 0.9.0 to 0.10.0 and I noticed that the output of my usual command is different:

0.9.0

pipdeptree --packages mando --reverse

mando==0.3.3
  - radon==1.5.0 [requires: mando<0.4,>=0.3]

0.10.0

pipdeptree --packages mando --reverse

mando==0.3.3

Example project: https://pypi.python.org/pypi/radon

I tried with both -r and --reverse, same problem, I think something broke.

Tests seem to be broken

 [email protected] ⮀ git-repos/pipdeptree ⮀ ⭠ master  ⮀
 ❯ tox -e py27
GLOB sdist-make: /Users/marca/dev/git-repos/pipdeptree/setup.py
py27 inst-nodeps: /Users/marca/dev/git-repos/pipdeptree/.tox/dist/pipdeptree-0.3.zip
py27 runtests: commands[0] | nosetests tests/
EEFFF
======================================================================
ERROR: pipdeptree_tests.test_req_version
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/marca/dev/git-repos/pipdeptree/.tox/py27/lib/python2.7/site-packages/nose/case.py", line 197, in runTest
    self.test(*self.arg)
  File "/Users/marca/dev/git-repos/pipdeptree/tests/pipdeptree_tests.py", line 28, in test_req_version
    sqlalchemy = find_req('sqlalchemy', 'alembic')
  File "/Users/marca/dev/git-repos/pipdeptree/tests/pipdeptree_tests.py", line 24, in find_req
    return [r for r in pkg_index[parent].requires() if r.key == req][0]
IndexError: list index out of range

======================================================================
ERROR: pipdeptree_tests.test_non_top_pkg_name
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/marca/dev/git-repos/pipdeptree/.tox/py27/lib/python2.7/site-packages/nose/case.py", line 197, in runTest
    self.test(*self.arg)
  File "/Users/marca/dev/git-repos/pipdeptree/tests/pipdeptree_tests.py", line 36, in test_non_top_pkg_name
    flask_r = find_req('flask', 'flask-script')
  File "/Users/marca/dev/git-repos/pipdeptree/tests/pipdeptree_tests.py", line 24, in find_req
    return [r for r in pkg_index[parent].requires() if r.key == req][0]
IndexError: list index out of range

======================================================================
FAIL: pipdeptree_tests.test_render_tree_only_top
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/marca/dev/git-repos/pipdeptree/.tox/py27/lib/python2.7/site-packages/nose/case.py", line 197, in runTest
    self.test(*self.arg)
  File "/Users/marca/dev/git-repos/pipdeptree/tests/pipdeptree_tests.py", line 52, in test_render_tree_only_top
    assert '  - SQLAlchemy [required: >=0.7.3, installed: 0.9.1]' in lines
AssertionError

======================================================================
FAIL: pipdeptree_tests.test_render_tree_list_all
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/marca/dev/git-repos/pipdeptree/.tox/py27/lib/python2.7/site-packages/nose/case.py", line 197, in runTest
    self.test(*self.arg)
  File "/Users/marca/dev/git-repos/pipdeptree/tests/pipdeptree_tests.py", line 62, in test_render_tree_list_all
    assert '  - SQLAlchemy [required: >=0.7.3, installed: 0.9.1]' in lines
AssertionError

======================================================================
FAIL: pipdeptree_tests.test_render_tree_freeze
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/marca/dev/git-repos/pipdeptree/.tox/py27/lib/python2.7/site-packages/nose/case.py", line 197, in runTest
    self.test(*self.arg)
  File "/Users/marca/dev/git-repos/pipdeptree/tests/pipdeptree_tests.py", line 72, in test_render_tree_freeze
    assert '  - SQLAlchemy==0.9.1' in lines
AssertionError

----------------------------------------------------------------------
Ran 5 tests in 0.986s

FAILED (errors=2, failures=3)
ERROR: InvocationError: '/Users/marca/dev/git-repos/pipdeptree/.tox/py27/bin/nosetests tests/'
___________________________________________________________________________________ summary ____________________________________________________________________________________
ERROR:   py27: commands failed

I wonder if it's because the pkgs.pickle file has references to /home/vineet/.virtualenvs/equimapper/src/lookupy and such in it? Maybe it works on your system, but not others because of this?

Need dependency additions for distribution packaging

The distribution package for pipdeptree does not check for the required module argparse, and it installs on Python 2.6 but will not run in that environment because of some apparent Python 2.7 features (i.e., what I believe are called "closures" in dictionary assignments).

Please note that I'm not asking for pipdeptree to support Python 2.6, just that the package information on the project page and the packaging itself inform the user that the package needs 2.7 and the argparse package.

No warning should be issued when a package is required by two packages, one requiring a specific version and the other not

I'm getting the following warning:

Warning!!! Possibly conflicting dependencies found:

  • cryptography==1.4
    • setuptools [required: >=11.3, installed: ]
  • zope.interface==4.2.0
    • setuptools [required: None, installed: ]
  • repoze.who==2.3
    • setuptools [required: None, installed: ]
  • protobuf==3.0.0b2.post2
    • setuptools [required: None, installed: ]

But I think no warning should be issued here as all packages but the first require just any version of setuptools.

Bug shown in readme

* Mako==0.9.1 -> MarkupSafe [required: >=0.9.2, installed: 0.18]

0.18 is actually later than 0.9.2

Suggest change `project_name` to lower case

Suggest change project_name to lower case, since pip package name is case insensitive.
Packages like Pillow, Pygments and PyYAML often has different spellings in other package's dependency list. This will reduce isolated packages / dependencies produced by pipdeptree.

This change only need to add four lines in build_dist_index:

    for p in pkgs:
        p.project_name = p.project_name.lower()
        for r in p.requires():
            r.project_name = r.project_name.lower()
    return dict((p.key, DistPackage(p)) for p in pkgs)

KeyError is thrown if an installed package depends on pip

I have the library pbr installed, and because it depends on pip, pipdeptree throws an error when trying to print out possible confusing dependencies. I think you just need to exclude any requirements that are in the skip list. Here's the traceback I get:

Traceback (most recent call last):
  File "/Users/rxia/envs/website/bin/pipdeptree", line 9, in <module>
    load_entry_point('pipdeptree==0.4.1', 'console_scripts', 'pipdeptree')()
  File "/Users/rxia/envs/website/lib/python2.7/site-packages/pipdeptree.py", line 245, in main
    req = non_top_pkg_name(d, pkg_index[d.key])
KeyError: 'pip

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.