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
271e9958
Unverified
Commit
271e9958
authored
Feb 27, 2019
by
Sébastien Eustace
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Improve retrieval of information for packages with two python specific wheels
parent
4a822878
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
157 additions
and
123 deletions
+157
-123
poetry/puzzle/provider.py
+7
-21
poetry/repositories/legacy_repository.py
+6
-25
poetry/repositories/pypi_repository.py
+95
-77
tests/repositories/fixtures/legacy/ipython.html
+13
-0
tests/repositories/fixtures/pypi.org/dists/ipython-5.7.0-py2-none-any.whl
+0
-0
tests/repositories/fixtures/pypi.org/dists/ipython-5.7.0-py3-none-any.whl
+0
-0
tests/repositories/fixtures/pypi.org/dists/ipython-5.7.0.tar.gz
+0
-0
tests/repositories/test_legacy_repository.py
+36
-0
No files found.
poetry/puzzle/provider.py
View file @
271e9958
...
@@ -35,6 +35,7 @@ from poetry.utils.env import Env
...
@@ -35,6 +35,7 @@ from poetry.utils.env import Env
from
poetry.utils.env
import
EnvCommandError
from
poetry.utils.env
import
EnvCommandError
from
poetry.utils.setup_reader
import
SetupReader
from
poetry.utils.setup_reader
import
SetupReader
from
poetry.version.markers
import
MarkerUnion
from
poetry.vcs.git
import
Git
from
poetry.vcs.git
import
Git
from
.exceptions
import
CompatibilityError
from
.exceptions
import
CompatibilityError
...
@@ -516,34 +517,19 @@ class Provider:
...
@@ -516,34 +517,19 @@ class Provider:
for
constraint
,
_deps
in
by_constraint
.
items
():
for
constraint
,
_deps
in
by_constraint
.
items
():
new_markers
=
[]
new_markers
=
[]
for
dep
in
_deps
:
for
dep
in
_deps
:
pep_508_dep
=
dep
.
to_pep_508
(
False
)
marker
=
dep
.
marker
.
without_extras
()
if
";"
not
in
pep_508_dep
:
if
marker
.
is_empty
():
# No marker or only extras
continue
continue
markers
=
pep_508_dep
.
split
(
";"
)[
1
]
.
strip
()
new_markers
.
append
(
marker
)
if
not
markers
:
# One of the constraint has no markers
# so this means we don't actually need to merge
new_markers
=
[]
break
new_markers
.
append
(
"({})"
.
format
(
markers
))
if
not
new_markers
:
if
not
new_markers
:
dependencies
+=
_deps
continue
continue
dep
=
_deps
[
0
]
dep
=
_deps
[
0
]
new_requirement
=
"{}; {}"
.
format
(
dep
.
marker
=
dep
.
marker
.
union
(
MarkerUnion
(
*
new_markers
))
dep
.
to_pep_508
(
False
)
.
split
(
";"
)[
0
],
" or "
.
join
(
new_markers
)
by_constraint
[
constraint
]
=
[
dep
]
)
new_dep
=
dependency_from_pep_508
(
new_requirement
)
if
dep
.
is_optional
()
and
not
dep
.
is_activated
():
new_dep
.
deactivate
()
else
:
new_dep
.
activate
()
by_constraint
[
constraint
]
=
[
new_dep
]
continue
continue
...
...
poetry/repositories/legacy_repository.py
View file @
271e9958
...
@@ -16,6 +16,7 @@ except ImportError:
...
@@ -16,6 +16,7 @@ except ImportError:
unescape
=
HTMLParser
()
.
unescape
unescape
=
HTMLParser
()
.
unescape
from
collections
import
defaultdict
from
typing
import
Generator
from
typing
import
Generator
from
typing
import
Optional
from
typing
import
Optional
from
typing
import
Union
from
typing
import
Union
...
@@ -344,23 +345,15 @@ class LegacyRepository(PyPiRepository):
...
@@ -344,23 +345,15 @@ class LegacyRepository(PyPiRepository):
name
,
version
name
,
version
)
)
)
)
urls
=
{}
urls
=
defaultdict
(
list
)
hashes
=
[]
hashes
=
[]
default_link
=
links
[
0
]
for
link
in
links
:
for
link
in
links
:
if
link
.
is_wheel
:
if
link
.
is_wheel
:
m
=
wheel_file_re
.
match
(
link
.
filename
)
urls
[
"bdist_wheel"
]
.
append
(
link
.
url
)
python
=
m
.
group
(
"pyver"
)
elif
link
.
filename
.
endswith
(
platform
=
m
.
group
(
"plat"
)
(
".tar.gz"
,
".zip"
,
".bz2"
,
".xz"
,
".Z"
,
".tar"
)
if
python
==
"py2.py3"
and
platform
==
"any"
:
urls
[
"bdist_wheel"
]
=
link
.
url
elif
link
.
filename
.
endswith
(
".tar.gz"
):
urls
[
"sdist"
]
=
link
.
url
elif
(
link
.
filename
.
endswith
((
".zip"
,
".bz2"
,
".xz"
,
".Z"
,
".tar"
))
and
"sdist"
not
in
urls
):
):
urls
[
"sdist"
]
=
link
.
url
urls
[
"sdist"
]
.
append
(
link
.
url
)
hash
=
link
.
hash
hash
=
link
.
hash
if
link
.
hash_name
==
"sha256"
:
if
link
.
hash_name
==
"sha256"
:
...
@@ -368,18 +361,6 @@ class LegacyRepository(PyPiRepository):
...
@@ -368,18 +361,6 @@ class LegacyRepository(PyPiRepository):
data
[
"digests"
]
=
hashes
data
[
"digests"
]
=
hashes
if
not
urls
:
if
default_link
.
is_wheel
:
urls
[
"bdist_wheel"
]
=
default_link
.
url
elif
default_link
.
filename
.
endswith
(
".tar.gz"
):
urls
[
"sdist"
]
=
default_link
.
url
elif
(
default_link
.
filename
.
endswith
((
".zip"
,
".bz2"
))
and
"sdist"
not
in
urls
):
urls
[
"sdist"
]
=
default_link
.
url
else
:
return
data
info
=
self
.
_get_info_from_urls
(
urls
)
info
=
self
.
_get_info_from_urls
(
urls
)
data
[
"summary"
]
=
info
[
"summary"
]
data
[
"summary"
]
=
info
[
"summary"
]
...
...
poetry/repositories/pypi_repository.py
View file @
271e9958
import
logging
import
logging
import
os
import
os
import
re
import
tarfile
import
tarfile
import
zipfile
import
zipfile
import
pkginfo
import
pkginfo
from
bz2
import
BZ2File
from
bz2
import
BZ2File
from
collections
import
defaultdict
from
gzip
import
GzipFile
from
gzip
import
GzipFile
from
typing
import
Dict
from
typing
import
Dict
from
typing
import
List
from
typing
import
List
...
@@ -31,6 +31,7 @@ from requests import session
...
@@ -31,6 +31,7 @@ from requests import session
from
poetry.locations
import
CACHE_DIR
from
poetry.locations
import
CACHE_DIR
from
poetry.packages
import
dependency_from_pep_508
from
poetry.packages
import
dependency_from_pep_508
from
poetry.packages
import
Package
from
poetry.packages
import
Package
from
poetry.packages.utils.link
import
Link
from
poetry.semver
import
parse_constraint
from
poetry.semver
import
parse_constraint
from
poetry.semver
import
VersionConstraint
from
poetry.semver
import
VersionConstraint
from
poetry.semver
import
VersionRange
from
poetry.semver
import
VersionRange
...
@@ -39,8 +40,10 @@ from poetry.utils._compat import Path
...
@@ -39,8 +40,10 @@ from poetry.utils._compat import Path
from
poetry.utils._compat
import
to_str
from
poetry.utils._compat
import
to_str
from
poetry.utils.helpers
import
parse_requires
from
poetry.utils.helpers
import
parse_requires
from
poetry.utils.helpers
import
temporary_directory
from
poetry.utils.helpers
import
temporary_directory
from
poetry.utils.patterns
import
wheel_file_re
from
poetry.utils.setup_reader
import
SetupReader
from
poetry.utils.setup_reader
import
SetupReader
from
poetry.version.markers
import
InvalidMarker
from
poetry.version.markers
import
InvalidMarker
from
poetry.version.markers
import
parse_marker
from
.exceptions
import
PackageNotFound
from
.exceptions
import
PackageNotFound
from
.repository
import
Repository
from
.repository
import
Repository
...
@@ -306,74 +309,14 @@ class PyPiRepository(Repository):
...
@@ -306,74 +309,14 @@ class PyPiRepository(Repository):
# or badly set metadata when uploading
# or badly set metadata when uploading
# So, we need to make sure there is actually no
# So, we need to make sure there is actually no
# dependencies by introspecting packages
# dependencies by introspecting packages
urls
=
{}
urls
=
defaultdict
(
list
)
for
url
in
json_data
[
"urls"
]:
for
url
in
json_data
[
"urls"
]:
# Only get sdist and
universal
wheels if they exist
# Only get sdist and wheels if they exist
dist_type
=
url
[
"packagetype"
]
dist_type
=
url
[
"packagetype"
]
if
dist_type
not
in
[
"sdist"
,
"bdist_wheel"
]:
if
dist_type
not
in
[
"sdist"
,
"bdist_wheel"
]:
continue
continue
if
dist_type
==
"sdist"
and
"sdist"
not
in
urls
:
urls
[
dist_type
]
.
append
(
url
[
"url"
])
urls
[
url
[
"packagetype"
]]
=
url
[
"url"
]
continue
if
"bdist_wheel"
in
urls
:
continue
# If bdist_wheel, check if it's universal
filename
=
url
[
"filename"
]
if
not
re
.
search
(
r"-py2\.py3-none-any.whl"
,
filename
):
continue
urls
[
dist_type
]
=
url
[
"url"
]
if
"sdist"
in
urls
and
"bdist_wheel"
not
in
urls
:
# If can't found a universal wheel
# but we found an sdist, inspect the sdist first
info
=
self
.
_get_info_from_urls
(
urls
)
if
info
[
"requires_dist"
]:
data
[
"requires_dist"
]
=
info
[
"requires_dist"
]
if
not
data
[
"requires_python"
]:
data
[
"requires_python"
]
=
info
[
"requires_python"
]
return
data
else
:
del
urls
[
"sdist"
]
if
not
urls
:
# If we don't have urls, we try to take the first one
# we find and go from there
if
not
json_data
[
"urls"
]:
return
data
for
url
in
json_data
[
"urls"
]:
# Only get sdist and universal wheels if they exist
dist_type
=
url
[
"packagetype"
]
if
dist_type
!=
"bdist_wheel"
:
continue
urls
[
url
[
"packagetype"
]]
=
url
[
"url"
]
break
if
not
urls
or
"bdist_wheel"
not
in
urls
:
# If we don't have urls, we try to take the first one
# we find and go from there
if
not
json_data
[
"urls"
]:
return
data
for
url
in
json_data
[
"urls"
]:
# Only get sdist and universal wheels if they exist
dist_type
=
url
[
"packagetype"
]
if
dist_type
!=
"bdist_wheel"
:
continue
urls
[
url
[
"packagetype"
]]
=
url
[
"url"
]
break
if
not
urls
:
if
not
urls
:
return
data
return
data
...
@@ -398,27 +341,98 @@ class PyPiRepository(Repository):
...
@@ -398,27 +341,98 @@ class PyPiRepository(Repository):
def
_get_info_from_urls
(
def
_get_info_from_urls
(
self
,
urls
self
,
urls
):
# type: (Dict[str, str]) -> Dict[str, Union[str, List, None]]
):
# type: (Dict[str, List[str]]) -> Dict[str, Union[str, List, None]]
# Checking wheels first as they are more likely to hold
# the necessary information
if
"bdist_wheel"
in
urls
:
if
"bdist_wheel"
in
urls
:
self
.
_log
(
# Check fo a universal wheel
"Downloading wheel: {}"
.
format
(
wheels
=
urls
[
"bdist_wheel"
]
urlparse
.
urlparse
(
urls
[
"bdist_wheel"
])
.
path
.
rsplit
(
"/"
)[
-
1
]
),
universal_wheel
=
None
level
=
"debug"
,
universal_python2_wheel
=
None
universal_python3_wheel
=
None
platform_specific_wheels
=
[]
for
wheel
in
wheels
:
link
=
Link
(
wheel
)
m
=
wheel_file_re
.
match
(
link
.
filename
)
if
not
m
:
continue
pyver
=
m
.
group
(
"pyver"
)
abi
=
m
.
group
(
"abi"
)
plat
=
m
.
group
(
"plat"
)
if
abi
==
"none"
and
plat
==
"any"
:
# Universal wheel
if
pyver
==
"py2.py3"
:
# Any Python
universal_wheel
=
wheel
elif
pyver
==
"py2"
:
universal_python2_wheel
=
wheel
else
:
universal_python3_wheel
=
wheel
else
:
platform_specific_wheels
.
append
(
wheel
)
if
universal_wheel
is
not
None
:
return
self
.
_get_info_from_wheel
(
universal_wheel
)
info
=
{}
if
universal_python2_wheel
and
universal_python3_wheel
:
info
=
self
.
_get_info_from_wheel
(
universal_python2_wheel
)
py3_info
=
self
.
_get_info_from_wheel
(
universal_python3_wheel
)
if
py3_info
[
"requires_dist"
]:
if
not
info
[
"requires_dist"
]:
info
[
"requires_dist"
]
=
py3_info
[
"requires_dist"
]
return
info
py2_requires_dist
=
set
(
dependency_from_pep_508
(
r
)
.
to_pep_508
()
for
r
in
info
[
"requires_dist"
]
)
)
return
self
.
_get_info_from_wheel
(
urls
[
"bdist_wheel"
])
py3_requires_dist
=
set
(
dependency_from_pep_508
(
r
)
.
to_pep_508
()
for
r
in
py3_info
[
"requires_dist"
]
)
base_requires_dist
=
py2_requires_dist
&
py3_requires_dist
py2_only_requires_dist
=
py2_requires_dist
-
py3_requires_dist
py3_only_requires_dist
=
py3_requires_dist
-
py2_requires_dist
# Normalizing requires_dist
requires_dist
=
list
(
base_requires_dist
)
for
requirement
in
py2_only_requires_dist
:
dep
=
dependency_from_pep_508
(
requirement
)
dep
.
marker
=
dep
.
marker
.
intersect
(
parse_marker
(
"python_version == '2.7'"
)
)
requires_dist
.
append
(
dep
.
to_pep_508
())
self
.
_log
(
for
requirement
in
py3_only_requires_dist
:
"Downloading sdist: {}"
.
format
(
dep
=
dependency_from_pep_508
(
requirement
)
urlparse
.
urlparse
(
urls
[
"sdist"
])
.
path
.
rsplit
(
"/"
)[
-
1
]
dep
.
marker
=
dep
.
marker
.
intersect
(
),
parse_marker
(
"python_version >= '3'"
)
level
=
"debug"
,
)
)
return
self
.
_get_info_from_sdist
(
urls
[
"sdist"
])
requires_dist
.
append
(
dep
.
to_pep_508
())
info
[
"requires_dist"
]
=
sorted
(
list
(
set
(
requires_dist
)))
if
info
:
return
info
if
platform_specific_wheels
and
"sdist"
not
in
urls
:
# Pick the first wheel available and hope for the best
return
self
.
_get_info_from_wheel
(
platform_specific_wheels
[
0
])
return
self
.
_get_info_from_sdist
(
urls
[
"sdist"
][
0
])
def
_get_info_from_wheel
(
def
_get_info_from_wheel
(
self
,
url
self
,
url
):
# type: (str) -> Dict[str, Union[str, List, None]]
):
# type: (str) -> Dict[str, Union[str, List, None]]
self
.
_log
(
"Downloading wheel: {}"
.
format
(
urlparse
.
urlparse
(
url
)
.
path
.
rsplit
(
"/"
)[
-
1
]),
level
=
"debug"
,
)
info
=
{
"summary"
:
""
,
"requires_python"
:
None
,
"requires_dist"
:
None
}
info
=
{
"summary"
:
""
,
"requires_python"
:
None
,
"requires_dist"
:
None
}
filename
=
os
.
path
.
basename
(
urlparse
.
urlparse
(
url
)
.
path
.
rsplit
(
"/"
)[
-
1
])
filename
=
os
.
path
.
basename
(
urlparse
.
urlparse
(
url
)
.
path
.
rsplit
(
"/"
)[
-
1
])
...
@@ -447,6 +461,10 @@ class PyPiRepository(Repository):
...
@@ -447,6 +461,10 @@ class PyPiRepository(Repository):
def
_get_info_from_sdist
(
def
_get_info_from_sdist
(
self
,
url
self
,
url
):
# type: (str) -> Dict[str, Union[str, List, None]]
):
# type: (str) -> Dict[str, Union[str, List, None]]
self
.
_log
(
"Downloading sdist: {}"
.
format
(
urlparse
.
urlparse
(
url
)
.
path
.
rsplit
(
"/"
)[
-
1
]),
level
=
"debug"
,
)
info
=
{
"summary"
:
""
,
"requires_python"
:
None
,
"requires_dist"
:
None
}
info
=
{
"summary"
:
""
,
"requires_python"
:
None
,
"requires_dist"
:
None
}
filename
=
os
.
path
.
basename
(
urlparse
.
urlparse
(
url
)
.
path
)
filename
=
os
.
path
.
basename
(
urlparse
.
urlparse
(
url
)
.
path
)
...
...
tests/repositories/fixtures/legacy/ipython.html
0 → 100644
View file @
271e9958
<!DOCTYPE html>
<html>
<head>
<title>
Links for ipython
</title>
</head>
<body>
<h1>
Links for ipython
</h1>
<a
href=
"https://files.pythonhosted.org/packages/52/19/aadde98d6bde1667d0bf431fb2d22451f880aaa373e0a241c7e7cb5815a0/ipython-5.7.0-py2-none-any.whl#sha256=707d1bbfc81e41e39ead1012af931bec6f80357b87e520af352e539cf5961dc0"
>
ipython-5.7.0-py2-none-any.whl
</a><br/>
<a
href=
"https://files.pythonhosted.org/packages/c7/b6/03e0b5b0972e6161d16c4cec8d41a20372bd0634f8cb4cc0c984b8a91db6/ipython-5.7.0-py3-none-any.whl#sha256=fc0464e68f9c65cd8c453474b4175432cc29ecb6c83775baedf6dbfcee9275ab"
>
ipython-5.7.0-py3-none-any.whl
</a><br/>
<a
href=
"https://files.pythonhosted.org/packages/3c/fd/559fead731a29eaa55cc235c8029807b2520976a937c30e9ee603f3bb566/ipython-5.7.0.tar.gz#sha256=8db43a7fb7619037c98626613ff08d03dda9d5d12c84814a4504c78c0da8323c"
>
ipython-5.7.0.tar.gz
</a><br/>
</body>
</html>
<!--SERIAL 4837213-->
tests/repositories/fixtures/pypi.org/dists/ipython-5.7.0-py2-none-any.whl
0 → 100644
View file @
271e9958
File added
tests/repositories/fixtures/pypi.org/dists/ipython-5.7.0-py3-none-any.whl
0 → 100644
View file @
271e9958
File added
tests/repositories/fixtures/pypi.org/dists/ipython-5.7.0.tar.gz
0 → 100644
View file @
271e9958
File added
tests/repositories/test_legacy_repository.py
View file @
271e9958
...
@@ -169,3 +169,39 @@ def test_get_package_information_sets_appropriate_python_versions_if_wheels_only
...
@@ -169,3 +169,39 @@ def test_get_package_information_sets_appropriate_python_versions_if_wheels_only
assert
package
.
name
==
"futures"
assert
package
.
name
==
"futures"
assert
package
.
version
.
text
==
"3.2.0"
assert
package
.
version
.
text
==
"3.2.0"
assert
package
.
python_versions
==
">=2.6, <3"
assert
package
.
python_versions
==
">=2.6, <3"
def
test_get_package_from_both_py2_and_py3_specific_wheels
():
repo
=
MockRepository
()
package
=
repo
.
package
(
"ipython"
,
"5.7.0"
)
assert
"ipython"
==
package
.
name
assert
"5.7.0"
==
package
.
version
.
text
assert
"*"
==
package
.
python_versions
expected
=
[
Dependency
(
"appnope"
,
"*"
),
Dependency
(
"backports.shutil-get-terminal-size"
,
"*"
),
Dependency
(
"colorama"
,
"*"
),
Dependency
(
"decorator"
,
"*"
),
Dependency
(
"pathlib2"
,
"*"
),
Dependency
(
"pexpect"
,
"*"
),
Dependency
(
"pickleshare"
,
"*"
),
Dependency
(
"prompt-toolkit"
,
">=1.0.4,<2.0.0"
),
Dependency
(
"pygments"
,
"*"
),
Dependency
(
"setuptools"
,
">=18.5"
),
Dependency
(
"simplegeneric"
,
">0.8"
),
Dependency
(
"traitlets"
,
">=4.2"
),
Dependency
(
"win-unicode-console"
,
">=0.5"
),
]
assert
expected
==
package
.
requires
assert
'python_version == "2.7"'
==
str
(
package
.
requires
[
1
]
.
marker
)
assert
'sys_platform == "win32" and python_version < "3.6"'
==
str
(
package
.
requires
[
12
]
.
marker
)
assert
'python_version == "2.7" or python_version == "3.3"'
==
str
(
package
.
requires
[
4
]
.
marker
)
assert
'sys_platform != "win32"'
==
str
(
package
.
requires
[
5
]
.
marker
)
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