Incompatible versions in resolved dependencies pip-compile 5.2.1

Environment Versions

OS Type: Debian Stretch (In Docker)
Python version: $ python -V: 2.7.18
pip version:  $ pip --version: 20.1.1
pip-tools version: $ pip-compile --version: 5.2.1

Steps to replicate

pip-compile test.in --verbose on project requirements file: here

Expected result
Ideally, this would work? But I think the incompatibilities are being discovered down-stream. I cannot see where importlib-resources==3.0.0,>=1.0,~=1.4 is generated as in the requirements generated so far I think they're all looking for 3.0.0.
...
Actual result
Could not find a version that matches importlib-resources==3.0.0,>=1.0,~=1.4 (from -r base.txt (line 36))
Tried: 0.2, 0.2, 0.3, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.8, 1.0, 1.0.1, 1.0.1, 1.0.2, 1.0.2, 1.1.0, 1.1.0, 1.2.0, 1.2.0, 1.3.0, 1.3.0, 1.3.1, 1.3.1, 1.4.0, 1.4.0, 1.5.0, 1.5.0, 2.0.0, 2.0.0, 2.0.1, 2.0.1, 3.0.0, 3.0.0
There are incompatible versions in the resolved dependencies:
  importlib-resources==3.0.0 (from -r base.txt (line 36))
  importlib_resources~=1.4 (from cfn-lint==0.33.2->moto==1.3.8->-r test.in (line 13))
  importlib-resources (from netaddr==0.8.0->-r base.txt (line 50))
  importlib-resources>=1.0 (from virtualenv==20.0.25->tox==3.16.1->-r test.in (line 9))

As far as I can work out from the dependency graph below, I think python-keystoneclient needs oslo needs netaddr needs a specific version of importlib_resources. Updating to the last compatible python-keystone 3.22.0 for py2 results in the same issue.
Is that a correct reading? Would you anticipate this type of thing to be resolvable by pip-compile normally?
Any advice appreciated :slightly_smiling_face:
Verbose output
root@a8b8a87ac8fb:/src/requirements# pip-compile test.in --verbose
Using indexes:
  https://pypi.org/simple

                          ROUND 1
Current constraints:
  agentarchives==0.6.0 (from -r base.txt (line 7))
  babel==2.8.0 (from -r base.txt (line 8))
  bagit==1.7.0 (from -r base.txt (line 9))
  boto3==1.9.174 (from -r base.txt (line 10))
  botocore==1.12.253 (from -r base.txt (line 11))
  brotli==0.5.2 (from -r base.txt (line 12))
  certifi==2020.6.20 (from -r base.txt (line 13))
  cffi==1.14.0 (from -r base.txt (line 14))
  chardet==3.0.4 (from -r base.txt (line 15))
  contextlib2==0.6.0.post1 (from -r base.txt (line 16))
  coverage==4.2 (from -r test.in (line 6))
  cryptography==2.9.2 (from -r base.txt (line 17))
  debtcollector==1.22.0 (from -r base.txt (line 18))
  defusedxml==0.5.0 (from -r base.txt (line 19))
  django==1.11.29 (from -r base.txt (line 25))
  django-auth-ldap==1.3.0 (from -r base.txt (line 20))
  django-extensions==1.7.9 (from -r base.txt (line 21))
  django-prometheus==1.0.15 (from -r base.txt (line 22))
  django-shibboleth-remoteuser from git+https://github.com/Brown-University-Library/django-shibboleth-remoteuser.git@67d270c65c201606fb86d548493d4b3fd8cc7a76#egg=django-shibboleth-remoteuser (from -r base.txt (line 23))
  django-tastypie==0.14.3 (from -r base.txt (line 24))
  docutils==0.15.2 (from -r base.txt (line 26))
  enum34==1.1.10 (from -r base.txt (line 27))
  funcsigs==1.0.2 (from -r base.txt (line 28))
  functools32 (from -r test.in (line 14))
  future==0.18.2 (from -r base.txt (line 29))
  futures==3.3.0 (from -r base.txt (line 30))
  gevent==1.3.6 (from -r base.txt (line 31))
  greenlet==0.4.16 (from -r base.txt (line 32))
  gunicorn==19.9.0 (from -r base.txt (line 33))
  httplib2==0.18.1 (from -r base.txt (line 34))
  idna==2.8 (from -r base.txt (line 35))
  importlib-resources==3.0.0 (from -r base.txt (line 36))
  ipaddress==1.0.23 (from -r base.txt (line 37))
  ipdb (from -r test.in (line 11))
  iso8601==0.1.12 (from -r base.txt (line 38))
  jmespath==0.10.0 (from -r base.txt (line 39))
  jsonfield==2.0.1 (from -r base.txt (line 40))
  keystoneauth1==4.0.1 (from -r base.txt (line 41))
  logutils==<IP_ADDRESS> (from -r base.txt (line 42))
  longerusername from git+https://github.com/seatme/django-longer-username.git@seatme#egg=longerusername (from -r base.txt (line 43))
  lxml==3.7.3 (from -r base.txt (line 44))
  metsrw==0.3.15 (from -r base.txt (line 45))
  monotonic==1.5 (from -r base.txt (line 46))
  moto==1.3.8 (from -r test.in (line 13))
  msgpack==1.0.0 (from -r base.txt (line 47))
  mysqlclient==1.4.6 (from -r base.txt (line 48))
  ndg-httpsclient==0.4.2 (from -r base.txt (line 49))
  netaddr==0.8.0 (from -r base.txt (line 50))
  netifaces==0.10.9 (from -r base.txt (line 51))
  oauthlib==3.1.0 (from -r base.txt (line 52))
  os-service-types==1.7.0 (from -r base.txt (line 53))
  oslo.config==7.0.0 (from -r base.txt (line 54))
  oslo.i18n==3.25.1 (from -r base.txt (line 55))
  oslo.serialization==2.29.2 (from -r base.txt (line 56))
  oslo.utils==3.42.1 (from -r base.txt (line 57))
  pathlib2==2.3.5 (from -r base.txt (line 58))
  pbr==5.4.5 (from -r base.txt (line 59))
  pip-tools==3.7.0 (from -r test.in (line 12))
  positional==1.2.1 (from -r base.txt (line 60))
  prometheus-client==0.7.1 (from -r base.txt (line 61))
  pyasn1==0.4.8 (from -r base.txt (line 63))
  pyasn1-modules==0.2.8 (from -r base.txt (line 62))
  pycparser==2.20 (from -r base.txt (line 64))
  pyopenssl==19.1.0 (from -r base.txt (line 65))
  pyparsing==2.4.7 (from -r base.txt (line 66))
  pytest==3.8.0 (from -r test.in (line 4))
  pytest-cov==2.4.0 (from -r test.in (line 5))
  pytest-django (from -r test.in (line 7))
  pytest-mock<2,>=1 (from -r test.in (line 8))
  python-dateutil==2.8.1 (from -r base.txt (line 67))
  python-gnupg==0.4.0 (from -r base.txt (line 68))
  python-keystoneclient==3.10.0 (from -r base.txt (line 69))
  python-ldap==3.2.0 (from -r base.txt (line 70))
  python-mimeparse==1.6.0 (from -r base.txt (line 71))
  python-swiftclient==3.3.0 (from -r base.txt (line 72))
  pytz==2020.1 (from -r base.txt (line 73))
  pyyaml==5.3.1 (from -r base.txt (line 74))
  requests==2.21.0 (from -r base.txt (line 76))
  requests-oauthlib==1.2.0 (from -r base.txt (line 75))
  rfc3986==1.4.0 (from -r base.txt (line 77))
  s3transfer==0.2.1 (from -r base.txt (line 78))
  scandir==1.10.0 (from -r base.txt (line 79))
  singledispatch==<IP_ADDRESS> (from -r base.txt (line 80))
  six==1.15.0 (from -r base.txt (line 81))
  stevedore==1.32.0 (from -r base.txt (line 82))
  sword2==0.2.1 (from -r base.txt (line 83))
  tox (from -r test.in (line 9))
  typing==<IP_ADDRESS> (from -r base.txt (line 84))
  urllib3==1.24.3 (from -r base.txt (line 85))
  vcrpy>=1.0.0 (from -r test.in (line 10))
  whitenoise==3.3.0 (from -r base.txt (line 86))
  wrapt==1.12.1 (from -r base.txt (line 87))
  zipp==1.2.0 (from -r base.txt (line 88))

Finding the best candidates:
  found candidate agentarchives==0.6.0 (constraint was ==0.6.0)
  found candidate babel==2.8.0 (constraint was ==2.8.0)
  found candidate bagit==1.7.0 (constraint was ==1.7.0)
  found candidate boto3==1.9.174 (constraint was ==1.9.174)
  found candidate botocore==1.12.253 (constraint was ==1.12.253)
  found candidate brotli==0.5.2 (constraint was ==0.5.2)
  found candidate certifi==2020.6.20 (constraint was ==2020.6.20)
  found candidate cffi==1.14.0 (constraint was ==1.14.0)
  found candidate chardet==3.0.4 (constraint was ==3.0.4)
  found candidate contextlib2==0.6.0.post1 (constraint was ==0.6.0.post1)
  found candidate coverage==4.2 (constraint was ==4.2)
  found candidate cryptography==2.9.2 (constraint was ==2.9.2)
  found candidate debtcollector==1.22.0 (constraint was ==1.22.0)
  found candidate defusedxml==0.5.0 (constraint was ==0.5.0)
  found candidate django==1.11.29 (constraint was ==1.11.29)
  found candidate django-auth-ldap==1.3.0 (constraint was ==1.3.0)
  found candidate django-extensions==1.7.9 (constraint was ==1.7.9)
  found candidate django-prometheus==1.0.15 (constraint was ==1.0.15)
  found candidate git+https://github.com/Brown-University-Library/django-shibboleth-remoteuser.git@67d270c65c201606fb86d548493d4b3fd8cc7a76#egg=django-shibboleth-remoteuser (constraint was <any>)
  found candidate django-tastypie==0.14.3 (constraint was ==0.14.3)
  found candidate docutils==0.15.2 (constraint was ==0.15.2)
  found candidate enum34==1.1.10 (constraint was ==1.1.10)
  found candidate funcsigs==1.0.2 (constraint was ==1.0.2)
  found candidate functools32==3.2.3.post2 (constraint was <any>)
  found candidate future==0.18.2 (constraint was ==0.18.2)
  found candidate futures==3.3.0 (constraint was ==3.3.0)
  found candidate gevent==1.3.6 (constraint was ==1.3.6)
  found candidate greenlet==0.4.16 (constraint was ==0.4.16)
  found candidate gunicorn==19.9.0 (constraint was ==19.9.0)
  found candidate httplib2==0.18.1 (constraint was ==0.18.1)
  found candidate idna==2.8 (constraint was ==2.8)
  found candidate importlib-resources==3.0.0 (constraint was ==3.0.0)
  found candidate ipaddress==1.0.23 (constraint was ==1.0.23)
  found candidate ipdb==0.13.3 (constraint was <any>)
  found candidate iso8601==0.1.12 (constraint was ==0.1.12)
  found candidate jmespath==0.10.0 (constraint was ==0.10.0)
  found candidate jsonfield==2.0.1 (constraint was ==2.0.1)
  found candidate keystoneauth1==4.0.1 (constraint was ==4.0.1)
  found candidate logutils==<IP_ADDRESS> (constraint was ==<IP_ADDRESS>)
  found candidate git+https://github.com/seatme/django-longer-username.git@seatme#egg=longerusername (constraint was <any>)
  found candidate lxml==3.7.3 (constraint was ==3.7.3)
  found candidate metsrw==0.3.15 (constraint was ==0.3.15)
  found candidate monotonic==1.5 (constraint was ==1.5)
  found candidate moto==1.3.8 (constraint was ==1.3.8)
  found candidate msgpack==1.0.0 (constraint was ==1.0.0)
  found candidate mysqlclient==1.4.6 (constraint was ==1.4.6)
  found candidate ndg-httpsclient==0.4.2 (constraint was ==0.4.2)
  found candidate netaddr==0.8.0 (constraint was ==0.8.0)
  found candidate netifaces==0.10.9 (constraint was ==0.10.9)
  found candidate oauthlib==3.1.0 (constraint was ==3.1.0)
  found candidate os-service-types==1.7.0 (constraint was ==1.7.0)
  found candidate oslo.config==7.0.0 (constraint was ==7.0.0)
  found candidate oslo.i18n==3.25.1 (constraint was ==3.25.1)
  found candidate oslo.serialization==2.29.2 (constraint was ==2.29.2)
  found candidate oslo.utils==3.42.1 (constraint was ==3.42.1)
  found candidate pathlib2==2.3.5 (constraint was ==2.3.5)
  found candidate pbr==5.4.5 (constraint was ==5.4.5)
  found candidate pip-tools==3.7.0 (constraint was ==3.7.0)
  found candidate positional==1.2.1 (constraint was ==1.2.1)
  found candidate prometheus-client==0.7.1 (constraint was ==0.7.1)
  found candidate pyasn1==0.4.8 (constraint was ==0.4.8)
  found candidate pyasn1-modules==0.2.8 (constraint was ==0.2.8)
  found candidate pycparser==2.20 (constraint was ==2.20)
  found candidate pyopenssl==19.1.0 (constraint was ==19.1.0)
  found candidate pyparsing==2.4.7 (constraint was ==2.4.7)
  found candidate pytest==3.8.0 (constraint was ==3.8.0)
  found candidate pytest-cov==2.4.0 (constraint was ==2.4.0)
  found candidate pytest-django==3.9.0 (constraint was <any>)
  found candidate pytest-mock==1.13.0 (constraint was >=1,<2)
  found candidate python-dateutil==2.8.1 (constraint was ==2.8.1)
  found candidate python-gnupg==0.4.0 (constraint was ==0.4.0)
  found candidate python-keystoneclient==3.10.0 (constraint was ==3.10.0)
  found candidate python-ldap==3.2.0 (constraint was ==3.2.0)
  found candidate python-mimeparse==1.6.0 (constraint was ==1.6.0)
  found candidate python-swiftclient==3.3.0 (constraint was ==3.3.0)
  found candidate pytz==2020.1 (constraint was ==2020.1)
  found candidate pyyaml==5.3.1 (constraint was ==5.3.1)
  found candidate requests==2.21.0 (constraint was ==2.21.0)
  found candidate requests-oauthlib==1.2.0 (constraint was ==1.2.0)
  found candidate rfc3986==1.4.0 (constraint was ==1.4.0)
  found candidate s3transfer==0.2.1 (constraint was ==0.2.1)
  found candidate scandir==1.10.0 (constraint was ==1.10.0)
  found candidate singledispatch==<IP_ADDRESS> (constraint was ==<IP_ADDRESS>)
  found candidate six==1.15.0 (constraint was ==1.15.0)
  found candidate stevedore==1.32.0 (constraint was ==1.32.0)
  found candidate sword2==0.2.1 (constraint was ==0.2.1)
  found candidate tox==3.16.1 (constraint was <any>)
  found candidate typing==<IP_ADDRESS> (constraint was ==<IP_ADDRESS>)
  found candidate urllib3==1.24.3 (constraint was ==1.24.3)
  found candidate vcrpy==3.0.0 (constraint was >=1.0.0)
  found candidate whitenoise==3.3.0 (constraint was ==3.3.0)
  found candidate wrapt==1.12.1 (constraint was ==1.12.1)
  found candidate zipp==1.2.0 (constraint was ==1.2.0)

Finding secondary dependencies:
  ndg-httpsclient==0.4.2    requires PyOpenSSL
  certifi==2020.6.20        requires -
  prometheus-client==0.7.1  requires -
  agentarchives==0.6.0      requires mysqlclient<2,>=1.3, requests<3,>=2
  pyasn1-modules==0.2.8     requires pyasn1<0.5.0,>=0.4.6
  tox==3.16.1               requires filelock>=3.0.0, importlib-metadata<2,>=0.12; python_version < "3.8", packaging>=14, pluggy>=0.12.0, py>=1.4.17, six>=1.14.0, toml>=0.9.4, virtualenv!=20.0.0,!=20.0.1,!=20.0.2,!=20.0.3,!=20.0.4,!=20.0.5,!=20.0.6,!=20.0.7,>=16.0.0
  babel==2.8.0              requires pytz>=2015.7
  django-prometheus==1.0.15 requires prometheus_client>=0.0.21
  httplib2==0.18.1          requires -
  pycparser==2.20           requires -
  pytest-mock==1.13.0       requires mock; python_version < "3.0", pytest>=2.7
  pyasn1==0.4.8             requires -
  msgpack==1.0.0            requires -
  pytest-django==3.9.0      requires pathlib2; python_version < "3.4", pytest>=3.6
  vcrpy==3.0.0              requires contextlib2; python_version == "2.7", mock; python_version == "2.7", PyYAML, six>=1.5, wrapt
  enum34==1.1.10            requires -
  python-keystoneclient==3.10.0 requires debtcollector>=1.2.0, keystoneauth1>=2.18.0, oslo.config!=3.18.0,>=3.14.0, oslo.i18n>=2.1.0, oslo.serialization>=1.10.0, oslo.utils>=3.18.0, pbr>=1.8, positional>=1.1.1, requests!=2.12.2,>=2.10.0, six>=1.9.0, stevedore>=1.17.1
  whitenoise==3.3.0         requires -
  python-mimeparse==1.6.0   requires -
  future==0.18.2            requires -
  docutils==0.15.2          requires -
  pyparsing==2.4.7          requires -
  positional==1.2.1         requires pbr>=1.8, wrapt
  importlib-resources==3.0.0 requires contextlib2; python_version < "3", pathlib2; python_version < "3", singledispatch; python_version < "3.4", typing; python_version < "3.5", zipp>=0.4; python_version < "3.8"
  python-gnupg==0.4.0       requires -
  django-extensions==1.7.9  requires six>=1.2
  pytz==2020.1              requires -
  moto==1.3.8               requires aws-xray-sdk!=0.96,>=0.93, backports.tempfile; python_version < "3.3", boto3>=1.9.86, boto>=2.36.0, botocore>=1.12.86, cfn-lint, cryptography>=2.3.0, docker>=2.5.1, idna<2.9,>=2.5, Jinja2>=2.10.1, jsondiff==1.1.2, mock, python-dateutil<3.0.0,>=2.1, python-jose<4.0.0, pytz, PyYAML, requests>=2.5, responses>=0.9.0, six>1.9, werkzeug, xmltodict
  django-auth-ldap==1.3.0   requires django>=1.8, python-ldap>=2.0; python_version < "3.0"
  django-tastypie==0.14.3   requires python-dateutil!=2.0,>=1.5, python-mimeparse!=1.5,>=0.1.4
  python-ldap==3.2.0        requires pyasn1>=0.3.7, pyasn1_modules>=0.1.5
  zipp==1.2.0               requires contextlib2; python_version < "3.4"
  requests-oauthlib==1.2.0  requires oauthlib>=3.0.0, requests>=2.0.0
  Collecting django-shibboleth-remoteuser
    Cloning https://github.com/Brown-University-Library/django-shibboleth-remoteuser.git (to revision 67d270c65c201606fb86d548493d4b3fd8cc7a76) to /tmp/pip-resolver-doil6B/django-shibboleth-remoteuser
    Running command git clone -q https://github.com/Brown-University-Library/django-shibboleth-remoteuser.git /tmp/pip-resolver-doil6B/django-shibboleth-remoteuser
    Running command git checkout -q 67d270c65c201606fb86d548493d4b3fd8cc7a76
  Collecting longerusername
    Cloning https://github.com/seatme/django-longer-username.git (to revision seatme) to /tmp/pip-resolver-6rcDwW/longerusername
    Running command git clone -q https://github.com/seatme/django-longer-username.git /tmp/pip-resolver-6rcDwW/longerusername
    Running command git checkout -b seatme --track origin/seatme
    Switched to a new branch 'seatme'
    Branch seatme set up to track remote branch seatme from origin.
  gevent==1.3.6             requires greenlet>=0.4.14; platform_python_implementation == "CPython"
  metsrw==0.3.15            requires future, lxml, six
  netifaces==0.10.9         requires -
  oslo.serialization==2.29.2 requires msgpack>=0.5.2, oslo.utils>=3.33.0, pbr!=2.1.0,>=2.0.0, pytz>=2013.6, PyYAML>=3.12, six>=1.10.0
  coverage==4.2             requires -
  pytest-cov==2.4.0         requires coverage>=3.7.1, pytest>=2.6.0
  debtcollector==1.22.0     requires funcsigs>=1.0.0; python_version == "2.7" or python_version == "2.6", pbr!=2.1.0,>=2.0.0, six>=1.10.0, wrapt>=1.7.0
  sword2==0.2.1             requires httplib2
  bagit==1.7.0              requires -
  ipaddress==1.0.23         requires -
  pyyaml==5.3.1             requires -
  pip-tools==3.7.0          requires click>=6, six
  jmespath==0.10.0          requires -
  python-swiftclient==3.3.0 requires futures>=3.0; python_version == "2.7" or python_version == "2.6", requests>=1.1, six>=1.5.2
  brotli==0.5.2             requires -
  pathlib2==2.3.5           requires scandir; python_version < "3.5", six
  defusedxml==0.5.0         requires -
  iso8601==0.1.12           requires -
  oslo.i18n==3.25.1         requires Babel!=2.4.0,>=2.3.4, pbr!=2.1.0,>=2.0.0, six>=1.10.0
  futures==3.3.0            requires -
  pbr==5.4.5                requires -
  rfc3986==1.4.0            requires -
  urllib3==1.24.3           requires -
  oslo.utils==3.42.1        requires debtcollector>=1.2.0, funcsigs>=1.0.0; python_version == "2.7" or python_version == "2.6", iso8601>=0.1.11, monotonic>=0.6; python_version < "3.3", netaddr>=0.7.18, netifaces>=0.10.4, oslo.i18n>=3.15.3, pbr!=2.1.0,>=2.0.0, pyparsing>=2.1.0, pytz>=2013.6, six>=1.10.0
  pyopenssl==19.1.0         requires cryptography>=2.8, six>=1.5.2
  cryptography==2.9.2       requires cffi!=1.11.3,>=1.8, enum34; python_version < "3", ipaddress; python_version < "3", six>=1.4.1
  os-service-types==1.7.0   requires pbr!=2.1.0,>=2.0.0
  functools32==3.2.3.post2  requires -
  jsonfield==2.0.1          requires Django>=1.8.0
  django==1.11.29           requires pytz
  scandir==1.10.0           requires -
  chardet==3.0.4            requires -
  stevedore==1.32.0         requires pbr!=2.1.0,>=2.0.0, six>=1.10.0
  pytest==3.8.0             requires atomicwrites>=1.0, attrs>=17.4.0, funcsigs; python_version < "3.0", more-itertools>=4.0.0, pathlib2>=2.2.0; python_version < "3.6", pluggy>=0.7, py>=1.5.0, setuptools, six>=1.10.0
  keystoneauth1==4.0.1      requires iso8601>=0.1.11, os-service-types>=1.2.0, pbr!=2.1.0,>=2.0.0, requests>=2.14.2, six>=1.10.0, stevedore>=1.20.0
  monotonic==1.5            requires -
  ipdb==0.13.3              requires ipython<6.0.0,>=5.1.0, setuptools
  netaddr==0.8.0            requires importlib-resources; python_version < "3.7"
  mysqlclient==1.4.6        requires -
  python-dateutil==2.8.1    requires six>=1.5
  s3transfer==0.2.1         requires botocore<2.0.0,>=1.12.36, futures<4.0.0,>=2.2.0; python_version == "2.6" or python_version == "2.7"
  contextlib2==0.6.0.post1  requires -
  lxml==3.7.3               requires -
  greenlet==0.4.16          requires -
  idna==2.8                 requires -
  botocore==1.12.253        requires docutils<0.16,>=0.10, jmespath<1.0.0,>=0.7.1, python-dateutil<3.0.0,>=2.1; python_version >= "2.7", urllib3<1.26,>=1.20; python_version == "2.7"
  requests==2.21.0          requires certifi>=2017.4.17, chardet<3.1.0,>=3.0.2, idna<2.9,>=2.5, urllib3<1.25,>=1.21.1
  oslo.config==7.0.0        requires debtcollector>=1.2.0, enum34>=1.0.4; python_version == "2.7" or python_version == "2.6" or python_version == "3.3", netaddr>=0.7.18, oslo.i18n>=3.15.3, PyYAML>=3.12, requests>=2.18.0, rfc3986>=1.2.0, six>=1.10.0, stevedore>=1.20.0
  funcsigs==1.0.2           requires -
  six==1.15.0               requires -
  wrapt==1.12.1             requires -
  boto3==1.9.174            requires botocore<1.13.0,>=1.12.174, jmespath<1.0.0,>=0.7.1, s3transfer<0.3.0,>=0.2.0
  cffi==1.14.0              requires pycparser
  singledispatch==<IP_ADDRESS>   requires six
  gunicorn==19.9.0          requires -
  oauthlib==3.1.0           requires -
  logutils==<IP_ADDRESS>         requires -
  typing==<IP_ADDRESS>           requires -

New dependencies found in this round:
  adding [u'atomicwrites', '>=1.0', '[]']
  adding [u'attrs', '>=17.4.0', '[]']
  adding [u'aws-xray-sdk', '!=0.96,>=0.93', '[]']
  adding [u'babel', '!=2.4.0,>=2.3.4', '[]']
  adding [u'backports.tempfile', '', '[]']
  adding [u'boto', '>=2.36.0', '[]']
  adding [u'boto3', '>=1.9.86', '[]']
  adding [u'botocore', '<1.13.0,<2.0.0,>=1.12.174,>=1.12.36,>=1.12.86', '[]']
  adding [u'certifi', '>=2017.4.17', '[]']
  adding [u'cffi', '!=1.11.3,>=1.8', '[]']
  adding [u'cfn-lint', '', '[]']
  adding [u'chardet', '<3.1.0,>=3.0.2', '[]']
  adding [u'click', '>=6', '[]']
  adding [u'contextlib2', '', '[]']
  adding [u'coverage', '>=3.7.1', '[]']
  adding [u'cryptography', '>=2.3.0,>=2.8', '[]']
  adding [u'debtcollector', '>=1.2.0', '[]']
  adding [u'django', '>=1.8,>=1.8.0', '[]']
  adding [u'docker', '>=2.5.1', '[]']
  adding [u'docutils', '<0.16,>=0.10', '[]']
  adding [u'enum34', '>=1.0.4', '[]']
  adding [u'filelock', '>=3.0.0', '[]']
  adding [u'funcsigs', '>=1.0.0', '[]']
  adding [u'future', '', '[]']
  adding [u'futures', '<4.0.0,>=2.2.0,>=3.0', '[]']
  adding [u'greenlet', '>=0.4.14', '[]']
  adding [u'httplib2', '', '[]']
  adding [u'idna', '<2.9,>=2.5', '[]']
  adding [u'importlib-metadata', '<2,>=0.12', '[]']
  adding [u'importlib-resources', '', '[]']
  adding [u'ipaddress', '', '[]']
  adding [u'ipython', '<6.0.0,>=5.1.0', '[]']
  adding [u'iso8601', '>=0.1.11', '[]']
  adding [u'jinja2', '>=2.10.1', '[]']
  adding [u'jmespath', '<1.0.0,>=0.7.1', '[]']
  adding [u'jsondiff', '==1.1.2', '[]']
  adding [u'keystoneauth1', '>=2.18.0', '[]']
  adding [u'lxml', '', '[]']
  adding [u'mock', '', '[]']
  adding [u'monotonic', '>=0.6', '[]']
  adding [u'more-itertools', '>=4.0.0', '[]']
  adding [u'msgpack', '>=0.5.2', '[]']
  adding [u'mysqlclient', '<2,>=1.3', '[]']
  adding [u'netaddr', '>=0.7.18', '[]']
  adding [u'netifaces', '>=0.10.4', '[]']
  adding [u'oauthlib', '>=3.0.0', '[]']
  adding [u'os-service-types', '>=1.2.0', '[]']
  adding [u'oslo.config', '!=3.18.0,>=3.14.0', '[]']
  adding [u'oslo.i18n', '>=2.1.0,>=3.15.3', '[]']
  adding [u'oslo.serialization', '>=1.10.0', '[]']
  adding [u'oslo.utils', '>=3.18.0,>=3.33.0', '[]']
  adding [u'packaging', '>=14', '[]']
  adding [u'pathlib2', '>=2.2.0', '[]']
  adding [u'pbr', '!=2.1.0,>=1.8,>=2.0.0', '[]']
  adding [u'pluggy', '>=0.12.0,>=0.7', '[]']
  adding [u'positional', '>=1.1.1', '[]']
  adding [u'prometheus-client', '>=0.0.21', '[]']
  adding [u'py', '>=1.4.17,>=1.5.0', '[]']
  adding [u'pyasn1', '<0.5.0,>=0.3.7,>=0.4.6', '[]']
  adding [u'pyasn1-modules', '>=0.1.5', '[]']
  adding [u'pycparser', '', '[]']
  adding [u'pyopenssl', '', '[]']
  adding [u'pyparsing', '>=2.1.0', '[]']
  adding [u'pytest', '>=2.6.0,>=2.7,>=3.6', '[]']
  adding [u'python-dateutil', '!=2.0,<3.0.0,>=1.5,>=2.1', '[]']
  adding [u'python-jose', '<4.0.0', '[]']
  adding [u'python-ldap', '>=2.0', '[]']
  adding [u'python-mimeparse', '!=1.5,>=0.1.4', '[]']
  adding [u'pytz', '>=2013.6,>=2015.7', '[]']
  adding [u'pyyaml', '>=3.12', '[]']
  adding [u'requests', '!=2.12.2,<3,>=1.1,>=2,>=2.0.0,>=2.10.0,>=2.14.2,>=2.18.0,>=2.5', '[]']
  adding [u'responses', '>=0.9.0', '[]']
  adding [u'rfc3986', '>=1.2.0', '[]']
  adding [u's3transfer', '<0.3.0,>=0.2.0', '[]']
  adding [u'scandir', '', '[]']
  adding [u'setuptools', '', '[]']
  adding [u'singledispatch', '', '[]']
  adding [u'six', '>1.9,>=1.10.0,>=1.14.0,>=1.2,>=1.4.1,>=1.5,>=1.5.2,>=1.9.0', '[]']
  adding [u'stevedore', '>=1.17.1,>=1.20.0', '[]']
  adding [u'toml', '>=0.9.4', '[]']
  adding [u'typing', '', '[]']
  adding [u'urllib3', '<1.25,<1.26,>=1.20,>=1.21.1', '[]']
  adding [u'virtualenv', '!=20.0.0,!=20.0.1,!=20.0.2,!=20.0.3,!=20.0.4,!=20.0.5,!=20.0.6,!=20.0.7,>=16.0.0', '[]']
  adding [u'werkzeug', '', '[]']
  adding [u'wrapt', '>=1.7.0', '[]']
  adding [u'xmltodict', '', '[]']
  adding [u'zipp', '>=0.4', '[]']
Removed dependencies in this round:
------------------------------------------------------------
Result of round 1: not stable

                          ROUND 2
Current constraints:
  agentarchives==0.6.0 (from -r base.txt (line 7))
  atomicwrites>=1.0 (from pytest==3.8.0->-r test.in (line 4))
  attrs>=17.4.0 (from pytest==3.8.0->-r test.in (line 4))
  aws-xray-sdk!=0.96,>=0.93 (from moto==1.3.8->-r test.in (line 13))
  babel!=2.4.0,==2.8.0,>=2.3.4 (from -r base.txt (line 8))
  backports.tempfile (from moto==1.3.8->-r test.in (line 13))
  bagit==1.7.0 (from -r base.txt (line 9))
  boto>=2.36.0 (from moto==1.3.8->-r test.in (line 13))
  boto3==1.9.174,>=1.9.86 (from -r base.txt (line 10))
  botocore<1.13.0,<2.0.0,==1.12.253,>=1.12.174,>=1.12.36,>=1.12.86 (from -r base.txt (line 11))
  brotli==0.5.2 (from -r base.txt (line 12))
  certifi==2020.6.20,>=2017.4.17 (from -r base.txt (line 13))
  cffi!=1.11.3,==1.14.0,>=1.8 (from -r base.txt (line 14))
  cfn-lint (from moto==1.3.8->-r test.in (line 13))
  chardet<3.1.0,==3.0.4,>=3.0.2 (from -r base.txt (line 15))
  click>=6 (from pip-tools==3.7.0->-r test.in (line 12))
  contextlib2==0.6.0.post1 (from -r base.txt (line 16))
  coverage==4.2,>=3.7.1 (from -r test.in (line 6))
  cryptography==2.9.2,>=2.3.0,>=2.8 (from -r base.txt (line 17))
  debtcollector==1.22.0,>=1.2.0 (from -r base.txt (line 18))
  defusedxml==0.5.0 (from -r base.txt (line 19))
  django==1.11.29,>=1.8,>=1.8.0 (from -r base.txt (line 25))
  django-auth-ldap==1.3.0 (from -r base.txt (line 20))
  django-extensions==1.7.9 (from -r base.txt (line 21))
  django-prometheus==1.0.15 (from -r base.txt (line 22))
  django-shibboleth-remoteuser from git+https://github.com/Brown-University-Library/django-shibboleth-remoteuser.git@67d270c65c201606fb86d548493d4b3fd8cc7a76#egg=django-shibboleth-remoteuser (from -r base.txt (line 23))
  django-tastypie==0.14.3 (from -r base.txt (line 24))
  docker>=2.5.1 (from moto==1.3.8->-r test.in (line 13))
  docutils<0.16,==0.15.2,>=0.10 (from -r base.txt (line 26))
  enum34==1.1.10,>=1.0.4 (from -r base.txt (line 27))
  filelock>=3.0.0 (from tox==3.16.1->-r test.in (line 9))
  funcsigs==1.0.2,>=1.0.0 (from -r base.txt (line 28))
  functools32 (from -r test.in (line 14))
  future==0.18.2 (from -r base.txt (line 29))
  futures<4.0.0,==3.3.0,>=2.2.0,>=3.0 (from -r base.txt (line 30))
  gevent==1.3.6 (from -r base.txt (line 31))
  greenlet==0.4.16,>=0.4.14 (from -r base.txt (line 32))
  gunicorn==19.9.0 (from -r base.txt (line 33))
  httplib2==0.18.1 (from -r base.txt (line 34))
  idna<2.9,==2.8,>=2.5 (from -r base.txt (line 35))
  importlib-metadata<2,>=0.12 (from tox==3.16.1->-r test.in (line 9))
  importlib-resources==3.0.0 (from -r base.txt (line 36))
  ipaddress==1.0.23 (from -r base.txt (line 37))
  ipdb (from -r test.in (line 11))
  ipython<6.0.0,>=5.1.0 (from ipdb==0.13.3->-r test.in (line 11))
  iso8601==0.1.12,>=0.1.11 (from -r base.txt (line 38))
  Jinja2>=2.10.1 (from moto==1.3.8->-r test.in (line 13))
  jmespath<1.0.0,==0.10.0,>=0.7.1 (from -r base.txt (line 39))
  jsondiff==1.1.2 (from moto==1.3.8->-r test.in (line 13))
  jsonfield==2.0.1 (from -r base.txt (line 40))
  keystoneauth1==4.0.1,>=2.18.0 (from -r base.txt (line 41))
  logutils==<IP_ADDRESS> (from -r base.txt (line 42))
  longerusername from git+https://github.com/seatme/django-longer-username.git@seatme#egg=longerusername (from -r base.txt (line 43))
  lxml==3.7.3 (from -r base.txt (line 44))
  metsrw==0.3.15 (from -r base.txt (line 45))
  mock (from moto==1.3.8->-r test.in (line 13))
  monotonic==1.5,>=0.6 (from -r base.txt (line 46))
  more-itertools>=4.0.0 (from pytest==3.8.0->-r test.in (line 4))
  moto==1.3.8 (from -r test.in (line 13))
  msgpack==1.0.0,>=0.5.2 (from -r base.txt (line 47))
  mysqlclient<2,==1.4.6,>=1.3 (from -r base.txt (line 48))
  ndg-httpsclient==0.4.2 (from -r base.txt (line 49))
  netaddr==0.8.0,>=0.7.18 (from -r base.txt (line 50))
  netifaces==0.10.9,>=0.10.4 (from -r base.txt (line 51))
  oauthlib==3.1.0,>=3.0.0 (from -r base.txt (line 52))
  os-service-types==1.7.0,>=1.2.0 (from -r base.txt (line 53))
  oslo.config!=3.18.0,==7.0.0,>=3.14.0 (from -r base.txt (line 54))
  oslo.i18n==3.25.1,>=2.1.0,>=3.15.3 (from -r base.txt (line 55))
  oslo.serialization==2.29.2,>=1.10.0 (from -r base.txt (line 56))
  oslo.utils==3.42.1,>=3.18.0,>=3.33.0 (from -r base.txt (line 57))
  packaging>=14 (from tox==3.16.1->-r test.in (line 9))
  pathlib2==2.3.5,>=2.2.0 (from -r base.txt (line 58))
  pbr!=2.1.0,==5.4.5,>=1.8,>=2.0.0 (from -r base.txt (line 59))
  pip-tools==3.7.0 (from -r test.in (line 12))
  pluggy>=0.12.0,>=0.7 (from tox==3.16.1->-r test.in (line 9))
  positional==1.2.1,>=1.1.1 (from -r base.txt (line 60))
  prometheus-client==0.7.1,>=0.0.21 (from -r base.txt (line 61))
  py>=1.4.17,>=1.5.0 (from tox==3.16.1->-r test.in (line 9))
  pyasn1<0.5.0,==0.4.8,>=0.3.7,>=0.4.6 (from -r base.txt (line 63))
  pyasn1-modules==0.2.8,>=0.1.5 (from -r base.txt (line 62))
  pycparser==2.20 (from -r base.txt (line 64))
  pyopenssl==19.1.0 (from -r base.txt (line 65))
  pyparsing==2.4.7,>=2.1.0 (from -r base.txt (line 66))
  pytest==3.8.0,>=2.6.0,>=2.7,>=3.6 (from -r test.in (line 4))
  pytest-cov==2.4.0 (from -r test.in (line 5))
  pytest-django (from -r test.in (line 7))
  pytest-mock<2,>=1 (from -r test.in (line 8))
  python-dateutil!=2.0,<3.0.0,==2.8.1,>=1.5,>=2.1 (from -r base.txt (line 67))
  python-gnupg==0.4.0 (from -r base.txt (line 68))
  python-jose<4.0.0 (from moto==1.3.8->-r test.in (line 13))
  python-keystoneclient==3.10.0 (from -r base.txt (line 69))
  python-ldap==3.2.0,>=2.0 (from -r base.txt (line 70))
  python-mimeparse!=1.5,==1.6.0,>=0.1.4 (from -r base.txt (line 71))
  python-swiftclient==3.3.0 (from -r base.txt (line 72))
  pytz==2020.1,>=2013.6,>=2015.7 (from -r base.txt (line 73))
  pyyaml==5.3.1,>=3.12 (from -r base.txt (line 74))
  requests!=2.12.2,<3,==2.21.0,>=1.1,>=2,>=2.0.0,>=2.10.0,>=2.14.2,>=2.18.0,>=2.5 (from -r base.txt (line 76))
  requests-oauthlib==1.2.0 (from -r base.txt (line 75))
  responses>=0.9.0 (from moto==1.3.8->-r test.in (line 13))
  rfc3986==1.4.0,>=1.2.0 (from -r base.txt (line 77))
  s3transfer<0.3.0,==0.2.1,>=0.2.0 (from -r base.txt (line 78))
  scandir==1.10.0 (from -r base.txt (line 79))
  setuptools (from ipdb==0.13.3->-r test.in (line 11))
  singledispatch==<IP_ADDRESS> (from -r base.txt (line 80))
  six==1.15.0,>1.9,>=1.10.0,>=1.14.0,>=1.2,>=1.4.1,>=1.5,>=1.5.2,>=1.9.0 (from -r base.txt (line 81))
  stevedore==1.32.0,>=1.17.1,>=1.20.0 (from -r base.txt (line 82))
  sword2==0.2.1 (from -r base.txt (line 83))
  toml>=0.9.4 (from tox==3.16.1->-r test.in (line 9))
  tox (from -r test.in (line 9))
  typing==<IP_ADDRESS> (from -r base.txt (line 84))
  urllib3<1.25,<1.26,==1.24.3,>=1.20,>=1.21.1 (from -r base.txt (line 85))
  vcrpy>=1.0.0 (from -r test.in (line 10))
  virtualenv!=20.0.0,!=20.0.1,!=20.0.2,!=20.0.3,!=20.0.4,!=20.0.5,!=20.0.6,!=20.0.7,>=16.0.0 (from tox==3.16.1->-r test.in (line 9))
  werkzeug (from moto==1.3.8->-r test.in (line 13))
  whitenoise==3.3.0 (from -r base.txt (line 86))
  wrapt==1.12.1,>=1.7.0 (from -r base.txt (line 87))
  xmltodict (from moto==1.3.8->-r test.in (line 13))
  zipp==1.2.0,>=0.4 (from -r base.txt (line 88))

Finding the best candidates:
  found candidate agentarchives==0.6.0 (constraint was ==0.6.0)
  found candidate atomicwrites==1.4.0 (constraint was >=1.0)
  found candidate attrs==19.3.0 (constraint was >=17.4.0)
  found candidate aws-xray-sdk==2.6.0 (constraint was >=0.93,!=0.96)
  found candidate babel==2.8.0 (constraint was >=2.3.4,!=2.4.0,==2.8.0)
  found candidate backports.tempfile==1.0 (constraint was <any>)
  found candidate bagit==1.7.0 (constraint was ==1.7.0)
  found candidate boto==2.49.0 (constraint was >=2.36.0)
  found candidate boto3==1.9.174 (constraint was ==1.9.174,>=1.9.86)
  found candidate botocore==1.12.253 (constraint was >=1.12.174,==1.12.253,>=1.12.36,>=1.12.86,<1.13.0,<2.0.0)
  found candidate brotli==0.5.2 (constraint was ==0.5.2)
  found candidate certifi==2020.6.20 (constraint was >=2017.4.17,==2020.6.20)
  found candidate cffi==1.14.0 (constraint was !=1.11.3,==1.14.0,>=1.8)
  found candidate cfn-lint==0.33.2 (constraint was <any>)
  found candidate chardet==3.0.4 (constraint was >=3.0.2,==3.0.4,<3.1.0)
  found candidate click==7.1.2 (constraint was >=6)
  found candidate contextlib2==0.6.0.post1 (constraint was ==0.6.0.post1)
  found candidate coverage==4.2 (constraint was >=3.7.1,==4.2)
  found candidate cryptography==2.9.2 (constraint was >=2.3.0,>=2.8,==2.9.2)
  found candidate debtcollector==1.22.0 (constraint was >=1.2.0,==1.22.0)
  found candidate defusedxml==0.5.0 (constraint was ==0.5.0)
  found candidate django==1.11.29 (constraint was ==1.11.29,>=1.8,>=1.8.0)
  found candidate django-auth-ldap==1.3.0 (constraint was ==1.3.0)
  found candidate django-extensions==1.7.9 (constraint was ==1.7.9)
  found candidate django-prometheus==1.0.15 (constraint was ==1.0.15)
  found candidate git+https://github.com/Brown-University-Library/django-shibboleth-remoteuser.git@67d270c65c201606fb86d548493d4b3fd8cc7a76#egg=django-shibboleth-remoteuser (constraint was <any>)
  found candidate django-tastypie==0.14.3 (constraint was ==0.14.3)
  found candidate docker==4.2.2 (constraint was >=2.5.1)
  found candidate docutils==0.15.2 (constraint was >=0.10,==0.15.2,<0.16)
  found candidate enum34==1.1.10 (constraint was >=1.0.4,==1.1.10)
  found candidate filelock==3.0.12 (constraint was >=3.0.0)
  found candidate funcsigs==1.0.2 (constraint was >=1.0.0,==1.0.2)
  found candidate functools32==3.2.3.post2 (constraint was <any>)
  found candidate future==0.18.2 (constraint was ==0.18.2)
  found candidate futures==3.3.0 (constraint was >=2.2.0,>=3.0,==3.3.0,<4.0.0)
  found candidate gevent==1.3.6 (constraint was ==1.3.6)
  found candidate greenlet==0.4.16 (constraint was >=0.4.14,==0.4.16)
  found candidate gunicorn==19.9.0 (constraint was ==19.9.0)
  found candidate httplib2==0.18.1 (constraint was ==0.18.1)
  found candidate idna==2.8 (constraint was >=2.5,==2.8,<2.9)
  found candidate importlib-metadata==1.7.0 (constraint was >=0.12,<2)
  found candidate importlib-resources==3.0.0 (constraint was ==3.0.0)
  found candidate ipaddress==1.0.23 (constraint was ==1.0.23)
  found candidate ipdb==0.13.3 (constraint was <any>)
  found candidate ipython==5.10.0 (constraint was >=5.1.0,<6.0.0)
  found candidate iso8601==0.1.12 (constraint was >=0.1.11,==0.1.12)
  found candidate jinja2==2.11.2 (constraint was >=2.10.1)
  found candidate jmespath==0.10.0 (constraint was ==0.10.0,>=0.7.1,<1.0.0)
  found candidate jsondiff==1.1.2 (constraint was ==1.1.2)
  found candidate jsonfield==2.0.1 (constraint was ==2.0.1)
  found candidate keystoneauth1==4.0.1 (constraint was >=2.18.0,==4.0.1)
  found candidate logutils==<IP_ADDRESS> (constraint was ==<IP_ADDRESS>)
  found candidate git+https://github.com/seatme/django-longer-username.git@seatme#egg=longerusername (constraint was <any>)
  found candidate lxml==3.7.3 (constraint was ==3.7.3)
  found candidate metsrw==0.3.15 (constraint was ==0.3.15)
  found candidate mock==3.0.5 (constraint was <any>)
  found candidate monotonic==1.5 (constraint was >=0.6,==1.5)
  found candidate more-itertools==5.0.0 (constraint was >=4.0.0)
  found candidate moto==1.3.8 (constraint was ==1.3.8)
  found candidate msgpack==1.0.0 (constraint was >=0.5.2,==1.0.0)
  found candidate mysqlclient==1.4.6 (constraint was >=1.3,==1.4.6,<2)
  found candidate ndg-httpsclient==0.4.2 (constraint was ==0.4.2)
  found candidate netaddr==0.8.0 (constraint was >=0.7.18,==0.8.0)
  found candidate netifaces==0.10.9 (constraint was >=0.10.4,==0.10.9)
  found candidate oauthlib==3.1.0 (constraint was >=3.0.0,==3.1.0)
  found candidate os-service-types==1.7.0 (constraint was >=1.2.0,==1.7.0)
  found candidate oslo.config==7.0.0 (constraint was >=3.14.0,!=3.18.0,==7.0.0)
  found candidate oslo.i18n==3.25.1 (constraint was >=2.1.0,>=3.15.3,==3.25.1)
  found candidate oslo.serialization==2.29.2 (constraint was >=1.10.0,==2.29.2)
  found candidate oslo.utils==3.42.1 (constraint was >=3.18.0,>=3.33.0,==3.42.1)
  found candidate packaging==20.4 (constraint was >=14)
  found candidate pathlib2==2.3.5 (constraint was >=2.2.0,==2.3.5)
  found candidate pbr==5.4.5 (constraint was >=1.8,>=2.0.0,!=2.1.0,==5.4.5)
  found candidate pip-tools==3.7.0 (constraint was ==3.7.0)
  found candidate pluggy==0.13.1 (constraint was >=0.12.0,>=0.7)
  found candidate positional==1.2.1 (constraint was >=1.1.1,==1.2.1)
  found candidate prometheus-client==0.7.1 (constraint was >=0.0.21,==0.7.1)
  found candidate py==1.9.0 (constraint was >=1.4.17,>=1.5.0)
  found candidate pyasn1==0.4.8 (constraint was >=0.3.7,>=0.4.6,==0.4.8,<0.5.0)
  found candidate pyasn1-modules==0.2.8 (constraint was >=0.1.5,==0.2.8)
  found candidate pycparser==2.20 (constraint was ==2.20)
  found candidate pyopenssl==19.1.0 (constraint was ==19.1.0)
  found candidate pyparsing==2.4.7 (constraint was >=2.1.0,==2.4.7)
  found candidate pytest==3.8.0 (constraint was >=2.6.0,>=2.7,>=3.6,==3.8.0)
  found candidate pytest-cov==2.4.0 (constraint was ==2.4.0)
  found candidate pytest-django==3.9.0 (constraint was <any>)
  found candidate pytest-mock==1.13.0 (constraint was >=1,<2)
  found candidate python-dateutil==2.8.1 (constraint was >=1.5,!=2.0,>=2.1,==2.8.1,<3.0.0)
  found candidate python-gnupg==0.4.0 (constraint was ==0.4.0)
  found candidate python-jose==3.1.0 (constraint was <4.0.0)
  found candidate python-keystoneclient==3.10.0 (constraint was ==3.10.0)
  found candidate python-ldap==3.2.0 (constraint was >=2.0,==3.2.0)
  found candidate python-mimeparse==1.6.0 (constraint was >=0.1.4,!=1.5,==1.6.0)
  found candidate python-swiftclient==3.3.0 (constraint was ==3.3.0)
  found candidate pytz==2020.1 (constraint was >=2013.6,>=2015.7,==2020.1)
  found candidate pyyaml==5.3.1 (constraint was >=3.12,==5.3.1)
  found candidate requests==2.21.0 (constraint was >=1.1,>=2,>=2.0.0,>=2.10.0,!=2.12.2,>=2.14.2,>=2.18.0,==2.21.0,>=2.5,<3)
  found candidate requests-oauthlib==1.2.0 (constraint was ==1.2.0)
  found candidate responses==0.10.15 (constraint was >=0.9.0)
  found candidate rfc3986==1.4.0 (constraint was >=1.2.0,==1.4.0)
  found candidate s3transfer==0.2.1 (constraint was >=0.2.0,==0.2.1,<0.3.0)
  found candidate scandir==1.10.0 (constraint was ==1.10.0)
  found candidate setuptools==44.1.1 (constraint was <any>)
  found candidate singledispatch==<IP_ADDRESS> (constraint was ==<IP_ADDRESS>)
  found candidate six==1.15.0 (constraint was >=1.10.0,>=1.14.0,==1.15.0,>=1.2,>=1.4.1,>=1.5,>=1.5.2,>1.9,>=1.9.0)
  found candidate stevedore==1.32.0 (constraint was >=1.17.1,>=1.20.0,==1.32.0)
  found candidate sword2==0.2.1 (constraint was ==0.2.1)
  found candidate toml==0.10.1 (constraint was >=0.9.4)
  found candidate tox==3.16.1 (constraint was <any>)
  found candidate typing==<IP_ADDRESS> (constraint was ==<IP_ADDRESS>)
  found candidate urllib3==1.24.3 (constraint was >=1.20,>=1.21.1,==1.24.3,<1.25,<1.26)
  found candidate vcrpy==3.0.0 (constraint was >=1.0.0)
  found candidate virtualenv==20.0.25 (constraint was >=16.0.0,!=20.0.0,!=20.0.1,!=20.0.2,!=20.0.3,!=20.0.4,!=20.0.5,!=20.0.6,!=20.0.7)
  found candidate werkzeug==1.0.1 (constraint was <any>)
  found candidate whitenoise==3.3.0 (constraint was ==3.3.0)
  found candidate wrapt==1.12.1 (constraint was ==1.12.1,>=1.7.0)
  found candidate xmltodict==0.12.0 (constraint was <any>)
  found candidate zipp==1.2.0 (constraint was >=0.4,==1.2.0)

