pypa / pip

The Python package installer
https://pip.pypa.io/
MIT License
9.52k stars 3.02k forks source link

Resolver spends too much time calculating "weights" to parents #10557

Closed Rizhiy closed 2 years ago

Rizhiy commented 3 years ago

Description

When running something like pip install -c requirements.txt <package_name> sometimes pip starts checking unnecessary versions.

I know that version checking is unnecessary because requirements.txt contains all the packages with exact versions.

Everything works as expected with legacy resolver.

Expected behaviour

Since all of the versions are already specified, just get them.

pip version

21.2.4

Python version

3.8.8

OS

Ubuntu

How to Reproduce

Unfortunately, I can't provide a reproducible example since it only happens with a package on internal pip index.

The offending package does have the version specified in requirements.txt and a different version is installed when the command is run.

Output

It says something like:

INFO: pip is looking at multiple versions of kiwisolver to determine which version is compatible with other requirements. This could take a while.

But I already have kiwisolver==1.3.1 in my requirements.txt.

Code of Conduct

Rizhiy commented 3 years ago

When I installed the offending package manually with the correct version, I got an error that it's version is incompatible with another specified package.

After resolving the conflict, the installation succeeds properly.

So I guess the problem is that there is a conflict in requirements.txt and pip tries to resolve it, but it is not possible.

Also, pip starts checking versions for packages which are not even part of the conflict which is bad.

Rizhiy commented 3 years ago

I think I got the rough behaviour:

I will try to make a reproducible example later.

uranusjr commented 3 years ago

There's no way to reproduce without your requirements.txt.

mauritsvanrees commented 3 years ago

We have (probably) the same problem when installing Plone with pip. To reproduce (using an alpha version here) do the following. With an older pip (19.2.3) this works, or with latest pip and the legacy resolver, like here:

$ python3.9 -mvenv .
$ bin/pip install -U pip
...
Successfully installed pip-21.2.4
$ bin/pip install Products.CMFPlone -c https://dist.plone.org/release/pip-resolver-test/constraints.txt --use-deprecated legacy-resolver
$ time bin/pip install Products.CMFPlone --use-deprecated legacy-resolver
...lots of: Requirement already satisfied...
real    0m2.379s
user    0m2.208s
sys 0m0.163s

The first pip command needs to install a lot of packages, so it will take a while. The last command as you can see takes maybe two or three seconds.

Now retry with the standard resolver. Remember that the package is already installed, all dependencies were pinned in the constraints, I can start python and import Products.CMFPlone, so this should again take just a few seconds, right?

$ time bin/pip install Products.CMFPlone
...
real    4m5.401s
user    4m3.950s
sys 0m0.703s

Yes, that is four minutes, instead of a few seconds. This is on Mac OS X 10.15.7. In an earlier try, I stopped the process after about ten minutes, as I thought it was probably stuck in an eternal loop. Today for a completely different problem I raised the open file limit from 256 to 400 (ulimit -n 400) and that makes the command at least finish, so that is interesting.

I had a look with py-spy and it said:

Process 43996: /Users/maurits/tmp/piptestoctober/bin/python3.9 bin/pip install Products.CMFPlone
Python v3.9.7 (/Users/maurits/.pyenv/versions/3.9.7/bin/python3.9)

Thread 0x10F3F5DC0 (active+gil): "MainThread"
    visit (pip/_internal/resolution/resolvelib/resolver.py:243)
    visit (pip/_internal/resolution/resolvelib/resolver.py:245)
    visit (pip/_internal/resolution/resolvelib/resolver.py:245)
    visit (pip/_internal/resolution/resolvelib/resolver.py:245)
    visit (pip/_internal/resolution/resolvelib/resolver.py:245)
    visit (pip/_internal/resolution/resolvelib/resolver.py:245)
    visit (pip/_internal/resolution/resolvelib/resolver.py:245)
    visit (pip/_internal/resolution/resolvelib/resolver.py:245)
    visit (pip/_internal/resolution/resolvelib/resolver.py:245)
    visit (pip/_internal/resolution/resolvelib/resolver.py:245)
    visit (pip/_internal/resolution/resolvelib/resolver.py:245)
    visit (pip/_internal/resolution/resolvelib/resolver.py:245)
    visit (pip/_internal/resolution/resolvelib/resolver.py:245)
    visit (pip/_internal/resolution/resolvelib/resolver.py:245)
    visit (pip/_internal/resolution/resolvelib/resolver.py:245)
    visit (pip/_internal/resolution/resolvelib/resolver.py:245)
    get_topological_weights (pip/_internal/resolution/resolvelib/resolver.py:252)
    get_installation_order (pip/_internal/resolution/resolvelib/resolver.py:202)
    run (pip/_internal/commands/install.py:371)
    wrapper (pip/_internal/cli/req_command.py:203)
    _main (pip/_internal/cli/base_command.py:173)
    main (pip/_internal/cli/base_command.py:98)
    main (pip/_internal/cli/main.py:70)
    <module> (pip:8)

See also a thread on community.plone.org. One problem we found there, were cyclic dependencies, but we solved them all in the constraints used in my example above.

mauritsvanrees commented 3 years ago

For good measure, I thought I would make pip more verbose, but there does not seem to be anything interesting:

$ time bin/pip install Products.CMFPlone -vvvvvvvvvvvvvvv
Using pip 21.2.4 from /Users/maurits/tmp/piptestoctober/lib/python3.9/site-packages/pip (python 3.9)
Non-user install because user site-packages disabled
Created temporary directory: /private/var/folders/26/1plvhxbs6yx7g_82v2xdxc500000gn/T/pip-ephem-wheel-cache-4am_pg69
Created temporary directory: /private/var/folders/26/1plvhxbs6yx7g_82v2xdxc500000gn/T/pip-req-tracker-8mhy15lm
Initialized build tracking at /private/var/folders/26/1plvhxbs6yx7g_82v2xdxc500000gn/T/pip-req-tracker-8mhy15lm
Created build tracker: /private/var/folders/26/1plvhxbs6yx7g_82v2xdxc500000gn/T/pip-req-tracker-8mhy15lm
Entered build tracker: /private/var/folders/26/1plvhxbs6yx7g_82v2xdxc500000gn/T/pip-req-tracker-8mhy15lm
Created temporary directory: /private/var/folders/26/1plvhxbs6yx7g_82v2xdxc500000gn/T/pip-install-erlzkofm
Requirement already satisfied: Products.CMFPlone in ./lib/python3.9/site-packages (6.0.0a1.dev0)
...
Created temporary directory: /private/var/folders/26/1plvhxbs6yx7g_82v2xdxc500000gn/T/pip-unpack-292uz9ut
... after again almost 4 minutes:
Removed build tracker: '/private/var/folders/26/1plvhxbs6yx7g_82v2xdxc500000gn/T/pip-req-tracker-8mhy15lm'

I checked the directories a couple of times during the process, but there was nothing in them.

uranusjr commented 3 years ago

Closing since OP did not provide a reproduction, and the available reproduction has been fixed in #10239.

Rizhiy commented 3 years ago

@uranusjr Except it clearly hasn't, as indicated by example in @mauritsvanrees response? This is either a new bug or you have a regression.

Here is the example:

pip install Products.CMFPlone -c https://dist.plone.org/release/pip-resolver-test/constraints.txt --use-deprecated legacy-resolver # Takes a long time for all dependencies
pip install Products.CMFPlone -c https://dist.plone.org/release/pip-resolver-test/constraints.txt --use-deprecated legacy-resolver # Takes 2 seconds
pip install Products.CMFPlone -c https://dist.plone.org/release/pip-resolver-test/constraints.txt # Hasn't finished after 2 minutes

Tested today with pip==21.2.4, which is after 21.2.2

P.S. Surely, closing the issue after 2 days just because I couldn't provide an example is ridiculous.

uranusjr commented 3 years ago

Likely I linked to an incorrect PR then. The bottom line is I couldn't reproduce on main.

Rizhiy commented 3 years ago

I have checked that all the installed packages are specified in https://dist.plone.org/release/pip-resolver-test/constraints.txt (in fact it is overspecified by quite a bit). Packages in constraints.txt are out of order, so you should sort it before comparing.

Rizhiy commented 3 years ago

@uranusjr

Likely I linked to an incorrect PR then. The bottom line is I couldn't reproduce on main.

Just checked on main (21.3.dev0), still having problem:

git clone https://github.com/pypa/pip.git
pip install -e pip
python -m pip install Products.CMFPlone -c https://dist.plone.org/release/pip-resolver-test/constraints.txt --use-deprecated legacy-resolver # Takes a long time for all dependencies
python -m pip install Products.CMFPlone -c https://dist.plone.org/release/pip-resolver-test/constraints.txt --use-deprecated legacy-resolver # Takes 2 seconds
python -m pip install Products.CMFPlone -c https://dist.plone.org/release/pip-resolver-test/constraints.txt # Hasn't finished after 2 minutes
Rizhiy commented 3 years ago

