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
5b7791c5
Commit
5b7791c5
authored
Mar 26, 2021
by
Sébastien Eustace
Committed by
Arun Babu Neelicattu
Apr 06, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Write PEP-610-compliant files when installing
parent
fcc2c839
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
277 additions
and
4 deletions
+277
-4
poetry/installation/executor.py
+131
-4
tests/fixtures/simple_project/pyproject.toml
+5
-0
tests/installation/test_executor.py
+141
-0
No files found.
poetry/installation/executor.py
View file @
5b7791c5
import
itertools
import
itertools
import
json
import
os
import
os
import
threading
import
threading
...
@@ -8,6 +9,7 @@ from pathlib import Path
...
@@ -8,6 +9,7 @@ from pathlib import Path
from
subprocess
import
CalledProcessError
from
subprocess
import
CalledProcessError
from
typing
import
TYPE_CHECKING
from
typing
import
TYPE_CHECKING
from
typing
import
Any
from
typing
import
Any
from
typing
import
Dict
from
typing
import
List
from
typing
import
List
from
typing
import
Union
from
typing
import
Union
...
@@ -35,6 +37,7 @@ if TYPE_CHECKING:
...
@@ -35,6 +37,7 @@ if TYPE_CHECKING:
from
cleo.io.io
import
IO
# noqa
from
cleo.io.io
import
IO
# noqa
from
poetry.config.config
import
Config
from
poetry.config.config
import
Config
from
poetry.core.packages.package
import
Package
from
poetry.repositories
import
Pool
from
poetry.repositories
import
Pool
from
poetry.utils.env
import
Env
from
poetry.utils.env
import
Env
...
@@ -82,6 +85,7 @@ class Executor:
...
@@ -82,6 +85,7 @@ class Executor:
self
.
_sections
=
dict
()
self
.
_sections
=
dict
()
self
.
_lock
=
threading
.
Lock
()
self
.
_lock
=
threading
.
Lock
()
self
.
_shutdown
=
False
self
.
_shutdown
=
False
self
.
_hashes
:
Dict
[
str
,
str
]
=
{}
@property
@property
def
installations_count
(
self
)
->
int
:
def
installations_count
(
self
)
->
int
:
...
@@ -434,10 +438,18 @@ class Executor:
...
@@ -434,10 +438,18 @@ class Executor:
self
.
_io
.
write_line
(
""
)
self
.
_io
.
write_line
(
""
)
def
_execute_install
(
self
,
operation
:
Union
[
Install
,
Update
])
->
int
:
def
_execute_install
(
self
,
operation
:
Union
[
Install
,
Update
])
->
int
:
return
self
.
_install
(
operation
)
status_code
=
self
.
_install
(
operation
)
self
.
_save_url_reference
(
operation
)
return
status_code
def
_execute_update
(
self
,
operation
:
Union
[
Install
,
Update
])
->
int
:
def
_execute_update
(
self
,
operation
:
Union
[
Install
,
Update
])
->
int
:
return
self
.
_update
(
operation
)
status_code
=
self
.
_update
(
operation
)
self
.
_save_url_reference
(
operation
)
return
status_code
def
_execute_uninstall
(
self
,
operation
:
Uninstall
)
->
int
:
def
_execute_uninstall
(
self
,
operation
:
Uninstall
)
->
int
:
message
=
(
message
=
(
...
@@ -594,12 +606,17 @@ class Executor:
...
@@ -594,12 +606,17 @@ class Executor:
git
=
Git
()
git
=
Git
()
git
.
clone
(
package
.
source_url
,
src_dir
)
git
.
clone
(
package
.
source_url
,
src_dir
)
git
.
checkout
(
package
.
source_reference
,
src_dir
)
git
.
checkout
(
package
.
source_re
solved_re
ference
,
src_dir
)
# Now we just need to install from the source directory
# Now we just need to install from the source directory
original_url
=
package
.
source_url
package
.
_source_url
=
str
(
src_dir
)
package
.
_source_url
=
str
(
src_dir
)
return
self
.
_install_directory
(
operation
)
status_code
=
self
.
_install_directory
(
operation
)
package
.
_source_url
=
original_url
return
status_code
def
_download
(
self
,
operation
:
Union
[
Install
,
Update
])
->
Link
:
def
_download
(
self
,
operation
:
Union
[
Install
,
Update
])
->
Link
:
link
=
self
.
_chooser
.
choose_for
(
operation
.
package
)
link
=
self
.
_chooser
.
choose_for
(
operation
.
package
)
...
@@ -636,6 +653,8 @@ class Executor:
...
@@ -636,6 +653,8 @@ class Executor:
f
"Invalid hash for {package} using archive {archive.name}"
f
"Invalid hash for {package} using archive {archive.name}"
)
)
self
.
_hashes
[
package
.
name
]
=
archive_hash
return
archive
return
archive
def
_download_archive
(
self
,
operation
:
Union
[
Install
,
Update
],
link
:
Link
)
->
Path
:
def
_download_archive
(
self
,
operation
:
Union
[
Install
,
Update
],
link
:
Link
)
->
Path
:
...
@@ -689,3 +708,111 @@ class Executor:
...
@@ -689,3 +708,111 @@ class Executor:
def
_should_write_operation
(
self
,
operation
:
Operation
)
->
bool
:
def
_should_write_operation
(
self
,
operation
:
Operation
)
->
bool
:
return
not
operation
.
skipped
or
self
.
_dry_run
or
self
.
_verbose
return
not
operation
.
skipped
or
self
.
_dry_run
or
self
.
_verbose
def
_save_url_reference
(
self
,
operation
:
"OperationTypes"
)
->
None
:
"""
Create and store a PEP-610 `direct_url.json` file, if needed.
"""
if
operation
.
job_type
not
in
{
"install"
,
"update"
}:
return
from
poetry.core.masonry.utils.helpers
import
escape_name
from
poetry.core.masonry.utils.helpers
import
escape_version
package
=
operation
.
package
if
not
package
.
source_url
:
# Since we are installing from our own distribution cache
# pip will write a `direct_url.json` file pointing to the cache
# distribution.
# That's not what we want so we remove the direct_url.json file,
# if it exists.
dist_info
=
self
.
_env
.
site_packages
.
path
.
joinpath
(
"{}-{}.dist-info"
.
format
(
escape_name
(
package
.
pretty_name
),
escape_version
(
package
.
version
.
text
),
)
)
if
dist_info
.
exists
()
and
dist_info
.
joinpath
(
"direct_url.json"
)
.
exists
():
dist_info
.
joinpath
(
"direct_url.json"
)
.
unlink
()
return
url_reference
=
None
if
package
.
source_type
==
"git"
:
url_reference
=
self
.
_create_git_url_reference
(
package
)
elif
package
.
source_type
==
"url"
:
url_reference
=
self
.
_create_url_url_reference
(
package
)
elif
package
.
source_type
==
"directory"
:
url_reference
=
self
.
_create_directory_url_reference
(
package
)
elif
package
.
source_type
==
"file"
:
url_reference
=
self
.
_create_file_url_reference
(
package
)
if
url_reference
:
dist_info
=
self
.
_env
.
site_packages
.
path
.
joinpath
(
"{}-{}.dist-info"
.
format
(
escape_name
(
package
.
name
),
escape_version
(
package
.
version
.
text
)
)
)
if
dist_info
.
exists
():
dist_info
.
joinpath
(
"direct_url.json"
)
.
write_text
(
json
.
dumps
(
url_reference
),
encoding
=
"utf-8"
)
def
_create_git_url_reference
(
self
,
package
:
"Package"
)
->
Dict
[
str
,
Union
[
str
,
Dict
[
str
,
str
]]]:
reference
=
{
"url"
:
package
.
source_url
,
"vcs_info"
:
{
"vcs"
:
"git"
,
"requested_revision"
:
package
.
source_reference
,
"commit_id"
:
package
.
source_resolved_reference
,
},
}
return
reference
def
_create_url_url_reference
(
self
,
package
:
"Package"
)
->
Dict
[
str
,
Union
[
str
,
Dict
[
str
,
str
]]]:
archive_info
=
{}
if
package
.
name
in
self
.
_hashes
:
archive_info
[
"hash"
]
=
self
.
_hashes
[
package
.
name
]
reference
=
{
"url"
:
package
.
source_url
,
"archive_info"
:
archive_info
}
return
reference
def
_create_file_url_reference
(
self
,
package
:
"Package"
)
->
Dict
[
str
,
Union
[
str
,
Dict
[
str
,
str
]]]:
archive_info
=
{}
if
package
.
name
in
self
.
_hashes
:
archive_info
[
"hash"
]
=
self
.
_hashes
[
package
.
name
]
reference
=
{
"url"
:
Path
(
package
.
source_url
)
.
as_uri
(),
"archive_info"
:
archive_info
,
}
return
reference
def
_create_directory_url_reference
(
self
,
package
:
"Package"
)
->
Dict
[
str
,
Union
[
str
,
Dict
[
str
,
str
]]]:
dir_info
=
{}
if
package
.
develop
:
dir_info
[
"editable"
]
=
True
reference
=
{
"url"
:
Path
(
package
.
source_url
)
.
as_uri
(),
"dir_info"
:
dir_info
,
}
return
reference
tests/fixtures/simple_project/pyproject.toml
View file @
5b7791c5
...
@@ -28,3 +28,8 @@ python = "~2.7 || ^3.4"
...
@@ -28,3 +28,8 @@ python = "~2.7 || ^3.4"
foo
=
"foo:bar"
foo
=
"foo:bar"
baz
=
"bar:baz.boom.bim"
baz
=
"bar:baz.boom.bim"
fox
=
"fuz.foo:bar.baz"
fox
=
"fuz.foo:bar.baz"
[build-system]
requires
=
["poetry-core>=1.0.2"]
build-backend
=
"poetry.core.masonry.api"
tests/installation/test_executor.py
View file @
5b7791c5
# -*- coding: utf-8 -*-
# -*- coding: utf-8 -*-
from
__future__
import
unicode_literals
from
__future__
import
unicode_literals
import
json
import
re
import
re
import
shutil
import
shutil
...
@@ -27,6 +28,7 @@ from tests.repositories.test_pypi_repository import MockRepository
...
@@ -27,6 +28,7 @@ from tests.repositories.test_pypi_repository import MockRepository
def
env
(
tmp_dir
):
def
env
(
tmp_dir
):
path
=
Path
(
tmp_dir
)
/
".venv"
path
=
Path
(
tmp_dir
)
/
".venv"
path
.
mkdir
(
parents
=
True
)
path
.
mkdir
(
parents
=
True
)
return
MockEnv
(
path
=
path
,
is_venv
=
True
)
return
MockEnv
(
path
=
path
,
is_venv
=
True
)
...
@@ -261,3 +263,142 @@ def test_executor_should_delete_incomplete_downloads(
...
@@ -261,3 +263,142 @@ def test_executor_should_delete_incomplete_downloads(
executor
.
_download
(
Install
(
Package
(
"tomlkit"
,
"0.5.3"
)))
executor
.
_download
(
Install
(
Package
(
"tomlkit"
,
"0.5.3"
)))
assert
not
destination_fixture
.
exists
()
assert
not
destination_fixture
.
exists
()
def
test_executor_should_write_pep610_url_references_for_files
(
tmp_venv
,
pool
,
config
,
io
):
url
=
(
Path
(
__file__
)
.
parent
.
parent
.
joinpath
(
"fixtures/distributions/demo-0.1.0-py2.py3-none-any.whl"
)
.
resolve
()
)
package
=
Package
(
"demo"
,
"0.1.0"
,
source_type
=
"file"
,
source_url
=
url
.
as_posix
())
executor
=
Executor
(
tmp_venv
,
pool
,
config
,
io
)
executor
.
execute
([
Install
(
package
)])
dist_info
=
tmp_venv
.
site_packages
.
path
.
joinpath
(
"demo-0.1.0.dist-info"
)
assert
dist_info
.
exists
()
direct_url_file
=
dist_info
.
joinpath
(
"direct_url.json"
)
assert
direct_url_file
.
exists
()
url_reference
=
json
.
loads
(
direct_url_file
.
read_text
(
encoding
=
"utf-8"
))
assert
url_reference
==
{
"archive_info"
:
{},
"url"
:
url
.
as_uri
()}
def
test_executor_should_write_pep610_url_references_for_directories
(
tmp_venv
,
pool
,
config
,
io
):
url
=
Path
(
__file__
)
.
parent
.
parent
.
joinpath
(
"fixtures/simple_project"
)
.
resolve
()
package
=
Package
(
"simple-project"
,
"1.2.3"
,
source_type
=
"directory"
,
source_url
=
url
.
as_posix
()
)
executor
=
Executor
(
tmp_venv
,
pool
,
config
,
io
)
executor
.
execute
([
Install
(
package
)])
dist_info
=
tmp_venv
.
site_packages
.
path
.
joinpath
(
"simple_project-1.2.3.dist-info"
)
assert
dist_info
.
exists
()
direct_url_file
=
dist_info
.
joinpath
(
"direct_url.json"
)
assert
direct_url_file
.
exists
()
url_reference
=
json
.
loads
(
direct_url_file
.
read_text
(
encoding
=
"utf-8"
))
assert
url_reference
==
{
"dir_info"
:
{},
"url"
:
url
.
as_uri
()}
def
test_executor_should_write_pep610_url_references_for_editable_directories
(
tmp_venv
,
pool
,
config
,
io
):
url
=
Path
(
__file__
)
.
parent
.
parent
.
joinpath
(
"fixtures/simple_project"
)
.
resolve
()
package
=
Package
(
"simple-project"
,
"1.2.3"
,
source_type
=
"directory"
,
source_url
=
url
.
as_posix
(),
develop
=
True
,
)
executor
=
Executor
(
tmp_venv
,
pool
,
config
,
io
)
executor
.
execute
([
Install
(
package
)])
dist_info
=
tmp_venv
.
site_packages
.
path
.
joinpath
(
"simple_project-1.2.3.dist-info"
)
assert
dist_info
.
exists
()
direct_url_file
=
dist_info
.
joinpath
(
"direct_url.json"
)
assert
direct_url_file
.
exists
()
url_reference
=
json
.
loads
(
direct_url_file
.
read_text
(
encoding
=
"utf-8"
))
assert
url_reference
==
{
"dir_info"
:
{
"editable"
:
True
},
"url"
:
url
.
as_uri
()}
def
test_executor_should_write_pep610_url_references_for_urls
(
tmp_venv
,
pool
,
config
,
io
,
mock_file_downloads
):
package
=
Package
(
"demo"
,
"0.1.0"
,
source_type
=
"url"
,
source_url
=
"https://files.pythonhosted.org/demo-0.1.0-py2.py3-none-any.whl"
,
)
executor
=
Executor
(
tmp_venv
,
pool
,
config
,
io
)
executor
.
execute
([
Install
(
package
)])
dist_info
=
tmp_venv
.
site_packages
.
path
.
joinpath
(
"demo-0.1.0.dist-info"
)
assert
dist_info
.
exists
()
direct_url_file
=
dist_info
.
joinpath
(
"direct_url.json"
)
assert
direct_url_file
.
exists
()
url_reference
=
json
.
loads
(
direct_url_file
.
read_text
(
encoding
=
"utf-8"
))
assert
url_reference
==
{
"archive_info"
:
{},
"url"
:
"https://files.pythonhosted.org/demo-0.1.0-py2.py3-none-any.whl"
,
}
def
test_executor_should_write_pep610_url_references_for_git
(
tmp_venv
,
pool
,
config
,
io
,
mock_file_downloads
):
package
=
Package
(
"demo"
,
"0.1.2"
,
source_type
=
"git"
,
source_reference
=
"master"
,
source_resolved_reference
=
"123456"
,
source_url
=
"https://github.com/demo/demo.git"
,
)
executor
=
Executor
(
tmp_venv
,
pool
,
config
,
io
)
executor
.
execute
([
Install
(
package
)])
dist_info
=
tmp_venv
.
site_packages
.
path
.
joinpath
(
"demo-0.1.2.dist-info"
)
assert
dist_info
.
exists
()
direct_url_file
=
dist_info
.
joinpath
(
"direct_url.json"
)
assert
direct_url_file
.
exists
()
url_reference
=
json
.
loads
(
direct_url_file
.
read_text
(
encoding
=
"utf-8"
))
assert
url_reference
==
{
"vcs_info"
:
{
"vcs"
:
"git"
,
"requested_revision"
:
"master"
,
"commit_id"
:
"123456"
,
},
"url"
:
"https://github.com/demo/demo.git"
,
}
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