Skip to content

Commit

Permalink
Add support for environment markers specification in dependencies (#1142
Browse files Browse the repository at this point in the history
)
  • Loading branch information
sdispater authored Jun 11, 2019
1 parent a61a1de commit ba81d8a
Show file tree
Hide file tree
Showing 10 changed files with 69 additions and 20 deletions.
11 changes: 11 additions & 0 deletions docs/docs/versions.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,17 @@ pathlib2 = { version = "^2.2", python = "~2.7" }
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

Expand Down
16 changes: 16 additions & 0 deletions poetry/json/schemas/poetry-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,10 @@
"type": "string",
"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": {
"type": "boolean",
"description": "Whether the dependency allows prereleases or not."
Expand Down Expand Up @@ -283,6 +287,10 @@
"type": "string",
"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": {
"type": "boolean",
"description": "Whether the dependency allows prereleases or not."
Expand Down Expand Up @@ -319,6 +327,10 @@
"type": "string",
"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": {
"type": "boolean",
"description": "Whether the dependency is optional or not."
Expand Down Expand Up @@ -351,6 +363,10 @@
"type": "string",
"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": {
"type": "boolean",
"description": "Whether the dependency is optional or not."
Expand Down
32 changes: 18 additions & 14 deletions poetry/packages/package.py
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,7 @@ def add_dependency(
optional = constraint.get("optional", False)
python_versions = constraint.get("python")
platform = constraint.get("platform")
markers = constraint.get("markers")
allows_prereleases = constraint.get("allows-prereleases", False)

if "git" in constraint:
Expand Down Expand Up @@ -301,25 +302,28 @@ def add_dependency(
source_name=constraint.get("source"),
)

marker = AnyMarker()
if python_versions:
dependency.python_versions = python_versions
marker = marker.intersect(
parse_marker(
create_nested_marker(
"python_version", dependency.python_constraint
if not markers:
marker = AnyMarker()
if python_versions:
dependency.python_versions = python_versions
marker = marker.intersect(
parse_marker(
create_nested_marker(
"python_version", dependency.python_constraint
)
)
)
)

if platform:
marker = marker.intersect(
parse_marker(
create_nested_marker(
"sys_platform", parse_generic_constraint(platform)
if platform:
marker = marker.intersect(
parse_marker(
create_nested_marker(
"sys_platform", parse_generic_constraint(platform)
)
)
)
)
else:
marker = parse_marker(markers)

if not marker.is_any():
dependency.marker = marker
Expand Down
3 changes: 3 additions & 0 deletions tests/fixtures/sample_project/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ my-package = { path = "../project_with_setup/" }
# Dir dependency with pyproject.toml
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]
db = [ "orator" ]
Expand Down
5 changes: 4 additions & 1 deletion tests/masonry/builders/fixtures/complete/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@ python = "^3.6"
cleo = "^0.6"
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]
pytest = "~3.4"
Expand Down
2 changes: 1 addition & 1 deletion tests/masonry/builders/test_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ def test_get_metadata_content():
assert requires == [
"cachy[msgpack] (>=0.2.0,<0.3.0)",
"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")
Expand Down
4 changes: 2 additions & 2 deletions tests/masonry/builders/test_complete.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ def test_complete():
Provides-Extra: time
Requires-Dist: cachy[msgpack] (>=0.2.0,<0.3.0)
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: Issue Tracker, https://github.com/sdispater/poetry/issues
Project-URL: Repository, https://github.com/sdispater/poetry
Expand Down Expand Up @@ -319,7 +319,7 @@ def test_complete_no_vcs():
Provides-Extra: time
Requires-Dist: cachy[msgpack] (>=0.2.0,<0.3.0)
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: Issue Tracker, https://github.com/sdispater/poetry/issues
Project-URL: Repository, https://github.com/sdispater/poetry
Expand Down
6 changes: 5 additions & 1 deletion tests/masonry/builders/test_sdist.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,11 @@ def test_make_setup():
"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):
Expand Down
2 changes: 1 addition & 1 deletion tests/masonry/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ def test_prepare_metadata_for_build_wheel():
Provides-Extra: time
Requires-Dist: cachy[msgpack] (>=0.2.0,<0.3.0)
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: Issue Tracker, https://github.com/sdispater/poetry/issues
Project-URL: Repository, https://github.com/sdispater/poetry
Expand Down
8 changes: 8 additions & 0 deletions tests/test_poetry.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,14 @@ def test_poetry():
assert simple_project.name == "simple-project"
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

classifiers = package.classifiers
Expand Down

0 comments on commit ba81d8a

Please sign in to comment.