Finding secondary dependencies:
  vcrpy==3.0.0              requires contextlib2; python_version == "2.7", mock; python_version == "2.7", PyYAML, six>=1.5, wrapt
  bagit==1.7.0              requires -
  mysqlclient==1.4.6        requires -
  gunicorn==19.9.0          requires -
  iso8601==0.1.12           requires -
  django-prometheus==1.0.15 requires prometheus_client>=0.0.21
  more-itertools==5.0.0     requires six<2.0.0,>=1.0.0
  oslo.utils==3.42.1        requires debtcollector>=1.2.0, funcsigs>=1.0.0; python_version == "2.7" or python_version == "2.6", iso8601>=0.1.11, monotonic>=0.6; python_version < "3.3", netaddr>=0.7.18, netifaces>=0.10.4, oslo.i18n>=3.15.3, pbr!=2.1.0,>=2.0.0, pyparsing>=2.1.0, pytz>=2013.6, six>=1.10.0
  django-extensions==1.7.9  requires six>=1.2
  aws-xray-sdk==2.6.0       requires botocore>=1.11.3, enum34; python_version < "3.4", future, jsonpickle, wrapt
  django-auth-ldap==1.3.0   requires django>=1.8, python-ldap>=2.0; python_version < "3.0"
  pluggy==0.13.1            requires importlib-metadata>=0.12; python_version < "3.8"
  packaging==20.4           requires pyparsing>=2.0.2, six
  tox==3.16.1               requires filelock>=3.0.0, importlib-metadata<2,>=0.12; python_version < "3.8", packaging>=14, pluggy>=0.12.0, py>=1.4.17, six>=1.14.0, toml>=0.9.4, virtualenv!=20.0.0,!=20.0.1,!=20.0.2,!=20.0.3,!=20.0.4,!=20.0.5,!=20.0.6,!=20.0.7,>=16.0.0
  scandir==1.10.0           requires -
  oslo.i18n==3.25.1         requires Babel!=2.4.0,>=2.3.4, pbr!=2.1.0,>=2.0.0, six>=1.10.0
  s3transfer==0.2.1         requires botocore<2.0.0,>=1.12.36, futures<4.0.0,>=2.2.0; python_version == "2.6" or python_version == "2.7"
  urllib3==1.24.3           requires -
  msgpack==1.0.0            requires -
  python-keystoneclient==3.10.0 requires debtcollector>=1.2.0, keystoneauth1>=2.18.0, oslo.config!=3.18.0,>=3.14.0, oslo.i18n>=2.1.0, oslo.serialization>=1.10.0, oslo.utils>=3.18.0, pbr>=1.8, positional>=1.1.1, requests!=2.12.2,>=2.10.0, six>=1.9.0, stevedore>=1.17.1
  oslo.config==7.0.0        requires debtcollector>=1.2.0, enum34>=1.0.4; python_version == "2.7" or python_version == "2.6" or python_version == "3.3", netaddr>=0.7.18, oslo.i18n>=3.15.3, PyYAML>=3.12, requests>=2.18.0, rfc3986>=1.2.0, six>=1.10.0, stevedore>=1.20.0
  docker==4.2.2             requires backports.ssl-match-hostname>=3.5; python_version < "3.5", ipaddress>=1.0.16; python_version < "3.3", requests!=2.18.0,>=2.14.2, six>=1.4.0, websocket-client>=0.32.0
  cfn-lint==0.33.2          requires aws-sam-translator>=1.25.0, importlib_resources~=1.4, jsonpatch, jsonschema~=3.0, junit-xml~=1.9, networkx<=2.2, pathlib2>=2.3.0, pyyaml, six~=1.11
  oslo.serialization==2.29.2 requires msgpack>=0.5.2, oslo.utils>=3.33.0, pbr!=2.1.0,>=2.0.0, pytz>=2013.6, PyYAML>=3.12, six>=1.10.0
  singledispatch==<IP_ADDRESS>   requires six
  idna==2.8                 requires -
  six==1.15.0               requires -
  pyparsing==2.4.7          requires -
  keystoneauth1==4.0.1      requires iso8601>=0.1.11, os-service-types>=1.2.0, pbr!=2.1.0,>=2.0.0, requests>=2.14.2, six>=1.10.0, stevedore>=1.20.0
  pytz==2020.1              requires -
  python-gnupg==0.4.0       requires -
  monotonic==1.5            requires -
  os-service-types==1.7.0   requires pbr!=2.1.0,>=2.0.0
  jsondiff==1.1.2           requires -
  moto==1.3.8               requires aws-xray-sdk!=0.96,>=0.93, backports.tempfile; python_version < "3.3", boto3>=1.9.86, boto>=2.36.0, botocore>=1.12.86, cfn-lint, cryptography>=2.3.0, docker>=2.5.1, idna<2.9,>=2.5, Jinja2>=2.10.1, jsondiff==1.1.2, mock, python-dateutil<3.0.0,>=2.1, python-jose<4.0.0, pytz, PyYAML, requests>=2.5, responses>=0.9.0, six>1.9, werkzeug, xmltodict
  pyasn1==0.4.8             requires -
  pathlib2==2.3.5           requires scandir; python_version < "3.5", six
  zipp==1.2.0               requires contextlib2; python_version < "3.4"
  django-tastypie==0.14.3   requires python-dateutil!=2.0,>=1.5, python-mimeparse!=1.5,>=0.1.4
  netifaces==0.10.9         requires -
  certifi==2020.6.20        requires -
  enum34==1.1.10            requires -
  python-dateutil==2.8.1    requires six>=1.5
  requests-oauthlib==1.2.0  requires oauthlib>=3.0.0, requests>=2.0.0
  python-ldap==3.2.0        requires pyasn1>=0.3.7, pyasn1_modules>=0.1.5
  cffi==1.14.0              requires pycparser
  pytest-mock==1.13.0       requires mock; python_version < "3.0", pytest>=2.7
  requests==2.21.0          requires certifi>=2017.4.17, chardet<3.1.0,>=3.0.2, idna<2.9,>=2.5, urllib3<1.25,>=1.21.1
  werkzeug==1.0.1           requires -
  docutils==0.15.2          requires -
  gevent==1.3.6             requires greenlet>=0.4.14; platform_python_implementation == "CPython"
  metsrw==0.3.15            requires future, lxml, six
  xmltodict==0.12.0         requires -
  futures==3.3.0            requires -
  py==1.9.0                 requires -
  pytest-cov==2.4.0         requires coverage>=3.7.1, pytest>=2.6.0
  importlib-resources==3.0.0 requires contextlib2; python_version < "3", pathlib2; python_version < "3", singledispatch; python_version < "3.4", typing; python_version < "3.5", zipp>=0.4; python_version < "3.8"
  sword2==0.2.1             requires httplib2
  pytest-django==3.9.0      requires pathlib2; python_version < "3.4", pytest>=3.6
  django==1.11.29           requires pytz
  pip-tools==3.7.0          requires click>=6, six
  virtualenv==20.0.25       requires appdirs<2,>=1.4.3, distlib<1,>=0.3.0, filelock<4,>=3.0.0, importlib-metadata<2,>=0.12; python_version < "3.8", importlib-resources>=1.0; python_version < "3.7", pathlib2<3,>=2.3.3; python_version < "3.4" and sys_platform != "win32", six<2,>=1.9.0
  netaddr==0.8.0            requires importlib-resources; python_version < "3.7"
  positional==1.2.1         requires pbr>=1.8, wrapt
  pycparser==2.20           requires -
  brotli==0.5.2             requires -
  responses==0.10.15        requires cookies; python_version < "3.4", mock; python_version < "3.3", requests>=2.0, six
  functools32==3.2.3.post2  requires -
  defusedxml==0.5.0         requires -
  greenlet==0.4.16          requires -
  agentarchives==0.6.0      requires mysqlclient<2,>=1.3, requests<3,>=2
  pyopenssl==19.1.0         requires cryptography>=2.8, six>=1.5.2
  pyyaml==5.3.1             requires -
  coverage==4.2             requires -
  jmespath==0.10.0          requires -
  pbr==5.4.5                requires -
  stevedore==1.32.0         requires pbr!=2.1.0,>=2.0.0, six>=1.10.0
  rfc3986==1.4.0            requires -
  ipython==5.10.0           requires backports.shutil-get-terminal-size; python_version == "2.7", decorator, pathlib2; python_version == "2.7" or python_version == "3.3", pexpect; sys_platform != "win32", pickleshare, prompt-toolkit<2.0.0,>=1.0.4, pygments<2.6, setuptools>=18.5, simplegeneric>0.8, traitlets>=4.2
  click==7.1.2              requires -
  boto==2.49.0              requires -
  contextlib2==0.6.0.post1  requires -
  python-mimeparse==1.6.0   requires -
  lxml==3.7.3               requires -
  wrapt==1.12.1             requires -
  mock==3.0.5               requires funcsigs>=1; python_version < "3.3", six
  attrs==19.3.0             requires -
  ndg-httpsclient==0.4.2    requires PyOpenSSL
  whitenoise==3.3.0         requires -
  jsonfield==2.0.1          requires Django>=1.8.0
  setuptools==44.1.1        requires -
  babel==2.8.0              requires pytz>=2015.7
  python-jose==3.1.0        requires ecdsa<1.0, pyasn1, rsa, six<2.0
  future==0.18.2            requires -
  httplib2==0.18.1          requires -
  typing==<IP_ADDRESS>           requires -
  pyasn1-modules==0.2.8     requires pyasn1<0.5.0,>=0.4.6
  python-swiftclient==3.3.0 requires futures>=3.0; python_version == "2.7" or python_version == "2.6", requests>=1.1, six>=1.5.2
  jinja2==2.11.2            requires MarkupSafe>=0.23
  toml==0.10.1              requires -
  pytest==3.8.0             requires atomicwrites>=1.0, attrs>=17.4.0, funcsigs; python_version < "3.0", more-itertools>=4.0.0, pathlib2>=2.2.0; python_version < "3.6", pluggy>=0.7, py>=1.5.0, setuptools, six>=1.10.0
  ipdb==0.13.3              requires ipython<6.0.0,>=5.1.0, setuptools
  filelock==3.0.12          requires -
  prometheus-client==0.7.1  requires -
  cryptography==2.9.2       requires cffi!=1.11.3,>=1.8, enum34; python_version < "3", ipaddress; python_version < "3", six>=1.4.1
  atomicwrites==1.4.0       requires -
  funcsigs==1.0.2           requires -
  chardet==3.0.4            requires -
  oauthlib==3.1.0           requires -
  backports.tempfile==1.0   requires backports.weakref
  ipaddress==1.0.23         requires -
  debtcollector==1.22.0     requires funcsigs>=1.0.0; python_version == "2.7" or python_version == "2.6", pbr!=2.1.0,>=2.0.0, six>=1.10.0, wrapt>=1.7.0
  botocore==1.12.253        requires docutils<0.16,>=0.10, jmespath<1.0.0,>=0.7.1, python-dateutil<3.0.0,>=2.1; python_version >= "2.7", urllib3<1.26,>=1.20; python_version == "2.7"
  importlib-metadata==1.7.0 requires configparser>=3.5; python_version < "3", contextlib2; python_version < "3", pathlib2; python_version < "3", zipp>=0.5
  boto3==1.9.174            requires botocore<1.13.0,>=1.12.174, jmespath<1.0.0,>=0.7.1, s3transfer<0.3.0,>=0.2.0
  logutils==<IP_ADDRESS>         requires -

New dependencies found in this round:
  adding [u'appdirs', '<2,>=1.4.3', '[]']
  adding [u'aws-sam-translator', '>=1.25.0', '[]']
  adding [u'backports.shutil-get-terminal-size', '', '[]']
  adding [u'backports.ssl-match-hostname', '>=3.5', '[]']
  adding [u'backports.weakref', '', '[]']
  adding [u'botocore', '<1.13.0,<2.0.0,>=1.11.3,>=1.12.174,>=1.12.36,>=1.12.86', '[]']
  adding [u'configparser', '>=3.5', '[]']
  adding [u'cookies', '', '[]']
  adding [u'decorator', '', '[]']
  adding [u'distlib', '<1,>=0.3.0', '[]']
  adding [u'ecdsa', '<1.0', '[]']
  adding [u'filelock', '<4,>=3.0.0', '[]']
  adding [u'funcsigs', '>=1,>=1.0.0', '[]']
  adding [u'importlib-resources', '>=1.0,~=1.4', '[]']
  adding [u'ipaddress', '>=1.0.16', '[]']
  adding [u'jsonpatch', '', '[]']
  adding [u'jsonpickle', '', '[]']
  adding [u'jsonschema', '~=3.0', '[]']
  adding [u'junit-xml', '~=1.9', '[]']
  adding [u'markupsafe', '>=0.23', '[]']
  adding [u'networkx', '<=2.2', '[]']
  adding [u'pathlib2', '<3,>=2.2.0,>=2.3.0,>=2.3.3', '[]']
  adding [u'pexpect', '', '[]']
  adding [u'pickleshare', '', '[]']
  adding [u'prompt-toolkit', '<2.0.0,>=1.0.4', '[]']
  adding [u'pygments', '<2.6', '[]']
  adding [u'pyparsing', '>=2.0.2,>=2.1.0', '[]']
  adding [u'requests', '!=2.12.2,!=2.18.0,<3,>=1.1,>=2,>=2.0,>=2.0.0,>=2.10.0,>=2.14.2,>=2.18.0,>=2.5', '[]']
  adding [u'rsa', '', '[]']
  adding [u'setuptools', '>=18.5', '[]']
  adding [u'simplegeneric', '>0.8', '[]']
  adding [u'six', '<2,<2.0,<2.0.0,>1.9,>=1.0.0,>=1.10.0,>=1.14.0,>=1.2,>=1.4.0,>=1.4.1,>=1.5,>=1.5.2,>=1.9.0,~=1.11', '[]']
  adding [u'traitlets', '>=4.2', '[]']
  adding [u'websocket-client', '>=0.32.0', '[]']
  adding [u'zipp', '>=0.4,>=0.5', '[]']
Removed dependencies in this round:
  removing [u'botocore', '<1.13.0,<2.0.0,>=1.12.174,>=1.12.36,>=1.12.86', '[]']
  removing [u'filelock', '>=3.0.0', '[]']
  removing [u'funcsigs', '>=1.0.0', '[]']
  removing [u'importlib-resources', '', '[]']
  removing [u'ipaddress', '', '[]']
  removing [u'pathlib2', '>=2.2.0', '[]']
  removing [u'pyparsing', '>=2.1.0', '[]']
  removing [u'requests', '!=2.12.2,<3,>=1.1,>=2,>=2.0.0,>=2.10.0,>=2.14.2,>=2.18.0,>=2.5', '[]']
  removing [u'setuptools', '', '[]']
  removing [u'six', '>1.9,>=1.10.0,>=1.14.0,>=1.2,>=1.4.1,>=1.5,>=1.5.2,>=1.9.0', '[]']
  removing [u'zipp', '>=0.4', '[]']
------------------------------------------------------------
Result of round 2: not stable

                          ROUND 3
Current constraints:
  agentarchives==0.6.0 (from -r base.txt (line 7))
  appdirs<2,>=1.4.3 (from virtualenv==20.0.25->tox==3.16.1->-r test.in (line 9))
  atomicwrites>=1.0 (from pytest==3.8.0->-r test.in (line 4))
  attrs>=17.4.0 (from pytest==3.8.0->-r test.in (line 4))
  aws-sam-translator>=1.25.0 (from cfn-lint==0.33.2->moto==1.3.8->-r test.in (line 13))
  aws-xray-sdk!=0.96,>=0.93 (from moto==1.3.8->-r test.in (line 13))
  babel!=2.4.0,==2.8.0,>=2.3.4 (from -r base.txt (line 8))
  backports.shutil-get-terminal-size (from ipython==5.10.0->ipdb==0.13.3->-r test.in (line 11))
  backports.ssl-match-hostname>=3.5 (from docker==4.2.2->moto==1.3.8->-r test.in (line 13))
  backports.tempfile (from moto==1.3.8->-r test.in (line 13))
  backports.weakref (from backports.tempfile==1.0->moto==1.3.8->-r test.in (line 13))
  bagit==1.7.0 (from -r base.txt (line 9))
  boto>=2.36.0 (from moto==1.3.8->-r test.in (line 13))
  boto3==1.9.174,>=1.9.86 (from -r base.txt (line 10))
  botocore<1.13.0,<2.0.0,==1.12.253,>=1.11.3,>=1.12.174,>=1.12.36,>=1.12.86 (from -r base.txt (line 11))
  brotli==0.5.2 (from -r base.txt (line 12))
  certifi==2020.6.20,>=2017.4.17 (from -r base.txt (line 13))
  cffi!=1.11.3,==1.14.0,>=1.8 (from -r base.txt (line 14))
  cfn-lint (from moto==1.3.8->-r test.in (line 13))
  chardet<3.1.0,==3.0.4,>=3.0.2 (from -r base.txt (line 15))
  click>=6 (from pip-tools==3.7.0->-r test.in (line 12))
  configparser>=3.5 (from importlib-metadata==1.7.0->tox==3.16.1->-r test.in (line 9))
  contextlib2==0.6.0.post1 (from -r base.txt (line 16))
  cookies (from responses==0.10.15->moto==1.3.8->-r test.in (line 13))
  coverage==4.2,>=3.7.1 (from -r test.in (line 6))
  cryptography==2.9.2,>=2.3.0,>=2.8 (from -r base.txt (line 17))
  debtcollector==1.22.0,>=1.2.0 (from -r base.txt (line 18))
  decorator (from ipython==5.10.0->ipdb==0.13.3->-r test.in (line 11))
  defusedxml==0.5.0 (from -r base.txt (line 19))
  distlib<1,>=0.3.0 (from virtualenv==20.0.25->tox==3.16.1->-r test.in (line 9))
  django==1.11.29,>=1.8,>=1.8.0 (from -r base.txt (line 25))
  django-auth-ldap==1.3.0 (from -r base.txt (line 20))
  django-extensions==1.7.9 (from -r base.txt (line 21))
  django-prometheus==1.0.15 (from -r base.txt (line 22))
  django-shibboleth-remoteuser from git+https://github.com/Brown-University-Library/django-shibboleth-remoteuser.git@67d270c65c201606fb86d548493d4b3fd8cc7a76#egg=django-shibboleth-remoteuser (from -r base.txt (line 23))
  django-tastypie==0.14.3 (from -r base.txt (line 24))
  docker>=2.5.1 (from moto==1.3.8->-r test.in (line 13))
  docutils<0.16,==0.15.2,>=0.10 (from -r base.txt (line 26))
  ecdsa<1.0 (from python-jose==3.1.0->moto==1.3.8->-r test.in (line 13))
  enum34==1.1.10,>=1.0.4 (from -r base.txt (line 27))
  filelock<4,>=3.0.0 (from tox==3.16.1->-r test.in (line 9))
  funcsigs==1.0.2,>=1,>=1.0.0 (from -r base.txt (line 28))
  functools32 (from -r test.in (line 14))
  future==0.18.2 (from -r base.txt (line 29))
  futures<4.0.0,==3.3.0,>=2.2.0,>=3.0 (from -r base.txt (line 30))
  gevent==1.3.6 (from -r base.txt (line 31))
  greenlet==0.4.16,>=0.4.14 (from -r base.txt (line 32))
  gunicorn==19.9.0 (from -r base.txt (line 33))
  httplib2==0.18.1 (from -r base.txt (line 34))
  idna<2.9,==2.8,>=2.5 (from -r base.txt (line 35))
  importlib-metadata<2,>=0.12 (from tox==3.16.1->-r test.in (line 9))
  importlib-resources==3.0.0,>=1.0,~=1.4 (from -r base.txt (line 36))
  ipaddress==1.0.23,>=1.0.16 (from -r base.txt (line 37))
  ipdb (from -r test.in (line 11))
  ipython<6.0.0,>=5.1.0 (from ipdb==0.13.3->-r test.in (line 11))
  iso8601==0.1.12,>=0.1.11 (from -r base.txt (line 38))
  Jinja2>=2.10.1 (from moto==1.3.8->-r test.in (line 13))
  jmespath<1.0.0,==0.10.0,>=0.7.1 (from -r base.txt (line 39))
  jsondiff==1.1.2 (from moto==1.3.8->-r test.in (line 13))
  jsonfield==2.0.1 (from -r base.txt (line 40))
  jsonpatch (from cfn-lint==0.33.2->moto==1.3.8->-r test.in (line 13))
  jsonpickle (from aws-xray-sdk==2.6.0->moto==1.3.8->-r test.in (line 13))
  jsonschema~=3.0 (from cfn-lint==0.33.2->moto==1.3.8->-r test.in (line 13))
  junit-xml~=1.9 (from cfn-lint==0.33.2->moto==1.3.8->-r test.in (line 13))
  keystoneauth1==4.0.1,>=2.18.0 (from -r base.txt (line 41))
  logutils==<IP_ADDRESS> (from -r base.txt (line 42))
  longerusername from git+https://github.com/seatme/django-longer-username.git@seatme#egg=longerusername (from -r base.txt (line 43))
  lxml==3.7.3 (from -r base.txt (line 44))
  MarkupSafe>=0.23 (from Jinja2==2.11.2->moto==1.3.8->-r test.in (line 13))
  metsrw==0.3.15 (from -r base.txt (line 45))
  mock (from moto==1.3.8->-r test.in (line 13))
  monotonic==1.5,>=0.6 (from -r base.txt (line 46))
  more-itertools>=4.0.0 (from pytest==3.8.0->-r test.in (line 4))
  moto==1.3.8 (from -r test.in (line 13))
  msgpack==1.0.0,>=0.5.2 (from -r base.txt (line 47))
  mysqlclient<2,==1.4.6,>=1.3 (from -r base.txt (line 48))
  ndg-httpsclient==0.4.2 (from -r base.txt (line 49))
  netaddr==0.8.0,>=0.7.18 (from -r base.txt (line 50))
  netifaces==0.10.9,>=0.10.4 (from -r base.txt (line 51))
  networkx<=2.2 (from cfn-lint==0.33.2->moto==1.3.8->-r test.in (line 13))
  oauthlib==3.1.0,>=3.0.0 (from -r base.txt (line 52))
  os-service-types==1.7.0,>=1.2.0 (from -r base.txt (line 53))
  oslo.config!=3.18.0,==7.0.0,>=3.14.0 (from -r base.txt (line 54))
  oslo.i18n==3.25.1,>=2.1.0,>=3.15.3 (from -r base.txt (line 55))
  oslo.serialization==2.29.2,>=1.10.0 (from -r base.txt (line 56))
  oslo.utils==3.42.1,>=3.18.0,>=3.33.0 (from -r base.txt (line 57))
  packaging>=14 (from tox==3.16.1->-r test.in (line 9))
  pathlib2<3,==2.3.5,>=2.2.0,>=2.3.0,>=2.3.3 (from -r base.txt (line 58))
  pbr!=2.1.0,==5.4.5,>=1.8,>=2.0.0 (from -r base.txt (line 59))
  pexpect (from ipython==5.10.0->ipdb==0.13.3->-r test.in (line 11))
  pickleshare (from ipython==5.10.0->ipdb==0.13.3->-r test.in (line 11))
  pip-tools==3.7.0 (from -r test.in (line 12))
  pluggy>=0.12.0,>=0.7 (from tox==3.16.1->-r test.in (line 9))
  positional==1.2.1,>=1.1.1 (from -r base.txt (line 60))
  prometheus-client==0.7.1,>=0.0.21 (from -r base.txt (line 61))
  prompt-toolkit<2.0.0,>=1.0.4 (from ipython==5.10.0->ipdb==0.13.3->-r test.in (line 11))
  py>=1.4.17,>=1.5.0 (from tox==3.16.1->-r test.in (line 9))
  pyasn1<0.5.0,==0.4.8,>=0.3.7,>=0.4.6 (from -r base.txt (line 63))
  pyasn1-modules==0.2.8,>=0.1.5 (from -r base.txt (line 62))
  pycparser==2.20 (from -r base.txt (line 64))
  pygments<2.6 (from ipython==5.10.0->ipdb==0.13.3->-r test.in (line 11))
  pyopenssl==19.1.0 (from -r base.txt (line 65))
  pyparsing==2.4.7,>=2.0.2,>=2.1.0 (from -r base.txt (line 66))
  pytest==3.8.0,>=2.6.0,>=2.7,>=3.6 (from -r test.in (line 4))
  pytest-cov==2.4.0 (from -r test.in (line 5))
  pytest-django (from -r test.in (line 7))
  pytest-mock<2,>=1 (from -r test.in (line 8))
  python-dateutil!=2.0,<3.0.0,==2.8.1,>=1.5,>=2.1 (from -r base.txt (line 67))
  python-gnupg==0.4.0 (from -r base.txt (line 68))
  python-jose<4.0.0 (from moto==1.3.8->-r test.in (line 13))
  python-keystoneclient==3.10.0 (from -r base.txt (line 69))
  python-ldap==3.2.0,>=2.0 (from -r base.txt (line 70))
  python-mimeparse!=1.5,==1.6.0,>=0.1.4 (from -r base.txt (line 71))
  python-swiftclient==3.3.0 (from -r base.txt (line 72))
  pytz==2020.1,>=2013.6,>=2015.7 (from -r base.txt (line 73))
  pyyaml==5.3.1,>=3.12 (from -r base.txt (line 74))
  requests!=2.12.2,!=2.18.0,<3,==2.21.0,>=1.1,>=2,>=2.0,>=2.0.0,>=2.10.0,>=2.14.2,>=2.18.0,>=2.5 (from -r base.txt (line 76))
  requests-oauthlib==1.2.0 (from -r base.txt (line 75))
  responses>=0.9.0 (from moto==1.3.8->-r test.in (line 13))
  rfc3986==1.4.0,>=1.2.0 (from -r base.txt (line 77))
  rsa (from python-jose==3.1.0->moto==1.3.8->-r test.in (line 13))
  s3transfer<0.3.0,==0.2.1,>=0.2.0 (from -r base.txt (line 78))
  scandir==1.10.0 (from -r base.txt (line 79))
  setuptools>=18.5 (from ipdb==0.13.3->-r test.in (line 11))
  simplegeneric>0.8 (from ipython==5.10.0->ipdb==0.13.3->-r test.in (line 11))
  singledispatch==<IP_ADDRESS> (from -r base.txt (line 80))
  six<2,<2.0,<2.0.0,==1.15.0,>1.9,>=1.0.0,>=1.10.0,>=1.14.0,>=1.2,>=1.4.0,>=1.4.1,>=1.5,>=1.5.2,>=1.9.0,~=1.11 (from -r base.txt (line 81))
  stevedore==1.32.0,>=1.17.1,>=1.20.0 (from -r base.txt (line 82))
  sword2==0.2.1 (from -r base.txt (line 83))
  toml>=0.9.4 (from tox==3.16.1->-r test.in (line 9))
  tox (from -r test.in (line 9))
  traitlets>=4.2 (from ipython==5.10.0->ipdb==0.13.3->-r test.in (line 11))
  typing==<IP_ADDRESS> (from -r base.txt (line 84))
  urllib3<1.25,<1.26,==1.24.3,>=1.20,>=1.21.1 (from -r base.txt (line 85))
  vcrpy>=1.0.0 (from -r test.in (line 10))
  virtualenv!=20.0.0,!=20.0.1,!=20.0.2,!=20.0.3,!=20.0.4,!=20.0.5,!=20.0.6,!=20.0.7,>=16.0.0 (from tox==3.16.1->-r test.in (line 9))
  websocket-client>=0.32.0 (from docker==4.2.2->moto==1.3.8->-r test.in (line 13))
  werkzeug (from moto==1.3.8->-r test.in (line 13))
  whitenoise==3.3.0 (from -r base.txt (line 86))
  wrapt==1.12.1,>=1.7.0 (from -r base.txt (line 87))
  xmltodict (from moto==1.3.8->-r test.in (line 13))
  zipp==1.2.0,>=0.4,>=0.5 (from -r base.txt (line 88))

Finding the best candidates:
  found candidate agentarchives==0.6.0 (constraint was ==0.6.0)
  found candidate appdirs==1.4.4 (constraint was >=1.4.3,<2)
  found candidate atomicwrites==1.4.0 (constraint was >=1.0)
  found candidate attrs==19.3.0 (constraint was >=17.4.0)
  found candidate aws-sam-translator==1.25.0 (constraint was >=1.25.0)
  found candidate aws-xray-sdk==2.6.0 (constraint was >=0.93,!=0.96)
  found candidate babel==2.8.0 (constraint was >=2.3.4,!=2.4.0,==2.8.0)
  found candidate backports.shutil-get-terminal-size==1.0.0 (constraint was <any>)
  found candidate backports.ssl-match-hostname==<IP_ADDRESS> (constraint was >=3.5)
  found candidate backports.tempfile==1.0 (constraint was <any>)
  found candidate backports.weakref==1.0.post1 (constraint was <any>)
  found candidate bagit==1.7.0 (constraint was ==1.7.0)
  found candidate boto==2.49.0 (constraint was >=2.36.0)
  found candidate boto3==1.9.174 (constraint was ==1.9.174,>=1.9.86)
  found candidate botocore==1.12.253 (constraint was >=1.11.3,>=1.12.174,==1.12.253,>=1.12.36,>=1.12.86,<1.13.0,<2.0.0)
  found candidate brotli==0.5.2 (constraint was ==0.5.2)
  found candidate certifi==2020.6.20 (constraint was >=2017.4.17,==2020.6.20)
  found candidate cffi==1.14.0 (constraint was !=1.11.3,==1.14.0,>=1.8)
  found candidate cfn-lint==0.33.2 (constraint was <any>)
  found candidate chardet==3.0.4 (constraint was >=3.0.2,==3.0.4,<3.1.0)
  found candidate click==7.1.2 (constraint was >=6)
  found candidate configparser==4.0.2 (constraint was >=3.5)
  found candidate contextlib2==0.6.0.post1 (constraint was ==0.6.0.post1)
  found candidate cookies==2.2.1 (constraint was <any>)
  found candidate coverage==4.2 (constraint was >=3.7.1,==4.2)
  found candidate cryptography==2.9.2 (constraint was >=2.3.0,>=2.8,==2.9.2)
  found candidate debtcollector==1.22.0 (constraint was >=1.2.0,==1.22.0)
  found candidate decorator==4.4.2 (constraint was <any>)
  found candidate defusedxml==0.5.0 (constraint was ==0.5.0)
  found candidate distlib==0.3.1 (constraint was >=0.3.0,<1)
  found candidate django==1.11.29 (constraint was ==1.11.29,>=1.8,>=1.8.0)
  found candidate django-auth-ldap==1.3.0 (constraint was ==1.3.0)
  found candidate django-extensions==1.7.9 (constraint was ==1.7.9)
  found candidate django-prometheus==1.0.15 (constraint was ==1.0.15)
  found candidate git+https://github.com/Brown-University-Library/django-shibboleth-remoteuser.git@67d270c65c201606fb86d548493d4b3fd8cc7a76#egg=django-shibboleth-remoteuser (constraint was <any>)
  found candidate django-tastypie==0.14.3 (constraint was ==0.14.3)
  found candidate docker==4.2.2 (constraint was >=2.5.1)
  found candidate docutils==0.15.2 (constraint was >=0.10,==0.15.2,<0.16)
  found candidate ecdsa==0.15 (constraint was <1.0)
  found candidate enum34==1.1.10 (constraint was >=1.0.4,==1.1.10)
  found candidate filelock==3.0.12 (constraint was >=3.0.0,<4)
  found candidate funcsigs==1.0.2 (constraint was >=1,>=1.0.0,==1.0.2)
  found candidate functools32==3.2.3.post2 (constraint was <any>)
  found candidate future==0.18.2 (constraint was ==0.18.2)
  found candidate futures==3.3.0 (constraint was >=2.2.0,>=3.0,==3.3.0,<4.0.0)
  found candidate gevent==1.3.6 (constraint was ==1.3.6)
  found candidate greenlet==0.4.16 (constraint was >=0.4.14,==0.4.16)
  found candidate gunicorn==19.9.0 (constraint was ==19.9.0)
  found candidate httplib2==0.18.1 (constraint was ==0.18.1)
  found candidate idna==2.8 (constraint was >=2.5,==2.8,<2.9)
  found candidate importlib-metadata==1.7.0 (constraint was >=0.12,<2)
Could not find a version that matches importlib-resources==3.0.0,>=1.0,~=1.4 (from -r base.txt (line 36))
Tried: 0.2, 0.2, 0.3, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.8, 1.0, 1.0.1, 1.0.1, 1.0.2, 1.0.2, 1.1.0, 1.1.0, 1.2.0, 1.2.0, 1.3.0, 1.3.0, 1.3.1, 1.3.1, 1.4.0, 1.4.0, 1.5.0, 1.5.0, 2.0.0, 2.0.0, 2.0.1, 2.0.1, 3.0.0, 3.0.0
There are incompatible versions in the resolved dependencies:
  importlib-resources==3.0.0 (from -r base.txt (line 36))
  importlib_resources~=1.4 (from cfn-lint==0.33.2->moto==1.3.8->-r test.in (line 13))
  importlib-resources>=1.0 (from virtualenv==20.0.25->tox==3.16.1->-r test.in (line 9))
  importlib-resources (from netaddr==0.8.0->-r base.txt (line 50))

Hello @ross-spencer,
Thanks for the issue! Regarding the output:
importlib-resources==3.0.0 (from -r base.txt (line 36))

the importlib-resources came from base.txt (though I can't see it in base.txt, actually).
However, since cfn-lint wants importlib_resources~=1.4, you can add this requirement to the base.in. That might help.

Thank you @atugushev that worked and I was able to compile the project's requirements. I appreciate the help there.

I'll close this based on the above. Thanks!


Implement expand & contract functions

VR instances have two forms, inlined and referential.
Inlined instances are self-contained, except for a reference to an external sequence.
Referential instances reference objects by id, which requires storage that is external to the instance.
The two forms need to be convertible in the reference implementation.

to_inlined(s, ro, keep_reference_ids=False, keep_self_ids=False) builds an inlined object using the given referential object ro and instances in storage s. keep_reference_ids controls whether the reference ids are preserved. keep_self_ids controls whether instance id attributes are removed from inlined representations.

to_referential(s, io) adds inlined object io to s and returns a referential object.

No longer relevant in current model.


Enhancement request : offset in specified axis only

There are a number of applications where I'd like to be able to offset geometry in only one axis (X or Y). I can't find my way through the code to implement this myself, so hoped an enhancement request might not be out of line.

Hi again Phil. This is already possible using the new DeltaCallback feature.

Oops, the new DeltaCallback feature would only work if all the edges were axis aligned.
Nevertheless, I think this could be very easily implemented by just zeroing either the x or y values in the norms array (see BuildNormals() in clipper.offset.cs).
However, I'm unlikely to implement this as an option in the Clipper2 unless I can be persuaded that this has significant (ie more general) appeal.

I'm looking forward to an example. I'd seen the variable offset thing and hadn't appreciated that this would be related.
For the  question about non-axis-aligned, I'd argue that Clipper2 is remarkably capable of processing arbitrary geometry - it would be a little peculiar to have restrictions (that the user may not be aware of) in one part of it.
In my case, for example, almost all of my cases are non-orthogonal (e.g. rounded corners, keyholes, elliptical ends, rotated shapes) based on the particular configuration at that point in time. Geometry is also not necessarily under my control (e.g. imported from external sources), which are universally not-orthogonal as a result of the external treatment (simulators) that generate the output.
Further, I can have mixed output - some polygons being orthogonal (but not axis aligned due to rotations), some orthogonal and axis-aligned, and then the not-orthogonal polygons in the set-up as well. Having some of these, to the user, randomly offset, and others not would probably yield bug reports aplenty. It wouldn't make sense to them and they would not really have a way to mitigate it up front.
With an example in hand, I can try your suggestion re. the normals and perhaps supply a PR for consideration to limit/eliminate any divergence from your library on my side. Currently, I'm not entirely sure how to use the existing feature :)

Nevertheless, I think this could be very easily implemented by just ...

I've just spent 2 days trying to implement this only to discover that it's really very difficult, except perhaps with mitered offsets.
However, I do think there's a much better (simpler and faster) way to achieve the same result.
Here's an example ...
      double delta = 50;
      Paths64 subject = new Paths64();
      subject.Add(Clipper.Ellipse(new Point64(500, 500), 450));
      Paths64 solution = Clipper.InflatePaths(subject, delta, JoinType.Square, EndType.Polygon);

      // undo horizontal offsetting
      Rect64 rec = Clipper.GetBounds(subject);
      rec.top -= (int) delta;
      rec.bottom += (int) delta;
      for (int i = 0; i < solution.Count; i++)
      {
        Paths64 sol = Clipper.ExecuteRectClip(rec, solution[i]);
        if (sol != null) solution[i] = sol[0]; else solution[i] = null;
      }

Interesting, I'd assumed that extracting normals and projecting to the world X or Y axis would have been enough to extract the relevant scaling factor in that direction (which is what I think your zeroing irrelevant normals would do), although I admit I was struggling to reconcile the 90 degree orthogonal corner case.
Still, an example of the variable offset callback usage would also be helpful to kick the tires on that.
I'm also not sure that that approach works. For example, inputting an orthogonal shape like this:
        PathD original = new()
        {
            new(0, 0),
            new(0, 100),
            new(40, 100),
            new(40, 60),
            new(60, 60),
            new(60, 100),
            new(100, 100),
            new(100, 0),
            new(0, 0)
        };

breaks down - the notch appears to be lost:
100 150
100 -50
0 -50
0 150
40 150
41.920000000000002<PHONE_NUMBER>0000001
43.840000000000003<PHONE_NUMBER>9999999
45.759999999999998<PHONE_NUMBER>0000002
47.660000000000004 149.41
49.560000000000002<PHONE_NUMBER>0000001
50<PHONE_NUMBER>9999999
50.75<PHONE_NUMBER>0000001
52.649999999999999<PHONE_NUMBER>0000001
54.560000000000002<PHONE_NUMBER>0000002
56.469999999999999 149.88
58.390000000000001 149.97
60 150

I'd assumed that extracting normals and projecting

That was my thought too, until I started implementing it.
While it works well for miter joins, it doesn't for square and round joins (at least not well).

I'm also not sure that that approach works. For example, inputting an orthogonal shape like this

Yep, that's no good.
I presume that simple scaling is no good for you.
Otehrwise I'm pretty much out of ideas.

Miter might well be good enough - it's what I tend to use to avoid artifacts. I'd be interested to at least take it for a test run. Was that a dedicated implementation, or were you using the offset callback system?

Unfortunately, just mitering isn't possible because narrow angled vertices will still require squaring.

So, just for the sake of curiosity, do you have an example of offsetting by-normal in that callback? It might not be perfect, but it would be a useful indicator of usage, perhaps.

It works reasonably well, but only for non-orthoganal shapes.
  Paths64 subject = { Ellipse(Rect64(50,50,450,450))};
  //Paths64 subject = { MakePath({100,0, 100,100, 70,100, 70,60, 30,60, 30,100, 0,100, 0,0}) };
  Paths64 solution;

  ClipperOffset co;
  co.AddPaths(subject, JoinType::Miter, EndType::Polygon);
  co.Execute(
    [](const Path64& path,
      const PathD& path_norms, size_t curr_idx, size_t prev_idx) {
        return Sqr(path_norms[curr_idx].y + path_norms[prev_idx].y) * 10; }
  , solution);

  SvgWriter svg;
  SvgAddSubject(svg, subject, FillRule::NonZero);
  SvgAddSolution(svg, solution, FillRule::NonZero, false);
  SvgSaveToFile(svg, "tmp.svg", 400,400, 50);
  System("tmp.svg");

Neat. I'll take it for a spin. One surprise is that the offset seems to be baked into the callback, rather than provided as part of the call to the callback itself. Was that deliberate?

I wonder if allowing the callback to adjust the normals would help, or alternately to provide a Point instance that has the relevant offset values in X and Y. From goofing around, the issue would appear to be that orthogonal geometry is expanded in all directions because it's not possible to zero one vs the other. I see the normals are showing up as [0 or (+/-)1, 0 or (+/-)1], so the expansion in both directions isn't immediately obvious (I thought I might see 45 degree normals, for example).
Just trying to see if there might be an avenue somewhere to allow the offset to be steered externally, without causing major disruption in the core code itself. If the user can own the customizations entirely in the callback, you wouldn't need to worry about it, would you?

Phil, I've exhausted myself of ideas here.
I believe you'd need to do a significant rewrite to achieve what you're hoping for.

Hi, just a comment - if I understand your use-case correctly, I think that it can be implemented by performing a convex decomposition of the input polygon. Then, for each of the convex parts, you can split them at the e.g. leftmost/rightmost edge/vertex, and shift the upper and lower portions. The result is the union of the processed parts. The problem could be considered as a simple special case of the minkowski sum.

@mmassing : That gets fairly close, but I'm puzzled by the lateral expansion here:

The original shape and path are:
        PathD original = new()
        {
            new(0, 0),
            new(0, 100),
            new(40, 100),
            new(40, 60),
            new(60, 30),
            new(40, 0),
            new(0, 0)
        };

        PathD vector = new()
        {
            new(0.0, 0.0),
            new PointD(0.0, 10.0)
        };

        var result = Minkowski.Sum(original, vector, true);

Something odd also happens if I insert a notch:

        PathD original = new()
        {
            new(0, 0),
            new (0, 50),
            new (20,50),
            new (20, 80),
            new (0,80),
            new(0, 100),
            new(40, 100),
            new(40, 60),
            new(60, 30),
            new(40, 0),
            new(0, 0)
        };

        PathD vector = new()
        {
            new(0.0, 0.0),
            new PointD(0.0, 10.0)
        };

        PathsD result = Minkowski.Sum(original, vector, true);

At the risk of spamming the issue, if I run the Minkowski sum with an inverted vector, and combine the results, I get, in principle, what I'm looking for (bar the horizontal expansion, but I can see how that happens and will make peace with it).

        PathD original = new()
        {
            new(0, 0),
            new (0, 50),
            new (20,50),
            new (20, 80),
            new (0,80),
            new(0, 100),
            new(40, 100),
            new(40, 60),
            new(60, 30),
            new(40, 0),
            new(0, 0)
        };

        PathsD original_ = new();
        original_.Add(original);

        PathD vector = new()
        {
            new(0.0, 0.0),
            new PointD(0.0, 10.0)
        };

        PathD vector2 = new()
        {
            new(0.0, 0.0),
            new PointD(0.0, -10.0)
        };

        PathsD result = Minkowski.Sum(original, vector, true);

        PathsD result_i = Minkowski.Sum(original, vector2, true);

        result.AddRange(result_i);


Feature/fix bug

Codecov Report

Merging #9 into master will not change coverage.
The diff coverage is 100%.

@@          Coverage Diff          @@
##           master     #9   +/-   ##
=====================================
  Coverage     100%   100%
=====================================
  Files           4      4
  Lines         244    244
=====================================
  Hits          244    244

Impacted Files
Coverage Δ

torchpipe/core.py
100% <100%> (ø)
:arrow_up:

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update d500b70...3cec1c7. Read the comment docs.


Create React App Gone From React.dev, What happens to it now?

I noticed CRA is gone from https://react.dev/learn/start-a-new-react-project
But there are lots of tutorials based on it.
(I literally just had a book printed that uses it because of wanting to teach react with a minimal toolchain.)
There had been a variety of options forward shared here: https://github.com/reactjs/reactjs.org/pull/5487#issuecomment-1409720741
This suggested there would be an RFC. Was there one?
It seems like "Option 3: Deprecate Create React App, suggest React frameworks" has become the reality, at least in the docs.
Is there an RFC somewhere?/What is the plan for CRA?

Good luck getting information - haven't seen a dev on here in a long time.
The biggest issue is that this project has been dead for a while, but it still isn't deprecated.  An RFC or a "rebirth" of CRA might be in the future, but that doesn't solve the issue that has been plaguing new react users: being told to work with a buggy and restrictive starter template.  Look at the amount of issues on this repo. So many of them are new people not being able to even run CRA.  So many of these people give up on React due to their experience with CRA.
This repo needs to be deprecated.  Maybe it can come back if there is an RFC or "rebirth" that was completed and ready to be shipped, but until then, it needs to be clear that this repo shouldn't be used.

we need this package, it is very useful for the beginner to set up the react and learn react not any framework.
If we go to start a new react project page they directly mention use a framework to build react project, so now the beginner will be confused about what needs to be learned first framework or ReactJs.

we need this package, it is very useful for the beginner to set up the react and learn react not any framework. If we go to start a new react project page they directly mention use a framework to build react project, so now the beginner will be confused about what needs to be learned first framework or ReactJs.

I kind of agree, but I think the documentation goes over this.  There is a difference between learning react and building an actual project you care about.   The react docs now have lots of build in sandbox examples/lessons for people to be able to experiment on. They also link to online sandbox environments for people to play around and learn with.  Being able to go to a sandbox environment that you can save and come back to later (accessible on any computer) is simply a lot easier than having to download a template, install the modules through either npm, yarn, or pnpm, and then have to do it again if you need to access the code outside of that one machine you are using.
Back when I was in college, I had to use the library computers a lot and did not have access to my PC. I ended up remoting into my PC from the library computers, but that took work that many people don't initially think about doing.  How easy is it now that we can just go to a sandbox website, save a project for free, and then just go to that website at the library to continue working?  This is the same thing as Microsoft Word vs Google Docs.  One is online, easily accessible, and sharable.  The only is installed locally and can be a pain to collaborate with others on.  This is why the React team recommends using online sandbox environments for learning/playing around:

Now I think there is a major point that makes me slightly hesitant to recommend any SPA template - React is moving away from SPAs.  The past year or so, the React team has been working hard on finishing up RFCs that relate to Server Components.   This is the main RFC, but there are many other supplemental ones like this RFC.  The reality is that just like Hooks shook up the React ecosystem and really helped React as a whole, Server Components are going to do the same thing.  React is going into a direction of having both Client and Server Components intermingling and making up the application.  I say this because Server Components are not compatible with SPAs.  Create React App is an SPA template.  As it is now, people who learn from Create React App are going to only learn a subsection about what React offers.  And what is worse, is that people are creatures of habit.  When we learn to do something one way, we don't always want to change that.  So limiting the scope of potential knowledge for a beginner could lead to bad or outdated habits.
Examples of why CRA is bad for beginners:
Lastly, why do you think CRA is good for beginners?  It is very narrow minded in the sense that it offers very little to the user at the beginning.  Sure it builds the project, allows for a dev mode with HMR, and has environment variables set up, but that's mainly it.  Literally every solution offers that as a base.  What happens when you want to add another page to a CRA project? Now you have to learn a router package.  Which one? Time to research packages.
CRA 1 example:
So the person types into Google "react add new url for page" because they don't know the term "router" yet.  Sure enough a tutorial pops up for React Router.

Edit: real quick, just wanted to make sure this example was 1-to-1 with its counterpart below, so I changed the search criteria to "create react app add new url for page". It still resulted in the same search results as above:

Lets look at the tutorial,

First they are using "yarn".  Wtf is yarn? Is it like npm? How do I get it? In the other tutorial from 2016, I was told to use npm. Is it the same? "npm add react-router-dom" isn't working.
What is up with Bulma? Now we are bringing in something called Bulma.  Do I need to learn that to make the url work?
This tutorial is from 2020. Is it outdated? I don't know.

NextJS example:
Now lets looks at the same issue, but lets assume the user is now using NextJS instead of CRA.  Type in "nextjs add new url for page".  On my end, Google looks like this:

Great. Lets look at the top link.

Oh it says to click on the Router documentation before reading further.  Lets click the link.

Oh, now I have an official tutorial by the same framework devs that I am using.  It goes over literally everything I need to know (without installing new packages).  I can learn a new concept called Routing without running into a issues not related to Routing.

CRA 2 example (aka the Try To Show CRA In The Best Light example):
Now for this last example, I am going to be as nice to Create React App as I can. Lets do the same issue (I want to learn about Routers and creating a new Route to a component), but now I know that the concept is called Routing and I decide to look through the Create React App's documentation website instead of using Google.
Oh hey, I found the Routing page on CRA's website:

Great. It has an npm command I can use to install and it has a yarn command that seems to be the equivalent.  How handy! I learned something new already :) .  I also see a link at the top telling me to use React Router. Let me click on it and learn about React Router.

Oh great.  Seems like they moved, lets click on the new link.

Cool! Looks like this is the website.  Let me quickly bring up the other link though.  On the CRA page, it said that "The Basic Example is a good place to get started."  So I learn better looking directly at code, so lets quickly click on the example link and if I run into anything hard, I will jump back to the official React Router page in my 2nd tab and read on up the issue.

Oh. Ok well the example link clearly goes to an example (I hovered over the link and saw the URL before clicking), but I am running into the same issue as before.  Let me just click this new link and see where it takes me.

Great... back at the React Router website.  Ok. So no examples for me. Let me at least click on the Tutorial section and see if I can add it to my app that way.

Wait... Wtf is Vite??? I am using CRA and now this tells me to use Vite? Can that fit into CRA? Now I need to research Vite (or go back to CRA 1 Example and follow that process).

I know I wrote a lot, but I am trying to show the issues in the easiest way possible.   It provides everything that CRA did in terms of learning.  If a user is going past the barebone basics (like setting up Routing), then CRA isn't the easiest solution for them.  It will cause headaches and make people want to leave the React ecosystem.  Using CRA burns out new react developers - it hurts more than it helps.
With all that said, if you want a almost 1-to-1 replace of CRA, but one that is actually being updated and has far more opportunities of growing your knowledge and project, use Vite.  But if you want to make sure you are learning all the features of React (including the new Server Components), your best bet is to migrate from an online sandbox to one of the Frameworks that the React Devs suggest.

@loren138 This is the closest thing we have to an official roadmap for create-react-app at this point: https://github.com/reactjs/react.dev/pull/5487#issuecomment-1409720741
To summarize, it will become a launcher for other recommended tools, rather than being a standalone tool.

Dan Abramov posted a thread on twitter that seems to answer this:
https://twitter.com/dan_abramov/status/1636827365677383700
Posting a little bit of it:

when i was thinking about possible futures for Create React App, it was clear client-only doesn’t make sense. way too limiting.
why are we always producing an empty HTML file if React can pre-render to HTML? why can’t i make a blog by map()ing over markdown files on my disk?
....
here’s the thing.
the current crop of modern frameworks (specifically, Next.js and Gatsby) already work this way.
they let you start 100% static + client. HTML generation, file-based routing, SPA navigations, and real client code (as much as you like). that’s the baseline.
however, if you do want to use the server for some dynamic route — like, reading from a DB instead of a file — they let you do that easily. you just change a couple of lines of code. your existing pages remain static/client.
frameworks provide LESS LOCK-IN in that sense.
so i realized that building this would just building a more limited version of what Next.js/Gatsby already have to offer. it would do exactly the same things they already do, but would not allow you to do more.
modern frameworks are hybrid. they let you build SPAs and more.
...

My summary, is CRA is dead because what he'd like to build is essentially what next.js and Gatsby already are.

Nope, it's actually my/my company's book https://www.amazon.com/React-Programming-Ranch-Guide-Guides/dp/0137901763/

I fully agree with the analysis of @getsalty !
Although I started to learn create-react-app without any pre-experience, I was running quickly into several limitations.
Now that I have a few years of React-experience, I am glad that more modern options are available.
More generally, I think it would be irresponsible to recommend a dead (or undead) framework to new developers, even if the framework still has many downloads.


[neo4j] count method performance problems

I'm seeing some severe performance issues with the count method on domain classes as the size of the data being counted increases.  Replicating the issue is straightforward:

Create a neo4j-mapped Person domain class with two properties: firstName, lastName

Insert 10,000 person records

Time how long a Person.count() method takes to execute

On a fairly beefy mac (2.53 GHz core 2 duo, 8 GB ram), I'm seeing the count method take 15 seconds, on average, for 10,000 records.

A static cypher query counting the Person instances executes in ~0.200 seconds against 10,000 records:
def population = Person.cypherStatic("start n=node({this}) match n-[:INSTANCE]->m return count(*) as population").iterator().next()['population']


Validation Renderer has no way to provide success styling

I'm submitting a feature request
Current behavior:
I am able to create a custom validation renderer that detects when an element has become invalid. With this we can apply error styling and then we can detect when that element is transitioning from an invalid state, back to a valid state and I can then apply success styling. As seen here:
    render(instruction: RenderInstruction) {
       for (let {error, elements} of instruction.unrender) {
            for (let element of elements) {
                this.remove(element, error);
            }
        }

        for (let {error, elements} of instruction.render) {
            for (let element of elements) {
                this.add(element, error);
            }
        }
    }

    private add(element: Element, error: ValidationError) {
        // Add error styling
    }

    private remove(element: Element, error: ValidationError) {
        // Remove error styling
        // Add success styling
    }

But how would I apply success styling when the element was never invalid? I can see in my custom renderer that the render function is called, but the RenderInstruction of kind "validate" contains no elements for me to add styling to. On a new form, on a valid field, the RenderInstruction provided to the render method on my custom renderer looks like this:
kind: "validate"
render: Array[0]
unrender:Array[0]

As you can see, I have no way of knowing which elements were validated successfully therefore cannot apply styling.
Perhaps adding an unrender() event on the ValidationRenderer or a new kind on RenderInstruction could work?

@jdanyow You may have a solution for this already but I marked this as an enhancement. Minimally, I think we would need some documentation on how to handle this.

Added this to the beta milestone- @Slimfit if you need an immediate workaround you could try doing something with the controller's bindings Map and it's getAssociatedElements method:
for ([binding] of controller.bindings) {
  const info = getPropertyInfo(binding.sourceExpression, binding.source);
  const elements = controller.getAssociatedElements(info);
  ...
  ...
}

The code for getPropertyInfo is here.

Thanks for the tip and the quick response!

I think this might require a change to the Validator interface, and some upstream APIs like the ValidationRenderer.
The current version (below) returns Promise<ValidationError[]>, which tells us what is invalid but provides no information on what exactly was validated.
Similarly, the ValidationRenderer is very "error-centric". It's all about rendering and un-rendering errors.

Consider the following (salesforce) UI:

To support something like this we'd need to refactor the Validator to return the rules that were validated and whether they were valid or invalid...
Instead of:
validateProperty(...): Promise<ValidationError[]>;

We'd need something like:
validateProperty(...): Promise<ValidateResult[]>;

interface ValidateResult {
  rule: any;
  object: any;
  propertyName?: string;
  error: ValidationError|null;
}

This would enable telling the renderer exactly what checked out and what failed. It would also enable adding some more targeted templating facilities. For example, today we can data-bind to the errors associated with an element or set of elements using the validation-errors custom attribute. With these changes we could enable data-binding to whether a specific rule or set of rules are valid or invalid.
@EisenbergEffect, @Slimfit, @jsobell, anyone, thoughts? We haven't put the beta stamp on this yet so now would be the time to do something breaking/intrusive like this. @jsobell you and I may have discussed something like this in the past, I can't remember, maybe I didn't quite "get it" at the time.

For reference, current Validator interface:
/**
 * Validates.
 * Responsible for validating objects and properties.
 */
export abstract class Validator {
  /**
   * Validates the specified property.
   * @param object The object to validate.
   * @param propertyName The name of the property to validate.
   * @param rules Optional. If unspecified, the implementation should lookup the rules for the
   * specified object. This may not be possible for all implementations of this interface.
   */
  public abstract validateProperty(object: any, propertyName: string, rules?: any): Promise<ValidationError[]>;

  /**
   * Validates all rules for specified object and it's properties.
   * @param object The object to validate.
   * @param rules Optional. If unspecified, the implementation should lookup the rules for the
   * specified object. This may not be possible for all implementations of this interface.
   */
  public abstract validateObject(object: any, rules?: any): Promise<ValidationError[]>;
}

OK, quick brain dump because it's 11:30pm here and my synapses are shutting down...
I have no issue making the change you suggest, as it should work around most of these problems, and this is one aspect I was wurbling on about when I mentioned needing more information in the renderer, but I think is also related to the discussion about having custom rules associated or 'bound' to arbitrary visual elements.
This is one of those tricky crossovers between object and UI validation. Because we can have object level rules, but the user wants the results reflected on-screen, what binds the object level rule to anything in the DOM? As far as validation feedback is concerned we don't care if the rule is linked to an input field or a span, as long as we can display the error.
If we implement the solution where the user is handed a list of both property validation result and the related DOM entity, we really need to provide the DOM elements that they consider related even if they were not validation-bound inputs.
A simple example might be that firstname+lastname are less than 50 characters. We add this as a model rule, but it's not linked to one input field, so the user wants the error displayed below those two fields. When the renderer is called, it has no visual element associated, so how does the user associate this with a point in the DOM to display the error or the green 'OK' result discussed by the OP?
My original suggestion was that all Model level rules have a fake property or 'ID', so we could have a custom attribute anywhere on the form to flag the location (or locations) to be passed to the renderer, and in the above example it would probably be on a div enclosing first and last name input fields.
Essentially, once we start raising events intended for UI feedback (even though they are really only property feedback) we need to allow this to happen, as moving the error-centric to be rule-centric needs to be able to provide enough details to allow ui-centric coding when required.
Treacherous partly gets around this by always having the entire collection of passed and failed rules available (as your solution would do), and you can request the message and status of any property by name, even if that property is an object level pseudo-property/ID/tag.

I would support the change. It's a more flexible design and similar to what I've seen done in other libraries.


[SR-15547] Implement Visitors for common Markdown transformations

Previous ID
SR-15547

Radar
None

Original Reporter
nfulkerson (JIRA User)

Type
New Feature

Additional Detail from JIRA

Votes
0

Component/s
Swift-Markdown

Labels
New Feature

Assignee
None

Priority
Medium

md5: b459899c195ae75c1b1c0d63ba0ada09

Issue Description:
Given similar third-party Markdown parsers include applications of a Visitor to transform a document into common outputs (HTML, LaTeX, etc) or platform-specific types (NSAttributedString), I wonder whether an appropriate enhancement of this package would be to implement Visitors to provide these transformations.

Yes, you can implements this by conforming MarkupVisitor or MarkupWalker.


removed the local time from personal menu

This pull request addresses the issue discussed in CZO where the local time is being displayed in the personal menu. As per the discussion, the local time feature is redundant in the personal menu and should be removed. Users can find the local time information in their user card if needed.

Removed local time display: The local time has been removed from the personal menu by modifying web/templates/personal_menu.hbs
Fixes:
Issue Link: https://github.com/zulip/zulip/issues/30044
Description: The only change made was removing the part where the user time was described in the personal menu file. No other parts of the file were altered as the goal was solely to remove the local time from the personal menu.
UI Change: This PR includes UI changes, as the local time display has been removed from the personal menu.

Self-review checklist

[x] Self-reviewed the changes for clarity and maintainability
(variable names, code reuse, readability, etc.).

Communicate decisions, questions, and potential concerns.

[x] Explains differences from previous plans (e.g., issue description).
[x] Highlights technical choices and bugs encountered.
[x] Calls out remaining decisions and concerns.
[x] Automated tests verify logic where appropriate.

Individual commits are ready for review (see commit discipline).

[x] Each commit is a coherent idea.
[x] Commit message(s) explain reasoning and motivation for changes.

Completed manual review and testing of the following:

[x] Visual appearance of the changes.
[x] Responsiveness and internationalization.
[x] Strings and tooltips.
[x] End-to-end functionality of buttons, interactions and flows.
[x] Corner cases, error conditions, and easily imagined bugs.

Hey @sayamsamal, tagged you here for a quick review, cause you had asked me to tag you on the previous PR.

Hey @sayamsamal , need a quick review for the PR closed PR


[PLAT-11566] Instrument navigation spans

Goal
Automatically instrument navigation spans when using react-native-navigation
Design
Add event listeners to the Navigation library to start and automatically end a navigation span when the route changes
Note: this approach also creates a navigation span for the initial route due to the way the end to end test is instrumented
Changeset

Add event listeners to plugin
Add navigation span attributes

Testing

Update unit tests to check that a span in automatically started on route change
Update end to end tests to check that a span is automatically started on a route change

@gareththackeray Should we know what the previous route was from a navigation?

@gareththackeray Should we know what the previous route was from a navigation?

If we do know, I would suggest we include it as an attribute (bugsnag.navigation.previous_route).  If it is not possible or very difficult I think we can live without it.  We should also add it for React Navigation if we can.

LGTM - possibly out of scope for this PR but do we need an additional test to check that the app start instrumentation works?

Added PLAT-11721 to instrument and test app start spans

@gareththackeray Should we know what the previous route was from a navigation?

If we do know, I would suggest we include it as an attribute (bugsnag.navigation.previous_route). If it is not possible or very difficult I think we can live without it. We should also add it for React Navigation if we can.

Raised ticket PLAT-11722 to add previous route attributes