Repository: pex-tool/pex

Issue:
Lockfiles: requirement might not be compatible with requested interpreter constraints
`pex3 lock create --style=universal --resolver-version=pip-2020-resolver --indent=2 --interpreter-constraint='CPython>=3.7' ipython` results in a lockfile that chooses `8.1.1` for `ipython`, which has: `"requires_python": ">=3.8"`. That means that the lockfile fails when run with Python 3.7.

Instead, we ideally would choose an ipython version from 7.*, the latest version compatible with 3.7. Note that this does happen if you use `--interpreter-constraint='CPython==3.7.*'`.


Discussion:
The full lock:

```json
{
  "allow_builds": true,
  "allow_prereleases": false,
  "allow_wheels": true,
  "build_isolation": true,
  "constraints": [],
  "locked_resolves": [
    {
      "locked_requirements": [
        {
          "artifacts": [
            {
              "algorithm": "sha256",
              "hash": "93aa393e9d6c54c5cd570ccadd8edad61ea0c4b9ea7a01409020c9aa019eb442",
              "url": "https://files.pythonhosted.org/packages/e4/fa/0c6c9786aa6927d12d100d322588e125e6ed466ab0a3d2d509ea18aeb56d/appnope-0.1.2-py2.py3-none-any.whl"
            },
            {
              "algorithm": "sha256",
              "hash": "dd83cd4b5b460958838f6eb3000c660b1f9caf2a5b1de4264e941512f603258a",
              "url": "https://files.pythonhosted.org/packages/e9/bc/2d2c567fe5ac1924f35df879dbf529dd7e7cabd94745dc9d89024a934e76/appnope-0.1.2.tar.gz"
            }
          ],
          "project_name": "appnope",
          "requires_dists": [],
          "requires_python": null,
          "version": "0.1.2"
        },
        {
          "artifacts": [
            {
              "algorithm": "sha256",
              "hash": "0844691e88552595a6f4a4281a9f7f79b8dd45ca4ccea82e5e05b4bbdb76705c",
              "url": "https://files.pythonhosted.org/packages/16/d5/b0ad240c22bba2f4591693b0ca43aae94fbd77fb1e2b107d54fff1462b6f/asttokens-2.0.5-py2.py3-none-any.whl"
            },
            {
              "algorithm": "sha256",
              "hash": "9a54c114f02c7a9480d56550932546a3f1fe71d8a02f1bc7ccd0ee3ee35cf4d5",
              "url": "https://files.pythonhosted.org/packages/aa/51/59965dead3960a97358f289c7c11ebc1f6c5d28710fab5d421000fe60353/asttokens-2.0.5.tar.gz"
            }
          ],
          "project_name": "asttokens",
          "requires_dists": [
            "astroid; extra == \"test\"",
            "pytest; extra == \"test\"",
            "six"
          ],
          "requires_python": null,
          "version": "2.0.5"
        },
        {
          "artifacts": [
            {
              "algorithm": "sha256",
              "hash": "fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255",
              "url": "https://files.pythonhosted.org/packages/4c/1c/ff6546b6c12603d8dd1070aa3c3d273ad4c07f5771689a7b69a550e8c951/backcall-0.2.0-py2.py3-none-any.whl"
            },
            {
              "algorithm": "sha256",
              "hash": "5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e",
              "url": "https://files.pythonhosted.org/packages/a2/40/764a663805d84deee23043e1426a9175567db89c8b3287b5c2ad9f71aa93/backcall-0.2.0.tar.gz"
            }
          ],
          "project_name": "backcall",
          "requires_dists": [],
          "requires_python": null,
          "version": "0.2"
        },
        {
          "artifacts": [
            {
              "algorithm": "sha256",
              "hash": "9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2",
              "url": "https://files.pythonhosted.org/packages/44/98/5b86278fbbf250d239ae0ecb724f8572af1c91f4a11edf4d36a206189440/colorama-0.4.4-py2.py3-none-any.whl"
            },
            {
              "algorithm": "sha256",
              "hash": "5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b",
              "url": "https://files.pythonhosted.org/packages/1f/bb/5d3246097ab77fa083a61bd8d3d527b7ae063c7d8e8671b1cf8c4ec10cbe/colorama-0.4.4.tar.gz"
            }
          ],
          "project_name": "colorama",
          "requires_dists": [],
          "requires_python": "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7",
          "version": "0.4.4"
        },
        {
          "artifacts": [
            {
              "algorithm": "sha256",
              "hash": "b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186",
              "url": "https://files.pythonhosted.org/packages/d5/50/83c593b07763e1161326b3b8c6686f0f4b0f24d5526546bee538c89837d6/decorator-5.1.1-py3-none-any.whl"
            },
            {
              "algorithm": "sha256",
              "hash": "637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330",
              "url": "https://files.pythonhosted.org/packages/66/0c/8d907af351aa16b42caae42f9d6aa37b900c67308052d10fdce809f8d952/decorator-5.1.1.tar.gz"
            }
          ],
          "project_name": "decorator",
          "requires_dists": [],
          "requires_python": ">=3.5",
          "version": "5.1.1"
        },
        {
          "artifacts": [
            {
              "algorithm": "sha256",
              "hash": "d1eef132db1b83649a3905ca6dd8897f71ac6f8cac79a7e58a1a09cf137546c9",
              "url": "https://files.pythonhosted.org/packages/61/d8/ad89910dc1da01a24135cb3dce702c72a8172f7b8f896ac0c4c34bcaf323/executing-0.8.3-py2.py3-none-any.whl"
            },
            {
              "algorithm": "sha256",
              "hash": "c6554e21c6b060590a6d3be4b82fb78f8f0194d809de5ea7df1c093763311501",
              "url": "https://files.pythonhosted.org/packages/16/14/5a9b7b7725e85aa66f00a89f1e912ded203217016562747f8b8effcf52bc/executing-0.8.3.tar.gz"
            }
          ],
          "project_name": "executing",
          "requires_dists": [],
          "requires_python": null,
          "version": "0.8.3"
        },
        {
          "artifacts": [
            {
              "algorithm": "sha256",
              "hash": "6f56bfaeaa3247aa3b9cd3b8cbab3a9c0abf7428392f97b21902d12b2f42a381",
              "url": "https://files.pythonhosted.org/packages/a0/fb/8a10b0d3293fab75ab4690925d3b790f1e4599b4b55eb3f4984ffc1753aa/ipython-8.1.1-py3-none-any.whl"
            },
            {
              "algorithm": "sha256",
              "hash": "8138762243c9b3a3ffcf70b37151a2a35c23d3a29f9743878c33624f4207be3d",
              "url": "https://files.pythonhosted.org/packages/fb/09/3501e84f146738e509d2ce98b862542b0f1e3448634e116b83acd7cb0c74/ipython-8.1.1.tar.gz"
            }
          ],
          "project_name": "ipython",
          "requires_dists": [
            "Sphinx>=1.3; extra == \"all\"",
            "Sphinx>=1.3; extra == \"doc\"",
            "appnope; sys_platform == \"darwin\"",
            "backcall",
            "black; extra == \"all\"",
            "black; extra == \"black\"",
            "colorama; sys_platform == \"win32\"",
            "curio; extra == \"all\"",
            "curio; extra == \"test_extra\"",
            "decorator",
            "ipykernel; extra == \"all\"",
            "ipykernel; extra == \"kernel\"",
            "ipyparallel; extra == \"all\"",
            "ipyparallel; extra == \"parallel\"",
            "ipywidgets; extra == \"all\"",
            "ipywidgets; extra == \"notebook\"",
            "jedi>=0.16",
            "matplotlib!=3.2.0; extra == \"all\"",
            "matplotlib!=3.2.0; extra == \"test_extra\"",
            "matplotlib-inline",
            "nbconvert; extra == \"all\"",
            "nbconvert; extra == \"nbconvert\"",
            "nbformat; extra == \"all\"",
            "nbformat; extra == \"nbformat\"",
            "nbformat; extra == \"test_extra\"",
            "notebook; extra == \"all\"",
            "notebook; extra == \"notebook\"",
            "numpy>=1.19; extra == \"all\"",
            "numpy>=1.19; extra == \"test_extra\"",
            "pandas; extra == \"all\"",
            "pandas; extra == \"test_extra\"",
            "pexpect>4.3; sys_platform != \"win32\"",
            "pickleshare",
            "prompt-toolkit!=3.0.0,!=3.0.1,<3.1.0,>=2.0.0",
            "pygments>=2.4.0",
            "pytest-asyncio; extra == \"all\"",
            "pytest-asyncio; extra == \"test\"",
            "pytest; extra == \"all\"",
            "pytest; extra == \"test\"",
            "pytest; extra == \"test_extra\"",
            "qtconsole; extra == \"all\"",
            "qtconsole; extra == \"qtconsole\"",
            "setuptools>=18.5",
            "stack-data",
            "testpath; extra == \"all\"",
            "testpath; extra == \"test\"",
            "testpath; extra == \"test_extra\"",
            "traitlets>=5",
            "trio; extra == \"all\"",
            "trio; extra == \"test_extra\""
          ],
          "requires_python": ">=3.8",
          "version": "8.1.1"
        },
        {
          "artifacts": [
            {
              "algorithm": "sha256",
              "hash": "637c9635fcf47945ceb91cd7f320234a7be540ded6f3e99a50cb6febdfd1ba8d",
              "url": "https://files.pythonhosted.org/packages/b3/0e/836f12ec50075161e365131f13f5758451645af75c2becf61c6351ecec39/jedi-0.18.1-py2.py3-none-any.whl"
            },
            {
              "algorithm": "sha256",
              "hash": "74137626a64a99c8eb6ae5832d99b3bdd7d29a3850fe2aa80a4126b2a7d949ab",
              "url": "https://files.pythonhosted.org/packages/c2/25/273288df952e07e3190446efbbb30b0e4871a0d63b4246475f3019d4f55e/jedi-0.18.1.tar.gz"
            }
          ],
          "project_name": "jedi",
          "requires_dists": [
            "Django<3.1; extra == \"testing\"",
            "colorama; extra == \"testing\"",
            "docopt; extra == \"testing\"",
            "flake8==3.8.3; extra == \"qa\"",
            "mypy==0.782; extra == \"qa\"",
            "parso<0.9.0,>=0.8.0",
            "pytest<7.0.0; extra == \"testing\""
          ],
          "requires_python": ">=3.6",
          "version": "0.18.1"
        },
        {
          "artifacts": [
            {
              "algorithm": "sha256",
              "hash": "aed605ba3b72462d64d475a21a9296f400a19c4f74a31b59103d2a99ffd5aa5c",
              "url": "https://files.pythonhosted.org/packages/a6/2d/2230afd570c70074e80fd06857ba2bdc5f10c055bd9125665fe276fadb67/matplotlib_inline-0.1.3-py3-none-any.whl"
            },
            {
              "algorithm": "sha256",
              "hash": "a04bfba22e0d1395479f866853ec1ee28eea1485c1d69a6faf00dc3e24ff34ee",
              "url": "https://files.pythonhosted.org/packages/0f/98/838f4c57f7b2679eec038ad0abefd1acaeec35e635d4d7af215acd7d1bd2/matplotlib-inline-0.1.3.tar.gz"
            }
          ],
          "project_name": "matplotlib-inline",
          "requires_dists": [
            "traitlets"
          ],
          "requires_python": ">=3.5",
          "version": "0.1.3"
        },
        {
          "artifacts": [
            {
              "algorithm": "sha256",
              "hash": "c001d4636cd3aecdaf33cbb40aebb59b094be2a74c556778ef5576c175e19e75",
              "url": "https://files.pythonhosted.org/packages/05/63/8011bd08a4111858f79d2b09aad86638490d62fbf881c44e434a6dfca87b/parso-0.8.3-py2.py3-none-any.whl"
            },
            {
              "algorithm": "sha256",
              "hash": "8c07be290bb59f03588915921e29e8a50002acaf2cdc5fa0e0114f91709fafa0",
              "url": "https://files.pythonhosted.org/packages/a2/0e/41f0cca4b85a6ea74d66d2226a7cda8e41206a624f5b330b958ef48e2e52/parso-0.8.3.tar.gz"
            }
          ],
          "project_name": "parso",
          "requires_dists": [
            "docopt; extra == \"testing\"",
            "flake8==3.8.3; extra == \"qa\"",
            "mypy==0.782; extra == \"qa\"",
            "pytest<6.0.0; extra == \"testing\""
          ],
          "requires_python": ">=3.6",
          "version": "0.8.3"
        },
        {
          "artifacts": [
            {
              "algorithm": "sha256",
              "hash": "0b48a55dcb3c05f3329815901ea4fc1537514d6ba867a152b581d69ae3710937",
              "url": "https://files.pythonhosted.org/packages/39/7b/88dbb785881c28a102619d46423cb853b46dbccc70d3ac362d99773a78ce/pexpect-4.8.0-py2.py3-none-any.whl"
            },
            {
              "algorithm": "sha256",
              "hash": "fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c",
              "url": "https://files.pythonhosted.org/packages/e5/9b/ff402e0e930e70467a7178abb7c128709a30dfb22d8777c043e501bc1b10/pexpect-4.8.0.tar.gz"
            }
          ],
          "project_name": "pexpect",
          "requires_dists": [
            "ptyprocess>=0.5"
          ],
          "requires_python": null,
          "version": "4.8"
        },
        {
          "artifacts": [
            {
              "algorithm": "sha256",
              "hash": "9649af414d74d4df115d5d718f82acb59c9d418196b7b4290ed47a12ce62df56",
              "url": "https://files.pythonhosted.org/packages/9a/41/220f49aaea88bc6fa6cba8d05ecf24676326156c23b991e80b3f2fc24c77/pickleshare-0.7.5-py2.py3-none-any.whl"
            },
            {
              "algorithm": "sha256",
              "hash": "87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca",
              "url": "https://files.pythonhosted.org/packages/d8/b6/df3c1c9b616e9c0edbc4fbab6ddd09df9535849c64ba51fcb6531c32d4d8/pickleshare-0.7.5.tar.gz"
            }
          ],
          "project_name": "pickleshare",
          "requires_dists": [
            "pathlib2; python_version in \"2.6 2.7 3.2 3.3\""
          ],
          "requires_python": null,
          "version": "0.7.5"
        },
        {
          "artifacts": [
            {
              "algorithm": "sha256",
              "hash": "30129d870dcb0b3b6a53efdc9d0a83ea96162ffd28ffe077e94215b233dc670c",
              "url": "https://files.pythonhosted.org/packages/00/e4/beb2fad0bec554a011b321d0f6b99981f9171c0b05d03a6948e45ac8a5be/prompt_toolkit-3.0.28-py3-none-any.whl"
            },
            {
              "algorithm": "sha256",
              "hash": "9f1cd16b1e86c2968f2519d7fb31dd9d669916f515612c269d14e9ed52b51650",
              "url": "https://files.pythonhosted.org/packages/37/34/c34c376882305c5051ed7f086daf07e68563d284015839bfb74d6e61d402/prompt_toolkit-3.0.28.tar.gz"
            }
          ],
          "project_name": "prompt-toolkit",
          "requires_dists": [
            "wcwidth"
          ],
          "requires_python": ">=3.6.2",
          "version": "3.0.28"
        },
        {
          "artifacts": [
            {
              "algorithm": "sha256",
              "hash": "4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35",
              "url": "https://files.pythonhosted.org/packages/22/a6/858897256d0deac81a172289110f31629fc4cee19b6f01283303e18c8db3/ptyprocess-0.7.0-py2.py3-none-any.whl"
            },
            {
              "algorithm": "sha256",
              "hash": "5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220",
              "url": "https://files.pythonhosted.org/packages/20/e5/16ff212c1e452235a90aeb09066144d0c5a6a8c0834397e03f5224495c4e/ptyprocess-0.7.0.tar.gz"
            }
          ],
          "project_name": "ptyprocess",
          "requires_dists": [],
          "requires_python": null,
          "version": "0.7"
        },
        {
          "artifacts": [
            {
              "algorithm": "sha256",
              "hash": "01eaab343580944bc56080ebe0a674b39ec44a945e6d09ba7db3cb8cec289350",
              "url": "https://files.pythonhosted.org/packages/2b/27/77f9d5684e6bce929f5cfe18d6cfbe5133013c06cb2fbf5933670e60761d/pure_eval-0.2.2-py3-none-any.whl"
            },
            {
              "algorithm": "sha256",
              "hash": "2b45320af6dfaa1750f543d714b6d1c520a1688dec6fd24d339063ce0aaa9ac3",
              "url": "https://files.pythonhosted.org/packages/97/5a/0bc937c25d3ce4e0a74335222aee05455d6afa2888032185f8ab50cdf6fd/pure_eval-0.2.2.tar.gz"
            }
          ],
          "project_name": "pure-eval",
          "requires_dists": [
            "pytest; extra == \"tests\""
          ],
          "requires_python": null,
          "version": "0.2.2"
        },
        {
          "artifacts": [
            {
              "algorithm": "sha256",
              "hash": "44238f1b60a76d78fc8ca0528ee429702aae011c265fe6a8dd8b63049ae41c65",
              "url": "https://files.pythonhosted.org/packages/1d/17/ed4d2df187995561b28f1073df24137cb750e12f9879d291cc8ab67c65d2/Pygments-2.11.2-py3-none-any.whl"
            },
            {
              "algorithm": "sha256",
              "hash": "4e426f72023d88d03b2fa258de560726ce890ff3b630f88c21cbb8b2503b8c6a",
              "url": "https://files.pythonhosted.org/packages/94/9c/cb656d06950268155f46d4f6ce25d7ffc51a0da47eadf1b164bbf23b718b/Pygments-2.11.2.tar.gz"
            }
          ],
          "project_name": "pygments",
          "requires_dists": [],
          "requires_python": ">=3.5",
          "version": "2.11.2"
        },
        {
          "artifacts": [
            {
              "algorithm": "sha256",
              "hash": "e4f30b9f84e5ab3decf945113119649fec09c1fc3507c6ebffec75646c56e62b",
              "url": "https://files.pythonhosted.org/packages/3b/02/8d4d27b1cacaac2d129a27d17a22d92a2a5eedcb7817d4ed8ab0d4daf5c4/setuptools-60.9.3-py3-none-any.whl"
            },
            {
              "algorithm": "sha256",
              "hash": "2347b2b432c891a863acadca2da9ac101eae6169b1d3dfee2ec605ecd50dbfe5",
              "url": "https://files.pythonhosted.org/packages/14/74/54890935244ce053abcc4fa01ef4982a84743a8d128d4cf5eae56e2d156c/setuptools-60.9.3.tar.gz"
            }
          ],
          "project_name": "setuptools",
          "requires_dists": [
            "build[virtualenv]; extra == \"testing\"",
            "build[virtualenv]; extra == \"testing-integration\"",
            "filelock>=3.4.0; extra == \"testing\"",
            "filelock>=3.4.0; extra == \"testing-integration\"",
            "flake8-2020; extra == \"testing\"",
            "furo; extra == \"docs\"",
            "jaraco.envs>=2.2; extra == \"testing\"",
            "jaraco.envs>=2.2; extra == \"testing-integration\"",
            "jaraco.packaging>=9; extra == \"docs\"",
            "jaraco.path>=3.2.0; extra == \"testing\"",
            "jaraco.path>=3.2.0; extra == \"testing-integration\"",
            "jaraco.tidelift>=1.4; extra == \"docs\"",
            "mock; extra == \"testing\"",
            "pip-run>=8.8; extra == \"testing\"",
            "pip>=19.1; extra == \"testing\"",
            "pygments-github-lexers==0.0.5; extra == \"docs\"",
            "pytest-black>=0.3.7; platform_python_implementation != \"PyPy\" and extra == \"testing\"",
            "pytest-checkdocs>=2.4; extra == \"testing\"",
            "pytest-cov; platform_python_implementation != \"PyPy\" and extra == \"testing\"",
            "pytest-enabler; extra == \"testing-integration\"",
            "pytest-enabler>=1.0.1; extra == \"testing\"",
            "pytest-flake8; extra == \"testing\"",
            "pytest-mypy>=0.9.1; platform_python_implementation != \"PyPy\" and extra == \"testing\"",
            "pytest-perf; extra == \"testing\"",
            "pytest-xdist; extra == \"testing\"",
            "pytest-xdist; extra == \"testing-integration\"",
            "pytest; extra == \"testing-integration\"",
            "pytest>=6; extra == \"testing\"",
            "rst.linker>=1.9; extra == \"docs\"",
            "sphinx-favicon; extra == \"docs\"",
            "sphinx-inline-tabs; extra == \"docs\"",
            "sphinx; extra == \"docs\"",
            "sphinx>=4.3.2; extra == \"testing\"",
            "sphinxcontrib-towncrier; extra == \"docs\"",
            "tomli; extra == \"testing-integration\"",
            "virtualenv>=13.0.0; extra == \"testing\"",
            "virtualenv>=13.0.0; extra == \"testing-integration\"",
            "wheel; extra == \"testing\"",
            "wheel; extra == \"testing-integration\""
          ],
          "requires_python": ">=3.7",
          "version": "60.9.3"
        },
        {
          "artifacts": [
            {
              "algorithm": "sha256",
              "hash": "8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254",
              "url": "https://files.pythonhosted.org/packages/d9/5a/e7c31adbe875f2abbb91bd84cf2dc52d792b5a01506781dbcf25c91daf11/six-1.16.0-py2.py3-none-any.whl"
            },
            {
              "algorithm": "sha256",
              "hash": "1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926",
              "url": "https://files.pythonhosted.org/packages/71/39/171f1c67cd00715f190ba0b100d606d440a28c93c7714febeca8b79af85e/six-1.16.0.tar.gz"
            }
          ],
          "project_name": "six",
          "requires_dists": [],
          "requires_python": "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7",
          "version": "1.16"
        },
        {
          "artifacts": [
            {
              "algorithm": "sha256",
              "hash": "999762f9c3132308789affa03e9271bbbe947bf78311851f4d485d8402ed858e",
              "url": "https://files.pythonhosted.org/packages/6b/25/9a454b432df53ffbbb4f03198c3347f393c34f4de07fb652563bdbdf91e8/stack_data-0.2.0-py3-none-any.whl"
            },
            {
              "algorithm": "sha256",
              "hash": "45692d41bd633a9503a5195552df22b583caf16f0b27c4e58c98d88c8b648e12",
              "url": "https://files.pythonhosted.org/packages/3c/71/3e7cdd62d35c863dc45248d827cb65858af6b58271da5ff930bc60ba2e87/stack_data-0.2.0.tar.gz"
            }
          ],
          "project_name": "stack-data",
          "requires_dists": [
            "asttokens",
            "cython; extra == \"tests\"",
            "executing",
            "littleutils; extra == \"tests\"",
            "pure-eval",
            "pygments; extra == \"tests\"",
            "pytest; extra == \"tests\"",
            "typeguard; extra == \"tests\""
          ],
          "requires_python": null,
          "version": "0.2"
        },
        {
          "artifacts": [
            {
              "algorithm": "sha256",
              "hash": "2d313cc50a42cd6c277e7d7dc8d4d7fedd06a2c215f78766ae7b1a66277e0033",
              "url": "https://files.pythonhosted.org/packages/37/46/be8a3c030bd3673f4800fa7f46eda972dfa2990089a51ec5dd0a26ed33e9/traitlets-5.1.1-py3-none-any.whl"
            },
            {
              "algorithm": "sha256",
              "hash": "059f456c5a7c1c82b98c2e8c799f39c9b8128f6d0d46941ee118daace9eb70c7",
              "url": "https://files.pythonhosted.org/packages/db/cf/e6cbf07ce2d21a17c8379f3f2f12db413a38da5ee20809638226b1490e48/traitlets-5.1.1.tar.gz"
            }
          ],
          "project_name": "traitlets",
          "requires_dists": [
            "pytest; extra == \"test\""
          ],
          "requires_python": ">=3.7",
          "version": "5.1.1"
        },
        {
          "artifacts": [
            {
              "algorithm": "sha256",
              "hash": "beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784",
              "url": "https://files.pythonhosted.org/packages/59/7c/e39aca596badaf1b78e8f547c807b04dae603a433d3e7a7e04d67f2ef3e5/wcwidth-0.2.5-py2.py3-none-any.whl"
            },
            {
              "algorithm": "sha256",
              "hash": "c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83",
              "url": "https://files.pythonhosted.org/packages/89/38/459b727c381504f361832b9e5ace19966de1a235d73cdbdea91c771a1155/wcwidth-0.2.5.tar.gz"
            }
          ],
          "project_name": "wcwidth",
          "requires_dists": [
            "backports.functools-lru-cache>=1.2.1; python_version < \"3.2\""
          ],
          "requires_python": null,
          "version": "0.2.5"
        }
      ],
      "platform_tag": [
        "cp39",
        "cp39",
        "macosx_11_0_arm64"
      ]
    }
  ],
  "pex_version": "2.1.71",
  "prefer_older_binary": false,
  "requirements": [
    "ipython"
  ],
  "requires_python": [
    ">=3.7"
  ],
  "resolver_version": "pip-2020-resolver",
  "style": "universal",
  "transitive": true,
  "use_pep517": null
}
```
I'm guessing this is some or all of the `any`s in the Pip patching used for universal locking need to switch to `all`s:
https://github.com/pantsbuild/pex/blob/735c6e4ccd85062339f8df7a4d3b76891fbab915/pex/pip.py#L617-L624
https://github.com/pantsbuild/pex/blob/735c6e4ccd85062339f8df7a4d3b76891fbab915/pex/pip.py#L644-L679
https://github.com/pantsbuild/pex/blob/735c6e4ccd85062339f8df7a4d3b76891fbab915/pex/pip.py#L696-L702
Yeah, changing the `any` to `all` in the `check_requires_python` fixes this particular case. I need to think harder about all these cases though before declaring victory with a 2-character change fix.

