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
1e23e57a
Unverified
Commit
1e23e57a
authored
Mar 22, 2018
by
Sébastien Eustace
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix handling of extras in wheels metadata
parent
aa740147
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
143 additions
and
43 deletions
+143
-43
CHANGELOG.md
+7
-0
poetry/installation/installer.py
+3
-3
poetry/masonry/builders/sdist.py
+3
-1
poetry/masonry/builders/wheel.py
+3
-2
poetry/masonry/metadata.py
+4
-2
poetry/packages/constraints/generic_constraint.py
+19
-14
poetry/packages/dependency.py
+36
-12
poetry/packages/package.py
+2
-2
poetry/poetry.py
+14
-5
tests/masonry/builders/test_complete.py
+25
-0
tests/packages/test_dependency.py
+27
-2
No files found.
CHANGELOG.md
View file @
1e23e57a
# Change Log
# Change Log
## [Unreleased]
### Fixed
-
Fixed handling of extras in wheels metadata.
## [0.6.4] - 2018-03-21
## [0.6.4] - 2018-03-21
### Added
### Added
...
...
poetry/installation/installer.py
View file @
1e23e57a
...
@@ -5,7 +5,7 @@ from typing import List
...
@@ -5,7 +5,7 @@ from typing import List
from
poetry.packages
import
Dependency
from
poetry.packages
import
Dependency
from
poetry.packages
import
Locker
from
poetry.packages
import
Locker
from
poetry.packages
import
Package
from
poetry.packages
import
Package
from
poetry.packages.constraints.
platform_constraint
import
Platform
Constraint
from
poetry.packages.constraints.
generic_constraint
import
Generic
Constraint
from
poetry.puzzle
import
Solver
from
poetry.puzzle
import
Solver
from
poetry.puzzle.operations
import
Install
from
poetry.puzzle.operations
import
Install
from
poetry.puzzle.operations
import
Uninstall
from
poetry.puzzle.operations
import
Uninstall
...
@@ -398,11 +398,11 @@ class Installer:
...
@@ -398,11 +398,11 @@ class Installer:
continue
continue
if
'platform'
in
package
.
requirements
:
if
'platform'
in
package
.
requirements
:
platform_constraint
=
Platform
Constraint
.
parse
(
platform_constraint
=
Generic
Constraint
.
parse
(
package
.
requirements
[
'platform'
]
package
.
requirements
[
'platform'
]
)
)
if
not
platform_constraint
.
matches
(
if
not
platform_constraint
.
matches
(
Platform
Constraint
(
'='
,
sys
.
platform
)
Generic
Constraint
(
'='
,
sys
.
platform
)
):
):
# Incompatible systems
# Incompatible systems
op
.
skip
(
'Not needed for the current platform'
)
op
.
skip
(
'Not needed for the current platform'
)
...
...
poetry/masonry/builders/sdist.py
View file @
1e23e57a
...
@@ -226,7 +226,9 @@ class SdistBuilder(Builder):
...
@@ -226,7 +226,9 @@ class SdistBuilder(Builder):
for
extra_name
,
reqs
in
package
.
extras
.
items
():
for
extra_name
,
reqs
in
package
.
extras
.
items
():
for
req
in
reqs
:
for
req
in
reqs
:
if
req
.
name
==
dependency
.
name
:
if
req
.
name
==
dependency
.
name
:
extras
[
extra_name
]
.
append
(
dependency
.
to_pep_508
())
extras
[
extra_name
]
.
append
(
dependency
.
to_pep_508
(
with_extras
=
False
)
)
continue
continue
requirement
=
dependency
.
to_pep_508
()
requirement
=
dependency
.
to_pep_508
()
...
...
poetry/masonry/builders/wheel.py
View file @
1e23e57a
...
@@ -311,6 +311,9 @@ class WheelBuilder(Builder):
...
@@ -311,6 +311,9 @@ class WheelBuilder(Builder):
for
classifier
in
self
.
_meta
.
classifiers
:
for
classifier
in
self
.
_meta
.
classifiers
:
fp
.
write
(
f
'Classifier: {classifier}
\n
'
)
fp
.
write
(
f
'Classifier: {classifier}
\n
'
)
for
extra
in
self
.
_meta
.
provides_extra
:
fp
.
write
(
f
'Provides-Extra: {extra}
\n
'
)
for
dep
in
self
.
_meta
.
requires_dist
:
for
dep
in
self
.
_meta
.
requires_dist
:
fp
.
write
(
f
'Requires-Dist: {dep}
\n
'
)
fp
.
write
(
f
'Requires-Dist: {dep}
\n
'
)
...
@@ -318,7 +321,5 @@ class WheelBuilder(Builder):
...
@@ -318,7 +321,5 @@ class WheelBuilder(Builder):
fp
.
write
(
f
'Description-Content-Type: '
fp
.
write
(
f
'Description-Content-Type: '
f
'{self._meta.description_content_type}
\n
'
)
f
'{self._meta.description_content_type}
\n
'
)
# TODO: Provides extra
if
self
.
_meta
.
description
is
not
None
:
if
self
.
_meta
.
description
is
not
None
:
fp
.
write
(
'
\n
'
+
self
.
_meta
.
description
+
'
\n
'
)
fp
.
write
(
'
\n
'
+
self
.
_meta
.
description
+
'
\n
'
)
poetry/masonry/metadata.py
View file @
1e23e57a
...
@@ -28,7 +28,7 @@ class Metadata:
...
@@ -28,7 +28,7 @@ class Metadata:
maintainer_email
=
None
maintainer_email
=
None
requires_python
=
None
requires_python
=
None
requires_external
=
()
requires_external
=
()
requires_dist
=
()
requires_dist
=
[]
provides_dist
=
()
provides_dist
=
()
obsoletes_dist
=
()
obsoletes_dist
=
()
project_urls
=
()
project_urls
=
()
...
@@ -59,6 +59,7 @@ class Metadata:
...
@@ -59,6 +59,7 @@ class Metadata:
meta
.
maintainer
=
meta
.
author
meta
.
maintainer
=
meta
.
author
meta
.
maintainer_email
=
meta
.
author_email
meta
.
maintainer_email
=
meta
.
author_email
meta
.
requires_python
=
package
.
python_constraint
meta
.
requires_python
=
package
.
python_constraint
meta
.
requires_dist
=
[
d
.
to_pep_508
()
for
d
in
package
.
requires
]
meta
.
requires_dist
=
[
d
.
to_pep_508
()
for
d
in
package
.
requires
]
# Requires python
# Requires python
...
@@ -73,5 +74,6 @@ class Metadata:
...
@@ -73,5 +74,6 @@ class Metadata:
else
:
else
:
meta
.
description_content_type
=
'text/plain'
meta
.
description_content_type
=
'text/plain'
# TODO: Provides extra
meta
.
provides_extra
=
[
e
for
e
in
package
.
extras
]
return
meta
return
meta
poetry/packages/constraints/
platform
_constraint.py
→
poetry/packages/constraints/
generic
_constraint.py
View file @
1e23e57a
...
@@ -6,7 +6,12 @@ from poetry.semver.constraints import MultiConstraint
...
@@ -6,7 +6,12 @@ from poetry.semver.constraints import MultiConstraint
from
poetry.semver.constraints.base_constraint
import
BaseConstraint
from
poetry.semver.constraints.base_constraint
import
BaseConstraint
class
PlatformConstraint
(
BaseConstraint
):
class
GenericConstraint
(
BaseConstraint
):
"""
Represents a generic constraint.
This is particularly useful for platform/system/os/extra constraints.
"""
OP_EQ
=
operator
.
eq
OP_EQ
=
operator
.
eq
OP_NE
=
operator
.
ne
OP_NE
=
operator
.
ne
...
@@ -22,7 +27,7 @@ class PlatformConstraint(BaseConstraint):
...
@@ -22,7 +27,7 @@ class PlatformConstraint(BaseConstraint):
OP_NE
:
'!='
OP_NE
:
'!='
}
}
def
__init__
(
self
,
operator
,
platform
):
def
__init__
(
self
,
operator
,
version
):
if
operator
not
in
self
.
_trans_op_str
:
if
operator
not
in
self
.
_trans_op_str
:
raise
ValueError
(
raise
ValueError
(
f
'Invalid operator "{operator}" given, '
f
'Invalid operator "{operator}" given, '
...
@@ -30,8 +35,8 @@ class PlatformConstraint(BaseConstraint):
...
@@ -30,8 +35,8 @@ class PlatformConstraint(BaseConstraint):
)
)
self
.
_operator
=
self
.
_trans_op_str
[
operator
]
self
.
_operator
=
self
.
_trans_op_str
[
operator
]
self
.
_string_operator
=
operator
self
.
_string_operator
=
self
.
_trans_op_int
[
self
.
_operator
]
self
.
_
platform
=
platform
self
.
_
version
=
version
@property
@property
def
supported_operators
(
self
)
->
list
:
def
supported_operators
(
self
)
->
list
:
...
@@ -46,13 +51,13 @@ class PlatformConstraint(BaseConstraint):
...
@@ -46,13 +51,13 @@ class PlatformConstraint(BaseConstraint):
return
self
.
_string_operator
return
self
.
_string_operator
@property
@property
def
platform
(
self
)
->
str
:
def
version
(
self
)
->
str
:
return
self
.
_
platform
return
self
.
_
version
def
matches
(
self
,
provider
):
def
matches
(
self
,
provider
):
if
not
isinstance
(
provider
,
(
Platform
Constraint
,
EmptyConstraint
)):
if
not
isinstance
(
provider
,
(
Generic
Constraint
,
EmptyConstraint
)):
raise
ValueError
(
raise
ValueError
(
'
Platform
constraints can only be compared with each other'
'
Generic
constraints can only be compared with each other'
)
)
if
isinstance
(
provider
,
EmptyConstraint
):
if
isinstance
(
provider
,
EmptyConstraint
):
...
@@ -67,13 +72,13 @@ class PlatformConstraint(BaseConstraint):
...
@@ -67,13 +72,13 @@ class PlatformConstraint(BaseConstraint):
is_equal_op
and
is_provider_equal_op
is_equal_op
and
is_provider_equal_op
or
is_non_equal_op
and
is_provider_non_equal_op
or
is_non_equal_op
and
is_provider_non_equal_op
):
):
return
self
.
_
platform
==
provider
.
platform
return
self
.
_
version
==
provider
.
version
if
(
if
(
is_equal_op
and
is_provider_non_equal_op
is_equal_op
and
is_provider_non_equal_op
or
is_non_equal_op
and
is_provider_equal_op
or
is_non_equal_op
and
is_provider_equal_op
):
):
return
self
.
_
platform
!=
provider
.
platform
return
self
.
_
version
!=
provider
.
version
return
False
return
False
...
@@ -125,10 +130,10 @@ class PlatformConstraint(BaseConstraint):
...
@@ -125,10 +130,10 @@ class PlatformConstraint(BaseConstraint):
# Basic Comparators
# Basic Comparators
m
=
re
.
match
(
'^(!=|==?)?
\
s*(.*)'
,
constraint
)
m
=
re
.
match
(
'^(!=|==?)?
\
s*(.*)'
,
constraint
)
if
m
:
if
m
:
return
Platform
Constraint
(
m
.
group
(
1
)
or
'='
,
m
.
group
(
2
)),
return
Generic
Constraint
(
m
.
group
(
1
)
or
'='
,
m
.
group
(
2
)),
raise
ValueError
(
raise
ValueError
(
'Could not parse
platform
constraint: {}'
.
format
(
constraint
)
'Could not parse
generic
constraint: {}'
.
format
(
constraint
)
)
)
def
__str__
(
self
):
def
__str__
(
self
):
...
@@ -140,8 +145,8 @@ class PlatformConstraint(BaseConstraint):
...
@@ -140,8 +145,8 @@ class PlatformConstraint(BaseConstraint):
return
'{}{}'
.
format
(
return
'{}{}'
.
format
(
op
,
op
,
self
.
_
platform
self
.
_
version
)
)
def
__repr__
(
self
):
def
__repr__
(
self
):
return
'<
Platform
Constraint
\'
{}
\'
>'
.
format
(
str
(
self
))
return
'<
Generic
Constraint
\'
{}
\'
>'
.
format
(
str
(
self
))
poetry/packages/dependency.py
View file @
1e23e57a
...
@@ -6,7 +6,7 @@ from poetry.semver.constraints import MultiConstraint
...
@@ -6,7 +6,7 @@ from poetry.semver.constraints import MultiConstraint
from
poetry.semver.constraints.base_constraint
import
BaseConstraint
from
poetry.semver.constraints.base_constraint
import
BaseConstraint
from
poetry.semver.version_parser
import
VersionParser
from
poetry.semver.version_parser
import
VersionParser
from
.constraints.
platform_constraint
import
Platform
Constraint
from
.constraints.
generic_constraint
import
Generic
Constraint
class
Dependency
:
class
Dependency
:
...
@@ -40,6 +40,7 @@ class Dependency:
...
@@ -40,6 +40,7 @@ class Dependency:
self
.
_platform_constraint
=
EmptyConstraint
()
self
.
_platform_constraint
=
EmptyConstraint
()
self
.
_extras
=
[]
self
.
_extras
=
[]
self
.
_in_extras
=
[]
@property
@property
def
name
(
self
):
def
name
(
self
):
...
@@ -81,7 +82,7 @@ class Dependency:
...
@@ -81,7 +82,7 @@ class Dependency:
@platform.setter
@platform.setter
def
platform
(
self
,
value
:
str
):
def
platform
(
self
,
value
:
str
):
self
.
_platform
=
value
self
.
_platform
=
value
self
.
_platform_constraint
=
Platform
Constraint
.
parse
(
value
)
self
.
_platform_constraint
=
Generic
Constraint
.
parse
(
value
)
@property
@property
def
platform_constraint
(
self
):
def
platform_constraint
(
self
):
...
@@ -91,6 +92,10 @@ class Dependency:
...
@@ -91,6 +92,10 @@ class Dependency:
def
extras
(
self
)
->
list
:
def
extras
(
self
)
->
list
:
return
self
.
_extras
return
self
.
_extras
@property
def
in_extras
(
self
)
->
list
:
return
self
.
_in_extras
def
allows_prereleases
(
self
):
def
allows_prereleases
(
self
):
return
self
.
_allows_prereleases
return
self
.
_allows_prereleases
...
@@ -110,7 +115,7 @@ class Dependency:
...
@@ -110,7 +115,7 @@ class Dependency:
and
(
not
package
.
is_prerelease
()
or
self
.
allows_prereleases
())
and
(
not
package
.
is_prerelease
()
or
self
.
allows_prereleases
())
)
)
def
to_pep_508
(
self
)
->
str
:
def
to_pep_508
(
self
,
with_extras
=
True
)
->
str
:
requirement
=
f
'{self.pretty_name}'
requirement
=
f
'{self.pretty_name}'
if
isinstance
(
self
.
constraint
,
MultiConstraint
):
if
isinstance
(
self
.
constraint
,
MultiConstraint
):
...
@@ -127,31 +132,50 @@ class Dependency:
...
@@ -127,31 +132,50 @@ class Dependency:
if
self
.
python_versions
!=
'*'
:
if
self
.
python_versions
!=
'*'
:
python_constraint
=
self
.
python_constraint
python_constraint
=
self
.
python_constraint
markers
.
append
(
self
.
_create_nested_marker
(
'python_version'
,
python_constraint
))
markers
.
append
(
self
.
_create_nested_marker
(
'python_version'
,
python_constraint
)
)
in_extras
=
' || '
.
join
(
self
.
_in_extras
)
if
in_extras
and
with_extras
:
markers
.
append
(
self
.
_create_nested_marker
(
'extra'
,
GenericConstraint
.
parse
(
in_extras
)
)
)
if
markers
:
if
markers
:
requirement
+=
f
'; {" and ".join(markers)}'
if
len
(
markers
)
>
1
:
markers
=
[
'({})'
.
format
(
m
)
for
m
in
markers
]
requirement
+=
f
'; {" and ".join(markers)}'
else
:
requirement
+=
f
'; {markers[0]}'
return
requirement
return
requirement
@classmethod
def
from_pep_508
(
cls
):
return
def
_create_nested_marker
(
self
,
name
,
constraint
):
def
_create_nested_marker
(
self
,
name
,
constraint
):
if
isinstance
(
constraint
,
MultiConstraint
):
if
isinstance
(
constraint
,
MultiConstraint
):
parts
=
[]
parts
=
[]
for
c
in
constraint
.
constraints
:
for
c
in
constraint
.
constraints
:
parts
.
append
(
self
.
_create_nested_marker
(
name
,
c
))
multi
=
False
if
isinstance
(
c
,
MultiConstraint
):
multi
=
True
parts
.
append
((
multi
,
self
.
_create_nested_marker
(
name
,
c
)))
glue
=
' and '
glue
=
' and '
if
constraint
.
is_disjunctive
():
if
constraint
.
is_disjunctive
():
parts
=
[
f
'({part})'
for
part
in
parts
]
parts
=
[
f
'({part[1]})'
if
part
[
0
]
else
f
'{part[1]}'
for
part
in
parts
]
glue
=
' or '
glue
=
' or '
else
:
parts
=
[
part
[
1
]
for
part
in
parts
]
marker
=
glue
.
join
(
parts
)
marker
=
glue
.
join
(
parts
)
else
:
else
:
marker
=
f
'{name}
{constraint.string_operator}
"{constraint.version}"'
marker
=
f
'{name}
{constraint.string_operator}
"{constraint.version}"'
return
marker
return
marker
...
...
poetry/packages/package.py
View file @
1e23e57a
...
@@ -7,7 +7,7 @@ from poetry.semver.helpers import parse_stability
...
@@ -7,7 +7,7 @@ from poetry.semver.helpers import parse_stability
from
poetry.semver.version_parser
import
VersionParser
from
poetry.semver.version_parser
import
VersionParser
from
poetry.version
import
parse
as
parse_version
from
poetry.version
import
parse
as
parse_version
from
.
constraints
.
platform_constraint
import
Platform
Constraint
from
.constraints.generic_constraint
import
Generic
Constraint
from
.dependency
import
Dependency
from
.dependency
import
Dependency
from
.vcs_dependency
import
VCSDependency
from
.vcs_dependency
import
VCSDependency
...
@@ -182,7 +182,7 @@ class Package:
...
@@ -182,7 +182,7 @@ class Package:
@platform.setter
@platform.setter
def
platform
(
self
,
value
:
str
):
def
platform
(
self
,
value
:
str
):
self
.
_platform
=
value
self
.
_platform
=
value
self
.
_platform_constraint
=
Platform
Constraint
.
parse
(
value
)
self
.
_platform_constraint
=
Generic
Constraint
.
parse
(
value
)
@property
@property
def
platform_constraint
(
self
):
def
platform_constraint
(
self
):
...
...
poetry/poetry.py
View file @
1e23e57a
...
@@ -107,11 +107,20 @@ class Poetry:
...
@@ -107,11 +107,20 @@ class Poetry:
for
name
,
constraint
in
local_config
[
'dev-dependencies'
]
.
items
():
for
name
,
constraint
in
local_config
[
'dev-dependencies'
]
.
items
():
package
.
add_dependency
(
name
,
constraint
,
category
=
'dev'
)
package
.
add_dependency
(
name
,
constraint
,
category
=
'dev'
)
if
'extras'
in
local_config
:
extras
=
local_config
.
get
(
'extras'
,
{})
for
extra_name
,
requirements
in
local_config
[
'extras'
]
.
items
():
for
extra_name
,
requirements
in
extras
.
items
():
package
.
extras
[
extra_name
]
=
[
package
.
extras
[
extra_name
]
=
[]
Dependency
(
req
,
'*'
)
for
req
in
requirements
]
# Checking for dependency
for
req
in
requirements
:
req
=
Dependency
(
req
,
'*'
)
for
dep
in
package
.
requires
:
if
dep
.
name
==
req
.
name
:
dep
.
in_extras
.
append
(
extra_name
)
package
.
extras
[
extra_name
]
.
append
(
dep
)
break
if
'build'
in
local_config
:
if
'build'
in
local_config
:
package
.
build
=
local_config
[
'build'
]
package
.
build
=
local_config
[
'build'
]
...
...
tests/masonry/builders/test_complete.py
View file @
1e23e57a
...
@@ -99,5 +99,30 @@ Generator: poetry {__version__}
...
@@ -99,5 +99,30 @@ Generator: poetry {__version__}
Root-Is-Purelib: true
Root-Is-Purelib: true
Tag: py3-none-any
Tag: py3-none-any
"""
"""
wheel_data
=
zip
.
read
(
'my_package-1.2.3.dist-info/METADATA'
)
.
decode
()
assert
wheel_data
==
"""
\
Metadata-Version: 2.1
Name: my-package
Version: 1.2.3
Summary: Some description.
Home-page: https://poetry.eustace.io/
License: MIT
Keywords: packaging,dependency,poetry
Author: Sébastien Eustace
Author-email: sebastien@eustace.io
Requires-Python: >= 3.6.0.0, < 4.0.0.0
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Provides-Extra: time
Requires-Dist: cleo (>=0.6.0.0,<0.7.0.0)
Requires-Dist: pendulum (>=1.4.0.0,<2.0.0.0); extra == "time"
Description-Content-Type: text/x-rst
My Package
==========
"""
finally
:
finally
:
zip
.
close
()
zip
.
close
()
tests/packages/test_dependency.py
View file @
1e23e57a
...
@@ -66,5 +66,30 @@ def test_to_pep_508():
...
@@ -66,5 +66,30 @@ def test_to_pep_508():
result
=
dependency
.
to_pep_508
()
result
=
dependency
.
to_pep_508
()
assert
result
==
'Django (>=1.23.0.0,<2.0.0.0); '
\
assert
result
==
'Django (>=1.23.0.0,<2.0.0.0); '
\
'(python_version>="2.7.0.0" and python_version<"2.8.0.0") '
\
'(python_version >= "2.7.0.0" and python_version < "2.8.0.0") '
\
'or (python_version>="3.6.0.0" and python_version<"4.0.0.0")'
'or (python_version >= "3.6.0.0" and python_version < "4.0.0.0")'
def
test_to_pep_508_in_extras
():
dependency
=
Dependency
(
'Django'
,
'^1.23'
)
dependency
.
in_extras
.
append
(
'foo'
)
result
=
dependency
.
to_pep_508
()
assert
result
==
'Django (>=1.23.0.0,<2.0.0.0); extra == "foo"'
dependency
.
in_extras
.
append
(
'bar'
)
result
=
dependency
.
to_pep_508
()
assert
result
==
'Django (>=1.23.0.0,<2.0.0.0); extra == "foo" or extra == "bar"'
dependency
.
python_versions
=
'~2.7 || ^3.6'
result
=
dependency
.
to_pep_508
()
assert
result
==
(
'Django (>=1.23.0.0,<2.0.0.0); '
'('
'(python_version >= "2.7.0.0" and python_version < "2.8.0.0") '
'or (python_version >= "3.6.0.0" and python_version < "4.0.0.0")'
') '
'and (extra == "foo" or extra == "bar")'
)
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