Also, if you run the installation command with -vv and Ctrl-C when it hangs, you get the stack trace which shows that resolver is doing too much work:

  File "/home/rizhiy/projects/pip/src/pip/_internal/cli/base_command.py", line 164, in exc_logging_wrapper
    status = run_func(*args)
  File "/home/rizhiy/projects/pip/src/pip/_internal/cli/req_command.py", line 204, in wrapper
    return func(self, options, args)
  File "/home/rizhiy/projects/pip/src/pip/_internal/commands/install.py", line 388, in run
    to_install = resolver.get_installation_order(requirement_set)
  File "/home/rizhiy/projects/pip/src/pip/_internal/resolution/resolvelib/resolver.py", line 181, in get_installation_order
    weights = get_topological_weights(
  File "/home/rizhiy/projects/pip/src/pip/_internal/resolution/resolvelib/resolver.py", line 231, in get_topological_weights
    visit(None)
  File "/home/rizhiy/projects/pip/src/pip/_internal/resolution/resolvelib/resolver.py", line 224, in visit
    visit(child)
  File "/home/rizhiy/projects/pip/src/pip/_internal/resolution/resolvelib/resolver.py", line 224, in visit
    visit(child)
  File "/home/rizhiy/projects/pip/src/pip/_internal/resolution/resolvelib/resolver.py", line 224, in visit
    visit(child)
  [Previous line repeated 13 more times]
  File "/home/rizhiy/projects/pip/src/pip/_internal/resolution/resolvelib/resolver.py", line 228, in visit
    weights[node] = max(last_known_parent_count, len(path))
uranusjr commented 3 years ago

If that's where the resolver hangs, your issue is not about constraints, since when the resolver reaches that point, it should have already finished version resolution, including constraints.

pradyunsg commented 3 years ago

Using #10481 and running:

$ pip install https://github.com/notatallshaw/pip/archive/refs/heads/prefer_failures.zip
$ python -m pip install Products.CMFPlone -c https://dist.plone.org/release/pip-resolver-test/constraints.txt --log /tmp/log.txt

The relevant log messages are:

2021-10-09T11:22:41,817 Using pip 21.3.dev0 from /Users/pradyunsg/Developer/resolvelib/.venv/lib/python3.9/site-packages/pip (python 3.9)
2021-10-09T11:24:36,613 Successfully built AccessControl ExtensionClass zope.i18nmessageid Acquisition pyScss z3c.autoinclude ZODB3 zope.container BTrees Chameleon lxml Persistence repoze.xmliter zope.hookable zope.proxy zope.security Zope2 python-gettext zope.globalrequest zodbpickle cffi future sgmllib3k z3c.formwidget.query zdaemon z3c.objpath

And that seems to tell me that the resolution is pretty quick with the fixes in #10481.

pradyunsg commented 3 years ago

Note that this involved downloads as well. Running again with wheel instead, with all the downloads cached:

uranusjr commented 3 years ago

From the report, resolution time isn't the actual issue though, it's after the resolution where we sort packages for installation.

pradyunsg commented 3 years ago

Indeed. Here's the graph we're trying to do that with:

2021-10-09T11:56:22,896 vertices: ['plone-namedfile[blobs]', 'zope-testbrowser', 'zope-container', 'plone-browserlayer', 'zope-hookable', 'zope-i18n[zcml]', 'plone-app-linkintegrity', 'z3c-autoinclude', 'zope-deprecation', 'plone-namedfile[scales]', 'plone-subrequest', 'plone-schemaeditor', 'plone-app-contentlisting', 'products-dcworkflow', 'products-pythonscripts', 'z3c-zcmlhook', 'zodbpickle', 'plone-session', 'zconfig', 'zope-componentvocabulary', 'plone-app-intid', 'products-btreefolder2', 'zope-schema', 'zope-cachedescriptors', 'zdaemon', 'products-pluggableauthservice', 'plone-portlet-collection', 'products-cmfdifftool', 'plone-app-event', 'plone-app-contenttypes', 'transaction', 'sgmllib3k', 'pillow', 'simplejson', 'zope-intid', '<Python from Requires-Python>', 'z3c-pt', 'zope-interface', None, 'zope-configuration', 'pytz', 'products-externalmethod', 'zope-browsermenu', 'setuptools', 'products-zopeversioncontrol', 'beautifulsoup4', 'authencoding', 'z3c-formwidget-query', 'plone-resourceeditor', 'zope-event', 'plone-app-registry', 'plone-scale', 'plone-app-customerize', 'products-standardcachemanagers', 'wsgiproxy2', 'zope-sendmail', 'products-pluginregistry', 'plone-scale[storage]', 'products-daterecurringindex', 'zope-component[zcml]', 'z3c-caching[zcml]', 'six', 'plone-folder', 'cssselect', 'zope-dottedname', 'record', 'plone-autoform', 'plone-app-portlets', 'plone-app-contentmenu', 'plone-app-workflow', 'zope-site', 'plone-z3cform', 'plone-protect', 'plone-app-uuid', 'plone-staticresources', 'plone-app-lockingbehavior', 'lxml[cssselect]', 'plone-intelligenttext', 'zope-contenttype', 'products-cmfdynamicviewfti', 'plone-app-contentrules', 'repoze-xmliter', 'zeo', 'restrictedpython', 'plone-portlets', 'zope-component', 'roman', 'waitress', 'plone-app-viewletmanager', 'plone-synchronize', 'cffi', 'zope-sequencesort', 'products-cmfcore', 'acquisition', 'products-genericsetup', 'plone-app-locales', 'plone-alterego', 'plone-registry', 'z3c-objpath', 'products-zcatalog', 'plone-app-dexterity', 'products-isurlinportal', 'products-portaltransforms', 'plone-app-relationfield', 'plone-behavior', 'soupsieve', 'plone-app-discussion', 'products-extendedpathindex', 'plone-app-users', 'docutils', 'mockup', 'plone-app-content', 'five-localsitemanager', 'zope-proxy', 'plone-portlet-static', 'zope-contentprovider', 'plone-supermodel', 'zope-browserpage', 'unidecode', 'plone-app-i18n', 'diazo', 'zope-tales', 'plone-app-versioningbehavior', 'products-mimetypesregistry', 'extensionclass', 'zope-i18nmessageid', 'zope-structuredtext', 'products-mailhost', 'python-dateutil', 'zope-security', 'pastedeploy', 'jsonschema', 'zope[wsgi]', 'plone-i18n', 'collective-monkeypatcher', 'zodb3', 'plone-app-textfield', 'zc-relation', 'zope-pagetemplate', 'zope-location', 'plone-formwidget-namedfile', 'products-cmfuid', 'zope-traversing', 'zope-deferredimport', 'zexceptions', 'zope-ramcache', 'products-siteerrorlog', 'products-cmfeditions', 'plone-app-multilingual', 'zodb', 'zope-app-locales', 'multipart', 'products-cmfplone', 'calmjs-parse', 'plone-app-theming', 'markdown', 'plone-memoize', 'plone-transformchain', 'z3c-relationfield', 'five-customerize', 'five-intid', 'plone-app-widgets', 'lxml', 'attrs', 'zope-publisher', 'plone-theme', 'zope-browserresource', 'accesscontrol', 'plone-caching', 'products-plonepas', 'plone-api', 'multimapping', 'documenttemplate', 'zope-testing', 'plone-resource', 'webtest', 'plone-namedfile', 'products-sessions', 'missing', 'chameleon', 'plone-app-layout', 'plone-app-vocabularies', 'plone-app-redirector', 'products-statusmessages', 'zope-viewlet', 'pyrsistent', 'plone-locking', 'plone-app-dexterity[relations]', 'plone-keyring', 'plone-stringinterp', 'python-gettext', 'zope2', 'piexif', 'plone-contentrules', 'zope-i18n', 'datetime', 'persistent', 'webob', 'pycparser', 'plone-dexterity', 'plonetheme-barceloneta', 'plone-batching', 'plone-event', 'zope-globalrequest', 'feedparser', 'zope-size', 'plone-app-querystring', 'decorator', 'z3c-form', 'btrees', 'zope-tal', 'zope-datetime', 'borg-localrole', 'zc-lockfile', 'zope-copy', 'plone-app-z3cform', 'zope-exceptions', 'plone-outputfilters', 'pyscss', 'plone-formwidget-recurrence', 'zope-browser', 'persistence', 'plone-formwidget-recurrence[z3cform]', 'paste', 'icalendar', 'zope-annotation', 'plone-indexer', 'zope-ptresource', 'zope-filerepresentation', 'plone-rfc822', 'plone-uuid', 'zope-keyreference', 'ply', 'future', 'zope-lifecycleevent', 'plone-schema', 'z3c-caching', 'zope-processlifetime', 'zope']
2021-10-09T11:56:22,897 edges: [(None, 'products-cmfplone'), ('products-cmfplone', 'zope-container'), ('products-cmfplone', 'plone-browserlayer'), ('products-cmfplone', 'plone-app-linkintegrity'), ('products-cmfplone', 'zope-deprecation'), ('products-cmfplone', 'plone-subrequest'), ('products-cmfplone', 'plone-app-contentlisting'), ('products-cmfplone', 'products-dcworkflow'), ('products-cmfplone', 'plone-session'), ('products-cmfplone', 'zope-cachedescriptors'), ('products-cmfplone', 'plone-portlet-collection'), ('products-cmfplone', 'products-pluggableauthservice'), ('products-cmfplone', 'products-cmfdifftool'), ('products-cmfplone', 'plone-app-contenttypes'), ('products-cmfplone', 'transaction'), ('products-cmfplone', 'pillow'), ('products-cmfplone', 'zope-interface'), ('products-cmfplone', 'setuptools'), ('products-cmfplone', 'zope-event'), ('products-cmfplone', 'plone-app-registry'), ('products-cmfplone', 'plone-app-customerize'), ('products-cmfplone', 'products-pluginregistry'), ('products-cmfplone', 'plone-folder'), ('products-cmfplone', 'zope-dottedname'), ('products-cmfplone', 'plone-app-portlets'), ('products-cmfplone', 'plone-app-contentmenu'), ('products-cmfplone', 'plone-app-workflow'), ('products-cmfplone', 'zope-site'), ('products-cmfplone', 'plone-protect'), ('products-cmfplone', 'plone-app-uuid'), ('products-cmfplone', 'plone-staticresources'), ('products-cmfplone', 'plone-intelligenttext'), ('products-cmfplone', 'products-cmfdynamicviewfti'), ('products-cmfplone', 'plone-app-contentrules'), ('products-cmfplone', 'plone-portlets'), ('products-cmfplone', 'zope-component'), ('products-cmfplone', 'plone-app-viewletmanager'), ('products-cmfplone', 'products-cmfcore'), ('products-cmfplone', 'acquisition'), ('products-cmfplone', 'products-genericsetup'), ('products-cmfplone', 'plone-app-locales'), ('products-cmfplone', 'plone-registry'), ('products-cmfplone', 'products-isurlinportal'), ('products-cmfplone', 'plone-app-dexterity'), ('products-cmfplone', 'products-portaltransforms'), ('products-cmfplone', 'plone-app-discussion'), ('products-cmfplone', 'products-extendedpathindex'), ('products-cmfplone', 'plone-app-users'), ('products-cmfplone', 'mockup'), ('products-cmfplone', 'plone-app-content'), ('products-cmfplone', 'five-localsitemanager'), ('products-cmfplone', 'plone-portlet-static'), ('products-cmfplone', 'plone-app-i18n'), ('products-cmfplone', 'zope-tales'), ('products-cmfplone', 'products-mimetypesregistry'), ('products-cmfplone', 'extensionclass'), ('products-cmfplone', 'zope-i18nmessageid'), ('products-cmfplone', 'zope-structuredtext'), ('products-cmfplone', 'zope[wsgi]'), ('products-cmfplone', 'plone-i18n'), ('products-cmfplone', 'zodb3'), ('products-cmfplone', 'zope-location'), ('products-cmfplone', 'zope-pagetemplate'), ('products-cmfplone', 'products-cmfuid'), ('products-cmfplone', 'zope-traversing'), ('products-cmfplone', 'zope-deferredimport'), ('products-cmfplone', 'products-siteerrorlog'), ('products-cmfplone', 'products-cmfeditions'), ('products-cmfplone', 'plone-app-multilingual'), ('products-cmfplone', 'zope-app-locales'), ('products-cmfplone', 'calmjs-parse'), ('products-cmfplone', 'plone-app-theming'), ('products-cmfplone', 'plone-memoize'), ('products-cmfplone', 'five-customerize'), ('products-cmfplone', 'zope-publisher'), ('products-cmfplone', 'plone-theme'), ('products-cmfplone', 'accesscontrol'), ('products-cmfplone', 'products-plonepas'), ('products-cmfplone', 'plone-api'), ('products-cmfplone', 'plone-app-vocabularies'), ('products-cmfplone', 'plone-app-redirector'), ('products-cmfplone', 'plone-app-layout'), ('products-cmfplone', 'products-statusmessages'), ('products-cmfplone', 'plone-locking'), ('products-cmfplone', 'plone-contentrules'), ('products-cmfplone', 'zope-i18n'), ('products-cmfplone', 'datetime'), ('products-cmfplone', 'plonetheme-barceloneta'), ('products-cmfplone', 'plone-batching'), ('products-cmfplone', 'zope-tal'), ('products-cmfplone', 'borg-localrole'), ('products-cmfplone', 'plone-outputfilters'), ('products-cmfplone', 'pyscss'), ('products-cmfplone', 'plone-indexer'), ('products-cmfplone', 'plone-schema'), ('products-cmfplone', 'z3c-autoinclude'), ('plone-app-event', 'plone-namedfile'), ('plone-app-event', 'plone-autoform'), ('plone-app-event', 'plone-app-portlets'), ('plone-app-event', 'zope-i18nmessageid'), ('plone-app-event', 'zope-container'), ('plone-app-event', 'plone-browserlayer'), ('plone-app-event', 'plone-app-vocabularies'), ('plone-app-event', 'plone-app-layout'), ('plone-app-event', 'products-statusmessages'), ('plone-app-event', 'plone-app-contentlisting'), ('plone-app-event', 'plone-z3cform'), ('plone-app-event', 'zope-schema'), ('plone-app-event', 'zope2'), ('plone-app-event', 'plone-app-textfield'), ('plone-app-event', 'zope-i18n'), ('plone-app-event', 'datetime'), ('plone-app-event', 'transaction'), ('plone-app-event', 'plone-portlets'), ('plone-app-event', 'plone-dexterity'), ('plone-app-event', 'zope-component'), ('plone-app-event', 'plone-event'), ('plone-app-event', 'zope-globalrequest'), ('plone-app-event', 'plone-app-querystring'), ('plone-app-event', 'zope-interface'), ('plone-app-event', 'z3c-form'), ('plone-app-event', 'plone-app-multilingual'), ('plone-app-event', 'products-cmfcore'), ('plone-app-event', 'acquisition'), ('plone-app-event', 'pytz'), ('plone-app-event', 'products-genericsetup'), ('plone-app-event', 'setuptools'), ('plone-app-event', 'products-cmfplone'), ('plone-app-event', 'plone-registry'), ('plone-app-event', 'products-zcatalog'), ('plone-app-event', 'plone-app-dexterity'), ('plone-app-event', 'plone-app-z3cform'), ('plone-app-event', 'plone-memoize'), ('plone-app-event', 'zope-event'), ('plone-app-event', 'plone-behavior'), ('plone-app-event', 'plone-app-registry'), ('plone-app-event', 'plone-formwidget-recurrence[z3cform]'), ('plone-app-event', 'icalendar'), ('plone-app-event', 'zope-annotation'), ('plone-app-event', 'plone-indexer'), ('plone-app-event', 'zope-publisher'), ('plone-app-event', 'plone-uuid'), ('plone-app-event', 'zope-contentprovider'), ('plone-app-event', 'products-daterecurringindex'), ('plone-app-event', 'plone-supermodel'), ('plone-app-event', 'six'), ('plone-app-event', 'zope-lifecycleevent'), ('plone-app-event', 'plone-folder'), ('plone-app-querystring', 'zope-dottedname'), ('plone-app-querystring', 'zope-i18nmessageid'), ('plone-app-querystring', 'plone-app-layout'), ('plone-app-querystring', 'python-dateutil'), ('plone-app-querystring', 'plone-app-contentlisting'), ('plone-app-querystring', 'zope-schema'), ('plone-app-querystring', 'zope-i18n'), ('plone-app-querystring', 'datetime'), ('plone-app-querystring', 'zope-component'), ('plone-app-querystring', 'plone-batching'), ('plone-app-querystring', 'zope-globalrequest'), ('plone-app-querystring', 'zope-interface'), ('plone-app-querystring', 'products-cmfcore'), ('plone-app-querystring', 'setuptools'), ('plone-app-querystring', 'products-cmfplone'), ('plone-app-querystring', 'plone-registry'), ('plone-app-querystring', 'plone-app-registry'), ('plone-app-querystring', 'zope-publisher'), ('plone-app-querystring', 'six'), ('plone-app-z3cform', 'zope-i18nmessageid'), ('plone-app-z3cform', 'zope-deprecation'), ('plone-app-z3cform', 'plone-z3cform'), ('plone-app-z3cform', 'plone-protect'), ('plone-app-z3cform', 'zope-schema'), ('plone-app-z3cform', 'zope2'), ('plone-app-z3cform', 'plone-app-textfield'), ('plone-app-z3cform', 'zope-i18n'), ('plone-app-z3cform', 'zope-component'), ('plone-app-z3cform', 'zope-traversing'), ('plone-app-z3cform', 'zope-globalrequest'), ('plone-app-z3cform', 'z3c-form'), ('plone-app-z3cform', 'zope-interface'), ('plone-app-z3cform', 'products-cmfcore'), ('plone-app-z3cform', 'acquisition'), ('plone-app-z3cform', 'setuptools'), ('plone-app-z3cform', 'products-cmfplone'), ('plone-app-z3cform', 'z3c-formwidget-query'), ('plone-app-z3cform', 'plone-app-widgets'), ('plone-app-z3cform', 'six'), ('plone-app-z3cform', 'zope-browserpage'), ('plone-app-widgets', 'products-cmfplone'), ('plone-app-widgets', 'six'), ('plone-app-widgets', 'setuptools'), ('plone-app-widgets', 'plone-app-vocabularies'), ('plone-formwidget-recurrence[z3cform]', 'z3c-form'), ('plone-formwidget-recurrence[z3cform]', 'zope-schema'), ('plone-formwidget-recurrence[z3cform]', 'setuptools'), ('plone-formwidget-recurrence[z3cform]', 'products-cmfplone'), ('plone-formwidget-recurrence[z3cform]', 'zope-i18nmessageid'), ('plone-formwidget-recurrence[z3cform]', 'zope-i18n'), ('plone-formwidget-recurrence[z3cform]', 'zope-component'), ('plone-formwidget-recurrence[z3cform]', 'zope-traversing'), ('plone-formwidget-recurrence[z3cform]', 'python-dateutil'), ('plone-formwidget-recurrence[z3cform]', 'plone-formwidget-recurrence'), ('plone-formwidget-recurrence[z3cform]', 'zope-interface'), ('plone-formwidget-recurrence[z3cform]', 'products-cmfcore'), ('plone-formwidget-recurrence', 'setuptools'), ('plone-formwidget-recurrence', 'products-cmfplone'), ('plone-formwidget-recurrence', 'zope-i18nmessageid'), ('plone-formwidget-recurrence', 'zope-i18n'), ('plone-formwidget-recurrence', 'zope-component'), ('plone-formwidget-recurrence', 'python-dateutil'), ('plone-formwidget-recurrence', 'zope-interface'), ('plone-formwidget-recurrence', 'products-cmfcore'), ('zope-dottedname', 'setuptools'), ('plone-app-layout', 'zope-dottedname'), ('plone-app-layout', 'plone-app-portlets'), ('plone-app-layout', 'zope-deprecation'), ('plone-app-layout', 'zope-viewlet'), ('plone-app-layout', 'zope-schema'), ('plone-app-layout', 'plone-i18n'), ('plone-app-layout', 'products-cmfdynamicviewfti'), ('plone-app-layout', 'zope2'), ('plone-app-layout', 'zope-i18n'), ('plone-app-layout', 'datetime'), ('plone-app-layout', 'plone-portlets'), ('plone-app-layout', 'zope-component'), ('plone-app-layout', 'plone-batching'), ('plone-app-layout', 'zope-deferredimport'), ('plone-app-layout', 'plone-app-viewletmanager'), ('plone-app-layout', 'zope-interface'), ('plone-app-layout', 'products-cmfeditions'), ('plone-app-layout', 'products-cmfcore'), ('plone-app-layout', 'acquisition'), ('plone-app-layout', 'setuptools'), ('plone-app-layout', 'plone-registry'), ('plone-app-layout', 'plone-memoize'), ('plone-app-layout', 'zope-publisher'), ('plone-app-layout', 'plone-app-content'), ('plone-app-layout', 'six'), ('products-cmfeditions', 'acquisition'), ('products-cmfeditions', 'zope-dottedname'), ('products-cmfeditions', 'products-genericsetup'), ('products-cmfeditions', 'zope2'), ('products-cmfeditions', 'setuptools'), ('products-cmfeditions', 'products-cmfdifftool'), ('products-cmfeditions', 'products-zopeversioncontrol'), ('products-cmfeditions', 'zope-i18nmessageid'), ('products-cmfeditions', 'transaction'), ('products-cmfeditions', 'datetime'), ('products-cmfeditions', 'zope-copy'), ('products-cmfeditions', 'products-cmfuid'), ('products-cmfeditions', 'six'), ('products-cmfeditions', 'zope-interface'), ('products-cmfeditions', 'products-cmfcore'), ('five-customerize', 'acquisition'), ('five-customerize', 'zope-dottedname'), ('five-customerize', 'zope-schema'), ('five-customerize', 'setuptools'), ('five-customerize', 'zope-pagetemplate'), ('five-customerize', 'plone-portlets'), ('five-customerize', 'zope-component'), ('five-customerize', 'zope-traversing'), ('five-customerize', 'zope-componentvocabulary'), ('five-customerize', 'zope-viewlet'), ('five-customerize', 'zope-lifecycleevent'), ('five-customerize', 'zope-interface'), ('five-customerize', 'zope'), ('plone-app-registry', 'zope-dottedname'), ('plone-app-registry', 'products-genericsetup'), ('plone-app-registry', 'zope2'), ('plone-app-registry', 'setuptools'), ('plone-app-registry', 'plone-autoform'), ('plone-app-registry', 'lxml'), ('plone-app-registry', 'plone-registry'), ('plone-app-registry', 'zope-i18nmessageid'), ('plone-app-registry', 'plone-app-z3cform'), ('plone-app-registry', 'zope-component'), ('plone-app-registry', 'products-statusmessages'), ('plone-app-registry', 'plone-supermodel'), ('plone-app-registry', 'zope-interface'), ('plone-app-registry', 'products-cmfcore'), ('plone-registry', 'zope-dottedname'), ('plone-registry', 'zope-schema'), ('plone-registry', 'setuptools'), ('plone-registry', 'zope-component'), ('plone-registry', 'zope-event'), ('plone-registry', 'zope-interface'), ('plone-app-workflow', 'zope-dottedname'), ('plone-app-workflow', 'zope-i18nmessageid'), ('plone-app-workflow', 'zope-site'), ('plone-app-workflow', 'products-statusmessages'), ('plone-app-workflow', 'products-dcworkflow'), ('plone-app-workflow', 'zope-schema'), ('plone-app-workflow', 'zope2'), ('plone-app-workflow', 'zope-i18n'), ('plone-app-workflow', 'datetime'), ('plone-app-workflow', 'transaction'), ('plone-app-workflow', 'zope-component'), ('plone-app-workflow', 'zope-interface'), ('plone-app-workflow', 'products-cmfcore'), ('plone-app-workflow', 'acquisition'), ('plone-app-workflow', 'products-genericsetup'), ('plone-app-workflow', 'setuptools'), ('plone-app-workflow', 'plone-memoize'), ('plone-app-workflow', 'six'), ('plone-app-workflow', 'zope-lifecycleevent'), ('plone-app-workflow', 'zope-testing'), ('z3c-autoinclude', 'zope-dottedname'), ('z3c-autoinclude', 'zope-schema'), ('z3c-autoinclude', 'setuptools'), ('z3c-autoinclude', 'zope-interface'), ('z3c-autoinclude', 'zope-configuration'), ('zope-container', 'zope-dottedname'), ('zope-container', 'zope-i18nmessageid'), ('zope-container', 'zope-security'), ('zope-container', 'zope-schema'), ('zope-container', 'zope-cachedescriptors'), ('zope-container', 'zope-location'), ('zope-container', 'persistent'), ('zope-container', 'zope-component'), ('zope-container', 'zope-traversing'), ('zope-container', '<Python from Requires-Python>'), ('zope-container', 'zope-size'), ('zope-container', 'zope-interface'), ('zope-container', 'btrees'), ('zope-container', 'setuptools'), ('zope-container', 'zope-event'), ('zope-container', 'zope-filerepresentation'), ('zope-container', 'zope-publisher'), ('zope-container', 'zope-proxy'), ('zope-container', 'six'), ('zope-container', 'zope-lifecycleevent'), ('plone-autoform', 'z3c-form'), ('plone-autoform', 'zope-dottedname'), ('plone-autoform', 'zope-schema'), ('plone-autoform', 'setuptools'), ('plone-autoform', 'plone-supermodel'), ('plone-autoform', 'six'), ('plone-autoform', 'zope-security'), ('plone-autoform', 'plone-z3cform'), ('plone-autoform', 'zope-interface'), ('plone-dexterity', 'zope-dottedname'), ('plone-dexterity', 'plone-autoform'), ('plone-dexterity', 'zope-container'), ('plone-dexterity', 'products-statusmessages'), ('plone-dexterity', 'zope-security'), ('plone-dexterity', 'plone-z3cform'), ('plone-dexterity', 'zope-schema'), ('plone-dexterity', 'products-cmfdynamicviewfti'), ('plone-dexterity', 'zope-location'), ('plone-dexterity', 'datetime'), ('plone-dexterity', 'zope-component'), ('plone-dexterity', 'zope-globalrequest'), ('plone-dexterity', 'zope-size'), ('plone-dexterity', 'plone-synchronize'), ('plone-dexterity', 'zope-interface'), ('plone-dexterity', 'products-cmfcore'), ('plone-dexterity', 'plone-alterego'), ('plone-dexterity', 'setuptools'), ('plone-dexterity', 'plone-memoize'), ('plone-dexterity', 'zope-browser'), ('plone-dexterity', 'plone-behavior'), ('plone-dexterity', 'zope-annotation'), ('plone-dexterity', 'zope-filerepresentation'), ('plone-dexterity', 'zope-publisher'), ('plone-dexterity', 'plone-rfc822'), ('plone-dexterity', 'plone-uuid'), ('plone-dexterity', 'plone-supermodel'), ('plone-dexterity', 'six'), ('plone-dexterity', 'zope-lifecycleevent'), ('plone-dexterity', 'plone-folder'), ('plone-dexterity', 'zope'), ('plone-supermodel', 'zope-dottedname'), ('plone-supermodel', 'zope-schema'), ('plone-supermodel', 'lxml'), ('plone-supermodel', 'setuptools'), ('plone-supermodel', 'zope-i18nmessageid'), ('plone-supermodel', 'zope-component'), ('plone-supermodel', 'zope-deferredimport'), ('plone-supermodel', 'six'), ('plone-supermodel', 'z3c-zcmlhook'), ('plone-supermodel', 'zope-interface'), ('products-zcatalog', 'zope-dottedname'), ('products-zcatalog', 'extensionclass'), ('products-zcatalog', 'record'), ('products-zcatalog', 'missing'), ('products-zcatalog', 'zope-schema'), ('products-zcatalog', 'datetime'), ('products-zcatalog', 'restrictedpython'), ('products-zcatalog', 'zope-globalrequest'), ('products-zcatalog', 'zope-deferredimport'), ('products-zcatalog', '<Python from Requires-Python>'), ('products-zcatalog', 'zexceptions'), ('products-zcatalog', 'zope-interface'), ('products-zcatalog', 'acquisition'), ('products-zcatalog', 'zodb'), ('products-zcatalog', 'btrees'), ('products-zcatalog', 'setuptools'), ('products-zcatalog', 'persistence'), ('products-zcatalog', 'accesscontrol'), ('products-zcatalog', 'six'), ('products-zcatalog', 'documenttemplate'), ('products-zcatalog', 'zope-testing'), ('products-zcatalog', 'zope'), ('plone-folder', 'products-btreefolder2'), ('plone-folder', 'zope2'), ('plone-folder', 'setuptools'), ('plone-folder', 'zope-container'), ('plone-folder', 'products-zcatalog'), ('plone-folder', 'zope-component'), ('plone-folder', 'plone-memoize'), ('plone-folder', 'six'), ('plone-folder', 'zope-interface'), ('plone-folder', 'products-cmfcore'), ('plone-folder', 'zope-annotation'), ('products-cmfdifftool', 'acquisition'), ('products-cmfdifftool', 'products-genericsetup'), ('products-cmfdifftool', 'zope2'), ('products-cmfdifftool', 'setuptools'), ('products-cmfdifftool', 'six'), ('products-cmfdifftool', 'zope-interface'), ('products-cmfdifftool', 'products-cmfcore'), ('zope-i18nmessageid', 'six'), ('zope-i18nmessageid', 'setuptools'), ('plone-app-contentmenu', 'acquisition'), ('plone-app-contentmenu', 'products-cmfdynamicviewfti'), ('plone-app-contentmenu', 'zope2'), ('plone-app-contentmenu', 'setuptools'), ('plone-app-contentmenu', 'zope-browsermenu'), ('plone-app-contentmenu', 'zope-publisher'), ('plone-app-contentmenu', 'plone-app-content'), ('plone-app-contentmenu', 'zope-i18nmessageid'), ('plone-app-contentmenu', 'zope-i18n'), ('plone-app-contentmenu', 'zope-contentprovider'), ('plone-app-contentmenu', 'zope-component'), ('plone-app-contentmenu', 'plone-memoize'), ('plone-app-contentmenu', 'plone-protect'), ('plone-app-contentmenu', 'zope-interface'), ('plone-app-contentmenu', 'products-cmfcore'), ('plone-app-contentmenu', 'plone-locking'), ('plone-app-content', 'zope-i18nmessageid'), ('plone-app-content', 'zope-container'), ('plone-app-content', 'plone-app-vocabularies'), ('plone-app-content', 'plone-protect'), ('plone-app-content', 'zope-schema'), ('plone-app-content', 'plone-i18n'), ('plone-app-content', 'products-cmfdynamicviewfti'), ('plone-app-content', 'zope-i18n'), ('plone-app-content', 'zope-component'), ('plone-app-content', 'plone-batching'), ('plone-app-content', 'simplejson'), ('plone-app-content', 'z3c-form'), ('plone-app-content', 'zope-interface'), ('plone-app-content', 'products-cmfcore'), ('plone-app-content', 'acquisition'), ('plone-app-content', 'setuptools'), ('plone-app-content', 'plone-memoize'), ('plone-app-content', 'zope-event'), ('plone-app-content', 'plone-app-widgets'), ('plone-app-content', 'zope-publisher'), ('plone-app-content', 'zope-lifecycleevent'), ('plone-app-content', 'zope'), ('plone-app-vocabularies', 'acquisition'), ('plone-app-vocabularies', 'zope-schema'), ('plone-app-vocabularies', 'zope2'), ('plone-app-vocabularies', 'setuptools'), ('plone-app-vocabularies', 'zope-i18n'), ('plone-app-vocabularies', 'zope-i18nmessageid'), ('plone-app-vocabularies', 'zope-component'), ('plone-app-vocabularies', 'zope-site'), ('plone-app-vocabularies', 'six'), ('plone-app-vocabularies', 'zope-browser'), ('plone-app-vocabularies', 'plone-app-querystring'), ('plone-app-vocabularies', 'pytz'), ('plone-app-vocabularies', 'zope-interface'), ('plone-app-vocabularies', 'products-cmfcore'), ('plone-i18n', 'zope-schema'), ('plone-i18n', 'zodb'), ('plone-i18n', 'setuptools'), ('plone-i18n', 'zope-publisher'), ('plone-i18n', 'zope-i18n'), ('plone-i18n', 'zope-i18nmessageid'), ('plone-i18n', 'accesscontrol'), ('plone-i18n', 'zope-component'), ('plone-i18n', 'zope-globalrequest'), ('plone-i18n', 'plone-supermodel'), ('plone-i18n', 'unidecode'), ('plone-i18n', 'zope-interface'), ('plone-i18n', 'zope'), ('plone-i18n', 'products-cmfcore'), ('zope-app-locales', 'zope-i18nmessageid'), ('zope-app-locales', 'zope-interface'), ('zope-app-locales', 'zope-cachedescriptors'), ('zope-app-locales', 'setuptools'), ('zope-traversing', 'setuptools'), ('zope-traversing', 'zope-publisher'), ('zope-traversing', 'zope-location'), ('zope-traversing', 'zope-i18n'), ('zope-traversing', 'zope-i18nmessageid'), ('zope-traversing', 'transaction'), ('zope-traversing', 'zope-proxy'), ('zope-traversing', 'zope-component'), ('zope-traversing', 'six'), ('zope-traversing', '<Python from Requires-Python>'), ('zope-traversing', 'zope-security'), ('zope-traversing', 'zope-interface'), ('zope[wsgi]', 'extensionclass'), ('zope[wsgi]', 'zope-testbrowser'), ('zope[wsgi]', 'zope-i18nmessageid'), ('zope[wsgi]', 'zope-container'), ('zope[wsgi]', 'chameleon'), ('zope[wsgi]', 'zope-i18n[zcml]'), ('zope[wsgi]', 'zope-site'), ('zope[wsgi]', 'zope-viewlet'), ('zope[wsgi]', 'zope-security'), ('zope[wsgi]', 'pastedeploy'), ('zope[wsgi]', 'zconfig'), ('zope[wsgi]', 'zope-contenttype'), ('zope[wsgi]', 'zope-schema'), ('zope[wsgi]', 'zope-location'), ('zope[wsgi]', 'zope-pagetemplate'), ('zope[wsgi]', 'datetime'), ('zope[wsgi]', 'transaction'), ('zope[wsgi]', 'restrictedpython'), ('zope[wsgi]', 'zope-component'), ('zope[wsgi]', 'zope-traversing'), ('zope[wsgi]', 'zope-globalrequest'), ('zope[wsgi]', 'zope-deferredimport'), ('zope[wsgi]', 'waitress'), ('zope[wsgi]', 'zope-size'), ('zope[wsgi]', 'zexceptions'), ('zope[wsgi]', 'z3c-pt'), ('zope[wsgi]', 'zope-interface'), ('zope[wsgi]', 'zope-sequencesort'), ('zope[wsgi]', 'zope-configuration'), ('zope[wsgi]', 'acquisition'), ('zope[wsgi]', 'zodb'), ('zope[wsgi]', 'btrees'), ('zope[wsgi]', 'zope-tal'), ('zope[wsgi]', 'setuptools'), ('zope[wsgi]', 'zope-browsermenu'), ('zope[wsgi]', 'zope-datetime'), ('zope[wsgi]', 'zope-exceptions'), ('zope[wsgi]', 'zope-event'), ('zope[wsgi]', 'zope-browser'), ('zope[wsgi]', 'persistence'), ('zope[wsgi]', 'paste'), ('zope[wsgi]', 'zope'), ('zope[wsgi]', 'zope-ptresource'), ('zope[wsgi]', 'zope-publisher'), ('zope[wsgi]', 'zope-proxy'), ('zope[wsgi]', 'zope-browserresource'), ('zope[wsgi]', 'accesscontrol'), ('zope[wsgi]', 'zope-contentprovider'), ('zope[wsgi]', 'multimapping'), ('zope[wsgi]', 'zope-lifecycleevent'), ('zope[wsgi]', 'zope-browserpage'), ('zope[wsgi]', 'documenttemplate'), ('zope[wsgi]', 'zope-testing'), ('zope[wsgi]', 'zope-processlifetime'), ('zope[wsgi]', 'zope-tales'), ('zope-pagetemplate', 'zope-tal'), ('zope-pagetemplate', 'setuptools'), ('zope-pagetemplate', 'zope-i18n'), ('zope-pagetemplate', 'zope-i18nmessageid'), ('zope-pagetemplate', 'zope-component'), ('zope-pagetemplate', 'zope-traversing'), ('zope-pagetemplate', 'six'), ('zope-pagetemplate', 'zope-interface'), ('zope-pagetemplate', 'zope-tales'), ('zope-i18n', 'zope-schema'), ('zope-i18n', 'setuptools'), ('zope-i18n', 'zope-i18nmessageid'), ('zope-i18n', 'zope-component'), ('zope-i18n', 'zope-deprecation'), ('zope-i18n', 'pytz'), ('zope-i18n', 'python-gettext'), ('zope-tal', 'zope-i18nmessageid'), ('zope-tal', 'zope-interface'), ('zope-tal', 'setuptools'), ('plone-app-contentrules', 'plone-autoform'), ('plone-app-contentrules', 'zope-i18nmessageid'), ('plone-app-contentrules', 'zope-container'), ('plone-app-contentrules', 'plone-app-vocabularies'), ('plone-app-contentrules', 'zope-site'), ('plone-app-contentrules', 'products-statusmessages'), ('plone-app-contentrules', 'plone-stringinterp'), ('plone-app-contentrules', 'zope-schema'), ('plone-app-contentrules', 'zope2'), ('plone-app-contentrules', 'zodb3'), ('plone-app-contentrules', 'plone-contentrules'), ('plone-app-contentrules', 'transaction'), ('plone-app-contentrules', 'zope-component'), ('plone-app-contentrules', 'zope-traversing'), ('plone-app-contentrules', 'zope-interface'), ('plone-app-contentrules', 'products-cmfcore'), ('plone-app-contentrules', 'acquisition'), ('plone-app-contentrules', 'products-genericsetup'), ('plone-app-contentrules', 'setuptools'), ('plone-app-contentrules', 'plone-app-z3cform'), ('plone-app-contentrules', 'plone-memoize'), ('plone-app-contentrules', 'zope-event'), ('plone-app-contentrules', 'zope-browser'), ('plone-app-contentrules', 'zope-annotation'), ('plone-app-contentrules', 'zope-publisher'), ('plone-app-contentrules', 'plone-uuid'), ('plone-app-contentrules', 'six'), ('plone-app-contentrules', 'zope-lifecycleevent'), ('plone-schema', 'z3c-form'), ('plone-schema', 'zope-schema'), ('plone-schema', 'setuptools'), ('plone-schema', 'zope-i18nmessageid'), ('plone-schema', 'plone-app-z3cform'), ('plone-schema', 'zope-component'), ('plone-schema', 'zope-interface'), ('plone-schema', 'jsonschema'), ('plone-app-portlets', 'plone-autoform'), ('plone-app-portlets', 'zope-i18nmessageid'), ('plone-app-portlets', 'zope-container'), ('plone-app-portlets', 'plone-app-vocabularies'), ('plone-app-portlets', 'zope-site'), ('plone-app-portlets', 'zope-schema'), ('plone-app-portlets', 'plone-i18n'), ('plone-app-portlets', 'products-cmfdynamicviewfti'), ('plone-app-portlets', 'products-pluggableauthservice'), ('plone-app-portlets', 'datetime'), ('plone-app-portlets', 'transaction'), ('plone-app-portlets', 'plone-portlets'), ('plone-app-portlets', 'zope-component'), ('plone-app-portlets', 'zope-traversing'), ('plone-app-portlets', 'feedparser'), ('plone-app-portlets', 'zope-interface'), ('plone-app-portlets', 'zope-configuration'), ('plone-app-portlets', 'products-cmfcore'), ('plone-app-portlets', 'acquisition'), ('plone-app-portlets', 'zodb'), ('plone-app-portlets', 'products-genericsetup'), ('plone-app-portlets', 'setuptools'), ('plone-app-portlets', 'plone-app-z3cform'), ('plone-app-portlets', 'plone-memoize'), ('plone-app-portlets', 'zope-event'), ('plone-app-portlets', 'zope-browser'), ('plone-app-portlets', 'five-customerize'), ('plone-app-portlets', 'zope-annotation'), ('plone-app-portlets', 'zope-publisher'), ('plone-app-portlets', 'zope-contentprovider'), ('plone-app-portlets', 'zope-lifecycleevent'), ('plone-app-portlets', 'plone-app-i18n'), ('plone-app-portlets', 'zope'), ('plone-contentrules', 'zope-schema'), ('plone-contentrules', 'zodb3'), ('plone-contentrules', 'setuptools'), ('plone-contentrules', 'zope-i18nmessageid'), ('plone-contentrules', 'zope-container'), ('plone-contentrules', 'zope-component'), ('plone-contentrules', 'zope-componentvocabulary'), ('plone-contentrules', 'six'), ('plone-contentrules', 'zope-lifecycleevent'), ('plone-contentrules', 'zope-testing'), ('plone-contentrules', 'zope-interface'), ('plone-contentrules', 'zope-configuration'), ('plone-contentrules', 'zope-annotation'), ('plone-locking', 'acquisition'), ('plone-locking', 'zope-schema'), ('plone-locking', 'zope2'), ('plone-locking', 'zodb3'), ('plone-locking', 'setuptools'), ('plone-locking', 'zope-i18nmessageid'), ('plone-locking', 'datetime'), ('plone-locking', 'zope-component'), ('plone-locking', 'zope-viewlet'), ('plone-locking', 'zope-interface'), ('plone-locking', 'products-cmfcore'), ('plone-locking', 'zope-annotation'), ('plone-portlet-static', 'zope-schema'), ('plone-portlet-static', 'plone-i18n'), ('plone-portlet-static', 'zope2'), ('plone-portlet-static', 'setuptools'), ('plone-portlet-static', 'plone-app-portlets'), ('plone-portlet-static', 'plone-app-textfield'), ('plone-portlet-static', 'zope-i18nmessageid'), ('plone-portlet-static', 'plone-portlets'), ('plone-portlet-static', 'zope-component'), ('plone-portlet-static', 'six'), ('plone-portlet-static', 'zope-interface'), ('z3c-form', 'zope-i18nmessageid'), ('z3c-form', 'zope-site'), ('z3c-form', 'zope-security'), ('z3c-form', 'zope-schema'), ('z3c-form', 'zope-location'), ('z3c-form', 'zope-pagetemplate'), ('z3c-form', 'zope-i18n'), ('z3c-form', 'zope-component'), ('z3c-form', 'zope-traversing'), ('z3c-form', 'zope-interface'), ('z3c-form', 'zope-configuration'), ('z3c-form', 'setuptools'), ('z3c-form', 'zope-event'), ('z3c-form', 'zope-browser'), ('z3c-form', 'zope-publisher'), ('z3c-form', 'zope-browserresource'), ('z3c-form', 'zope-contentprovider'), ('z3c-form', 'six'), ('z3c-form', 'zope-lifecycleevent'), ('z3c-form', 'zope-browserpage'), ('zope', 'extensionclass'), ('zope', 'zope-testbrowser'), ('zope', 'zope-i18nmessageid'), ('zope', 'zope-container'), ('zope', 'chameleon'), ('zope', 'zope-i18n[zcml]'), ('zope', 'zope-site'), ('zope', 'zope-viewlet'), ('zope', 'zope-security'), ('zope', 'pastedeploy'), ('zope', 'zconfig'), ('zope', 'zope-contenttype'), ('zope', 'zope-schema'), ('zope', 'zope-location'), ('zope', 'zope-pagetemplate'), ('zope', 'datetime'), ('zope', 'transaction'), ('zope', 'restrictedpython'), ('zope', 'zope-component'), ('zope', 'zope-traversing'), ('zope', 'zope-globalrequest'), ('zope', 'zope-deferredimport'), ('zope', '<Python from Requires-Python>'), ('zope', 'zope-size'), ('zope', 'waitress'), ('zope', 'zexceptions'), ('zope', 'z3c-pt'), ('zope', 'zope-interface'), ('zope', 'zope-sequencesort'), ('zope', 'zope-configuration'), ('zope', 'acquisition'), ('zope', 'zodb'), ('zope', 'btrees'), ('zope', 'zope-tal'), ('zope', 'setuptools'), ('zope', 'zope-browsermenu'), ('zope', 'zope-datetime'), ('zope', 'zope-exceptions'), ('zope', 'zope-event'), ('zope', 'zope-browser'), ('zope', 'persistence'), ('zope', 'zope-ptresource'), ('zope', 'zope-publisher'), ('zope', 'zope-proxy'), ('zope', 'zope-browserresource'), ('zope', 'accesscontrol'), ('zope', 'zope-contentprovider'), ('zope', 'multimapping'), ('zope', 'zope-lifecycleevent'), ('zope', 'zope-browserpage'), ('zope', 'documenttemplate'), ('zope', 'zope-testing'), ('zope', 'zope-processlifetime'), ('zope', 'zope-tales'), ('zope-security', 'zope-schema'), ('zope-security', 'setuptools'), ('zope-security', 'zope-location'), ('zope-security', 'zope-i18nmessageid'), ('zope-security', 'zope-proxy'), ('zope-security', 'zope-component'), ('zope-security', '<Python from Requires-Python>'), ('zope-security', 'zope-interface'), ('zope-browsermenu', 'zope-schema'), ('zope-browsermenu', 'setuptools'), ('zope-browsermenu', 'zope-publisher'), ('zope-browsermenu', 'zope-pagetemplate'), ('zope-browsermenu', 'zope-i18nmessageid'), ('zope-browsermenu', 'zope-component'), ('zope-browsermenu', 'zope-traversing'), ('zope-browsermenu', 'six'), ('zope-browsermenu', 'zope-browser'), ('zope-browsermenu', 'zope-security'), ('zope-browsermenu', 'zope-interface'), ('zope-browsermenu', 'zope-configuration'), ('zope-componentvocabulary', 'zope-schema'), ('zope-componentvocabulary', 'setuptools'), ('zope-componentvocabulary', 'zope-i18nmessageid'), ('zope-componentvocabulary', 'zope-component'), ('zope-componentvocabulary', 'six'), ('zope-componentvocabulary', 'zope-security'), ('zope-componentvocabulary', 'zope-interface'), ('zope-configuration', 'zope-i18nmessageid'), ('zope-configuration', 'zope-interface'), ('zope-configuration', 'setuptools'), ('zope-configuration', 'zope-schema'), ('zope-i18n[zcml]', 'zope-schema'), ('zope-i18n[zcml]', 'setuptools'), ('zope-i18n[zcml]', 'zope-i18n'), ('zope-i18n[zcml]', 'zope-i18nmessageid'), ('zope-i18n[zcml]', 'zope-component'), ('zope-i18n[zcml]', 'zope-component[zcml]'), ('zope-i18n[zcml]', 'zope-deprecation'), ('zope-i18n[zcml]', 'zope-security'), ('zope-i18n[zcml]', 'zope-configuration'), ('zope-i18n[zcml]', 'pytz'), ('zope-i18n[zcml]', 'python-gettext'), ('zope-size', 'zope-i18nmessageid'), ('zope-size', 'zope-interface'), ('zope-size', 'setuptools'), ('zope-viewlet', 'zope-schema'), ('zope-viewlet', 'setuptools'), ('zope-viewlet', 'zope-location'), ('zope-viewlet', 'zope-publisher'), ('zope-viewlet', 'zope-i18nmessageid'), ('zope-viewlet', 'zope-contentprovider'), ('zope-viewlet', 'zope-component'), ('zope-viewlet', 'zope-traversing'), ('zope-viewlet', 'zope-event'), ('zope-viewlet', 'zope-security'), ('zope-viewlet', 'zope-browserpage'), ('zope-viewlet', 'zope-interface'), ('zope-viewlet', 'zope-configuration'), ('zope-sendmail', 'zope-schema'), ('zope-sendmail', 'setuptools'), ('zope-sendmail', 'zope-i18nmessageid'), ('zope-sendmail', 'transaction'), ('zope-sendmail', 'zope-component'), ('zope-sendmail', '<Python from Requires-Python>'), ('zope-sendmail', 'zope-interface'), ('zope-sendmail', 'zope-configuration'), ('plone-caching', 'zope-schema'), ('plone-caching', 'zope2'), ('plone-caching', 'setuptools'), ('plone-caching', 'plone-registry'), ('plone-caching', 'zope-i18nmessageid'), ('plone-caching', 'zope-component'), ('plone-caching', 'plone-transformchain'), ('plone-caching', 'z3c-caching[zcml]'), ('plone-caching', 'zope-interface'), ('z3c-formwidget-query', 'z3c-form'), ('z3c-formwidget-query', 'zope-schema'), ('z3c-formwidget-query', 'setuptools'), ('z3c-formwidget-query', 'zope-i18nmessageid'), ('z3c-formwidget-query', 'zope-component'), ('z3c-formwidget-query', 'zope-interface'), ('zope-component[zcml]', 'setuptools'), ('zope-component[zcml]', 'zope-i18nmessageid'), ('zope-component[zcml]', 'zope-hookable'), ('zope-component[zcml]', 'zope-component'), ('zope-component[zcml]', 'zope-deprecation'), ('zope-component[zcml]', 'zope-deferredimport'), ('zope-component[zcml]', 'zope-event'), ('zope-component[zcml]', 'zope-interface'), ('zope-component[zcml]', 'zope-configuration'), ('zope-keyreference', 'zope-schema'), ('zope-keyreference', 'zodb'), ('zope-keyreference', 'setuptools'), ('zope-keyreference', 'zope-i18nmessageid'), ('zope-keyreference', 'zope-component'), ('zope-keyreference', 'zope-interface'), ('products-plonepas', 'plone-i18n'), ('products-plonepas', 'products-genericsetup'), ('products-plonepas', 'setuptools'), ('products-plonepas', 'products-pluggableauthservice'), ('products-plonepas', 'plone-registry'), ('products-plonepas', 'datetime'), ('products-plonepas', 'zope-component'), ('products-plonepas', 'zope-deprecation'), ('products-plonepas', 'plone-memoize'), ('products-plonepas', 'six'), ('products-plonepas', 'plone-protect'), ('products-plonepas', 'plone-session'), ('products-plonepas', 'zope'), ('products-plonepas', 'products-cmfcore'), ('plone-app-multilingual', 'plone-i18n'), ('plone-app-multilingual', 'six'), ('plone-app-multilingual', 'setuptools'), ('products-portaltransforms', 'acquisition'), ('products-portaltransforms', 'products-mimetypesregistry'), ('products-portaltransforms', 'zope2'), ('products-portaltransforms', 'zodb3'), ('products-portaltransforms', 'setuptools'), ('products-portaltransforms', 'zope-structuredtext'), ('products-portaltransforms', 'pillow'), ('products-portaltransforms', 'markdown'), ('products-portaltransforms', 'six'), ('products-portaltransforms', 'zope-interface'), ('products-portaltransforms', 'plone-intelligenttext'), ('products-portaltransforms', 'products-cmfcore'), ('plone-outputfilters', 'products-mimetypesregistry'), ('plone-outputfilters', 'products-genericsetup'), ('plone-outputfilters', 'lxml'), ('plone-outputfilters', 'setuptools'), ('plone-outputfilters', 'beautifulsoup4'), ('plone-outputfilters', 'products-portaltransforms'), ('plone-outputfilters', 'six'), ('plone-outputfilters', 'unidecode'), ('plone-outputfilters', 'products-cmfcore'), ('zope-tales', 'zope-interface'), ('zope-tales', 'six'), ('zope-tales', 'setuptools'), ('zope-tales', '<Python from Requires-Python>'), ('zope-contentprovider', 'zope-schema'), ('zope-contentprovider', 'setuptools'), ('zope-contentprovider', 'zope-location'), ('zope-contentprovider', 'zope-publisher'), ('zope-contentprovider', 'zope-component'), ('zope-contentprovider', 'zope-event'), ('zope-contentprovider', 'zope-interface'), ('zope-contentprovider', 'zope-tales'), ('borg-localrole', 'acquisition'), ('borg-localrole', 'products-genericsetup'), ('borg-localrole', 'zope2'), ('borg-localrole', 'setuptools'), ('borg-localrole', 'products-pluggableauthservice'), ('borg-localrole', 'zope-component'), ('borg-localrole', 'products-plonepas'), ('borg-localrole', 'zope-deferredimport'), ('borg-localrole', 'plone-memoize'), ('borg-localrole', 'six'), ('borg-localrole', 'zope-interface'), ('borg-localrole', 'products-cmfcore'), ('borg-localrole', 'zope-annotation'), ('plone-app-users', 'plone-namedfile'), ('plone-app-users', 'plone-autoform'), ('plone-app-users', 'plone-app-layout'), ('plone-app-users', 'products-statusmessages'), ('plone-app-users', 'plone-protect'), ('plone-app-users', 'zope-schema'), ('plone-app-users', 'zope2'), ('plone-app-users', 'plone-formwidget-namedfile'), ('plone-app-users', 'zope-component'), ('plone-app-users', 'z3c-form'), ('plone-app-users', 'zope-interface'), ('plone-app-users', 'products-cmfcore'), ('plone-app-users', 'acquisition'), ('plone-app-users', 'setuptools'), ('plone-app-users', 'zope-event'), ('plone-app-users', 'plone-uuid'), ('plone-app-users', 'accesscontrol'), ('plone-app-users', 'products-plonepas'), ('plone-app-users', 'six'), ('plone-app-users', 'plone-schema'), ('pyscss', 'six'), ('pillow', '<Python from Requires-Python>'), ('plone-theme', 'zope2'), ('plone-theme', 'setuptools'), ('plone-theme', 'zope-publisher'), ('plone-theme', 'zope-component'), ('plone-theme', 'zope-traversing'), ('plone-theme', 'zope-interface'), ('plone-theme', 'products-cmfcore'), ('zope-structuredtext', 'setuptools'), ('documenttemplate', 'acquisition'), ('documenttemplate', 'extensionclass'), ('documenttemplate', 'zope-structuredtext'), ('documenttemplate', 'restrictedpython'), ('documenttemplate', 'accesscontrol'), ('documenttemplate', 'roman'), ('documenttemplate', '<Python from Requires-Python>'), ('documenttemplate', 'zexceptions'), ('documenttemplate', 'zope-sequencesort'), ('zope-deprecation', 'setuptools'), ('plone-app-contenttypes', 'plone-namedfile[blobs]'), ('plone-app-contenttypes', 'setuptools'), ('plone-app-contenttypes', 'plone-app-event'), ('plone-app-contenttypes', 'plone-app-dexterity'), ('plone-app-contenttypes', 'plone-app-vocabularies'), ('plone-app-contenttypes', 'plone-app-contentmenu'), ('plone-app-contenttypes', 'plone-app-z3cform'), ('plone-app-contenttypes', 'plone-app-linkintegrity'), ('plone-app-contenttypes', 'plone-dexterity'), ('plone-app-contenttypes', 'zope-deprecation'), ('plone-app-contenttypes', 'six'), ('plone-app-contenttypes', 'plone-app-relationfield'), ('plone-app-contenttypes', 'plone-app-querystring'), ('plone-app-contenttypes', 'plone-behavior'), ('plone-app-contenttypes', 'plone-app-lockingbehavior'), ('plone-app-contenttypes', 'pytz'), ('plone-app-contenttypes', 'plone-app-versioningbehavior'), ('plone-app-dexterity', 'plone-autoform'), ('plone-app-dexterity', 'plone-app-layout'), ('plone-app-dexterity', 'plone-namedfile[scales]'), ('plone-app-dexterity', 'zope-deprecation'), ('plone-app-dexterity', 'plone-schemaeditor'), ('plone-app-dexterity', 'plone-z3cform'), ('plone-app-dexterity', 'plone-app-uuid'), ('plone-app-dexterity', 'zope-schema'), ('plone-app-dexterity', 'zope2'), ('plone-app-dexterity', 'plone-app-textfield'), ('plone-app-dexterity', 'plone-contentrules'), ('plone-app-dexterity', 'plone-portlets'), ('plone-app-dexterity', 'plone-formwidget-namedfile'), ('plone-app-dexterity', 'plone-dexterity'), ('plone-app-dexterity', 'zope-component'), ('plone-app-dexterity', 'z3c-form'), ('plone-app-dexterity', 'zope-interface'), ('plone-app-dexterity', 'products-cmfcore'), ('plone-app-dexterity', 'products-genericsetup'), ('plone-app-dexterity', 'setuptools'), ('plone-app-dexterity', 'plone-app-z3cform'), ('plone-app-dexterity', 'plone-behavior'), ('plone-app-dexterity', 'lxml'), ('plone-app-dexterity', 'zope-publisher'), ('plone-app-dexterity', 'plone-app-content'), ('plone-app-dexterity', 'plone-rfc822'), ('plone-app-dexterity', 'plone-supermodel'), ('plone-app-dexterity', 'six'), ('plone-app-dexterity', 'plone-schema'), ('plone-app-dexterity', 'zope-browserpage'), ('zope-component', 'setuptools'), ('zope-component', 'zope-hookable'), ('zope-component', 'zope-deprecation'), ('zope-component', 'zope-deferredimport'), ('zope-component', 'zope-event'), ('zope-component', 'zope-interface'), ('zope-site', 'setuptools'), ('zope-site', 'zope-location'), ('zope-site', 'zope-container'), ('zope-site', 'zope-component'), ('zope-site', 'zope-deprecation'), ('zope-site', 'zope-event'), ('zope-site', '<Python from Requires-Python>'), ('zope-site', 'zope-security'), ('zope-site', 'zope-lifecycleevent'), ('zope-site', 'zope-interface'), ('zope-site', 'zope-annotation'), ('plone-rfc822', 'zope-schema'), ('plone-rfc822', 'setuptools'), ('plone-rfc822', 'zope-component'), ('plone-rfc822', 'zope-deprecation'), ('plone-rfc822', 'python-dateutil'), ('plone-rfc822', 'zope-interface'), ('plone-app-dexterity[relations]', 'plone-autoform'), ('plone-app-dexterity[relations]', 'plone-app-layout'), ('plone-app-dexterity[relations]', 'plone-namedfile[scales]'), ('plone-app-dexterity[relations]', 'zope-deprecation'), ('plone-app-dexterity[relations]', 'plone-schemaeditor'), ('plone-app-dexterity[relations]', 'plone-z3cform'), ('plone-app-dexterity[relations]', 'plone-app-uuid'), ('plone-app-dexterity[relations]', 'plone-app-intid'), ('plone-app-dexterity[relations]', 'zope-schema'), ('plone-app-dexterity[relations]', 'zope2'), ('plone-app-dexterity[relations]', 'plone-app-textfield'), ('plone-app-dexterity[relations]', 'plone-contentrules'), ('plone-app-dexterity[relations]', 'plone-portlets'), ('plone-app-dexterity[relations]', 'plone-formwidget-namedfile'), ('plone-app-dexterity[relations]', 'plone-dexterity'), ('plone-app-dexterity[relations]', 'zope-component'), ('plone-app-dexterity[relations]', 'z3c-form'), ('plone-app-dexterity[relations]', 'zope-interface'), ('plone-app-dexterity[relations]', 'products-cmfcore'), ('plone-app-dexterity[relations]', 'products-genericsetup'), ('plone-app-dexterity[relations]', 'setuptools'), ('plone-app-dexterity[relations]', 'plone-app-dexterity'), ('plone-app-dexterity[relations]', 'plone-app-z3cform'), ('plone-app-dexterity[relations]', 'plone-app-relationfield'), ('plone-app-dexterity[relations]', 'z3c-relationfield'), ('plone-app-dexterity[relations]', 'plone-behavior'), ('plone-app-dexterity[relations]', 'lxml'), ('plone-app-dexterity[relations]', 'zope-publisher'), ('plone-app-dexterity[relations]', 'plone-app-content'), ('plone-app-dexterity[relations]', 'plone-rfc822'), ('plone-app-dexterity[relations]', 'plone-supermodel'), ('plone-app-dexterity[relations]', 'six'), ('plone-app-dexterity[relations]', 'plone-schema'), ('plone-app-dexterity[relations]', 'zope-browserpage'), ('plone-app-locales', 'setuptools'), ('plone-app-lockingbehavior', 'plone-app-locales'), ('plone-app-lockingbehavior', 'setuptools'), ('plone-app-lockingbehavior', 'plone-dexterity'), ('plone-app-lockingbehavior', 'plone-behavior'), ('plone-app-lockingbehavior', 'plone-locking'), ('transaction', 'zope-interface'), ('accesscontrol', 'extensionclass'), ('accesscontrol', 'zope-security'), ('accesscontrol', 'zope-schema'), ('accesscontrol', 'datetime'), ('accesscontrol', 'transaction'), ('accesscontrol', 'restrictedpython'), ('accesscontrol', 'zope-component'), ('accesscontrol', 'zope-deferredimport'), ('accesscontrol', '<Python from Requires-Python>'), ('accesscontrol', 'zexceptions'), ('accesscontrol', 'zope-interface'), ('accesscontrol', 'zope-configuration'), ('accesscontrol', 'acquisition'), ('accesscontrol', 'btrees'), ('accesscontrol', 'authencoding'), ('accesscontrol', 'persistence'), ('accesscontrol', 'zope-publisher'), ('accesscontrol', 'six'), ('accesscontrol', 'zope-testing'), ('products-siteerrorlog', 'acquisition'), ('products-siteerrorlog', 'setuptools'), ('products-siteerrorlog', 'transaction'), ('products-siteerrorlog', 'accesscontrol'), ('products-siteerrorlog', 'zope-component'), ('products-siteerrorlog', 'zope-event'), ('products-siteerrorlog', '<Python from Requires-Python>'), ('products-siteerrorlog', 'zexceptions'), ('products-siteerrorlog', 'zope-interface'), ('products-siteerrorlog', 'zope'), ('zodb3', 'zodb'), ('zodb3', 'btrees'), ('zodb3', 'zeo'), ('zodb3', 'transaction'), ('zodb3', 'persistent'), ('zeo', 'zdaemon'), ('zeo', 'zodb'), ('zeo', 'zc-lockfile'), ('zeo', 'transaction'), ('zeo', 'persistent'), ('zeo', 'six'), ('zeo', '<Python from Requires-Python>'), ('zeo', 'zconfig'), ('zeo', 'zope-interface'), ('zodb', 'btrees'), ('zodb', 'zc-lockfile'), ('zodb', 'transaction'), ('zodb', 'persistent'), ('zodb', 'six'), ('zodb', '<Python from Requires-Python>'), ('zodb', 'zconfig'), ('zodb', 'zodbpickle'), ('zodb', 'zope-interface'), ('products-sessions', 'acquisition'), ('products-sessions', 'zodb'), ('products-sessions', 'setuptools'), ('products-sessions', 'transaction'), ('products-sessions', 'persistent'), ('products-sessions', 'accesscontrol'), ('products-sessions', 'six'), ('products-sessions', '<Python from Requires-Python>'), ('products-sessions', 'persistence'), ('products-sessions', 'zope-interface'), ('products-sessions', 'zope'), ('products-standardcachemanagers', 'zope2'), ('products-standardcachemanagers', 'setuptools'), ('products-standardcachemanagers', 'transaction'), ('products-standardcachemanagers', 'accesscontrol'), ('products-standardcachemanagers', 'zope-component'), ('products-standardcachemanagers', 'six'), ('products-standardcachemanagers', '<Python from Requires-Python>'), ('products-zopeversioncontrol', 'acquisition'), ('products-zopeversioncontrol', 'zodb'), ('products-zopeversioncontrol', 'zope2'), ('products-zopeversioncontrol', 'setuptools'), ('products-zopeversioncontrol', 'datetime'), ('products-zopeversioncontrol', 'transaction'), ('products-zopeversioncontrol', 'six'), ('products-zopeversioncontrol', 'zope-interface'), ('acquisition', 'zope-interface'), ('acquisition', 'extensionclass'), ('acquisition', '<Python from Requires-Python>'), ('plone-app-viewletmanager', 'acquisition'), ('plone-app-viewletmanager', 'products-genericsetup'), ('plone-app-viewletmanager', 'zope2'), ('plone-app-viewletmanager', 'zodb3'), ('plone-app-viewletmanager', 'setuptools'), ('plone-app-viewletmanager', 'zope-contentprovider'), ('plone-app-viewletmanager', 'plone-app-vocabularies'), ('plone-app-viewletmanager', 'zope-component'), ('plone-app-viewletmanager', 'zope-site'), ('plone-app-viewletmanager', 'zope-viewlet'), ('plone-app-viewletmanager', 'zope-interface'), ('five-localsitemanager', 'acquisition'), ('five-localsitemanager', 'setuptools'), ('five-localsitemanager', 'zope-location'), ('five-localsitemanager', 'persistent'), ('five-localsitemanager', 'zope-component'), ('five-localsitemanager', 'zope-site'), ('five-localsitemanager', 'six'), ('five-localsitemanager', 'zope-event'), ('five-localsitemanager', 'zope-lifecycleevent'), ('five-localsitemanager', 'zope-testing'), ('five-localsitemanager', 'zope-interface'), ('five-localsitemanager', 'zope'), ('plone-app-customerize', 'acquisition'), ('plone-app-customerize', 'zope2'), ('plone-app-customerize', 'setuptools'), ('plone-app-customerize', 'zope-publisher'), ('plone-app-customerize', 'plone-portlets'), ('plone-app-customerize', 'plone-browserlayer'), ('plone-app-customerize', 'five-customerize'), ('plone-app-customerize', 'zope-component'), ('plone-app-customerize', 'zope-viewlet'), ('plone-app-customerize', 'zope-interface'), ('plone-app-customerize', 'products-cmfcore'), ('products-cmfdynamicviewfti', 'acquisition'), ('products-cmfdynamicviewfti', 'products-genericsetup'), ('products-cmfdynamicviewfti', 'extensionclass'), ('products-cmfdynamicviewfti', 'setuptools'), ('products-cmfdynamicviewfti', 'zope2'), ('products-cmfdynamicviewfti', 'zope-browsermenu'), ('products-cmfdynamicviewfti', 'zope-component'), ('products-cmfdynamicviewfti', 'six'), ('products-cmfdynamicviewfti', 'zope-interface'), ('products-cmfdynamicviewfti', 'products-cmfcore'), ('products-mailhost', 'acquisition'), ('products-mailhost', 'extensionclass'), ('products-mailhost', 'setuptools'), ('products-mailhost', 'datetime'), ('products-mailhost', 'zope-sendmail'), ('products-mailhost', 'accesscontrol'), ('products-mailhost', 'zope-deferredimport'), ('products-mailhost', 'six'), ('products-mailhost', '<Python from Requires-Python>'), ('products-mailhost', 'persistence'), ('products-mailhost', 'documenttemplate'), ('products-mailhost', 'zope-interface'), ('products-mailhost', 'zope'), ('plone-uuid', 'acquisition'), ('plone-uuid', 'setuptools'), ('plone-uuid', 'zope-publisher'), ('plone-uuid', 'zope-component'), ('plone-uuid', 'zope-lifecycleevent'), ('plone-uuid', 'zope-browserpage'), ('plone-uuid', 'zope-interface'), ('products-btreefolder2', 'acquisition'), ('products-btreefolder2', 'extensionclass'), ('products-btreefolder2', 'btrees'), ('products-btreefolder2', 'setuptools'), ('products-btreefolder2', 'zope2'), ('products-btreefolder2', 'zope-container'), ('products-btreefolder2', 'accesscontrol'), ('products-btreefolder2', 'six'), ('products-btreefolder2', 'zope-event'), ('products-btreefolder2', '<Python from Requires-Python>'), ('products-btreefolder2', 'persistence'), ('products-btreefolder2', 'zope-lifecycleevent'), ('products-btreefolder2', 'future'), ('products-externalmethod', 'acquisition'), ('products-externalmethod', 'zodb'), ('products-externalmethod', 'extensionclass'), ('products-externalmethod', 'setuptools'), ('products-externalmethod', 'accesscontrol'), ('products-externalmethod', '<Python from Requires-Python>'), ('products-externalmethod', 'persistence'), ('products-externalmethod', 'zope'), ('products-pythonscripts', 'acquisition'), ('products-pythonscripts', 'setuptools'), ('products-pythonscripts', 'datetime'), ('products-pythonscripts', 'restrictedpython'), ('products-pythonscripts', 'accesscontrol'), ('products-pythonscripts', '<Python from Requires-Python>'), ('products-pythonscripts', 'documenttemplate'), ('products-pythonscripts', 'zexceptions'), ('products-pythonscripts', 'zope'), ('five-intid', 'acquisition'), ('five-intid', 'setuptools'), ('five-intid', 'zope-location'), ('five-intid', 'five-localsitemanager'), ('five-intid', 'zope-keyreference'), ('five-intid', 'zope-component'), ('five-intid', 'zope-intid'), ('five-intid', 'zope-event'), ('five-intid', 'zope-lifecycleevent'), ('five-intid', 'zope-interface'), ('five-intid', 'zope'), ('datetime', 'zope-interface'), ('datetime', 'pytz'), ('zope-publisher', 'multipart'), ('zope-publisher', 'setuptools'), ('zope-publisher', 'zope-location'), ('zope-publisher', 'zope-i18n'), ('zope-publisher', 'zope-proxy'), ('zope-publisher', 'zope-exceptions'), ('zope-publisher', 'zope-component'), ('zope-publisher', 'six'), ('zope-publisher', 'zope-event'), ('zope-publisher', '<Python from Requires-Python>'), ('zope-publisher', 'zope-security'), ('zope-publisher', 'zope-browser'), ('zope-publisher', 'zope-interface'), ('zope-publisher', 'zope-configuration'), ('zope-publisher', 'zope-contenttype'), ('plone-portlets', 'zope-schema'), ('plone-portlets', 'zodb3'), ('plone-portlets', 'setuptools'), ('plone-portlets', 'zope-publisher'), ('plone-portlets', 'zope-container'), ('plone-portlets', 'zope-contentprovider'), ('plone-portlets', 'zope-component'), ('plone-portlets', 'zope-site'), ('plone-portlets', 'plone-memoize'), ('plone-portlets', 'zope-interface'), ('plone-portlets', 'zope-annotation'), ('plone-app-uuid', 'plone-indexer'), ('plone-app-uuid', 'setuptools'), ('plone-app-uuid', 'zope-publisher'), ('plone-app-uuid', 'plone-uuid'), ('plone-app-uuid', 'zope-interface'), ('plone-resourceeditor', 'zope-schema'), ('plone-resourceeditor', 'zope2'), ('plone-resourceeditor', 'setuptools'), ('plone-resourceeditor', 'zope-publisher'), ('plone-resourceeditor', 'zope-component'), ('plone-resourceeditor', 'six'), ('plone-resourceeditor', 'plone-staticresources'), ('plone-resourceeditor', 'zope-interface'), ('plone-schemaeditor', 'z3c-form'), ('plone-schemaeditor', 'zope-schema'), ('plone-schemaeditor', 'zope-cachedescriptors'), ('plone-schemaeditor', 'setuptools'), ('plone-schemaeditor', 'plone-autoform'), ('plone-schemaeditor', 'zope-publisher'), ('plone-schemaeditor', 'zope-container'), ('plone-schemaeditor', 'plone-app-z3cform'), ('plone-schemaeditor', 'zope-component'), ('plone-schemaeditor', 'zope-globalrequest'), ('plone-schemaeditor', 'six'), ('plone-schemaeditor', 'zope-lifecycleevent'), ('plone-schemaeditor', 'plone-z3cform'), ('plone-schemaeditor', 'zope-interface'), ('plone-schemaeditor', 'zope'), ('zexceptions', 'zope-interface'), ('zexceptions', 'setuptools'), ('zexceptions', 'zope-publisher'), ('zexceptions', 'zope-security'), ('zope-browserpage', 'zope-schema'), ('zope-browserpage', 'zope-tal'), ('zope-browserpage', 'setuptools'), ('zope-browserpage', 'zope-publisher'), ('zope-browserpage', 'zope-pagetemplate'), ('zope-browserpage', 'zope-component'), ('zope-browserpage', 'zope-traversing'), ('zope-browserpage', 'zope-security'), ('zope-browserpage', 'zope-interface'), ('zope-browserpage', 'zope-configuration'), ('zope-browserresource', 'zope-schema'), ('zope-browserresource', 'setuptools'), ('zope-browserresource', 'zope-location'), ('zope-browserresource', 'zope-publisher'), ('zope-browserresource', 'zope-i18n'), ('zope-browserresource', 'zope-component'), ('zope-browserresource', 'zope-traversing'), ('zope-browserresource', 'zope-interface'), ('zope-browserresource', 'zope-configuration'), ('zope-browserresource', 'zope-contenttype'), ('plone-resource', 'zope-schema'), ('plone-resource', 'zope2'), ('plone-resource', 'setuptools'), ('plone-resource', 'zope-filerepresentation'), ('plone-resource', 'zope-publisher'), ('plone-resource', 'zope-component'), ('plone-resource', 'zope-traversing'), ('plone-resource', 'plone-caching'), ('plone-resource', 'six'), ('plone-resource', 'python-dateutil'), ('plone-resource', 'z3c-caching'), ('plone-resource', 'zope-interface'), ('plone-resource', 'zope-configuration'), ('zope-globalrequest', 'zope-traversing'), ('zope-globalrequest', 'zope-interface'), ('zope-globalrequest', 'setuptools'), ('zope-globalrequest', 'zope-publisher'), ('zope-ptresource', 'setuptools'), ('zope-ptresource', 'zope-publisher'), ('zope-ptresource', 'zope-pagetemplate'), ('zope-ptresource', 'zope-browserresource'), ('zope-ptresource', 'zope-security'), ('zope-ptresource', 'zope-interface'), ('products-genericsetup', 'setuptools'), ('products-genericsetup', 'five-localsitemanager'), ('products-genericsetup', 'products-zcatalog'), ('products-genericsetup', 'six'), ('products-genericsetup', '<Python from Requires-Python>'), ('products-genericsetup', 'products-pythonscripts'), ('products-genericsetup', 'zope'), ('plone-browserlayer', 'products-genericsetup'), ('plone-browserlayer', 'zope2'), ('plone-browserlayer', 'setuptools'), ('plone-browserlayer', 'zope-component'), ('plone-browserlayer', 'zope-traversing'), ('plone-browserlayer', 'zope-interface'), ('plone-browserlayer', 'products-cmfcore'), ('products-cmfcore', 'products-standardcachemanagers'), ('products-cmfcore', 'products-genericsetup'), ('products-cmfcore', 'products-btreefolder2'), ('products-cmfcore', 'setuptools'), ('products-cmfcore', 'zope-datetime'), ('products-cmfcore', 'docutils'), ('products-cmfcore', 'five-localsitemanager'), ('products-cmfcore', 'products-mailhost'), ('products-cmfcore', 'products-zcatalog'), ('products-cmfcore', 'six'), ('products-cmfcore', '<Python from Requires-Python>'), ('products-cmfcore', 'products-pythonscripts'), ('products-cmfcore', 'zope-interface'), ('products-cmfcore', 'zope'), ('products-pluggableauthservice', 'products-standardcachemanagers'), ('products-pluggableauthservice', 'products-genericsetup'), ('products-pluggableauthservice', 'setuptools'), ('products-pluggableauthservice', 'products-sessions'), ('products-pluggableauthservice', 'products-pluginregistry'), ('products-pluggableauthservice', 'accesscontrol'), ('products-pluggableauthservice', 'six'), ('products-pluggableauthservice', '<Python from Requires-Python>'), ('products-pluggableauthservice', 'zope'), ('products-pluginregistry', 'products-genericsetup'), ('products-pluginregistry', 'setuptools'), ('products-pluginregistry', 'six'), ('products-pluginregistry', '<Python from Requires-Python>'), ('products-pluginregistry', 'zope'), ('plone-staticresources', 'products-genericsetup'), ('plone-staticresources', 'setuptools'), ('plone-staticresources', 'plone-resource'), ('products-dcworkflow', 'products-genericsetup'), ('products-dcworkflow', 'setuptools'), ('products-dcworkflow', 'six'), ('products-dcworkflow', '<Python from Requires-Python>'), ('products-dcworkflow', 'products-pythonscripts'), ('products-dcworkflow', 'zope'), ('products-dcworkflow', 'products-cmfcore'), ('products-dcworkflow', 'products-externalmethod'), ('plone-app-theming', 'docutils'), ('plone-app-theming', 'repoze-xmliter'), ('plone-app-theming', 'lxml'), ('plone-app-theming', 'setuptools'), ('plone-app-theming', 'zope-traversing'), ('plone-app-theming', 'roman'), ('plone-app-theming', 'plone-subrequest'), ('plone-app-theming', 'six'), ('plone-app-theming', 'plone-transformchain'), ('plone-app-theming', 'plone-resourceeditor'), ('plone-app-theming', 'python-dateutil'), ('plone-app-theming', 'plone-app-registry'), ('plone-app-theming', 'plone-staticresources'), ('plone-app-theming', 'diazo'), ('plone-portlet-collection', 'setuptools'), ('plone-portlet-collection', 'plone-app-portlets'), ('plone-portlet-collection', 'plone-portlets'), ('plone-portlet-collection', 'plone-app-vocabularies'), ('plone-portlet-collection', 'plone-memoize'), ('plone-app-relationfield', 'z3c-form'), ('plone-app-relationfield', 'zope-schema'), ('plone-app-relationfield', 'plone-app-intid'), ('plone-app-relationfield', 'setuptools'), ('plone-app-relationfield', 'plone-autoform'), ('plone-app-relationfield', 'plone-rfc822'), ('plone-app-relationfield', 'z3c-formwidget-query'), ('plone-app-relationfield', 'plone-app-vocabularies'), ('plone-app-relationfield', 'plone-app-z3cform'), ('plone-app-relationfield', 'zope-component'), ('plone-app-relationfield', 'zope-intid'), ('plone-app-relationfield', 'plone-supermodel'), ('plone-app-relationfield', 'plone-schemaeditor'), ('plone-app-relationfield', 'z3c-relationfield'), ('plone-app-relationfield', 'zope-interface'), ('plone-app-relationfield', 'five-intid'), ('plone-app-relationfield', 'products-cmfcore'), ('plone-api', 'setuptools'), ('plone-api', 'plone-uuid'), ('plone-api', 'plone-app-linkintegrity'), ('plone-api', 'products-statusmessages'), ('plone-api', 'zope-globalrequest'), ('plone-api', 'plone-app-uuid'), ('plone-api', 'decorator'), ('plone-app-discussion', 'plone-indexer'), ('plone-app-discussion', 'z3c-form'), ('plone-app-discussion', 'zodb3'), ('plone-app-discussion', 'setuptools'), ('plone-app-discussion', 'plone-registry'), ('plone-app-discussion', 'zope-container'), ('plone-app-discussion', 'plone-app-layout'), ('plone-app-discussion', 'plone-app-z3cform'), ('plone-app-discussion', 'zope-component'), ('plone-app-discussion', 'zope-site'), ('plone-app-discussion', 'six'), ('plone-app-discussion', 'zope-event'), ('plone-app-discussion', 'zope-lifecycleevent'), ('plone-app-discussion', 'plone-z3cform'), ('plone-app-discussion', 'plone-app-registry'), ('plone-app-discussion', 'plone-app-uuid'), ('plone-app-discussion', 'zope-interface'), ('plone-app-discussion', 'zope-annotation'), ('plone-app-redirector', 'plone-memoize'), ('plone-app-redirector', 'six'), ('plone-app-redirector', 'setuptools'), ('products-mimetypesregistry', 'zope2'), ('products-mimetypesregistry', 'setuptools'), ('products-mimetypesregistry', 'zope-contenttype'), ('products-mimetypesregistry', 'accesscontrol'), ('products-mimetypesregistry', 'zope-deferredimport'), ('products-mimetypesregistry', 'six'), ('products-mimetypesregistry', 'zope-interface'), ('products-mimetypesregistry', 'products-cmfcore'), ('plone-app-versioningbehavior', 'plone-namedfile[blobs]'), ('plone-app-versioningbehavior', 'plone-autoform'), ('plone-app-versioningbehavior', 'setuptools'), ('plone-app-versioningbehavior', 'plone-rfc822'), ('plone-app-versioningbehavior', 'zope-container'), ('plone-app-versioningbehavior', 'plone-dexterity'), ('plone-app-versioningbehavior', 'plone-behavior'), ('plone-app-versioningbehavior', 'plone-app-dexterity[relations]'), ('plone-app-versioningbehavior', 'products-cmfeditions'), ('zope-deferredimport', 'zope-proxy'), ('zope-deferredimport', 'setuptools'), ('plone-protect', 'repoze-xmliter'), ('plone-protect', 'zope2'), ('plone-protect', 'setuptools'), ('plone-protect', 'collective-monkeypatcher'), ('plone-protect', 'zope-component'), ('plone-protect', 'plone-transformchain'), ('plone-protect', 'six'), ('plone-protect', 'zope-interface'), ('plone-protect', 'lxml[cssselect]'), ('plone-protect', 'plone-keyring'), ('plone-indexer', 'setuptools'), ('plone-indexer', 'products-zcatalog'), ('plone-indexer', 'zope-component'), ('plone-indexer', 'zope-interface'), ('plone-indexer', 'products-cmfcore'), ('plone-memoize', 'setuptools'), ('plone-memoize', 'zope-component'), ('plone-memoize', 'six'), ('plone-memoize', 'zope-ramcache'), ('plone-memoize', 'zope-interface'), ('plone-memoize', 'zope-annotation'), ('plone-session', 'zope2'), ('plone-session', 'setuptools'), ('plone-session', 'products-pluggableauthservice'), ('plone-session', 'zope-component'), ('plone-session', 'six'), ('plone-session', 'plone-protect'), ('plone-session', 'zope-interface'), ('plone-session', 'plone-keyring'), ('plone-behavior', 'zope-schema'), ('plone-behavior', 'setuptools'), ('plone-behavior', 'zope-component'), ('plone-behavior', 'zope-interface'), ('plone-behavior', 'zope-configuration'), ('plone-behavior', 'zope-annotation'), ('plone-namedfile[blobs]', 'plone-namedfile'), ('plone-namedfile[blobs]', 'setuptools'), ('plone-namedfile[blobs]', 'piexif'), ('plone-namedfile[blobs]', 'plone-rfc822'), ('plone-namedfile[blobs]', 'zope-copy'), ('plone-namedfile[blobs]', 'plone-scale[storage]'), ('plone-namedfile[blobs]', 'zope-component'), ('plone-namedfile[blobs]', 'zope-traversing'), ('plone-namedfile[blobs]', 'plone-supermodel'), ('plone-namedfile[blobs]', 'six'), ('plone-namedfile[blobs]', 'plone-schemaeditor'), ('plone-namedfile[blobs]', 'zope-security'), ('plone-namedfile[blobs]', 'zope-browserpage'), ('plone-namedfile[scales]', 'plone-namedfile'), ('plone-namedfile[scales]', 'setuptools'), ('plone-namedfile[scales]', 'piexif'), ('plone-namedfile[scales]', 'plone-rfc822'), ('plone-namedfile[scales]', 'zope-copy'), ('plone-namedfile[scales]', 'plone-scale[storage]'), ('plone-namedfile[scales]', 'zope-component'), ('plone-namedfile[scales]', 'zope-traversing'), ('plone-namedfile[scales]', 'plone-supermodel'), ('plone-namedfile[scales]', 'six'), ('plone-namedfile[scales]', 'plone-schemaeditor'), ('plone-namedfile[scales]', 'zope-security'), ('plone-namedfile[scales]', 'zope-browserpage'), ('plone-z3cform', 'setuptools'), ('plone-z3cform', 'zope-i18n'), ('plone-z3cform', 'zope-component'), ('plone-z3cform', 'plone-batching'), ('plone-z3cform', 'six'), ('plone-z3cform', 'zope-browserpage'), ('plone-z3cform', 'z3c-form'), ('plone-z3cform', 'zope'), ('plone-app-textfield', 'zope-schema'), ('plone-app-textfield', 'setuptools'), ('plone-app-textfield', 'zodb3'), ('plone-app-textfield', 'zope-component'), ('plone-app-textfield', 'six'), ('plone-app-textfield', 'zope-interface'), ('plone-namedfile', 'setuptools'), ('plone-namedfile', 'piexif'), ('plone-namedfile', 'plone-rfc822'), ('plone-namedfile', 'zope-copy'), ('plone-namedfile', 'plone-scale[storage]'), ('plone-namedfile', 'zope-component'), ('plone-namedfile', 'zope-traversing'), ('plone-namedfile', 'plone-supermodel'), ('plone-namedfile', 'six'), ('plone-namedfile', 'plone-schemaeditor'), ('plone-namedfile', 'zope-security'), ('plone-namedfile', 'zope-browserpage'), ('plone-transformchain', 'zope-schema'), ('plone-transformchain', 'zope2'), ('plone-transformchain', 'setuptools'), ('plone-transformchain', 'zope-component'), ('plone-transformchain', 'six'), ('plone-transformchain', 'zope-interface'), ('z3c-pt', 'setuptools'), ('z3c-pt', 'zope-i18n'), ('z3c-pt', 'zope-contentprovider'), ('z3c-pt', 'chameleon'), ('z3c-pt', 'zope-component'), ('z3c-pt', 'zope-traversing'), ('z3c-pt', 'six'), ('z3c-pt', '<Python from Requires-Python>'), ('z3c-pt', 'zope-interface'), ('zope-annotation', 'setuptools'), ('zope-annotation', 'zope-location'), ('zope-annotation', 'zope-proxy'), ('zope-annotation', 'zope-component'), ('zope-annotation', 'zope-interface'), ('plone-event', 'setuptools'), ('plone-event', 'zope-component'), ('plone-event', 'python-dateutil'), ('plone-event', 'zope-interface'), ('plone-event', 'pytz'), ('plone-scale[storage]', 'setuptools'), ('plone-scale[storage]', 'zope-component'), ('plone-scale[storage]', 'six'), ('plone-scale[storage]', 'plone-scale'), ('plone-scale[storage]', 'persistence'), ('plone-scale[storage]', 'zope-interface'), ('plone-scale[storage]', 'zope-configuration'), ('plone-scale[storage]', 'zope-annotation'), ('plone-alterego', 'zope-interface'), ('plone-alterego', 'setuptools'), ('plone-alterego', 'zope-component'), ('z3c-caching', 'setuptools'), ('z3c-caching', 'zope-component'), ('z3c-caching', 'zope-event'), ('z3c-caching', 'zope-lifecycleevent'), ('z3c-caching', 'zope-browser'), ('z3c-caching', 'zope-interface'), ('z3c-zcmlhook', 'zope-schema'), ('z3c-zcmlhook', 'setuptools'), ('z3c-zcmlhook', 'zope-component'), ('z3c-zcmlhook', 'zope-interface'), ('z3c-zcmlhook', 'zope-configuration'), ('zope-intid', 'btrees'), ('zope-intid', 'setuptools'), ('zope-intid', 'zope-location'), ('zope-intid', 'persistent'), ('zope-intid', 'zope-keyreference'), ('zope-intid', 'zope-component'), ('zope-intid', 'zope-event'), ('zope-intid', 'zope-lifecycleevent'), ('zope-intid', 'zope-security'), ('zope-intid', 'zope-interface'), ('z3c-caching[zcml]', 'setuptools'), ('z3c-caching[zcml]', 'zope-component'), ('z3c-caching[zcml]', 'zope-event'), ('z3c-caching[zcml]', 'zope-lifecycleevent'), ('z3c-caching[zcml]', 'zope-browser'), ('z3c-caching[zcml]', 'z3c-caching'), ('z3c-caching[zcml]', 'zope-interface'), ('z3c-caching[zcml]', 'zope-configuration'), ('plone-keyring', 'zodb3'), ('plone-keyring', 'setuptools'), ('plone-keyring', 'zope-location'), ('plone-keyring', 'zope-container'), ('plone-keyring', 'zope-interface'), ('zc-relation', 'zodb3'), ('zc-relation', 'setuptools'), ('zc-relation', 'six'), ('zc-relation', 'zope-testing'), ('zc-relation', 'zope-interface'), ('zope-interface', 'setuptools'), ('zope-interface', '<Python from Requires-Python>'), ('zope-location', 'zope-schema'), ('zope-location', 'zope-interface'), ('zope-location', 'setuptools'), ('zope-location', 'zope-proxy'), ('products-statusmessages', 'setuptools'), ('products-statusmessages', 'zope-i18n'), ('products-statusmessages', 'six'), ('products-statusmessages', 'zope-interface'), ('products-statusmessages', 'zope-annotation'), ('btrees', 'persistent'), ('btrees', 'zope-interface'), ('persistent', 'zope-interface'), ('persistent', 'cffi'), ('zope-filerepresentation', 'zope-schema'), ('zope-filerepresentation', 'zope-interface'), ('zope-filerepresentation', 'setuptools'), ('zope-filerepresentation', '<Python from Requires-Python>'), ('zope-lifecycleevent', 'zope-interface'), ('zope-lifecycleevent', 'zope-event'), ('zope-lifecycleevent', 'setuptools'), ('zope-proxy', 'zope-interface'), ('zope-proxy', 'setuptools'), ('zope-schema', 'zope-interface'), ('zope-schema', 'zope-event'), ('zope-schema', '<Python from Requires-Python>'), ('zope-schema', 'setuptools'), ('zope-browser', 'zope-interface'), ('zope-browser', 'setuptools'), ('zope-copy', 'zope-interface'), ('zope-copy', 'setuptools'), ('zope-exceptions', 'zope-interface'), ('zope-exceptions', 'setuptools'), ('zope-processlifetime', 'zope-interface'), ('zope-processlifetime', 'setuptools'), ('zope-ramcache', 'persistent'), ('zope-ramcache', 'zope-interface'), ('zope-ramcache', 'setuptools'), ('zope-ramcache', 'zope-location'), ('zope-testbrowser', 'zope-schema'), ('zope-testbrowser', 'zope-cachedescriptors'), ('zope-testbrowser', 'setuptools'), ('zope-testbrowser', 'wsgiproxy2'), ('zope-testbrowser', 'beautifulsoup4'), ('zope-testbrowser', 'six'), ('zope-testbrowser', 'soupsieve'), ('zope-testbrowser', 'zope-interface'), ('zope-testbrowser', 'webtest'), ('zope-testbrowser', 'pytz'), ('products-daterecurringindex', 'zodb'), ('products-daterecurringindex', 'btrees'), ('products-daterecurringindex', 'zope-schema'), ('products-daterecurringindex', 'setuptools'), ('products-daterecurringindex', 'products-zcatalog'), ('products-daterecurringindex', 'plone-event'), ('products-daterecurringindex', 'zope-interface'), ('z3c-objpath', 'zope-interface'), ('z3c-objpath', 'setuptools'), ('plone-app-linkintegrity', 'plone-app-intid'), ('plone-app-linkintegrity', 'plone-app-relationfield'), ('plone-app-linkintegrity', 'six'), ('plone-app-linkintegrity', 'setuptools'), ('products-extendedpathindex', 'six'), ('products-extendedpathindex', 'setuptools'), ('products-extendedpathindex', 'zope'), ('products-extendedpathindex', 'products-zcatalog'), ('zope-cachedescriptors', 'setuptools'), ('plone-stringinterp', 'zope-i18n'), ('plone-stringinterp', 'plone-memoize'), ('plone-stringinterp', 'setuptools'), ('plone-stringinterp', 'products-cmfcore'), ('plone-app-i18n', 'setuptools'), ('plonetheme-barceloneta', 'plone-batching'), ('plonetheme-barceloneta', 'setuptools'), ('plonetheme-barceloneta', 'plone-app-theming'), ('products-isurlinportal', 'setuptools'), ('plone-app-contentlisting', 'setuptools'), ('plone-batching', 'zope2'), ('plone-batching', 'setuptools'), ('plone-intelligenttext', 'setuptools'), ('zope-event', 'setuptools'), ('products-cmfuid', 'products-zcatalog'), ('products-cmfuid', 'setuptools'), ('products-cmfuid', 'zope'), ('products-cmfuid', 'products-cmfcore'), ('calmjs-parse', 'ply'), ('calmjs-parse', 'setuptools'), ('plone-subrequest', 'zope-globalrequest'), ('plone-subrequest', 'six'), ('plone-subrequest', 'setuptools'), ('persistence', 'persistent'), ('persistence', 'extensionclass'), ('persistence', 'six'), ('multimapping', 'extensionclass'), ('missing', 'extensionclass'), ('record', 'extensionclass'), ('setuptools', '<Python from Requires-Python>'), ('plone-formwidget-namedfile', 'plone-namedfile'), ('plone-formwidget-namedfile', 'z3c-form'), ('plone-formwidget-namedfile', 'setuptools'), ('plone-formwidget-namedfile', 'plone-z3cform'), ('repoze-xmliter', 'lxml'), ('repoze-xmliter', 'setuptools'), ('repoze-xmliter', 'future'), ('zope-contenttype', 'setuptools'), ('zope-hookable', 'setuptools'), ('zope-hookable', '<Python from Requires-Python>'), ('collective-monkeypatcher', 'six'), ('collective-monkeypatcher', 'setuptools'), ('jsonschema', 'six'), ('jsonschema', 'setuptools'), ('jsonschema', 'attrs'), ('jsonschema', 'pyrsistent'), ('paste', 'six'), ('paste', 'setuptools'), ('pastedeploy', 'setuptools'), ('plone-app-intid', 'setuptools'), ('plone-app-intid', 'zope-intid'), ('plone-app-intid', 'zope-lifecycleevent'), ('plone-app-intid', 'five-intid'), ('plone-app-intid', 'products-cmfcore'), ('zope-datetime', 'six'), ('zope-datetime', 'setuptools'), ('zope-sequencesort', 'setuptools'), ('zope-testing', 'setuptools'), ('z3c-relationfield', 'zope-intid'), ('z3c-relationfield', 'z3c-objpath'), ('z3c-relationfield', 'setuptools'), ('z3c-relationfield', 'zc-relation'), ('zodbpickle', 'setuptools'), ('plone-synchronize', 'setuptools'), ('zc-lockfile', 'setuptools'), ('zdaemon', 'zconfig'), ('zdaemon', 'setuptools'), ('plone-scale', 'six'), ('plone-scale', 'setuptools'), ('restrictedpython', '<Python from Requires-Python>'), ('authencoding', 'six'), ('authencoding', '<Python from Requires-Python>'), ('six', '<Python from Requires-Python>'), ('diazo', 'cssselect'), ('diazo', 'six'), ('diazo', 'future'), ('diazo', 'lxml'), ('python-dateutil', 'six'), ('python-dateutil', '<Python from Requires-Python>'), ('webtest', 'beautifulsoup4'), ('webtest', 'six'), ('webtest', 'webob'), ('webtest', 'waitress'), ('wsgiproxy2', 'six'), ('wsgiproxy2', 'webob'), ('chameleon', '<Python from Requires-Python>'), ('docutils', '<Python from Requires-Python>'), ('lxml', '<Python from Requires-Python>'), ('markdown', '<Python from Requires-Python>'), ('unidecode', '<Python from Requires-Python>'), ('decorator', '<Python from Requires-Python>'), ('feedparser', '<Python from Requires-Python>'), ('feedparser', 'sgmllib3k'), ('roman', '<Python from Requires-Python>'), ('simplejson', '<Python from Requires-Python>'), ('waitress', '<Python from Requires-Python>'), ('attrs', '<Python from Requires-Python>'), ('cssselect', '<Python from Requires-Python>'), ('pyrsistent', '<Python from Requires-Python>'), ('soupsieve', '<Python from Requires-Python>'), ('future', '<Python from Requires-Python>'), ('icalendar', 'python-dateutil'), ('icalendar', '<Python from Requires-Python>'), ('icalendar', 'pytz'), ('piexif', '<Python from Requires-Python>'), ('webob', '<Python from Requires-Python>'), ('pycparser', '<Python from Requires-Python>'), ('zope2', 'zope'), ('lxml[cssselect]', 'lxml'), ('lxml[cssselect]', 'cssselect'), ('beautifulsoup4', 'soupsieve'), ('cffi', 'pycparser')]
Rizhiy commented 3 years ago

I think I have made a reproducible example: https://github.com/Rizhiy/pip-conflicts

While making it, I realised that the problem is, most likely, that pip conflict resolution is just very slow/stupid and not that it is incorrect.

notatallshaw commented 3 years ago

While making it I realised that the problem is that pip conflict resolution it just very slow/stupid and not incorrect.

As someone who had that gut feeling many months ago and have been trying to come up with better approaches ever since I can tell you it's not an easy problem to solve.

Finding a solution on a dependency graph is basically a brute force problem if you don't make any assumptions about said dependency graph. Hopefully though https://github.com/pypa/pip/pull/10481 will fix the time it takes your requirements to resolve. Otherwise I have some more ideas on how to improve resolution time further.

pradyunsg commented 3 years ago

It's not the dependency resolution that is slow here -- I've demonstrated that above. As @uranusjr noted, the problem in this case is the logic that's computing the "order to install packages" (get_installation_order -> get_topological_weights). That logic is being ridiculously slow, likely due to the very edge-heavy/dense dependency graph that this situation has; and possibly due to a state management bug in that logic.

notatallshaw commented 3 years ago

It's not the dependency resolution that is slow here -- I've demonstrated that above. As @uranusjr noted, the problem in this case is the logic that's computing the "order to install packages" (get_installation_order -> get_topological_weights). That logic is being ridiculously slow, likely due to the very edge-heavy/dense dependency graph that this situation has; and possibly due to a state management bug in that logic.

I see, I thought OP had changed their mind on what the issue was, thanks for the correction.

Rizhiy commented 3 years ago

@pradyunsg Did you look at the example I provided? The behaviour seems different from the @mauritsvanrees case.

Even if resolver is not at fault here, there seems to be erroneous logging since I'm getting messages like:

INFO: This is taking longer than usual. You might need to provide the dependency resolver with stricter constraints to reduce runtime. If you want to abort this run, you can press Ctrl + C to do so. To improve how pip performs, tell us what happened here: https://pip.pypa.io/surveys/backtracking
INFO: pip is looking at multiple versions of srsly to determine which version is compatible with other requirements. This could take a while.
INFO: pip is looking at multiple versions of idna to determine which version is compatible with other requirements. This could take a while.

P.S. I checked behaviour using #10481 and the problem is still there.

pradyunsg commented 3 years ago

No, I haven't played with your example repository yet. There's two separate things in this issue, as far as I'm concerned:

Based on a quick look, it looks like your example repository demonstrates the first issue, where the resolver is going to try too hard to get a solution; especially if one doesn't exist. That's already got a bunch of other issues to track it -- #9517 is one that is handy right now.

$ python -m pip install Products.CMFPlone -c https://dist.plone.org/release/pip-resolver-test/constraints.txt --log /tmp/log.txt

For this example, #10481 solves the stupid backtracking issue; although the computation of what order to install packages in still takes a long time; likely due to the dense nature of the dependency graph.

P.S. I checked behaviour using #1048 and the problem is still there.

I'm guessing this is a typo?

Rizhiy commented 3 years ago

Yes, I meant #10481, fixed original.

mauritsvanrees commented 3 years ago

I added a bit of debugging code in the pip main branch to see how often nodes are visited in the "get installation order" logic, especially setuptools which is a dependency of most packages:

$ git diff
diff --git a/src/pip/_internal/resolution/resolvelib/resolver.py b/src/pip/_internal/resolution/resolvelib/resolver.py
index 12f967020..90fe1aa7d 100644
--- a/src/pip/_internal/resolution/resolvelib/resolver.py
+++ b/src/pip/_internal/resolution/resolvelib/resolver.py
@@ -212,6 +212,7 @@ def get_topological_weights(
     """
     path: Set[Optional[str]] = set()
     weights: Dict[Optional[str], int] = {}
+    visited: Dict[Optional[str], int] = {}

     def visit(node: Optional[str]) -> None:
         if node in path:
@@ -219,6 +220,11 @@ def get_topological_weights(
             return

         # Time to visit the children!
+        if node in visited:
+            visited[node] += 1
+        else:
+            visited[node] = 1
+        visited["dummy"] += 1
         path.add(node)
         for child in graph.iter_children(node):
             visit(child)
@@ -228,7 +234,13 @@ def get_topological_weights(
         weights[node] = max(last_known_parent_count, len(path))

     # `None` is guaranteed to be the root node by resolvelib.
+    # breakpoint()
+    print(f"Expected node count: {expected_node_count}")
+    visited["dummy"] = 0
     visit(None)
+    print(f"Weight setuptools: {weights['setuptools']}.")
+    print(f"Visited setuptools {visited['setuptools']} times.")
+    print(f"Visited any node: {visited['dummy']} times.")

     # Sanity checks
     assert weights[None] == 0

I tried this with Zope, which is a sub part of Plone, so it is installed already if you followed my example from above:

$ bin/python -m pip install Zope -c https://dist.plone.org/release/pip-resolver-test/constraints.txt
...
Expected node count: 80
Weight setuptools: 12.
Visited setuptools 4486 times.
Visited any node: 9545 times.

So for 80 packages, the setuptools node is visited about 4500 times, and the visit function is called almost 10,000 times. This goes fast, the part that calculated the weights takes about a second.

Then try Products.CMFPlone, with lots more packages:

$ bin/python -m pip install Products.CMFPlone -c https://dist.plone.org/release/pip-resolver-test/constraints.txt
...
Expected node count: 238
Weight setuptools: 30.
Visited setuptools 150681071 times.
Visited any node: 321043495 times.

So the setuptools node is visited 150 million times, and the visit function is called over 300 million times. It takes a few minutes.

As suspected, it does not scale very well. :-)

Maybe iterating over graph.iter_edges helps, but I don't yet see how.

pradyunsg commented 3 years ago

Yup yup. This was written for correctness, rather than speed, so that looks about right to me.

It's basically exploring all paths on the graph, and remembering the length of the longest one.

It makes sense to me that this would be horrendous for a dense graph like that. :)

mauritsvanrees commented 3 years ago

This much simpler version of get_topological_weights works for me, but I suppose it is too simplistic:

weights: Dict[Optional[str], int] = {}
for key in graph:
    weights[key] = len(graph._backwards[key]) - len(graph._forwards[key])
assert len(weights) == expected_node_count
return weights

In my case, setuptools gets a lot of points, just like zope.interface which is a very central package in the Zope/Plone universe. Products.CMFPlone has a large negative value, because it depends on lots of packages, without other packages depending on it.

Hypothetically, if ten packages depend on zope.interface, and zope.interface is the only one that depends on setuptools, then this simple method gives zope.interface 10-1=9 points, so it gets installed before setuptools which has only one point. And I can imagine this was actually the initial implementation, and then smarter people than me made it more correct.

So:

Rizhiy commented 3 years ago

I guess I'm missing something here. Why does installation order matter at all? Unless a package has install_requires specified, can't you just install them in any order?

uranusjr commented 3 years ago

A lot of packages out there depend on installation ordering to work correctly, e.g. some namespace packages overwrite files already installed by another package, and produce incorrect end results if we swap the order.

Rizhiy commented 3 years ago

Somehow I have a feeling that while it might be a lot in absolute terms, it is a very small as a percentage of all packages. I think this problem should be solved by forcing such packages to specify install_requires or something similar and then running graph resolution only on that sub-graph.

Rizhiy commented 3 years ago

In the meantime, another question: why is setuptools in @mauritsvanrees example visited so many times? Can't you check each package once, construct a dependency DAG and then optimise weights on that?

uranusjr commented 3 years ago

First of all, the dependency graph is not guaranteed to be acyclic 🙂 The resolver indeed constructed a graph, so feel free to contribute an implementation that reduces node visits if you have algorithmics insights on this .

pradyunsg commented 3 years ago

The discussion in https://github.com/pypa/pip/pull/8127 is relevant, in case someone wants to tackle this. There's existing tests for this method's logic here:

https://github.com/pypa/pip/blob/b392833a0f1cff1bbee1ac6dbe0270cccdd0c11f/tests/unit/resolution_resolvelib/test_resolver.py#L241

If this were guarenteed to be an DAG, then we wouldn't be having this conversation. :)


I suppose it is too simplistic

Yea, we're not measuring in-degree vs out-degree here. This implementation will fail all the tests for what get_topological_weights is supposed to do. :)

From https://github.com/pypa/pip/pull/8127:

We want the length for the longest path to any node from root, ignoring any paths containing cycles.

mauritsvanrees commented 3 years ago

Okay, I have a solution that works for me, and passes the test_resolver tests, except for one but I think the slightly different outcome is actually okay. I'll do a PR (my first on pip).

mauritsvanrees commented 3 years ago

Done: https://github.com/pypa/pip/pull/10574 But I guess this may need to be done in resolvelib first.