Resolving patch:
diff --git a/pex/interpreter_constraints.py b/pex/interpreter_constraints.py
--- a/pex/interpreter_constraints.py
+++ b/pex/interpreter_constraints.py
@@ -190,7 +190,7 @@ def iter_compatible_versions(
     PythonVersion(Lifecycle.EOL, 3, 5, 10),
     PythonVersion(Lifecycle.EOL, 3, 6, 15),
     PythonVersion(Lifecycle.STABLE, 3, 7, 12),
-    PythonVersion(Lifecycle.STABLE, 3, 8, 11),
+    PythonVersion(Lifecycle.STABLE, 3, 8, 12),
     PythonVersion(Lifecycle.STABLE, 3, 9, 10),
     PythonVersion(Lifecycle.STABLE, 3, 10, 2),
     PythonVersion(Lifecycle.DEV, 3, 11, 0),
diff --git a/pex/pip/runtime_patches.py b/pex/pip/runtime_patches.py
--- a/pex/pip/runtime_patches.py
+++ b/pex/pip/runtime_patches.py
@@ -141,7 +141,11 @@ def patch_requires_python():
             orig_check_requires_python = packaging.check_requires_python
 
             def check_requires_python(requires_python, *_args, **_kw):
-                return any(
+                # Ensure any dependency we lock is compatible with the full interpreter range
+                # specified since we have no way to force Pip to backtrack and follow paths for any
+                # divergences. Most (all?) true divergences should be covered by forked environment
+                # markers.
+                return all(
                     orig_check_requires_python(requires_python, python_full_version)
                     for python_full_version in python_full_versions
                 )
diff --git a/pex/pip/tool.py b/pex/pip/tool.py
--- a/pex/pip/tool.py
+++ b/pex/pip/tool.py
@@ -12,7 +12,6 @@
 import sys
 from abc import abstractmethod
 from collections import defaultdict, deque
-from textwrap import dedent
 
 from pex import dist_metadata, targets, third_party
 from pex.common import atomic_directory, safe_mkdtemp


Test patch:
diff --git a/tests/integration/cli/commands/test_issue_1667.py b/tests/integration/cli/commands/test_issue_1667.py
new file mode 100644
--- /dev/null
+++ b/tests/integration/cli/commands/test_issue_1667.py
@@ -0,0 +1,82 @@
+# Copyright 2022 Pants project contributors (see CONTRIBUTORS.md).
+# Licensed under the Apache License, Version 2.0 (see LICENSE).
+
+import os.path
+import subprocess
+import sys
+
+import pytest
+
+from pex.cli.testing import run_pex3
+from pex.interpreter import PythonInterpreter
+from pex.testing import run_pex_command
+from pex.typing import TYPE_CHECKING
+
+if TYPE_CHECKING:
+    from typing import Any
+
+
+@pytest.mark.skipif(
+    sys.version_info[0] < 3,
+    reason=(
+        "The lock under test takes ~infinite time to generate under Python 2.7 using the "
+        "pip-2020-resolver. Since the original issue and even this use in-the-small will "
+        "by-definition never try to use a Python 2.7 interpreter to perform the lock, simply avoid "
+        "the issue."
+    ),
+)
+def test_interpreter_constraints_range_coverage(
+    tmpdir,  # type: Any
+    py37,  # type: PythonInterpreter
+):
+    # type: (...) -> None
+
+    # We lock with an unconstrained IPython requirement and we know IPython latest does not support
+    # Python 3.7. If locking respects ICs it should not pick latest, but a version that supports at
+    # least 3.7
+    lock = os.path.join(str(tmpdir), "lock.json")
+    run_pex3(
+        "lock",
+        "create",
+        "--style",
+        "universal",
+        "--resolver-version",
+        "pip-2020-resolver",
+        "--interpreter-constraint",
+        ">=3.7,<3.11",
+        "ipython",
+        "-o",
+        lock,
+    ).assert_success()
+
+    pex_root = os.path.join(str(tmpdir), "pex_root")
+    ipython_pex = os.path.join(str(tmpdir), "ipython.pex")
+    run_pex_command(
+        args=[
+            "--interpreter-constraint",
+            ">=3.7,<3.11",
+            "--lock",
+            lock,
+            "-c",
+            "ipython",
+            "-o",
+            ipython_pex,
+            "--runtime-pex-root",
+            pex_root,
+        ],
+    ).assert_success()
+
+    def assert_pex_works(python):
+        # type: (str) -> None
+        assert (
+            subprocess.check_output(
+                args=[python, ipython_pex, "-c", "import IPython; print(IPython.__file__)"]
+            )
+            .decode("utf-8")
+            .strip()
+            .startswith(pex_root)
+        )
+
+    assert_pex_works(py37.binary)
+    if (3, 7) <= sys.version_info[:2] < (3, 11):
+        assert_pex_works(sys.executable)