Commit ba81d8a1 by Sébastien Eustace Committed by GitHub

Add support for environment markers specification in dependencies (#1142)

parent a61a1def
...@@ -129,6 +129,17 @@ pathlib2 = { version = "^2.2", python = "~2.7" } ...@@ -129,6 +129,17 @@ pathlib2 = { version = "^2.2", python = "~2.7" }
pathlib2 = { version = "^2.2", python = ["~2.7", "^3.2"] } pathlib2 = { version = "^2.2", python = ["~2.7", "^3.2"] }
``` ```
### Using environment markers
If you need more complex install conditions for your dependencies,
Poetry supports [environment markers](https://www.python.org/dev/peps/pep-0508/#environment-markers)
via the `markers` property:
```toml
[tool.poetry.dependencies]
pathlib2 = { version = "^2.2", markers = "python_version ~= '2.7' or sys_platform == 'win32'" }
```
### Multiple constraints dependencies ### Multiple constraints dependencies
......
...@@ -230,6 +230,10 @@ ...@@ -230,6 +230,10 @@
"type": "string", "type": "string",
"description": "The platform(s) for which the dependency should be installed." "description": "The platform(s) for which the dependency should be installed."
}, },
"markers": {
"type": "string",
"description": "The PEP 508 compliant environment markers for which the dependency should be installed."
},
"allows-prereleases": { "allows-prereleases": {
"type": "boolean", "type": "boolean",
"description": "Whether the dependency allows prereleases or not." "description": "Whether the dependency allows prereleases or not."
...@@ -283,6 +287,10 @@ ...@@ -283,6 +287,10 @@
"type": "string", "type": "string",
"description": "The platform(s) for which the dependency should be installed." "description": "The platform(s) for which the dependency should be installed."
}, },
"markers": {
"type": "string",
"description": "The PEP 508 compliant environment markers for which the dependency should be installed."
},
"allows-prereleases": { "allows-prereleases": {
"type": "boolean", "type": "boolean",
"description": "Whether the dependency allows prereleases or not." "description": "Whether the dependency allows prereleases or not."
...@@ -319,6 +327,10 @@ ...@@ -319,6 +327,10 @@
"type": "string", "type": "string",
"description": "The platform(s) for which the dependency should be installed." "description": "The platform(s) for which the dependency should be installed."
}, },
"markers": {
"type": "string",
"description": "The PEP 508 compliant environment markers for which the dependency should be installed."
},
"optional": { "optional": {
"type": "boolean", "type": "boolean",
"description": "Whether the dependency is optional or not." "description": "Whether the dependency is optional or not."
...@@ -351,6 +363,10 @@ ...@@ -351,6 +363,10 @@
"type": "string", "type": "string",
"description": "The platform(s) for which the dependency should be installed." "description": "The platform(s) for which the dependency should be installed."
}, },
"markers": {
"type": "string",
"description": "The PEP 508 compliant environment markers for which the dependency should be installed."
},
"optional": { "optional": {
"type": "boolean", "type": "boolean",
"description": "Whether the dependency is optional or not." "description": "Whether the dependency is optional or not."
......
...@@ -245,6 +245,7 @@ class Package(object): ...@@ -245,6 +245,7 @@ class Package(object):
optional = constraint.get("optional", False) optional = constraint.get("optional", False)
python_versions = constraint.get("python") python_versions = constraint.get("python")
platform = constraint.get("platform") platform = constraint.get("platform")
markers = constraint.get("markers")
allows_prereleases = constraint.get("allows-prereleases", False) allows_prereleases = constraint.get("allows-prereleases", False)
if "git" in constraint: if "git" in constraint:
...@@ -301,25 +302,28 @@ class Package(object): ...@@ -301,25 +302,28 @@ class Package(object):
source_name=constraint.get("source"), source_name=constraint.get("source"),
) )
marker = AnyMarker() if not markers:
if python_versions: marker = AnyMarker()
dependency.python_versions = python_versions if python_versions:
marker = marker.intersect( dependency.python_versions = python_versions
parse_marker( marker = marker.intersect(
create_nested_marker( parse_marker(
"python_version", dependency.python_constraint create_nested_marker(
"python_version", dependency.python_constraint
)
) )
) )
)
if platform: if platform:
marker = marker.intersect( marker = marker.intersect(
parse_marker( parse_marker(
create_nested_marker( create_nested_marker(
"sys_platform", parse_generic_constraint(platform) "sys_platform", parse_generic_constraint(platform)
)
) )
) )
) else:
marker = parse_marker(markers)
if not marker.is_any(): if not marker.is_any():
dependency.marker = marker dependency.marker = marker
......
...@@ -39,6 +39,9 @@ my-package = { path = "../project_with_setup/" } ...@@ -39,6 +39,9 @@ my-package = { path = "../project_with_setup/" }
# Dir dependency with pyproject.toml # Dir dependency with pyproject.toml
simple-project = { path = "../simple_project/" } simple-project = { path = "../simple_project/" }
# Dependency with markers
functools32 = { version = "^3.2.3", markers = "python_version ~= '2.7' and sys_platform == 'win32' or python_version in '3.4 3.5'" }
[tool.poetry.extras] [tool.poetry.extras]
db = [ "orator" ] db = [ "orator" ]
......
...@@ -30,7 +30,10 @@ python = "^3.6" ...@@ -30,7 +30,10 @@ python = "^3.6"
cleo = "^0.6" cleo = "^0.6"
cachy = { version = "^0.2.0", extras = ["msgpack"] } cachy = { version = "^0.2.0", extras = ["msgpack"] }
pendulum = { version = "^1.4", optional = true } [tool.poetry.dependencies.pendulum]
version = "^1.4"
markers= 'python_version ~= "2.7" and sys_platform == "win32" or python_version in "3.4 3.5"'
optional = true
[tool.poetry.dev-dependencies] [tool.poetry.dev-dependencies]
pytest = "~3.4" pytest = "~3.4"
......
...@@ -97,7 +97,7 @@ def test_get_metadata_content(): ...@@ -97,7 +97,7 @@ def test_get_metadata_content():
assert requires == [ assert requires == [
"cachy[msgpack] (>=0.2.0,<0.3.0)", "cachy[msgpack] (>=0.2.0,<0.3.0)",
"cleo (>=0.6,<0.7)", "cleo (>=0.6,<0.7)",
'pendulum (>=1.4,<2.0); extra == "time"', 'pendulum (>=1.4,<2.0); (python_version ~= "2.7" and sys_platform == "win32" or python_version in "3.4 3.5") and (extra == "time")',
] ]
urls = parsed.get_all("Project-URL") urls = parsed.get_all("Project-URL")
......
...@@ -219,7 +219,7 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules ...@@ -219,7 +219,7 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
Provides-Extra: time Provides-Extra: time
Requires-Dist: cachy[msgpack] (>=0.2.0,<0.3.0) Requires-Dist: cachy[msgpack] (>=0.2.0,<0.3.0)
Requires-Dist: cleo (>=0.6,<0.7) Requires-Dist: cleo (>=0.6,<0.7)
Requires-Dist: pendulum (>=1.4,<2.0); extra == "time" Requires-Dist: pendulum (>=1.4,<2.0); (python_version ~= "2.7" and sys_platform == "win32" or python_version in "3.4 3.5") and (extra == "time")
Project-URL: Documentation, https://poetry.eustace.io/docs Project-URL: Documentation, https://poetry.eustace.io/docs
Project-URL: Issue Tracker, https://github.com/sdispater/poetry/issues Project-URL: Issue Tracker, https://github.com/sdispater/poetry/issues
Project-URL: Repository, https://github.com/sdispater/poetry Project-URL: Repository, https://github.com/sdispater/poetry
...@@ -319,7 +319,7 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules ...@@ -319,7 +319,7 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
Provides-Extra: time Provides-Extra: time
Requires-Dist: cachy[msgpack] (>=0.2.0,<0.3.0) Requires-Dist: cachy[msgpack] (>=0.2.0,<0.3.0)
Requires-Dist: cleo (>=0.6,<0.7) Requires-Dist: cleo (>=0.6,<0.7)
Requires-Dist: pendulum (>=1.4,<2.0); extra == "time" Requires-Dist: pendulum (>=1.4,<2.0); (python_version ~= "2.7" and sys_platform == "win32" or python_version in "3.4 3.5") and (extra == "time")
Project-URL: Documentation, https://poetry.eustace.io/docs Project-URL: Documentation, https://poetry.eustace.io/docs
Project-URL: Issue Tracker, https://github.com/sdispater/poetry/issues Project-URL: Issue Tracker, https://github.com/sdispater/poetry/issues
Project-URL: Repository, https://github.com/sdispater/poetry Project-URL: Repository, https://github.com/sdispater/poetry
......
...@@ -133,7 +133,11 @@ def test_make_setup(): ...@@ -133,7 +133,11 @@ def test_make_setup():
"my-script = my_package:main", "my-script = my_package:main",
] ]
} }
assert ns["extras_require"] == {"time": ["pendulum>=1.4,<2.0"]} assert ns["extras_require"] == {
'time:python_version ~= "2.7" and sys_platform == "win32" or python_version in "3.4 3.5"': [
"pendulum>=1.4,<2.0"
]
}
def test_make_pkg_info(mocker): def test_make_pkg_info(mocker):
......
...@@ -97,7 +97,7 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules ...@@ -97,7 +97,7 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
Provides-Extra: time Provides-Extra: time
Requires-Dist: cachy[msgpack] (>=0.2.0,<0.3.0) Requires-Dist: cachy[msgpack] (>=0.2.0,<0.3.0)
Requires-Dist: cleo (>=0.6,<0.7) Requires-Dist: cleo (>=0.6,<0.7)
Requires-Dist: pendulum (>=1.4,<2.0); extra == "time" Requires-Dist: pendulum (>=1.4,<2.0); (python_version ~= "2.7" and sys_platform == "win32" or python_version in "3.4 3.5") and (extra == "time")
Project-URL: Documentation, https://poetry.eustace.io/docs Project-URL: Documentation, https://poetry.eustace.io/docs
Project-URL: Issue Tracker, https://github.com/sdispater/poetry/issues Project-URL: Issue Tracker, https://github.com/sdispater/poetry/issues
Project-URL: Repository, https://github.com/sdispater/poetry Project-URL: Repository, https://github.com/sdispater/poetry
......
...@@ -82,6 +82,14 @@ def test_poetry(): ...@@ -82,6 +82,14 @@ def test_poetry():
assert simple_project.name == "simple-project" assert simple_project.name == "simple-project"
assert simple_project.pretty_constraint == "*" assert simple_project.pretty_constraint == "*"
functools32 = dependencies["functools32"]
assert functools32.name == "functools32"
assert functools32.pretty_constraint == "^3.2.3"
assert (
str(functools32.marker)
== 'python_version ~= "2.7" and sys_platform == "win32" or python_version in "3.4 3.5"'
)
assert "db" in package.extras assert "db" in package.extras
classifiers = package.classifiers classifiers = package.classifiers
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment