From 17b56d24722bc57fd7c8adf8583fb1ca28181b8f Mon Sep 17 00:00:00 2001 From: Brian Marroquin Date: Sun, 5 Jun 2022 14:02:24 -0700 Subject: [PATCH] uses python-finder during env activate --- poetry.lock | 143 +++++++++++++++++-------- pyproject.toml | 1 + src/poetry/config/config.py | 7 +- src/poetry/utils/env.py | 81 ++++++++++---- tests/conftest.py | 14 +++ tests/console/commands/env/helpers.py | 10 ++ tests/console/commands/env/test_use.py | 15 ++- tests/console/commands/test_config.py | 3 + tests/utils/test_env.py | 43 ++++++++ 9 files changed, 246 insertions(+), 71 deletions(-) diff --git a/poetry.lock b/poetry.lock index d98783c894c..1e8a7072ad4 100644 --- a/poetry.lock +++ b/poetry.lock @@ -10,7 +10,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" name = "attrs" version = "21.4.0" description = "Classes Without Boilerplate" -category = "dev" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" @@ -37,6 +37,14 @@ requests = "*" filecache = ["lockfile (>=0.9)"] redis = ["redis (>=2.10.5)"] +[[package]] +name = "cached-property" +version = "1.5.2" +description = "A decorator for caching properties in classes." +category = "main" +optional = false +python-versions = "*" + [[package]] name = "cachy" version = "0.3.0" @@ -100,24 +108,36 @@ python-versions = ">=3.6,<4.0" crashtest = ">=0.3.1,<0.4.0" pylev = ">=1.3.0,<2.0.0" +[[package]] +name = "click" +version = "8.1.3" +description = "Composable command line interface toolkit" +category = "main" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} +importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} + [[package]] name = "colorama" version = "0.4.4" description = "Cross-platform colored terminal text." -category = "dev" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [[package]] name = "coverage" -version = "6.3.3" +version = "6.4" description = "Code coverage measurement for Python" category = "dev" optional = false python-versions = ">=3.7" [package.dependencies] -tomli = {version = "*", optional = true, markers = "extra == \"toml\""} +tomli = {version = "*", optional = true, markers = "python_version < \"3.11\" and extra == \"toml\""} [package.extras] toml = ["tomli"] @@ -586,6 +606,25 @@ packaging = ">=14.1" pytest = ">=2.9" termcolor = ">=1.1.0" +[[package]] +name = "pythonfinder" +version = "1.2.10" +description = "A cross-platform python discovery tool to help locate python on any system." +category = "main" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" + +[package.dependencies] +attrs = "*" +cached-property = "*" +click = "*" +packaging = "*" +six = "*" + +[package.extras] +dev = ["parver", "wheel (>=0.33.4)", "invoke", "twine", "lxml", "pre-commit", "towncrier"] +tests = ["pytest", "pytest-cov", "pytest-timeout", "coverage (<5)"] + [[package]] name = "pywin32-ctypes" version = "0.2.0" @@ -828,7 +867,7 @@ testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest- [metadata] lock-version = "1.1" python-versions = "^3.7" -content-hash = "35d68e6eba695382502b1b6faab833606823a2e0cadc1b96137059f1e343e1ad" +content-hash = "2404b5b85546db2736bf998bf587fb062f5ecbe681e114d822951a2abd3a8f3f" [metadata.files] atomicwrites = [ @@ -843,6 +882,10 @@ cachecontrol = [ {file = "CacheControl-0.12.11-py2.py3-none-any.whl", hash = "sha256:2c75d6a8938cb1933c75c50184549ad42728a27e9f6b92fd677c3151aa72555b"}, {file = "CacheControl-0.12.11.tar.gz", hash = "sha256:a5b9fcc986b184db101aa280b42ecdcdfc524892596f606858e0b7a8b4d9e144"}, ] +cached-property = [ + {file = "cached-property-1.5.2.tar.gz", hash = "sha256:9fa5755838eecbb2d234c3aa390bd80fbd3ac6b6869109bfc1b499f7bd89a130"}, + {file = "cached_property-1.5.2-py2.py3-none-any.whl", hash = "sha256:df4f613cf7ad9a588cc381aaf4a512d26265ecebd5eb9e1ba12f1319eb85a6a0"}, +] cachy = [ {file = "cachy-0.3.0-py2.py3-none-any.whl", hash = "sha256:338ca09c8860e76b275aff52374330efedc4d5a5e45dc1c5b539c1ead0786fe7"}, {file = "cachy-0.3.0.tar.gz", hash = "sha256:186581f4ceb42a0bbe040c407da73c14092379b1e4c0e327fdb72ae4a9b269b1"}, @@ -915,52 +958,56 @@ cleo = [ {file = "cleo-1.0.0a4-py3-none-any.whl", hash = "sha256:cdd0c3458c15ced3a9f0204b1e53a1b4bee3c56ebcb3ac54c872a56acc657a09"}, {file = "cleo-1.0.0a4.tar.gz", hash = "sha256:a103a065d031b7d936ee88a6b93086a69bd9c1b40fa2ebfe8c056285a66b481d"}, ] +click = [ + {file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"}, + {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"}, +] colorama = [ {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"}, {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"}, ] coverage = [ - {file = "coverage-6.3.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df32ee0f4935a101e4b9a5f07b617d884a531ed5666671ff6ac66d2e8e8246d8"}, - {file = "coverage-6.3.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:75b5dbffc334e0beb4f6c503fb95e6d422770fd2d1b40a64898ea26d6c02742d"}, - {file = "coverage-6.3.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:114944e6061b68a801c5da5427b9173a0dd9d32cd5fcc18a13de90352843737d"}, - {file = "coverage-6.3.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2ab88a01cd180b5640ccc9c47232e31924d5f9967ab7edd7e5c91c68eee47a69"}, - {file = "coverage-6.3.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad8f9068f5972a46d50fe5f32c09d6ee11da69c560fcb1b4c3baea246ca4109b"}, - {file = "coverage-6.3.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4cd696aa712e6cd16898d63cf66139dc70d998f8121ab558f0e1936396dbc579"}, - {file = "coverage-6.3.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c1a9942e282cc9d3ed522cd3e3cab081149b27ea3bda72d6f61f84eaf88c1a63"}, - {file = "coverage-6.3.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c06455121a089252b5943ea682187a4e0a5cf0a3fb980eb8e7ce394b144430a9"}, - {file = "coverage-6.3.3-cp310-cp310-win32.whl", hash = "sha256:cb5311d6ccbd22578c80028c5e292a7ab9adb91bd62c1982087fad75abe2e63d"}, - {file = "coverage-6.3.3-cp310-cp310-win_amd64.whl", hash = "sha256:6d4a6f30f611e657495cc81a07ff7aa8cd949144e7667c5d3e680d73ba7a70e4"}, - {file = "coverage-6.3.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:79bf405432428e989cad7b8bc60581963238f7645ae8a404f5dce90236cc0293"}, - {file = "coverage-6.3.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:338c417613f15596af9eb7a39353b60abec9d8ce1080aedba5ecee6a5d85f8d3"}, - {file = "coverage-6.3.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:db094a6a4ae6329ed322a8973f83630b12715654c197dd392410400a5bfa1a73"}, - {file = "coverage-6.3.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1414e8b124611bf4df8d77215bd32cba6e3425da8ce9c1f1046149615e3a9a31"}, - {file = "coverage-6.3.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:93b16b08f94c92cab88073ffd185070cdcb29f1b98df8b28e6649145b7f2c90d"}, - {file = "coverage-6.3.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:fbc86ae8cc129c801e7baaafe3addf3c8d49c9c1597c44bdf2d78139707c3c62"}, - {file = "coverage-6.3.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:b5ba058610e8289a07db2a57bce45a1793ec0d3d11db28c047aae2aa1a832572"}, - {file = "coverage-6.3.3-cp37-cp37m-win32.whl", hash = "sha256:8329635c0781927a2c6ae068461e19674c564e05b86736ab8eb29c420ee7dc20"}, - {file = "coverage-6.3.3-cp37-cp37m-win_amd64.whl", hash = "sha256:e5af1feee71099ae2e3b086ec04f57f9950e1be9ecf6c420696fea7977b84738"}, - {file = "coverage-6.3.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e814a4a5a1d95223b08cdb0f4f57029e8eab22ffdbae2f97107aeef28554517e"}, - {file = "coverage-6.3.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:61f4fbf3633cb0713437291b8848634ea97f89c7e849c2be17a665611e433f53"}, - {file = "coverage-6.3.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3401b0d2ed9f726fadbfa35102e00d1b3547b73772a1de5508ef3bdbcb36afe7"}, - {file = "coverage-6.3.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8586b177b4407f988731eb7f41967415b2197f35e2a6ee1a9b9b561f6323c8e9"}, - {file = "coverage-6.3.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:892e7fe32191960da559a14536768a62e83e87bbb867e1b9c643e7e0fbce2579"}, - {file = "coverage-6.3.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:afb03f981fadb5aed1ac6e3dd34f0488e1a0875623d557b6fad09b97a942b38a"}, - {file = "coverage-6.3.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:cbe91bc84be4e5ef0b1480d15c7b18e29c73bdfa33e07d3725da7d18e1b0aff2"}, - {file = "coverage-6.3.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:91502bf27cbd5c83c95cfea291ef387469f2387508645602e1ca0fd8a4ba7548"}, - {file = "coverage-6.3.3-cp38-cp38-win32.whl", hash = "sha256:c488db059848702aff30aa1d90ef87928d4e72e4f00717343800546fdbff0a94"}, - {file = "coverage-6.3.3-cp38-cp38-win_amd64.whl", hash = "sha256:ceb6534fcdfb5c503affb6b1130db7b5bfc8a0f77fa34880146f7a5c117987d0"}, - {file = "coverage-6.3.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:cc692c9ee18f0dd3214843779ba6b275ee4bb9b9a5745ba64265bce911aefd1a"}, - {file = "coverage-6.3.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:462105283de203df8de58a68c1bb4ba2a8a164097c2379f664fa81d6baf94b81"}, - {file = "coverage-6.3.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc972d829ad5ef4d4c5fcabd2bbe2add84ce8236f64ba1c0c72185da3a273130"}, - {file = "coverage-6.3.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:06f54765cdbce99901871d50fe9f41d58213f18e98b170a30ca34f47de7dd5e8"}, - {file = "coverage-6.3.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7835f76a081787f0ca62a53504361b3869840a1620049b56d803a8cb3a9eeea3"}, - {file = "coverage-6.3.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:6f5fee77ec3384b934797f1873758f796dfb4f167e1296dc00f8b2e023ce6ee9"}, - {file = "coverage-6.3.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:baa8be8aba3dd1e976e68677be68a960a633a6d44c325757aefaa4d66175050f"}, - {file = "coverage-6.3.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4d06380e777dd6b35ee936f333d55b53dc4a8271036ff884c909cf6e94be8b6c"}, - {file = "coverage-6.3.3-cp39-cp39-win32.whl", hash = "sha256:f8cabc5fd0091976ab7b020f5708335033e422de25e20ddf9416bdce2b7e07d8"}, - {file = "coverage-6.3.3-cp39-cp39-win_amd64.whl", hash = "sha256:9c9441d57b0963cf8340268ad62fc83de61f1613034b79c2b1053046af0c5284"}, - {file = "coverage-6.3.3-pp36.pp37.pp38-none-any.whl", hash = "sha256:d522f1dc49127eab0bfbba4e90fa068ecff0899bbf61bf4065c790ddd6c177fe"}, - {file = "coverage-6.3.3.tar.gz", hash = "sha256:2781c43bffbbec2b8867376d4d61916f5e9c4cc168232528562a61d1b4b01879"}, + {file = "coverage-6.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:50ed480b798febce113709846b11f5d5ed1e529c88d8ae92f707806c50297abf"}, + {file = "coverage-6.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:26f8f92699756cb7af2b30720de0c5bb8d028e923a95b6d0c891088025a1ac8f"}, + {file = "coverage-6.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:60c2147921da7f4d2d04f570e1838db32b95c5509d248f3fe6417e91437eaf41"}, + {file = "coverage-6.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:750e13834b597eeb8ae6e72aa58d1d831b96beec5ad1d04479ae3772373a8088"}, + {file = "coverage-6.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af5b9ee0fc146e907aa0f5fb858c3b3da9199d78b7bb2c9973d95550bd40f701"}, + {file = "coverage-6.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:a022394996419142b33a0cf7274cb444c01d2bb123727c4bb0b9acabcb515dea"}, + {file = "coverage-6.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:5a78cf2c43b13aa6b56003707c5203f28585944c277c1f3f109c7b041b16bd39"}, + {file = "coverage-6.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:9229d074e097f21dfe0643d9d0140ee7433814b3f0fc3706b4abffd1e3038632"}, + {file = "coverage-6.4-cp310-cp310-win32.whl", hash = "sha256:fb45fe08e1abc64eb836d187b20a59172053999823f7f6ef4f18a819c44ba16f"}, + {file = "coverage-6.4-cp310-cp310-win_amd64.whl", hash = "sha256:3cfd07c5889ddb96a401449109a8b97a165be9d67077df6802f59708bfb07720"}, + {file = "coverage-6.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:03014a74023abaf5a591eeeaf1ac66a73d54eba178ff4cb1fa0c0a44aae70383"}, + {file = "coverage-6.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c82f2cd69c71698152e943f4a5a6b83a3ab1db73b88f6e769fabc86074c3b08"}, + {file = "coverage-6.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7b546cf2b1974ddc2cb222a109b37c6ed1778b9be7e6b0c0bc0cf0438d9e45a6"}, + {file = "coverage-6.4-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc173f1ce9ffb16b299f51c9ce53f66a62f4d975abe5640e976904066f3c835d"}, + {file = "coverage-6.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c53ad261dfc8695062fc8811ac7c162bd6096a05a19f26097f411bdf5747aee7"}, + {file = "coverage-6.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:eef5292b60b6de753d6e7f2d128d5841c7915fb1e3321c3a1fe6acfe76c38052"}, + {file = "coverage-6.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:543e172ce4c0de533fa892034cce260467b213c0ea8e39da2f65f9a477425211"}, + {file = "coverage-6.4-cp37-cp37m-win32.whl", hash = "sha256:00c8544510f3c98476bbd58201ac2b150ffbcce46a8c3e4fb89ebf01998f806a"}, + {file = "coverage-6.4-cp37-cp37m-win_amd64.whl", hash = "sha256:b84ab65444dcc68d761e95d4d70f3cfd347ceca5a029f2ffec37d4f124f61311"}, + {file = "coverage-6.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d548edacbf16a8276af13063a2b0669d58bbcfca7c55a255f84aac2870786a61"}, + {file = "coverage-6.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:033ebec282793bd9eb988d0271c211e58442c31077976c19c442e24d827d356f"}, + {file = "coverage-6.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:742fb8b43835078dd7496c3c25a1ec8d15351df49fb0037bffb4754291ef30ce"}, + {file = "coverage-6.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d55fae115ef9f67934e9f1103c9ba826b4c690e4c5bcf94482b8b2398311bf9c"}, + {file = "coverage-6.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5cd698341626f3c77784858427bad0cdd54a713115b423d22ac83a28303d1d95"}, + {file = "coverage-6.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:62d382f7d77eeeaff14b30516b17bcbe80f645f5cf02bb755baac376591c653c"}, + {file = "coverage-6.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:016d7f5cf1c8c84f533a3c1f8f36126fbe00b2ec0ccca47cc5731c3723d327c6"}, + {file = "coverage-6.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:69432946f154c6add0e9ede03cc43b96e2ef2733110a77444823c053b1ff5166"}, + {file = "coverage-6.4-cp38-cp38-win32.whl", hash = "sha256:83bd142cdec5e4a5c4ca1d4ff6fa807d28460f9db919f9f6a31babaaa8b88426"}, + {file = "coverage-6.4-cp38-cp38-win_amd64.whl", hash = "sha256:4002f9e8c1f286e986fe96ec58742b93484195defc01d5cc7809b8f7acb5ece3"}, + {file = "coverage-6.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e4f52c272fdc82e7c65ff3f17a7179bc5f710ebc8ce8a5cadac81215e8326740"}, + {file = "coverage-6.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b5578efe4038be02d76c344007b13119b2b20acd009a88dde8adec2de4f630b5"}, + {file = "coverage-6.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8099ea680201c2221f8468c372198ceba9338a5fec0e940111962b03b3f716a"}, + {file = "coverage-6.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a00441f5ea4504f5abbc047589d09e0dc33eb447dc45a1a527c8b74bfdd32c65"}, + {file = "coverage-6.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e76bd16f0e31bc2b07e0fb1379551fcd40daf8cdf7e24f31a29e442878a827c"}, + {file = "coverage-6.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:8d2e80dd3438e93b19e1223a9850fa65425e77f2607a364b6fd134fcd52dc9df"}, + {file = "coverage-6.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:341e9c2008c481c5c72d0e0dbf64980a4b2238631a7f9780b0fe2e95755fb018"}, + {file = "coverage-6.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:21e6686a95025927775ac501e74f5940cdf6fe052292f3a3f7349b0abae6d00f"}, + {file = "coverage-6.4-cp39-cp39-win32.whl", hash = "sha256:968ed5407f9460bd5a591cefd1388cc00a8f5099de9e76234655ae48cfdbe2c3"}, + {file = "coverage-6.4-cp39-cp39-win_amd64.whl", hash = "sha256:e35217031e4b534b09f9b9a5841b9344a30a6357627761d4218818b865d45055"}, + {file = "coverage-6.4-pp36.pp37.pp38-none-any.whl", hash = "sha256:e637ae0b7b481905358624ef2e81d7fb0b1af55f5ff99f9ba05442a444b11e45"}, + {file = "coverage-6.4.tar.gz", hash = "sha256:727dafd7f67a6e1cad808dc884bd9c5a2f6ef1f8f6d2f22b37b96cb0080d4f49"}, ] crashtest = [ {file = "crashtest-0.3.1-py3-none-any.whl", hash = "sha256:300f4b0825f57688b47b6d70c6a31de33512eb2fa1ac614f780939aa0cf91680"}, @@ -1187,6 +1234,10 @@ pytest-mock = [ pytest-sugar = [ {file = "pytest-sugar-0.9.4.tar.gz", hash = "sha256:b1b2186b0a72aada6859bea2a5764145e3aaa2c1cfbb23c3a19b5f7b697563d3"}, ] +pythonfinder = [ + {file = "pythonfinder-1.2.10-py2.py3-none-any.whl", hash = "sha256:27818b4c6023c2b79dbe0e67b3da348ef30affa70dc4c256d5d5cb67e5e70573"}, + {file = "pythonfinder-1.2.10.tar.gz", hash = "sha256:ce2a1c2b313d605788173caf68d074f80c00b067364bc57047e68735bc9037d0"}, +] pywin32-ctypes = [ {file = "pywin32-ctypes-0.2.0.tar.gz", hash = "sha256:24ffc3b341d457d48e8922352130cf2644024a4ff09762a2261fd34c36ee5942"}, {file = "pywin32_ctypes-0.2.0-py2.py3-none-any.whl", hash = "sha256:9dc2d991b3479cc2df15930958b674a48a227d5361d413827a4cfd0b5876fc98"}, diff --git a/pyproject.toml b/pyproject.toml index 589fdd0d49e..f832d1b5023 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -58,6 +58,7 @@ tomlkit = ">=0.7.0,<1.0.0" virtualenv = "(>=20.4.3,<20.4.5 || >=20.4.7)" urllib3 = "^1.26.0" dulwich = "^0.20.35" +pythonfinder = "^1.2.10" [tool.poetry.dev-dependencies] tox = "^3.18" diff --git a/src/poetry/config/config.py b/src/poetry/config/config.py index 8bd4a5070b8..85aec9488bb 100644 --- a/src/poetry/config/config.py +++ b/src/poetry/config/config.py @@ -124,7 +124,11 @@ class Config: }, "prefer-active-python": False, }, - "experimental": {"new-installer": True, "system-git-client": False}, + "experimental": { + "new-installer": True, + "system-git-client": False, + "python-finder": True, + }, "installer": {"parallel": True, "max-workers": None, "no-binary": None}, } @@ -249,6 +253,7 @@ def _get_normalizer(name: str) -> Callable[[str], Any]: "virtualenvs.options.system-site-packages", "virtualenvs.options.prefer-active-python", "experimental.new-installer", + "experimental.python-finder", "experimental.system-git-client", "installer.parallel", }: diff --git a/src/poetry/utils/env.py b/src/poetry/utils/env.py index 3f6a87696ad..d1592a27d7d 100644 --- a/src/poetry/utils/env.py +++ b/src/poetry/utils/env.py @@ -34,6 +34,7 @@ from poetry.core.semver.version import Version from poetry.core.toml.file import TOMLFile from poetry.core.utils.helpers import temporary_directory +from pythonfinder import Finder from virtualenv.seed.wheels.embed import get_embed_wheel from poetry.locations import CACHE_DIR @@ -489,6 +490,13 @@ def __init__(self, expected: str, given: str) -> None: super().__init__(message) +class InterpreterNotFound(EnvError): + def __init__(self, python: str) -> None: + message = f"Python interpreter not found for input ({python})" + + super().__init__(message) + + class EnvManager: """ Environments manager @@ -535,28 +543,7 @@ def _detect_active_python(self, io: IO) -> str: ) return executable - def activate(self, python: str, io: IO) -> Env: - venv_path = self._poetry.config.get("virtualenvs.path") - if venv_path is None: - venv_path = CACHE_DIR / "virtualenvs" - else: - venv_path = Path(venv_path) - - cwd = self._poetry.file.parent - - envs_file = TOMLFile(venv_path / self.ENVS_FILE) - - try: - python_version = Version.parse(python) - python = f"python{python_version.major}" - if python_version.precision > 1: - python += f".{python_version.minor}" - except ValueError: - # Executable in PATH or full executable path - pass - - python = self._full_python_path(python) - + def _get_python_versions(self, python: str) -> tuple[str, str]: try: python_version = decode( subprocess.check_output( @@ -570,6 +557,56 @@ def activate(self, python: str, io: IO) -> Env: python_version = Version.parse(python_version.strip()) minor = f"{python_version.major}.{python_version.minor}" patch = python_version.text + return minor, patch + + def _find_python(self, python: str) -> tuple[str, str, str]: + # Handle full path + path = Path(python) + if path.is_absolute(): + if path.exists(): + minor, patch = self._get_python_versions(python) + return python, minor, patch + else: + raise InterpreterNotFound(python) + + # python is either [.] or python[[.]] + # both are supported as first parameter to Finder.find_python_version + finder = Finder(sort_by_path=True) + try: + path = finder.find_python_version(python) + if path: + minor = f"{path.py_version.major}.{path.py_version.minor}" + patch = f"{minor}.{path.py_version.patch}" + return str(path.path), minor, patch + except ValueError: + pass + + raise InterpreterNotFound(python) + + def activate(self, python: str, io: IO) -> Env: + venv_path = self._poetry.config.get("virtualenvs.path") + if venv_path is None: + venv_path = CACHE_DIR / "virtualenvs" + else: + venv_path = Path(venv_path) + + cwd = self._poetry.file.parent + + envs_file = TOMLFile(venv_path / self.ENVS_FILE) + experimental_finder = self._poetry.config.get("experimental.python-finder") + if experimental_finder: + python, minor, patch = self._find_python(python) + else: + try: + python_version = Version.parse(python) + python = f"python{python_version.major}" + if python_version.precision > 1: + python += f".{python_version.minor}" + except ValueError: + # Executable in PATH or full executable path + pass + python = self._full_python_path(python) + minor, patch = self._get_python_versions(python) create = False is_root_venv = self._poetry.config.get("virtualenvs.in-project") diff --git a/tests/conftest.py b/tests/conftest.py index b2c232e1fb5..40f66de20c9 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -43,6 +43,7 @@ from _pytest.config import Config as PyTestConfig from _pytest.config.argparsing import Parser + from _pytest.fixtures import FixtureRequest from pytest_mock import MockerFixture from poetry.poetry import Poetry @@ -441,3 +442,16 @@ def set_simple_log_formatter() -> None: for handler in logging.getLogger(name).handlers: # replace formatter with simple formatter for testing handler.setFormatter(logging.Formatter(fmt="%(message)s")) + + +@pytest.fixture(params=[True, False]) +def find_python_mode(config: Config, request: FixtureRequest) -> None: + config.merge( + { + "experimental": { + # param is an optional attribute present + # when fixtures are parameterized + "python-finder": request.param # type: ignore + } + } + ) diff --git a/tests/console/commands/env/helpers.py b/tests/console/commands/env/helpers.py index c9dc0a7a41a..435d32ba6ff 100644 --- a/tests/console/commands/env/helpers.py +++ b/tests/console/commands/env/helpers.py @@ -33,3 +33,13 @@ def check_output(cmd: str, *_: Any, **__: Any) -> str: return str(Path("/prefix")) return check_output + + +def find_python_wrapper( + version: PEP440Version = VERSION_3_7_1, +) -> Callable[[str], tuple[str, str, str]]: + def find_python_output(python: str) -> tuple[str, str, str]: + path = f"/usr/bin/python{version.major}.{version.minor}" + return path, f"{version.major}.{version.minor}", version.text + + return find_python_output diff --git a/tests/console/commands/env/test_use.py b/tests/console/commands/env/test_use.py index ba26064765c..1c080dff856 100644 --- a/tests/console/commands/env/test_use.py +++ b/tests/console/commands/env/test_use.py @@ -14,6 +14,7 @@ from poetry.utils.env import MockEnv from tests.console.commands.env.helpers import build_venv from tests.console.commands.env.helpers import check_output_wrapper +from tests.console.commands.env.helpers import find_python_wrapper if TYPE_CHECKING: @@ -34,18 +35,25 @@ def setup(mocker: MockerFixture) -> None: def mock_subprocess_calls( setup: None, current_python: tuple[int, int, int], mocker: MockerFixture ) -> None: + version = Version.from_parts(*current_python) mocker.patch( "subprocess.check_output", - side_effect=check_output_wrapper(Version.from_parts(*current_python)), + side_effect=check_output_wrapper(version), ) mocker.patch( "subprocess.Popen.communicate", side_effect=[("/prefix", None), ("/prefix", None), ("/prefix", None)], ) + mocker.patch( + "poetry.utils.env.EnvManager._find_python", + side_effect=find_python_wrapper(version), + ) @pytest.fixture -def tester(command_tester_factory: CommandTesterFactory) -> CommandTester: +def tester( + command_tester_factory: CommandTesterFactory, find_python_mode: None +) -> CommandTester: return command_tester_factory("env use") @@ -60,6 +68,9 @@ def test_activate_activates_non_existing_virtualenv_no_envs_file( "subprocess.check_output", side_effect=check_output_wrapper(), ) + mocker.patch( + "poetry.utils.env.EnvManager._find_python", side_effect=find_python_wrapper() + ) mock_build_env = mocker.patch( "poetry.utils.env.EnvManager.build_venv", side_effect=build_venv diff --git a/tests/console/commands/test_config.py b/tests/console/commands/test_config.py index bf5fb06ab67..cbad7a173c5 100644 --- a/tests/console/commands/test_config.py +++ b/tests/console/commands/test_config.py @@ -52,6 +52,7 @@ def test_list_displays_default_value_if_not_set( venv_path = json.dumps(os.path.join("{cache-dir}", "virtualenvs")) expected = f"""cache-dir = {cache_dir} experimental.new-installer = true +experimental.python-finder = true experimental.system-git-client = false installer.max-workers = null installer.no-binary = null @@ -80,6 +81,7 @@ def test_list_displays_set_get_setting( venv_path = json.dumps(os.path.join("{cache-dir}", "virtualenvs")) expected = f"""cache-dir = {cache_dir} experimental.new-installer = true +experimental.python-finder = true experimental.system-git-client = false installer.max-workers = null installer.no-binary = null @@ -132,6 +134,7 @@ def test_list_displays_set_get_local_setting( venv_path = json.dumps(os.path.join("{cache-dir}", "virtualenvs")) expected = f"""cache-dir = {cache_dir} experimental.new-installer = true +experimental.python-finder = true experimental.system-git-client = false installer.max-workers = null installer.no-binary = null diff --git a/tests/utils/test_env.py b/tests/utils/test_env.py index 9769eee5898..1b636da39be 100644 --- a/tests/utils/test_env.py +++ b/tests/utils/test_env.py @@ -184,12 +184,23 @@ def check_output(cmd: str, *args: Any, **kwargs: Any) -> str: return check_output +def find_python_wrapper( + version: Version = VERSION_3_7_1, +) -> Callable[[str], tuple[str, str, str]]: + def find_python_output(python: str) -> tuple[str, str, str]: + path = f"/usr/bin/python{version.major}.{version.minor}" + return path, f"{version.major}.{version.minor}", version.text + + return find_python_output + + def test_activate_activates_non_existing_virtualenv_no_envs_file( tmp_dir: str, manager: EnvManager, poetry: Poetry, config: Config, mocker: MockerFixture, + find_python_mode: None, ): if "VIRTUAL_ENV" in os.environ: del os.environ["VIRTUAL_ENV"] @@ -204,6 +215,11 @@ def test_activate_activates_non_existing_virtualenv_no_envs_file( "subprocess.Popen.communicate", side_effect=[("/prefix", None), ("/prefix", None)], ) + + mocker.patch( + "poetry.utils.env.EnvManager._find_python", side_effect=find_python_wrapper() + ) + m = mocker.patch("poetry.utils.env.EnvManager.build_venv", side_effect=build_venv) env = manager.activate("python3.7", NullIO()) @@ -236,6 +252,7 @@ def test_activate_activates_existing_virtualenv_no_envs_file( poetry: Poetry, config: Config, mocker: MockerFixture, + find_python_mode: None, ): if "VIRTUAL_ENV" in os.environ: del os.environ["VIRTUAL_ENV"] @@ -254,6 +271,9 @@ def test_activate_activates_existing_virtualenv_no_envs_file( "subprocess.Popen.communicate", side_effect=[("/prefix", None)], ) + mocker.patch( + "poetry.utils.env.EnvManager._find_python", side_effect=find_python_wrapper() + ) m = mocker.patch("poetry.utils.env.EnvManager.build_venv", side_effect=build_venv) env = manager.activate("python3.7", NullIO()) @@ -276,6 +296,7 @@ def test_activate_activates_same_virtualenv_with_envs_file( poetry: Poetry, config: Config, mocker: MockerFixture, + find_python_mode: None, ): if "VIRTUAL_ENV" in os.environ: del os.environ["VIRTUAL_ENV"] @@ -299,6 +320,9 @@ def test_activate_activates_same_virtualenv_with_envs_file( "subprocess.Popen.communicate", side_effect=[("/prefix", None)], ) + mocker.patch( + "poetry.utils.env.EnvManager._find_python", side_effect=find_python_wrapper() + ) m = mocker.patch("poetry.utils.env.EnvManager.create_venv") env = manager.activate("python3.7", NullIO()) @@ -320,6 +344,7 @@ def test_activate_activates_different_virtualenv_with_envs_file( poetry: Poetry, config: Config, mocker: MockerFixture, + find_python_mode: None, ): if "VIRTUAL_ENV" in os.environ: del os.environ["VIRTUAL_ENV"] @@ -342,6 +367,10 @@ def test_activate_activates_different_virtualenv_with_envs_file( "subprocess.Popen.communicate", side_effect=[("/prefix", None), ("/prefix", None), ("/prefix", None)], ) + mocker.patch( + "poetry.utils.env.EnvManager._find_python", + side_effect=find_python_wrapper(Version.parse("3.6.6")), + ) m = mocker.patch("poetry.utils.env.EnvManager.build_venv", side_effect=build_venv) env = manager.activate("python3.6", NullIO()) @@ -372,6 +401,7 @@ def test_activate_activates_recreates_for_different_patch( poetry: Poetry, config: Config, mocker: MockerFixture, + find_python_mode: None, ): if "VIRTUAL_ENV" in os.environ: del os.environ["VIRTUAL_ENV"] @@ -407,6 +437,9 @@ def test_activate_activates_recreates_for_different_patch( "poetry.utils.env.EnvManager.remove_venv", side_effect=EnvManager.remove_venv ) + mocker.patch( + "poetry.utils.env.EnvManager._find_python", side_effect=find_python_wrapper() + ) env = manager.activate("python3.7", NullIO()) build_venv_m.assert_called_with( @@ -437,6 +470,7 @@ def test_activate_does_not_recreate_when_switching_minor( poetry: Poetry, config: Config, mocker: MockerFixture, + find_python_mode: None, ): if "VIRTUAL_ENV" in os.environ: del os.environ["VIRTUAL_ENV"] @@ -460,6 +494,10 @@ def test_activate_does_not_recreate_when_switching_minor( "subprocess.Popen.communicate", side_effect=[("/prefix", None), ("/prefix", None), ("/prefix", None)], ) + mocker.patch( + "poetry.utils.env.EnvManager._find_python", + side_effect=find_python_wrapper(Version.parse("3.6.6")), + ) build_venv_m = mocker.patch( "poetry.utils.env.EnvManager.build_venv", side_effect=build_venv ) @@ -1057,6 +1095,7 @@ def test_activate_with_in_project_setting_does_not_fail_if_no_venvs_dir( config: Config, tmp_dir: str, mocker: MockerFixture, + find_python_mode: None, ): if "VIRTUAL_ENV" in os.environ: del os.environ["VIRTUAL_ENV"] @@ -1078,6 +1117,10 @@ def test_activate_with_in_project_setting_does_not_fail_if_no_venvs_dir( "subprocess.Popen.communicate", side_effect=[("/prefix", None), ("/prefix", None)], ) + + mocker.patch( + "poetry.utils.env.EnvManager._find_python", side_effect=find_python_wrapper() + ) m = mocker.patch("poetry.utils.env.EnvManager.build_venv") manager.activate("python3.7", NullIO())