Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
P
python-poetry
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
open
python-poetry
Commits
c7342e45
Unverified
Commit
c7342e45
authored
Sep 06, 2021
by
Sébastien Eustace
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix executables discovery for generic environments
parent
d526348c
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
197 additions
and
28 deletions
+197
-28
poetry/utils/env.py
+115
-28
tests/utils/test_env.py
+82
-0
No files found.
poetry/utils/env.py
View file @
c7342e45
...
...
@@ -1042,10 +1042,11 @@ class EnvManager:
(e.g. plugin installation or self update).
"""
prefix
,
base_prefix
=
Path
(
sys
.
prefix
),
Path
(
cls
.
get_base_prefix
())
env
=
SystemEnv
(
prefix
)
if
not
naive
:
if
prefix
.
joinpath
(
"poetry_env"
)
.
exists
():
return
GenericEnv
(
base_prefix
)
env
=
GenericEnv
(
base_prefix
,
child_env
=
env
)
else
:
from
poetry.locations
import
data_dir
try
:
...
...
@@ -1053,9 +1054,9 @@ class EnvManager:
except
ValueError
:
pass
else
:
return
GenericEnv
(
base_prefix
)
env
=
GenericEnv
(
base_prefix
,
child_env
=
env
)
return
SystemEnv
(
prefix
)
return
env
@classmethod
def
get_base_prefix
(
cls
)
->
Path
:
...
...
@@ -1093,29 +1094,10 @@ class Env:
self
.
_path
=
path
self
.
_bin_dir
=
self
.
_path
/
bin_dir
try
:
python_executables
=
sorted
(
[
p
.
name
for
p
in
self
.
_bin_dir
.
glob
(
"python*"
)
if
re
.
match
(
r"python(?:\d+(?:\.\d+)?)?(?:\.exe)?$"
,
p
.
name
)
]
)
self
.
_executable
=
python_executables
[
0
]
.
rstrip
(
".exe"
)
except
IndexError
:
self
.
_executable
=
"python"
+
(
".exe"
if
self
.
_is_windows
else
""
)
self
.
_executable
=
"python"
self
.
_pip_executable
=
"pip"
try
:
pip_executables
=
sorted
(
[
p
.
name
for
p
in
self
.
_bin_dir
.
glob
(
"pip*"
)
if
re
.
match
(
r"pip(?:\d+(?:\.\d+)?)?(?:\.exe)?$"
,
p
.
name
)
]
)
self
.
_pip_executable
=
pip_executables
[
0
]
.
rstrip
(
".exe"
)
except
IndexError
:
self
.
_pip_executable
=
"pip"
+
(
".exe"
if
self
.
_is_windows
else
""
)
self
.
find_executables
()
self
.
_base
=
base
or
path
...
...
@@ -1160,6 +1142,39 @@ class Env:
return
self
.
_marker_env
@property
def
parent_env
(
self
)
->
"GenericEnv"
:
return
GenericEnv
(
self
.
base
,
child_env
=
self
)
def
find_executables
(
self
)
->
None
:
python_executables
=
sorted
(
[
p
.
name
for
p
in
self
.
_bin_dir
.
glob
(
"python*"
)
if
re
.
match
(
r"python(?:\d+(?:\.\d+)?)?(?:\.exe)?$"
,
p
.
name
)
]
)
if
python_executables
:
executable
=
python_executables
[
0
]
if
executable
.
endswith
(
".exe"
):
executable
=
executable
[:
-
4
]
self
.
_executable
=
executable
pip_executables
=
sorted
(
[
p
.
name
for
p
in
self
.
_bin_dir
.
glob
(
"pip*"
)
if
re
.
match
(
r"pip(?:\d+(?:\.\d+)?)?(?:\.exe)?$"
,
p
.
name
)
]
)
if
pip_executables
:
pip_executable
=
pip_executables
[
0
]
if
pip_executable
.
endswith
(
".exe"
):
pip_executable
=
pip_executable
[:
-
4
]
self
.
_pip_executable
=
pip_executable
def
get_embedded_wheel
(
self
,
distribution
):
return
get_embed_wheel
(
distribution
,
"{}.{}"
.
format
(
self
.
version_info
[
0
],
self
.
version_info
[
1
])
...
...
@@ -1390,7 +1405,11 @@ class Env:
"""
Return path to the given executable.
"""
bin_path
=
(
self
.
_bin_dir
/
bin
)
.
with_suffix
(
".exe"
if
self
.
_is_windows
else
""
)
if
self
.
_is_windows
and
not
bin
.
endswith
(
".exe"
):
bin_path
=
self
.
_bin_dir
/
(
bin
+
".exe"
)
else
:
bin_path
=
self
.
_bin_dir
/
bin
if
not
bin_path
.
exists
():
# On Windows, some executables can be in the base path
# This is especially true when installing Python with
...
...
@@ -1401,7 +1420,11 @@ class Env:
# that creates a fake virtual environment pointing to
# a base Python install.
if
self
.
_is_windows
:
bin_path
=
(
self
.
_path
/
bin
)
.
with_suffix
(
".exe"
)
if
not
bin
.
endswith
(
".exe"
):
bin_path
=
self
.
_bin_dir
/
(
bin
+
".exe"
)
else
:
bin_path
=
self
.
_path
/
bin
if
bin_path
.
exists
():
return
str
(
bin_path
)
...
...
@@ -1649,6 +1672,70 @@ class VirtualEnv(Env):
class
GenericEnv
(
VirtualEnv
):
def
__init__
(
self
,
path
:
Path
,
base
:
Optional
[
Path
]
=
None
,
child_env
:
Optional
[
"Env"
]
=
None
)
->
None
:
self
.
_child_env
=
child_env
super
()
.
__init__
(
path
,
base
=
base
)
def
find_executables
(
self
)
->
None
:
patterns
=
[(
"python*"
,
"pip*"
)]
if
self
.
_child_env
:
minor_version
=
"{}.{}"
.
format
(
self
.
_child_env
.
version_info
[
0
],
self
.
_child_env
.
version_info
[
1
]
)
major_version
=
"{}"
.
format
(
self
.
_child_env
.
version_info
[
0
])
patterns
=
[
(
"python{}"
.
format
(
minor_version
),
"pip{}"
.
format
(
minor_version
)),
(
"python{}"
.
format
(
major_version
),
"pip{}"
.
format
(
major_version
)),
]
python_executable
=
None
pip_executable
=
None
for
python_pattern
,
pip_pattern
in
patterns
:
if
python_executable
and
pip_executable
:
break
if
not
python_executable
:
python_executables
=
sorted
(
[
p
.
name
for
p
in
self
.
_bin_dir
.
glob
(
python_pattern
)
if
re
.
match
(
r"python(?:\d+(?:\.\d+)?)?(?:\.exe)?$"
,
p
.
name
)
]
)
if
python_executables
:
executable
=
python_executables
[
0
]
if
executable
.
endswith
(
".exe"
):
executable
=
executable
[:
-
4
]
python_executable
=
executable
if
not
pip_executable
:
pip_executables
=
sorted
(
[
p
.
name
for
p
in
self
.
_bin_dir
.
glob
(
pip_pattern
)
if
re
.
match
(
r"pip(?:\d+(?:\.\d+)?)?(?:\.exe)?$"
,
p
.
name
)
]
)
if
pip_executables
:
pip_executable
=
pip_executables
[
0
]
if
pip_executable
.
endswith
(
".exe"
):
pip_executable
=
pip_executable
[:
-
4
]
pip_executable
=
pip_executable
if
python_executable
:
self
.
_executable
=
python_executable
if
pip_executable
:
self
.
_pip_executable
=
pip_executable
def
get_paths
(
self
)
->
Dict
[
str
,
str
]:
output
=
self
.
run_python_script
(
GET_PATHS_FOR_GENERIC_ENVS
)
...
...
tests/utils/test_env.py
View file @
c7342e45
...
...
@@ -19,6 +19,7 @@ from poetry.utils._compat import WINDOWS
from
poetry.utils.env
import
GET_BASE_PREFIX
from
poetry.utils.env
import
EnvCommandError
from
poetry.utils.env
import
EnvManager
from
poetry.utils.env
import
GenericEnv
from
poetry.utils.env
import
NoCompatiblePythonVersionFound
from
poetry.utils.env
import
SystemEnv
from
poetry.utils.env
import
VirtualEnv
...
...
@@ -1001,3 +1002,84 @@ def test_env_finds_the_correct_executables(tmp_dir, manager):
assert
Path
(
venv
.
python
)
.
name
==
expected_executable
assert
Path
(
venv
.
pip
)
.
name
==
expected_pip_executable
def
test_env_finds_the_correct_executables_for_generic_env
(
tmp_dir
,
manager
):
venv_path
=
Path
(
tmp_dir
)
/
"Virtual Env"
child_venv_path
=
Path
(
tmp_dir
)
/
"Child Virtual Env"
manager
.
build_venv
(
str
(
venv_path
),
with_pip
=
True
)
parent_venv
=
VirtualEnv
(
venv_path
)
manager
.
build_venv
(
str
(
child_venv_path
),
executable
=
parent_venv
.
python
,
with_pip
=
True
)
venv
=
GenericEnv
(
parent_venv
.
path
,
child_env
=
VirtualEnv
(
child_venv_path
))
expected_executable
=
"python{}.{}{}"
.
format
(
sys
.
version_info
[
0
],
sys
.
version_info
[
1
],
".exe"
if
WINDOWS
else
""
)
expected_pip_executable
=
"pip{}.{}{}"
.
format
(
sys
.
version_info
[
0
],
sys
.
version_info
[
1
],
".exe"
if
WINDOWS
else
""
)
assert
Path
(
venv
.
python
)
.
name
==
expected_executable
assert
Path
(
venv
.
pip
)
.
name
==
expected_pip_executable
def
test_env_finds_fallback_executables_for_generic_env
(
tmp_dir
,
manager
):
venv_path
=
Path
(
tmp_dir
)
/
"Virtual Env"
child_venv_path
=
Path
(
tmp_dir
)
/
"Child Virtual Env"
manager
.
build_venv
(
str
(
venv_path
),
with_pip
=
True
)
parent_venv
=
VirtualEnv
(
venv_path
)
manager
.
build_venv
(
str
(
child_venv_path
),
executable
=
parent_venv
.
python
,
with_pip
=
True
)
venv
=
GenericEnv
(
parent_venv
.
path
,
child_env
=
VirtualEnv
(
child_venv_path
))
default_executable
=
"python"
+
(
".exe"
if
WINDOWS
else
""
)
major_executable
=
"python{}{}"
.
format
(
sys
.
version_info
[
0
],
".exe"
if
WINDOWS
else
""
)
minor_executable
=
"python{}.{}{}"
.
format
(
sys
.
version_info
[
0
],
sys
.
version_info
[
1
],
".exe"
if
WINDOWS
else
""
)
expected_executable
=
minor_executable
if
(
venv
.
_bin_dir
.
joinpath
(
expected_executable
)
.
exists
()
and
venv
.
_bin_dir
.
joinpath
(
major_executable
)
.
exists
()
):
venv
.
_bin_dir
.
joinpath
(
expected_executable
)
.
unlink
()
expected_executable
=
major_executable
if
(
venv
.
_bin_dir
.
joinpath
(
expected_executable
)
.
exists
()
and
venv
.
_bin_dir
.
joinpath
(
default_executable
)
.
exists
()
):
venv
.
_bin_dir
.
joinpath
(
expected_executable
)
.
unlink
()
expected_executable
=
default_executable
default_pip_executable
=
"pip"
+
(
".exe"
if
WINDOWS
else
""
)
major_pip_executable
=
"pip{}{}"
.
format
(
sys
.
version_info
[
0
],
".exe"
if
WINDOWS
else
""
)
minor_pip_executable
=
"pip{}.{}{}"
.
format
(
sys
.
version_info
[
0
],
sys
.
version_info
[
1
],
".exe"
if
WINDOWS
else
""
)
expected_pip_executable
=
minor_pip_executable
if
(
venv
.
_bin_dir
.
joinpath
(
expected_pip_executable
)
.
exists
()
and
venv
.
_bin_dir
.
joinpath
(
major_pip_executable
)
.
exists
()
):
venv
.
_bin_dir
.
joinpath
(
expected_pip_executable
)
.
unlink
()
expected_pip_executable
=
major_pip_executable
if
(
venv
.
_bin_dir
.
joinpath
(
expected_pip_executable
)
.
exists
()
and
venv
.
_bin_dir
.
joinpath
(
default_pip_executable
)
.
exists
()
):
venv
.
_bin_dir
.
joinpath
(
expected_pip_executable
)
.
unlink
()
expected_pip_executable
=
default_pip_executable
venv
=
GenericEnv
(
parent_venv
.
path
,
child_env
=
VirtualEnv
(
child_venv_path
))
assert
Path
(
venv
.
python
)
.
name
==
expected_executable
assert
Path
(
venv
.
pip
)
.
name
==
expected_pip_executable
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment