diff --git a/CHANGES.md b/CHANGES.md index 28cfe8f..f6ae897 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,10 @@ # Release Notes +## 0.6.0 + +Add an interpreter provider for [PyPy](https://pypy.org/) that provides the distributions they +release at https://downloads.python.org/pypy/. + ## 0.5.0 Add support to the PythonBuildStandalone interpreter provider for the new `install_only_stripped` diff --git a/lock.json b/lock.json index 1ab3d52..ba4abc1 100644 --- a/lock.json +++ b/lock.json @@ -148,6 +148,31 @@ "requires_python": ">=3.8", "version": "2.15.0" }, + { + "artifacts": [ + { + "algorithm": "sha256", + "hash": "b80878c9f40111313e55da8ba20bdba06d8fa3969fc68304167741bbf9e082ed", + "url": "https://files.pythonhosted.org/packages/b1/fe/e8c672695b37eecc5cbf43e1d0638d88d66ba3a44c4d321c796f4e59167f/beautifulsoup4-4.12.3-py3-none-any.whl" + }, + { + "algorithm": "sha256", + "hash": "74e3d1928edc070d21748185c46e3fb33490f22f52a3addee9aee0f4f7781051", + "url": "https://files.pythonhosted.org/packages/b3/ca/824b1195773ce6166d388573fc106ce56d4a805bd7427b624e063596ec58/beautifulsoup4-4.12.3.tar.gz" + } + ], + "project_name": "beautifulsoup4", + "requires_dists": [ + "cchardet; extra == \"cchardet\"", + "chardet; extra == \"chardet\"", + "charset-normalizer; extra == \"charset-normalizer\"", + "html5lib; extra == \"html5lib\"", + "lxml; extra == \"lxml\"", + "soupsieve>1.2" + ], + "requires_python": ">=3.6.0", + "version": "4.12.3" + }, { "artifacts": [ { @@ -204,19 +229,19 @@ "artifacts": [ { "algorithm": "sha256", - "hash": "ddc6c8ce995e6987e7faf5e3f1b02b302836a0e5d98ece18392cb1a36c72ad56", - "url": "https://files.pythonhosted.org/packages/5b/11/1e78951465b4a225519b8c3ad29769c49e0d8d157a070f681d5b6d64737f/certifi-2024.6.2-py3-none-any.whl" + "hash": "c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90", + "url": "https://files.pythonhosted.org/packages/1c/d5/c84e1a17bf61d4df64ca866a1c9a913874b4e9bdc131ec689a0ad013fb36/certifi-2024.7.4-py3-none-any.whl" }, { "algorithm": "sha256", - "hash": "3cd43f1c6fa7dedc5899d69d3ad0398fd018ad1a17fba83ddaf78aa46c747516", - "url": "https://files.pythonhosted.org/packages/07/b3/e02f4f397c81077ffc52a538e0aec464016f1860c472ed33bd2a1d220cc5/certifi-2024.6.2.tar.gz" + "hash": "5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b", + "url": "https://files.pythonhosted.org/packages/c2/02/a95f2b11e207f68bc64d7aae9666fed2e2b3f307748d5123dffb72a1bbea/certifi-2024.7.4.tar.gz" } ], "project_name": "certifi", "requires_dists": [], "requires_python": ">=3.6", - "version": "2024.6.2" + "version": "2024.7.4" }, { "artifacts": [ @@ -866,38 +891,38 @@ "artifacts": [ { "algorithm": "sha256", - "hash": "71d8ac0b906354ebda8ef1673e5fde785936ac1f29ff6987c7483cfbd5a4235a", - "url": "https://files.pythonhosted.org/packages/2b/ee/d53a3d4792a09b6cd757978951d6dcf8b10825a8b8522b68e9b5eb53b9a1/mypy-1.10.1-py3-none-any.whl" + "hash": "0624bdb940255d2dd24e829d99a13cfeb72e4e9031f9492148f410ed30bcab54", + "url": "https://files.pythonhosted.org/packages/f8/d4/4960d0df55f30a7625d9c3c9414dfd42f779caabae137ef73ffaed0c97b9/mypy-1.11.1-py3-none-any.whl" }, { "algorithm": "sha256", - "hash": "701b5f71413f1e9855566a34d6e9d12624e9e0a8818a5704d74d6b0402e66c04", - "url": "https://files.pythonhosted.org/packages/02/3c/1f5e57c8cfab4299f7189821ae8bb4896e8e623a04d293fd32e32eb0e617/mypy-1.10.1-cp312-cp312-musllinux_1_1_x86_64.whl" + "hash": "b868d3bcff720dd7217c383474008ddabaf048fad8d78ed948bb4b624870a417", + "url": "https://files.pythonhosted.org/packages/1c/21/a6b46c91b4c9d1918ee59c305f46850cde7cbea748635a352e7c3c8ed204/mypy-1.11.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl" }, { "algorithm": "sha256", - "hash": "d8681909f7b44d0b7b86e653ca152d6dff0eb5eb41694e163c6092124f8246d7", - "url": "https://files.pythonhosted.org/packages/5d/86/3c3bdaccc3cbd1372acb15667a2c2cb773523a710a22e2748cbda9a7c1e2/mypy-1.10.1-cp312-cp312-macosx_10_9_x86_64.whl" + "hash": "64f4a90e3ea07f590c5bcf9029035cf0efeae5ba8be511a8caada1a4893f5525", + "url": "https://files.pythonhosted.org/packages/1e/b7/3a50f318979c8c541428c2f1ee973cda813bcc89614de982dafdd0df2b3e/mypy-1.11.1-cp312-cp312-win_amd64.whl" }, { "algorithm": "sha256", - "hash": "1f8f492d7db9e3593ef42d4f115f04e556130f2819ad33ab84551403e97dd4c0", - "url": "https://files.pythonhosted.org/packages/c7/b9/81e4c6dbb1ec1e72503de3ff2c5fe4b7f224e04613b670f8b9004cd8a4dd/mypy-1.10.1.tar.gz" + "hash": "f39918a50f74dc5969807dcfaecafa804fa7f90c9d60506835036cc1bc891dc8", + "url": "https://files.pythonhosted.org/packages/3a/34/69638cee2e87303f19a0c35e80d42757e14d9aba328f272fdcdc0bf3c9b8/mypy-1.11.1-cp312-cp312-macosx_10_9_x86_64.whl" }, { "algorithm": "sha256", - "hash": "378c03f53f10bbdd55ca94e46ec3ba255279706a6aacaecac52ad248f98205d3", - "url": "https://files.pythonhosted.org/packages/ec/05/7c87b26b6a769b70f6c0b8a6daef01fc6f3ae566df89a2fa9d04f690b0d3/mypy-1.10.1-cp312-cp312-macosx_11_0_arm64.whl" + "hash": "f404a0b069709f18bbdb702eb3dcfe51910602995de00bd39cea3050b5772d08", + "url": "https://files.pythonhosted.org/packages/b6/9c/a4b3bda53823439cf395db8ecdda6229a83f9bf201714a68a15190bb2919/mypy-1.11.1.tar.gz" }, { "algorithm": "sha256", - "hash": "3c4c2992f6ea46ff7fce0072642cfb62af7a2484efe69017ed8b095f7b39ef31", - "url": "https://files.pythonhosted.org/packages/f9/20/d33608e8dc3bc0f5966fc1f6c2d16671f0725dcca279beec47c3e19afd9d/mypy-1.10.1-cp312-cp312-win_amd64.whl" + "hash": "0bc71d1fb27a428139dd78621953effe0d208aed9857cb08d002280b0422003a", + "url": "https://files.pythonhosted.org/packages/c4/3c/3e0611348fc53a4a7c80485959478b4f6eae706baf3b7c03cafa22639216/mypy-1.11.1-cp312-cp312-macosx_11_0_arm64.whl" }, { "algorithm": "sha256", - "hash": "6bacf8f3a3d7d849f40ca6caea5c055122efe70e81480c8328ad29c55c69e93e", - "url": "https://files.pythonhosted.org/packages/ff/b5/cbccba4dca9703c4c467171e7f61ea6a1a75eae991208aa5bc7d49807f91/mypy-1.10.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" + "hash": "a707ec1527ffcdd1c784d0924bf5cb15cd7f22683b919668a04d2b9c34549d2e", + "url": "https://files.pythonhosted.org/packages/c4/55/07904d4c8f408e70308015edcbff067eaa77514475938a9dd81b063de2a8/mypy-1.11.1-cp312-cp312-musllinux_1_1_x86_64.whl" } ], "project_name": "mypy", @@ -908,10 +933,10 @@ "psutil>=4.0; extra == \"dmypy\"", "setuptools>=50; extra == \"mypyc\"", "tomli>=1.1.0; python_version < \"3.11\"", - "typing-extensions>=4.1.0" + "typing-extensions>=4.6.0" ], "requires_python": ">=3.8", - "version": "1.10.1" + "version": "1.11.1" }, { "artifacts": [ @@ -1049,19 +1074,19 @@ "artifacts": [ { "algorithm": "sha256", - "hash": "efca15145a95e95c00608afeab66311d40bfb73bb2266a855befd705e6bb15a0", - "url": "https://files.pythonhosted.org/packages/f4/ab/e3c039b5ddba9335bd8f82d599eb310de1d2a2db0411b8d804d507405c74/pip-24.1.1-py3-none-any.whl" + "hash": "2cd581cf58ab7fcfca4ce8efa6dcacd0de5bf8d0a3eb9ec927e07405f4d9e2a2", + "url": "https://files.pythonhosted.org/packages/d4/55/90db48d85f7689ec6f81c0db0622d704306c5284850383c090e6c7195a5c/pip-24.2-py3-none-any.whl" }, { "algorithm": "sha256", - "hash": "5aa64f65e1952733ee0a9a9b1f52496ebdb3f3077cc46f80a16d983b58d1180a", - "url": "https://files.pythonhosted.org/packages/c0/d0/9641dc7b05877874c6418f8034ddefc809495e65caa14d38c7551cd114bb/pip-24.1.1.tar.gz" + "hash": "5b5e490b5e9cb275c879595064adce9ebd31b854e3e803740b72f9ccf34a45b8", + "url": "https://files.pythonhosted.org/packages/4d/87/fb90046e096a03aeab235e139436b3fe804cdd447ed2093b0d70eba3f7f8/pip-24.2.tar.gz" } ], "project_name": "pip", "requires_dists": [], "requires_python": ">=3.8", - "version": "24.1.1" + "version": "24.2" }, { "artifacts": [ @@ -1211,13 +1236,13 @@ "artifacts": [ { "algorithm": "sha256", - "hash": "c434598117762e2bd304e526244f67bf66bbd7b5d6cf22138be51ff661980343", - "url": "https://files.pythonhosted.org/packages/4e/e7/81ebdd666d3bff6670d27349b5053605d83d55548e6bd5711f3b0ae7dd23/pytest-8.2.2-py3-none-any.whl" + "hash": "4ba08f9ae7dcf84ded419494d229b48d0903ea6407b030eaec46df5e6a73bba5", + "url": "https://files.pythonhosted.org/packages/0f/f9/cf155cf32ca7d6fa3601bc4c5dd19086af4b320b706919d48a4c79081cf9/pytest-8.3.2-py3-none-any.whl" }, { "algorithm": "sha256", - "hash": "de4bb8104e201939ccdc688b27a89a7be2079b22e2bd2b07f806b6ba71117977", - "url": "https://files.pythonhosted.org/packages/a6/58/e993ca5357553c966b9e73cb3475d9c935fe9488746e13ebdf9b80fae508/pytest-8.2.2.tar.gz" + "hash": "c132345d12ce551242c87269de812483f5bcc87cdbb4722e48487ba194f9fdce", + "url": "https://files.pythonhosted.org/packages/b4/8c/9862305bdcd6020bc7b45b1b5e7397a6caf1a33d3025b9a003b39075ffb2/pytest-8.3.2.tar.gz" } ], "project_name": "pytest", @@ -1230,7 +1255,7 @@ "iniconfig", "mock; extra == \"dev\"", "packaging", - "pluggy<2.0,>=1.5", + "pluggy<2,>=1.5", "pygments>=2.7.2; extra == \"dev\"", "requests; extra == \"dev\"", "setuptools; extra == \"dev\"", @@ -1238,7 +1263,7 @@ "xmlschema; extra == \"dev\"" ], "requires_python": ">=3.8", - "version": "8.2.2" + "version": "8.3.2" }, { "artifacts": [ @@ -1341,13 +1366,13 @@ "artifacts": [ { "algorithm": "sha256", - "hash": "b8b8060bb426838fbe942479c90296ce976249451118ef566a5a0b7d8b78fb05", - "url": "https://files.pythonhosted.org/packages/42/54/2a8ecfcc9a714a6fbf86559a4b0f50b126a4ac4269ea8134f2c75c3e73de/setuptools-70.2.0-py3-none-any.whl" + "hash": "5a03e1860cf56bb6ef48ce186b0e557fdba433237481a9a625176c2831be15d1", + "url": "https://files.pythonhosted.org/packages/e1/58/e0ef3b9974a04ce9cde2a7a33881ddcb2d68450803745804545cdd8d258f/setuptools-72.1.0-py3-none-any.whl" }, { "algorithm": "sha256", - "hash": "bd63e505105011b25c3c11f753f7e3b8465ea739efddaccef8f0efac2137bac1", - "url": "https://files.pythonhosted.org/packages/8d/e6/2fc95aec377988ff3ca882aa58d4f6ab35ff59a12b1611a9fe3075eb3019/setuptools-70.2.0.tar.gz" + "hash": "8d243eff56d095e5817f796ede6ae32941278f542e0f941867cc05ae52b162ec", + "url": "https://files.pythonhosted.org/packages/5e/11/487b18cc768e2ae25a919f230417983c8d5afa1b6ee0abd8b6db0b89fa1d/setuptools-72.1.0.tar.gz" } ], "project_name": "setuptools", @@ -1356,16 +1381,23 @@ "filelock>=3.4.0; extra == \"test\"", "furo; extra == \"doc\"", "importlib-metadata; extra == \"test\"", + "importlib-metadata>=6; python_version < \"3.10\" and extra == \"core\"", + "importlib-resources>=5.10.2; python_version < \"3.9\" and extra == \"core\"", "ini2toml[lite]>=0.14; extra == \"test\"", "jaraco.develop>=7.21; (python_version >= \"3.9\" and sys_platform != \"cygwin\") and extra == \"test\"", "jaraco.envs>=2.2; extra == \"test\"", "jaraco.packaging>=9.3; extra == \"doc\"", "jaraco.path>=3.2.0; extra == \"test\"", "jaraco.test; extra == \"test\"", + "jaraco.text>=3.7; extra == \"core\"", "jaraco.tidelift>=1.4; extra == \"doc\"", - "mypy==1.10.0; extra == \"test\"", + "more-itertools>=8.8; extra == \"core\"", + "mypy==1.11.*; extra == \"test\"", + "ordered-set>=3.1.1; extra == \"core\"", "packaging>=23.2; extra == \"test\"", + "packaging>=24; extra == \"core\"", "pip>=19.1; extra == \"test\"", + "platformdirs>=2.6.2; extra == \"core\"", "pygments-github-lexers==0.0.5; extra == \"doc\"", "pyproject-hooks!=1.1; extra == \"doc\"", "pyproject-hooks!=1.1; extra == \"test\"", @@ -1376,6 +1408,8 @@ "pytest-home>=0.5; extra == \"test\"", "pytest-mypy; extra == \"test\"", "pytest-perf; sys_platform != \"cygwin\" and extra == \"test\"", + "pytest-ruff<0.4; platform_system == \"Windows\" and extra == \"test\"", + "pytest-ruff>=0.2.1; sys_platform != \"cygwin\" and extra == \"test\"", "pytest-ruff>=0.3.2; sys_platform != \"cygwin\" and extra == \"test\"", "pytest-subprocess; extra == \"test\"", "pytest-timeout; extra == \"test\"", @@ -1390,11 +1424,13 @@ "sphinxcontrib-towncrier; extra == \"doc\"", "tomli-w>=1.0.0; extra == \"test\"", "tomli; extra == \"test\"", + "tomli>=2.0.1; python_version < \"3.11\" and extra == \"core\"", "virtualenv>=13.0.0; extra == \"test\"", - "wheel; extra == \"test\"" + "wheel; extra == \"test\"", + "wheel>=0.43.0; extra == \"core\"" ], "requires_python": ">=3.8", - "version": "70.2.0" + "version": "72.1.0" }, { "artifacts": [ @@ -1460,38 +1496,56 @@ "artifacts": [ { "algorithm": "sha256", - "hash": "413f75440be4cacf328f580b4274ada4565fb2187d696a84970c23f77b64d8c3", - "url": "https://files.pythonhosted.org/packages/b4/fa/130c32ed94cf270e3d0b9ded16fb7b2c8fea86fa7263c29a696a30c1dde7/sphinx-7.3.7-py3-none-any.whl" + "hash": "eaa337ff55a1579b6549dc679565eac1e3d000563bcb1c8ab0d0fefbc0c2cdc7", + "url": "https://files.pythonhosted.org/packages/4c/f3/038b302fdfbe3be7da016777069f26ceefe11a681055ea1f7817546508e3/soupsieve-2.5-py3-none-any.whl" }, { "algorithm": "sha256", - "hash": "a4a7db75ed37531c05002d56ed6948d4c42f473a36f46e1382b0bd76ca9627bc", - "url": "https://files.pythonhosted.org/packages/b7/0a/b88033900b1582f5ed8f880263363daef968d1cd064175e32abfd9714410/sphinx-7.3.7.tar.gz" + "hash": "5663d5a7b3bfaeee0bc4372e7fc48f9cff4940b3eec54a6451cc5299f1097690", + "url": "https://files.pythonhosted.org/packages/ce/21/952a240de1c196c7e3fbcd4e559681f0419b1280c617db21157a0390717b/soupsieve-2.5.tar.gz" + } + ], + "project_name": "soupsieve", + "requires_dists": [], + "requires_python": ">=3.8", + "version": "2.5" + }, + { + "artifacts": [ + { + "algorithm": "sha256", + "hash": "c2419e2135d11f1951cd994d6eb18a1835bd8fdd8429f9ca375dc1f3281bd239", + "url": "https://files.pythonhosted.org/packages/0d/ef/153f6803c5d5f8917dbb7f7fcf6d34a871ede3296fa89c2c703f5f8a6c8e/sphinx-7.4.7-py3-none-any.whl" + }, + { + "algorithm": "sha256", + "hash": "242f92a7ea7e6c5b406fdc2615413890ba9f699114a9c09192d7dfead2ee9cfe", + "url": "https://files.pythonhosted.org/packages/5b/be/50e50cb4f2eff47df05673d361095cafd95521d2a22521b920c67a372dcb/sphinx-7.4.7.tar.gz" } ], "project_name": "sphinx", "requires_dists": [ - "Jinja2>=3.0", - "Pygments>=2.14", + "Jinja2>=3.1", + "Pygments>=2.17", "alabaster~=0.7.14", - "babel>=2.9", - "colorama>=0.4.5; sys_platform == \"win32\"", + "babel>=2.13", + "colorama>=0.4.6; sys_platform == \"win32\"", "cython>=3.0; extra == \"test\"", "defusedxml>=0.7.1; extra == \"test\"", - "docutils<0.22,>=0.18.1", - "flake8>=3.5.0; extra == \"lint\"", + "docutils<0.22,>=0.20", + "flake8>=6.0; extra == \"lint\"", "imagesize>=1.3", - "importlib-metadata>=4.8; python_version < \"3.10\"", - "importlib_metadata; extra == \"lint\"", - "mypy==1.9.0; extra == \"lint\"", - "packaging>=21.0", + "importlib-metadata>=6.0; extra == \"lint\"", + "importlib-metadata>=6.0; python_version < \"3.10\"", + "mypy==1.10.1; extra == \"lint\"", + "packaging>=23.0", "pytest>=6.0; extra == \"lint\"", - "pytest>=6.0; extra == \"test\"", - "requests>=2.25.0", - "ruff==0.3.7; extra == \"lint\"", - "setuptools>=67.0; extra == \"test\"", - "snowballstemmer>=2.0", - "sphinx-lint; extra == \"lint\"", + "pytest>=8.0; extra == \"test\"", + "requests>=2.30.0", + "ruff==0.5.2; extra == \"lint\"", + "setuptools>=70.0; extra == \"test\"", + "snowballstemmer>=2.2", + "sphinx-lint>=0.9; extra == \"lint\"", "sphinxcontrib-applehelp", "sphinxcontrib-devhelp", "sphinxcontrib-htmlhelp>=2.0.0", @@ -1499,13 +1553,14 @@ "sphinxcontrib-qthelp", "sphinxcontrib-serializinghtml>=1.1.9", "sphinxcontrib-websupport; extra == \"docs\"", - "tomli; extra == \"lint\"", + "tomli>=2; extra == \"lint\"", "tomli>=2; python_version < \"3.11\"", - "types-docutils; extra == \"lint\"", - "types-requests; extra == \"lint\"" + "types-docutils==0.21.0.20240711; extra == \"lint\"", + "types-requests>=2.30.0; extra == \"lint\"", + "typing_extensions>=4.9; extra == \"test\"" ], "requires_python": ">=3.9", - "version": "7.3.7" + "version": "7.4.7" }, { "artifacts": [ @@ -1546,74 +1601,74 @@ "artifacts": [ { "algorithm": "sha256", - "hash": "cb61eb0ec1b61f349e5cc36b2028e9e7ca765be05e49641c97241274753067b4", - "url": "https://files.pythonhosted.org/packages/56/89/fea3fbf6785b388e6cb8a1beaf62f96e80b37311bdeed6e133388a732426/sphinxcontrib_applehelp-1.0.8-py3-none-any.whl" + "hash": "4cd3f0ec4ac5dd9c17ec65e9ab272c9b867ea77425228e68ecf08d6b28ddbdb5", + "url": "https://files.pythonhosted.org/packages/5d/85/9ebeae2f76e9e77b952f4b274c27238156eae7979c5421fba91a28f4970d/sphinxcontrib_applehelp-2.0.0-py3-none-any.whl" }, { "algorithm": "sha256", - "hash": "c40a4f96f3776c4393d933412053962fac2b84f4c99a7982ba42e09576a70619", - "url": "https://files.pythonhosted.org/packages/26/6b/68f470fc337ed24043fec987b101f25b35010970bd958970c2ae5990859f/sphinxcontrib_applehelp-1.0.8.tar.gz" + "hash": "2f29ef331735ce958efa4734873f084941970894c6090408b079c61b2e1c06d1", + "url": "https://files.pythonhosted.org/packages/ba/6e/b837e84a1a704953c62ef8776d45c3e8d759876b4a84fe14eba2859106fe/sphinxcontrib_applehelp-2.0.0.tar.gz" } ], "project_name": "sphinxcontrib-applehelp", "requires_dists": [ "Sphinx>=5; extra == \"standalone\"", - "docutils-stubs; extra == \"lint\"", - "flake8; extra == \"lint\"", "mypy; extra == \"lint\"", - "pytest; extra == \"test\"" + "pytest; extra == \"test\"", + "ruff==0.5.5; extra == \"lint\"", + "types-docutils; extra == \"lint\"" ], "requires_python": ">=3.9", - "version": "1.0.8" + "version": "2.0.0" }, { "artifacts": [ { "algorithm": "sha256", - "hash": "6485d09629944511c893fa11355bda18b742b83a2b181f9a009f7e500595c90f", - "url": "https://files.pythonhosted.org/packages/a0/52/1049d918d1d1c72857d285c3f0c64c1cbe0be394ce1c93a3d2aa4f39fe3b/sphinxcontrib_devhelp-1.0.6-py3-none-any.whl" + "hash": "aefb8b83854e4b0998877524d1029fd3e6879210422ee3780459e28a1f03a8a2", + "url": "https://files.pythonhosted.org/packages/35/7a/987e583882f985fe4d7323774889ec58049171828b58c2217e7f79cdf44e/sphinxcontrib_devhelp-2.0.0-py3-none-any.whl" }, { "algorithm": "sha256", - "hash": "9893fd3f90506bc4b97bdb977ceb8fbd823989f4316b28c3841ec128544372d3", - "url": "https://files.pythonhosted.org/packages/c7/a1/80b7e9f677abc673cb9320bf255ad4e08931ccbc2e66bde4b59bad3809ad/sphinxcontrib_devhelp-1.0.6.tar.gz" + "hash": "411f5d96d445d1d73bb5d52133377b4248ec79db5c793ce7dbe59e074b4dd1ad", + "url": "https://files.pythonhosted.org/packages/f6/d2/5beee64d3e4e747f316bae86b55943f51e82bb86ecd325883ef65741e7da/sphinxcontrib_devhelp-2.0.0.tar.gz" } ], "project_name": "sphinxcontrib-devhelp", "requires_dists": [ "Sphinx>=5; extra == \"standalone\"", - "docutils-stubs; extra == \"lint\"", - "flake8; extra == \"lint\"", "mypy; extra == \"lint\"", - "pytest; extra == \"test\"" + "pytest; extra == \"test\"", + "ruff==0.5.5; extra == \"lint\"", + "types-docutils; extra == \"lint\"" ], "requires_python": ">=3.9", - "version": "1.0.6" + "version": "2.0.0" }, { "artifacts": [ { "algorithm": "sha256", - "hash": "393f04f112b4d2f53d93448d4bce35842f62b307ccdc549ec1585e950bc35e04", - "url": "https://files.pythonhosted.org/packages/c2/e9/74c4cda5b409af3222fda38f0774e616011bc935f639dbc0da5ca2d1be7d/sphinxcontrib_htmlhelp-2.0.5-py3-none-any.whl" + "hash": "166759820b47002d22914d64a075ce08f4c46818e17cfc9470a9786b759b19f8", + "url": "https://files.pythonhosted.org/packages/0a/7b/18a8c0bcec9182c05a0b3ec2a776bba4ead82750a55ff798e8d406dae604/sphinxcontrib_htmlhelp-2.1.0-py3-none-any.whl" }, { "algorithm": "sha256", - "hash": "0dc87637d5de53dd5eec3a6a01753b1ccf99494bd756aafecd74b4fa9e729015", - "url": "https://files.pythonhosted.org/packages/8a/03/2f9d699fbfdf03ecb3b6d0e2a268a8998d009f2a9f699c2dcc936899257d/sphinxcontrib_htmlhelp-2.0.5.tar.gz" + "hash": "c9e2916ace8aad64cc13a0d233ee22317f2b9025b9cf3295249fa985cc7082e9", + "url": "https://files.pythonhosted.org/packages/43/93/983afd9aa001e5201eab16b5a444ed5b9b0a7a010541e0ddfbbfd0b2470c/sphinxcontrib_htmlhelp-2.1.0.tar.gz" } ], "project_name": "sphinxcontrib-htmlhelp", "requires_dists": [ "Sphinx>=5; extra == \"standalone\"", - "docutils-stubs; extra == \"lint\"", - "flake8; extra == \"lint\"", "html5lib; extra == \"test\"", "mypy; extra == \"lint\"", - "pytest; extra == \"test\"" + "pytest; extra == \"test\"", + "ruff==0.5.5; extra == \"lint\"", + "types-docutils; extra == \"lint\"" ], "requires_python": ">=3.9", - "version": "2.0.5" + "version": "2.1.0" }, { "artifacts": [ @@ -1641,49 +1696,50 @@ "artifacts": [ { "algorithm": "sha256", - "hash": "e2ae3b5c492d58fcbd73281fbd27e34b8393ec34a073c792642cd8e529288182", - "url": "https://files.pythonhosted.org/packages/80/b3/1beac14a88654d2e5120d0143b49be5ad450b86eb1963523d8dbdcc51eb2/sphinxcontrib_qthelp-1.0.7-py3-none-any.whl" + "hash": "b18a828cdba941ccd6ee8445dbe72ffa3ef8cbe7505d8cd1fa0d42d3f2d5f3eb", + "url": "https://files.pythonhosted.org/packages/27/83/859ecdd180cacc13b1f7e857abf8582a64552ea7a061057a6c716e790fce/sphinxcontrib_qthelp-2.0.0-py3-none-any.whl" }, { "algorithm": "sha256", - "hash": "053dedc38823a80a7209a80860b16b722e9e0209e32fea98c90e4e6624588ed6", - "url": "https://files.pythonhosted.org/packages/ac/29/705cd4e93e98a8473d62b5c32288e6de3f0c9660d3c97d4e80d3dbbad82b/sphinxcontrib_qthelp-1.0.7.tar.gz" + "hash": "4fe7d0ac8fc171045be623aba3e2a8f613f8682731f9153bb2e40ece16b9bbab", + "url": "https://files.pythonhosted.org/packages/68/bc/9104308fc285eb3e0b31b67688235db556cd5b0ef31d96f30e45f2e51cae/sphinxcontrib_qthelp-2.0.0.tar.gz" } ], "project_name": "sphinxcontrib-qthelp", "requires_dists": [ "Sphinx>=5; extra == \"standalone\"", - "docutils-stubs; extra == \"lint\"", - "flake8; extra == \"lint\"", + "defusedxml>=0.7.1; extra == \"test\"", "mypy; extra == \"lint\"", - "pytest; extra == \"test\"" + "pytest; extra == \"test\"", + "ruff==0.5.5; extra == \"lint\"", + "types-docutils; extra == \"lint\"" ], "requires_python": ">=3.9", - "version": "1.0.7" + "version": "2.0.0" }, { "artifacts": [ { "algorithm": "sha256", - "hash": "326369b8df80a7d2d8d7f99aa5ac577f51ea51556ed974e7716cfd4fca3f6cb7", - "url": "https://files.pythonhosted.org/packages/38/24/228bb903ea87b9e08ab33470e6102402a644127108c7117ac9c00d849f82/sphinxcontrib_serializinghtml-1.1.10-py3-none-any.whl" + "hash": "6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331", + "url": "https://files.pythonhosted.org/packages/52/a7/d2782e4e3f77c8450f727ba74a8f12756d5ba823d81b941f1b04da9d033a/sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl" }, { "algorithm": "sha256", - "hash": "93f3f5dc458b91b192fe10c397e324f262cf163d79f3282c158e8436a2c4511f", - "url": "https://files.pythonhosted.org/packages/54/13/8dd7a7ed9c58e16e20c7f4ce8e4cb6943eb580955236d0c0d00079a73c49/sphinxcontrib_serializinghtml-1.1.10.tar.gz" + "hash": "e9d912827f872c029017a53f0ef2180b327c3f7fd23c87229f7a8e8b70031d4d", + "url": "https://files.pythonhosted.org/packages/3b/44/6716b257b0aa6bfd51a1b31665d1c205fb12cb5ad56de752dfa15657de2f/sphinxcontrib_serializinghtml-2.0.0.tar.gz" } ], "project_name": "sphinxcontrib-serializinghtml", "requires_dists": [ "Sphinx>=5; extra == \"standalone\"", - "docutils-stubs; extra == \"lint\"", - "flake8; extra == \"lint\"", "mypy; extra == \"lint\"", - "pytest; extra == \"test\"" + "pytest; extra == \"test\"", + "ruff==0.5.5; extra == \"lint\"", + "types-docutils; extra == \"lint\"" ], "requires_python": ">=3.9", - "version": "1.1.10" + "version": "2.0.0" }, { "artifacts": [ @@ -1752,19 +1808,57 @@ "artifacts": [ { "algorithm": "sha256", - "hash": "7f6e84ba8fcd2454c5b8bb8d77384d091a901929cc2b31079316e10eb346580a", - "url": "https://files.pythonhosted.org/packages/a3/36/665402239b46069189e69a60ed1ed0ff97818069e1289461fab66ca52911/types_docutils-0.21.0.20240423-py3-none-any.whl" + "hash": "7ceda66a93ba28d759d5046d7fec9f4cad2f563a77b3a789efc90bcadafeefd1", + "url": "https://files.pythonhosted.org/packages/3d/93/c2a9ecb06a2740b59342eaa51099b4f56c398196f99b826586ab0febc31b/types_beautifulsoup4-4.12.0.20240511-py3-none-any.whl" }, { "algorithm": "sha256", - "hash": "7716ec6c68b5179b7ba1738cace2f1326e64df9f44b7ab08d9904d32c23fc15f", - "url": "https://files.pythonhosted.org/packages/60/bb/84ce13cef1856a0091664f828bea7489c1c4323a7cb389ebbcc85908cc6c/types-docutils-0.21.0.20240423.tar.gz" + "hash": "004f6096fdd83b19cdbf6cb10e4eae57b10205eccc365d0a69d77da836012e28", + "url": "https://files.pythonhosted.org/packages/56/4a/a5630805a9ab67c7bc852a16826e72b884a9460328c95f5202fb37e3473c/types-beautifulsoup4-4.12.0.20240511.tar.gz" + } + ], + "project_name": "types-beautifulsoup4", + "requires_dists": [ + "types-html5lib" + ], + "requires_python": ">=3.8", + "version": "4.12.0.20240511" + }, + { + "artifacts": [ + { + "algorithm": "sha256", + "hash": "bf51c6c488d23c0412f9b3ba10686fb1a6cb0b957ef04b45128d8a55c79ebb00", + "url": "https://files.pythonhosted.org/packages/29/87/331235eaad70a8ac6c4f959887e3a9cfb4f89d30f9522d7c97bc070111ee/types_docutils-0.21.0.20240724-py3-none-any.whl" + }, + { + "algorithm": "sha256", + "hash": "29ff7e27660f4fe76ea61d7e54d05ca3ce3b733ca9e8e8721e0fa587dbc10489", + "url": "https://files.pythonhosted.org/packages/41/a9/045b5193f96e505c52b94b1d9ece219161e705967add917186beda781aee/types-docutils-0.21.0.20240724.tar.gz" } ], "project_name": "types-docutils", "requires_dists": [], "requires_python": ">=3.8", - "version": "0.21.0.20240423" + "version": "0.21.0.20240724" + }, + { + "artifacts": [ + { + "algorithm": "sha256", + "hash": "af5de0125cb0fe5667543b158db83849b22e25c0e36c9149836b095548bf1020", + "url": "https://files.pythonhosted.org/packages/9a/75/5947ce2d3c41943bad9cd8c7976a3f896904e9b4d5c1cd785b866d185436/types_html5lib-1.1.11.20240228-py3-none-any.whl" + }, + { + "algorithm": "sha256", + "hash": "22736b7299e605ec4ba539d48691e905fd0c61c3ea610acc59922232dc84cede", + "url": "https://files.pythonhosted.org/packages/cc/82/1989f42c68cc60cd0d28b185665e9a1ffc1beb9bff12b3849c49d82cd70a/types-html5lib-1.1.11.20240228.tar.gz" + } + ], + "project_name": "types-html5lib", + "requires_dists": [], + "requires_python": ">=3.8", + "version": "1.1.11.20240228" }, { "artifacts": [ @@ -1939,6 +2033,7 @@ "requirements": [ "appdirs", "autoflake", + "beautifulsoup4", "black", "click", "click-log", @@ -1961,6 +2056,7 @@ "toml", "tqdm", "types-appdirs", + "types-beautifulsoup4", "types-docutils", "types-psutil", "types-toml", diff --git a/nox-support/check-reqs.txt b/nox-support/check-reqs.txt index cf0e96a..d82c260 100644 --- a/nox-support/check-reqs.txt +++ b/nox-support/check-reqs.txt @@ -1,6 +1,7 @@ mypy nox types-appdirs +types-beautifulsoup4 types-docutils types-psutil types-toml diff --git a/nox-support/check-reqs.windows-amd64.lock.txt b/nox-support/check-reqs.windows-amd64.lock.txt index e7d00ac..6c4e679 100644 --- a/nox-support/check-reqs.windows-amd64.lock.txt +++ b/nox-support/check-reqs.windows-amd64.lock.txt @@ -1,16 +1,19 @@ -mypy==1.10.1 \ - --hash=sha256:3c4c2992f6ea46ff7fce0072642cfb62af7a2484efe69017ed8b095f7b39ef31 \ - --hash=sha256:71d8ac0b906354ebda8ef1673e5fde785936ac1f29ff6987c7483cfbd5a4235a \ - --hash=sha256:1f8f492d7db9e3593ef42d4f115f04e556130f2819ad33ab84551403e97dd4c0 +mypy==1.11.1 \ + --hash=sha256:64f4a90e3ea07f590c5bcf9029035cf0efeae5ba8be511a8caada1a4893f5525 \ + --hash=sha256:0624bdb940255d2dd24e829d99a13cfeb72e4e9031f9492148f410ed30bcab54 \ + --hash=sha256:f404a0b069709f18bbdb702eb3dcfe51910602995de00bd39cea3050b5772d08 nox==2024.4.15 \ --hash=sha256:6492236efa15a460ecb98e7b67562a28b70da006ab0be164e8821177577c0565 \ --hash=sha256:ecf6700199cdfa9e5ea0a41ff5e6ef4641d09508eda6edb89d9987864115817f types-appdirs==1.4.3.5 \ --hash=sha256:337c750e423c40911d389359b4edabe5bbc2cdd5cd0bd0518b71d2839646273b \ --hash=sha256:83268da64585361bfa291f8f506a209276212a0497bd37f0512a939b3d69ff14 -types-docutils==0.21.0.20240423 \ - --hash=sha256:7f6e84ba8fcd2454c5b8bb8d77384d091a901929cc2b31079316e10eb346580a \ - --hash=sha256:7716ec6c68b5179b7ba1738cace2f1326e64df9f44b7ab08d9904d32c23fc15f +types-beautifulsoup4==4.12.0.20240511 \ + --hash=sha256:7ceda66a93ba28d759d5046d7fec9f4cad2f563a77b3a789efc90bcadafeefd1 \ + --hash=sha256:004f6096fdd83b19cdbf6cb10e4eae57b10205eccc365d0a69d77da836012e28 +types-docutils==0.21.0.20240724 \ + --hash=sha256:bf51c6c488d23c0412f9b3ba10686fb1a6cb0b957ef04b45128d8a55c79ebb00 \ + --hash=sha256:29ff7e27660f4fe76ea61d7e54d05ca3ce3b733ca9e8e8721e0fa587dbc10489 types-psutil==6.0.0.20240621 \ --hash=sha256:b02f05d2c4141cd5926d82d8b56e4292a4d8f483d8a3400b73edf153834a3c64 \ --hash=sha256:1be027326c42ff51ebd65255a5146f9dc57e5cf8c4f9519a88b3f3f6a7fcd00e @@ -38,6 +41,9 @@ packaging==24.1 \ virtualenv==20.26.3 \ --hash=sha256:8cc4a31139e796e9a7de2cd5cf2489de1217193116a8fd42328f1bd65f434589 \ --hash=sha256:4c43a2a236279d9ea36a0d76f98d84bd6ca94ac4e0f4a3b9d46d05e10fea542a +types-html5lib==1.1.11.20240228 \ + --hash=sha256:af5de0125cb0fe5667543b158db83849b22e25c0e36c9149836b095548bf1020 \ + --hash=sha256:22736b7299e605ec4ba539d48691e905fd0c61c3ea610acc59922232dc84cede colorama==0.4.6 \ --hash=sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6 \ --hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 diff --git a/nox-support/doc-reqs.windows-amd64.lock.txt b/nox-support/doc-reqs.windows-amd64.lock.txt index 4e0fd04..8e24686 100644 --- a/nox-support/doc-reqs.windows-amd64.lock.txt +++ b/nox-support/doc-reqs.windows-amd64.lock.txt @@ -4,9 +4,9 @@ docutils==0.21.2 \ myst-parser==3.0.1 \ --hash=sha256:6457aaa33a5d474aca678b8ead9b3dc298e89c68e67012e73146ea6fd54babf1 \ --hash=sha256:88f0cb406cb363b077d176b51c476f62d60604d68a8dcdf4832e080441301a87 -sphinx==7.3.7 \ - --hash=sha256:413f75440be4cacf328f580b4274ada4565fb2187d696a84970c23f77b64d8c3 \ - --hash=sha256:a4a7db75ed37531c05002d56ed6948d4c42f473a36f46e1382b0bd76ca9627bc +sphinx==7.4.7 \ + --hash=sha256:c2419e2135d11f1951cd994d6eb18a1835bd8fdd8429f9ca375dc1f3281bd239 \ + --hash=sha256:242f92a7ea7e6c5b406fdc2615413890ba9f699114a9c09192d7dfead2ee9cfe sphinx-click==6.0.0 \ --hash=sha256:1e0a3c83bcb7c55497751b19d07ebe56b5d7b85eb76dd399cf9061b497adc317 \ --hash=sha256:f5d664321dc0c6622ff019f1e1c84e58ce0cecfddeb510e004cf60c2a3ab465b @@ -57,24 +57,24 @@ requests==2.32.3 \ snowballstemmer==2.2.0 \ --hash=sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a \ --hash=sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1 -sphinxcontrib-applehelp==1.0.8 \ - --hash=sha256:cb61eb0ec1b61f349e5cc36b2028e9e7ca765be05e49641c97241274753067b4 \ - --hash=sha256:c40a4f96f3776c4393d933412053962fac2b84f4c99a7982ba42e09576a70619 -sphinxcontrib-devhelp==1.0.6 \ - --hash=sha256:6485d09629944511c893fa11355bda18b742b83a2b181f9a009f7e500595c90f \ - --hash=sha256:9893fd3f90506bc4b97bdb977ceb8fbd823989f4316b28c3841ec128544372d3 -sphinxcontrib-htmlhelp==2.0.5 \ - --hash=sha256:393f04f112b4d2f53d93448d4bce35842f62b307ccdc549ec1585e950bc35e04 \ - --hash=sha256:0dc87637d5de53dd5eec3a6a01753b1ccf99494bd756aafecd74b4fa9e729015 +sphinxcontrib-applehelp==2.0.0 \ + --hash=sha256:4cd3f0ec4ac5dd9c17ec65e9ab272c9b867ea77425228e68ecf08d6b28ddbdb5 \ + --hash=sha256:2f29ef331735ce958efa4734873f084941970894c6090408b079c61b2e1c06d1 +sphinxcontrib-devhelp==2.0.0 \ + --hash=sha256:aefb8b83854e4b0998877524d1029fd3e6879210422ee3780459e28a1f03a8a2 \ + --hash=sha256:411f5d96d445d1d73bb5d52133377b4248ec79db5c793ce7dbe59e074b4dd1ad +sphinxcontrib-htmlhelp==2.1.0 \ + --hash=sha256:166759820b47002d22914d64a075ce08f4c46818e17cfc9470a9786b759b19f8 \ + --hash=sha256:c9e2916ace8aad64cc13a0d233ee22317f2b9025b9cf3295249fa985cc7082e9 sphinxcontrib-jsmath==1.0.1 \ --hash=sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178 \ --hash=sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8 -sphinxcontrib-qthelp==1.0.7 \ - --hash=sha256:e2ae3b5c492d58fcbd73281fbd27e34b8393ec34a073c792642cd8e529288182 \ - --hash=sha256:053dedc38823a80a7209a80860b16b722e9e0209e32fea98c90e4e6624588ed6 -sphinxcontrib-serializinghtml==1.1.10 \ - --hash=sha256:326369b8df80a7d2d8d7f99aa5ac577f51ea51556ed974e7716cfd4fca3f6cb7 \ - --hash=sha256:93f3f5dc458b91b192fe10c397e324f262cf163d79f3282c158e8436a2c4511f +sphinxcontrib-qthelp==2.0.0 \ + --hash=sha256:b18a828cdba941ccd6ee8445dbe72ffa3ef8cbe7505d8cd1fa0d42d3f2d5f3eb \ + --hash=sha256:4fe7d0ac8fc171045be623aba3e2a8f613f8682731f9153bb2e40ece16b9bbab +sphinxcontrib-serializinghtml==2.0.0 \ + --hash=sha256:6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331 \ + --hash=sha256:e9d912827f872c029017a53f0ef2180b327c3f7fd23c87229f7a8e8b70031d4d click==8.1.7 \ --hash=sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28 \ --hash=sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de @@ -87,9 +87,9 @@ uc-micro-py==1.0.3 \ mdurl==0.1.2 \ --hash=sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8 \ --hash=sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba -certifi==2024.6.2 \ - --hash=sha256:ddc6c8ce995e6987e7faf5e3f1b02b302836a0e5d98ece18392cb1a36c72ad56 \ - --hash=sha256:3cd43f1c6fa7dedc5899d69d3ad0398fd018ad1a17fba83ddaf78aa46c747516 +certifi==2024.7.4 \ + --hash=sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90 \ + --hash=sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b charset-normalizer==3.3.2 \ --hash=sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001 \ --hash=sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc \ diff --git a/nox-support/lock.checksums b/nox-support/lock.checksums index 1cd9921..468fee1 100644 --- a/nox-support/lock.checksums +++ b/nox-support/lock.checksums @@ -1,4 +1,4 @@ { - "lock_checksum": "75eade5e4d981033ef344d7f351f830105d0d507277e719048998d59b881d4e1", - "requirements_checksum": "5ee5ab1e27ddf34d1d903f95dcdb9a4577cf73c83cd8bbcd449aaa9ac9d62f53" + "lock_checksum": "6cbbc6f77d7ec60ee96f041d119d7b3e70f254d5a46cddedfe4172a093093382", + "requirements_checksum": "559a46abe99f69bbe869289ed7118f232d62d8e422f18ea84c31a77f424920e0" } \ No newline at end of file diff --git a/nox-support/package-reqs.windows-amd64.lock.txt b/nox-support/package-reqs.windows-amd64.lock.txt index 2cd3518..0a80b75 100644 --- a/nox-support/package-reqs.windows-amd64.lock.txt +++ b/nox-support/package-reqs.windows-amd64.lock.txt @@ -4,12 +4,12 @@ shiv==1.0.6 \ click==8.1.7 \ --hash=sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28 \ --hash=sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de -pip==24.1.1 \ - --hash=sha256:efca15145a95e95c00608afeab66311d40bfb73bb2266a855befd705e6bb15a0 \ - --hash=sha256:5aa64f65e1952733ee0a9a9b1f52496ebdb3f3077cc46f80a16d983b58d1180a -setuptools==70.2.0 \ - --hash=sha256:b8b8060bb426838fbe942479c90296ce976249451118ef566a5a0b7d8b78fb05 \ - --hash=sha256:bd63e505105011b25c3c11f753f7e3b8465ea739efddaccef8f0efac2137bac1 +pip==24.2 \ + --hash=sha256:2cd581cf58ab7fcfca4ce8efa6dcacd0de5bf8d0a3eb9ec927e07405f4d9e2a2 \ + --hash=sha256:5b5e490b5e9cb275c879595064adce9ebd31b854e3e803740b72f9ccf34a45b8 +setuptools==72.1.0 \ + --hash=sha256:5a03e1860cf56bb6ef48ce186b0e557fdba433237481a9a625176c2831be15d1 \ + --hash=sha256:8d243eff56d095e5817f796ede6ae32941278f542e0f941867cc05ae52b162ec colorama==0.4.6 \ --hash=sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6 \ --hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 diff --git a/nox-support/test-reqs.windows-amd64.lock.txt b/nox-support/test-reqs.windows-amd64.lock.txt index 6977551..56ee83e 100644 --- a/nox-support/test-reqs.windows-amd64.lock.txt +++ b/nox-support/test-reqs.windows-amd64.lock.txt @@ -1,6 +1,6 @@ -pytest==8.2.2 \ - --hash=sha256:c434598117762e2bd304e526244f67bf66bbd7b5d6cf22138be51ff661980343 \ - --hash=sha256:de4bb8104e201939ccdc688b27a89a7be2079b22e2bd2b07f806b6ba71117977 +pytest==8.3.2 \ + --hash=sha256:4ba08f9ae7dcf84ded419494d229b48d0903ea6407b030eaec46df5e6a73bba5 \ + --hash=sha256:c132345d12ce551242c87269de812483f5bcc87cdbb4722e48487ba194f9fdce pytest-xdist==3.6.1 \ --hash=sha256:9ed4adfb68a016610848639bb7e02c9352d5d9f03d04809919e2dafc3be4cca7 \ --hash=sha256:ead156a4db231eec769737f57668ef58a2084a34b2e55c4a8fa20d861107300d diff --git a/requirements.txt b/requirements.txt index 4e49d90..8010327 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,5 @@ appdirs +beautifulsoup4 click click-log click_didyoumean diff --git a/requirements.windows-amd64.lock.txt b/requirements.windows-amd64.lock.txt index c41b86b..8dee0a1 100644 --- a/requirements.windows-amd64.lock.txt +++ b/requirements.windows-amd64.lock.txt @@ -1,6 +1,9 @@ appdirs==1.4.4 \ --hash=sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128 \ --hash=sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41 +beautifulsoup4==4.12.3 \ + --hash=sha256:b80878c9f40111313e55da8ba20bdba06d8fa3969fc68304167741bbf9e082ed \ + --hash=sha256:74e3d1928edc070d21748185c46e3fb33490f22f52a3addee9aee0f4f7781051 click==8.1.7 \ --hash=sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28 \ --hash=sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de @@ -25,15 +28,18 @@ psutil==6.0.0 \ tqdm==4.66.4 \ --hash=sha256:b75ca56b413b030bc3f00af51fd2c1a1a5eac6a0c1cca83cbb37a5c52abce644 \ --hash=sha256:e4d936c9de8727928f3be6079590e97d9abfe8d39a590be678eb5919ffc186bb +soupsieve==2.5 \ + --hash=sha256:eaa337ff55a1579b6549dc679565eac1e3d000563bcb1c8ab0d0fefbc0c2cdc7 \ + --hash=sha256:5663d5a7b3bfaeee0bc4372e7fc48f9cff4940b3eec54a6451cc5299f1097690 colorama==0.4.6 \ --hash=sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6 \ --hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 anyio==4.4.0 \ --hash=sha256:c1b2d8f46a8a812513012e1107cb0e68c17159a7a594208005a57dc776e1bdc7 \ --hash=sha256:5aadc6a1bbb7cdb0bede386cac5e2940f5e2ff3aa20277e991cf028e0585ce94 -certifi==2024.6.2 \ - --hash=sha256:ddc6c8ce995e6987e7faf5e3f1b02b302836a0e5d98ece18392cb1a36c72ad56 \ - --hash=sha256:3cd43f1c6fa7dedc5899d69d3ad0398fd018ad1a17fba83ddaf78aa46c747516 +certifi==2024.7.4 \ + --hash=sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90 \ + --hash=sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b httpcore==1.0.5 \ --hash=sha256:421f18bac248b25d310f3cacd198d55b8e6125c107797b609ff9b7a6ba7991b5 \ --hash=sha256:34a38e2f9291467ee3b44e89dd52615370e152954ba21721378a87b2960f7a61 diff --git a/science/__init__.py b/science/__init__.py index 5fe230a..ca56cd6 100644 --- a/science/__init__.py +++ b/science/__init__.py @@ -3,6 +3,6 @@ from packaging.version import Version -__version__ = "0.5.0" +__version__ = "0.6.0" VERSION = Version(__version__) diff --git a/science/fetcher.py b/science/fetcher.py index ed73cc8..b6156f8 100644 --- a/science/fetcher.py +++ b/science/fetcher.py @@ -83,7 +83,7 @@ def require_password(auth_type: str) -> str: return None -def _configured_client(url: Url, headers: Mapping[str, str] | None = None) -> httpx.Client: +def configured_client(url: Url, headers: Mapping[str, str] | None = None) -> httpx.Client: headers = dict(headers) if headers else {} auth = _configure_auth(url) if "Authorization" not in headers else None return httpx.Client(follow_redirects=True, headers=headers, auth=auth) @@ -96,7 +96,7 @@ def _fetch_to_cache( match cache_result: case Missing(work=work): with ( - _configured_client(url, headers).stream("GET", url) as response, + configured_client(url, headers).stream("GET", url) as response, work.open("wb") as cache_fp, ): for data in response.iter_bytes(): @@ -128,7 +128,7 @@ def _maybe_expected_digest( case Fingerprint(_): return ExpectedDigest(fingerprint=fingerprint, algorithm=algorithm) case Url(url): - with _configured_client(url, headers) as client: + with configured_client(url, headers) as client: return ExpectedDigest( fingerprint=Fingerprint(client.get(url).text.split(" ", 1)[0].strip()), algorithm=algorithm, @@ -147,7 +147,7 @@ def _expected_digest( if expected_digest: return expected_digest - with _configured_client(url, headers) as client: + with configured_client(url, headers) as client: return ExpectedDigest( fingerprint=Fingerprint(client.get(f"{url}.{algorithm}").text.split(" ", 1)[0].strip()), algorithm=algorithm, @@ -167,7 +167,7 @@ def fetch_and_verify( match cache_result: case Missing(work=work): click.secho(f"Downloading {url} ...", fg="green") - with _configured_client(url, headers) as client: + with configured_client(url, headers) as client: expected_digest = _expected_digest( url, headers, fingerprint, algorithm=digest_algorithm ) diff --git a/science/providers/__init__.py b/science/providers/__init__.py index 3e4cc75..9270568 100644 --- a/science/providers/__init__.py +++ b/science/providers/__init__.py @@ -15,10 +15,10 @@ from science.dataclass.reflect import FieldInfo, dataclass_info from science.errors import InputError from science.model import Provider +from science.providers.pypy import PyPy from science.providers.python_build_standalone import PythonBuildStandalone -_BUILTIN_PROVIDER_TYPES = (PythonBuildStandalone,) - +_BUILTIN_PROVIDER_TYPES: tuple[type[Provider], ...] = (PythonBuildStandalone, PyPy) ConfigDataclass = TypeVar("ConfigDataclass", bound=Dataclass) diff --git a/science/providers/pypy.py b/science/providers/pypy.py new file mode 100644 index 0000000..8d48a0e --- /dev/null +++ b/science/providers/pypy.py @@ -0,0 +1,238 @@ +# Copyright 2024 Science project contributors. +# Licensed under the Apache License, Version 2.0 (see LICENSE). + +from __future__ import annotations + +import dataclasses +import os +import re +from dataclasses import dataclass +from datetime import timedelta + +from bs4 import BeautifulSoup +from packaging.version import Version + +from science.cache import download_cache +from science.dataclass.reflect import metadata +from science.errors import InputError +from science.fetcher import configured_client, fetch_text +from science.frozendict import FrozenDict +from science.hashing import Digest, Fingerprint +from science.model import Distribution, Fetch, File, FileType, Identifier, Provider, Url +from science.platform import Platform + + +@dataclass(frozen=True) +class FingerprintedAsset: + url: Url + name: str + extension: str + version: Version + release: str + arch: str + fingerprint: Fingerprint + file_type: FileType + + def file_stem(self) -> str: + return self.name[: -(len(self.extension) + 1)] + + +@dataclass(frozen=True) +class Config: + version: str = dataclasses.field( + metadata=metadata( + """The Python version to select. + + Must be in `.` form; e.g.: '3.11'. + + ```{caution} + PyPy does not provide all minor versions; so you should check + [their releases page][releases-page] to make sure they support the version you want. + ``` + + [releases-page]: https://downloads.python.org/pypy/ + """ + ) + ) + release: str | None = dataclasses.field( + default=None, + metadata=metadata( + f"""The PyPy release to use. + + Currently, stable releases are of the form `v..`, e.g.: 'v7.3.16'. + See the [PyPy releases page][releases-page] to discover available releases. + + If left unspecified the [latest release][latest-release] providing the specified Python + version is used. + + ```{{note}} + The latest lookup is cached for 5 days. To force a fresh lookup you can remove + the cache at `{download_cache().base_dir}`. + ``` + + [releases-page]: https://downloads.python.org/pypy/ + [latest-release]: https://pypy.org/download.html + """ + ), + ) + + +@dataclass(frozen=True) +class PyPy(Provider[Config]): + """Provides distributions from the [PyPy][PyPy] project. + + All science platforms are supported for PyPy release v7.3.0 and up. + + For all platforms, both a `pypy` placeholder (`#{:pypy}`) and a `python` placeholder + (`#{:python}`) are supported and will be substituted with the selected distribution's PyPy + interpreter binary path. + + [PyPy]: https://pypy.org/ + """ + + @staticmethod + def rank_compatibility(platform: Platform, arch: str) -> int | None: + match platform: + case Platform.Linux_aarch64: + match arch: + case "aarch64-portable": + return 0 + case "aarch64": + return 1 + case Platform.Linux_x86_64: + match arch: + case "linux64": + return 0 + case Platform.Macos_aarch64: + match arch: + case "macos_arm64": + return 0 + case Platform.Macos_x86_64: + match arch: + case "macos_x86_64": + return 0 + case "osx64": + return 1 + case Platform.Windows_x86_64: + match arch: + case "win64": + return 0 + case "win32": + return 1 + return None + + @classmethod + def config_dataclass(cls) -> type[Config]: + return Config + + @classmethod + def create(cls, identifier: Identifier, lazy: bool, config: Config) -> PyPy: + configured_version = Version(config.version) + configured_release = config.release + + checksums_html = BeautifulSoup( + fetch_text(url=Url("https://pypy.org/checksums.html"), ttl=timedelta(days=5)), + features="html.parser", + ) + assets = [] + for block in checksums_html.find_all( + string=re.compile(r"^[a-f0-9]{64}\s+pypy\d+\.\d+-.*$", flags=re.DOTALL | re.MULTILINE) + ): + for line in block.splitlines(): + match = re.match( + r"^\s*(?P[a-f0-9]{64})\s+" + r"(?P" + r"pypy(?P\d+\.\d+)-" + r"(?Pv[^-]+)-" + r"(?P[^.]+)\." + r"(?P.+)" + r")", + line, + ) + if not match: + continue + + version = Version(match["version"]) + if configured_version != version: + continue + + release = match["release"] + if configured_release and configured_release != release: + continue + + name = match["name"] + extension = match["extension"] + assets.append( + FingerprintedAsset( + url=Url(f"https://downloads.python.org/pypy/{name}"), + name=name, + extension=extension, + version=version, + release=release, + arch=match["arch"], + fingerprint=Fingerprint(match["fingerprint"]), + file_type=FileType.for_extension(extension), + ) + ) + + return PyPy(id=identifier, lazy=lazy, assets=tuple(assets)) + + id: Identifier + lazy: bool + assets: tuple[FingerprintedAsset, ...] + + def distribution(self, platform: Platform) -> Distribution | None: + selected_asset: FingerprintedAsset | None = None + asset_rank: int | None = None + for asset in self.assets: + if (rank := self.rank_compatibility(platform, asset.arch)) is not None and ( + asset_rank is None or rank < asset_rank + ): + asset_rank = rank + selected_asset = asset + if selected_asset is None: + raise InputError( + f"No compatible distribution was found for {platform} from amongst:\n" + f"{os.linesep.join(asset.name for asset in self.assets)}" + ) + + size = int( + configured_client(selected_asset.url).head(selected_asset.url).headers["Content-Length"] + ) + + file = File( + name=selected_asset.name, + key=self.id, + digest=Digest(size=size, fingerprint=selected_asset.fingerprint), + type=selected_asset.file_type, + is_executable=False, + eager_extract=False, + source=Fetch(url=Url(selected_asset.url), lazy=self.lazy), + ) + + placeholders = {} + pypy = ( + "pypy" if 2 == selected_asset.version.major else f"pypy{selected_asset.version.major}" + ) + + # These 4 distributions are the only distributions with `-portable` in the archive name, but + # not in the top level archive dir name: + # pypy2.7-v7.3.8-aarch64-portable.tar.bz2 + # pypy3.7-v7.3.8-aarch64-portable.tar.bz2 + # pypy3.8-v7.3.8-aarch64-portable.tar.bz2 + # pypy3.9-v7.3.8-aarch64-portable.tar.bz2 + # + # We correct for that discrepency here: + top_level_archive_dir = re.sub(r"-portable$", "", selected_asset.file_stem()) + + match platform: + case Platform.Windows_x86_64: + pypy_binary = f"{top_level_archive_dir}\\{pypy}.exe" + placeholders[Identifier("pypy")] = pypy_binary + placeholders[Identifier("python")] = pypy_binary + case _: + pypy_binary = f"{top_level_archive_dir}/bin/{pypy}" + placeholders[Identifier("pypy")] = pypy_binary + placeholders[Identifier("python")] = pypy_binary + + return Distribution(id=self.id, file=file, placeholders=FrozenDict(placeholders)) diff --git a/tests/test_exe.py b/tests/test_exe.py index 6f14758..df2e3c5 100644 --- a/tests/test_exe.py +++ b/tests/test_exe.py @@ -690,3 +690,48 @@ def test_invert_lazy_non_lazy(tmp_path: Path, science_exe: Path) -> None: assert "Cannot lazy fetch local file 'exe.py'." in result.stderr.strip().splitlines( keepends=False ) + + +def working_pypy_versions(): + match Platform.current(): + case Platform.Macos_aarch64: + return ["2.7", "3.8", "3.9", "3.10"] + case Platform.Linux_aarch64: + return ["2.7", "3.7", "3.8", "3.9", "3.10"] + return ["2.7", "3.6", "3.7", "3.8", "3.9", "3.10"] + + +@pytest.mark.parametrize("version", working_pypy_versions()) +def test_pypy_provider(tmp_path: Path, science_exe: Path, version: str) -> None: + dest = tmp_path / "dest" + chroot = tmp_path / "chroot" + chroot.mkdir(parents=True, exist_ok=True) + + subprocess.run( + args=[str(science_exe), "lift", "build", "--dest-dir", str(dest), "-"], + input=dedent( + f"""\ + [lift] + name = "pypy" + + [[lift.interpreters]] + id = "pypy" + provider = "PyPy" + version = "{version}" + lazy = true + + [[lift.commands]] + exe = "#{{pypy:python}}" + args = ["-c", "import sys; print('.'.join(map(str, sys.version_info[:2])))"] + """ + ), + cwd=chroot, + text=True, + check=True, + ) + + scie = dest / Platform.current().binary_name("pypy") + assert ( + version + == subprocess.run(args=[scie], text=True, stdout=subprocess.PIPE, check=True).stdout.strip() + )