Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit f2e01f9

Browse filesBrowse files
nikhaldimattmoor
authored andcommitted
Evaluate PEP 508 environment markers for package dependencies (bazel-contrib#50)
* Evaluate PEP 508 environment markers for package dependencies Previously any wheel dependencies that had an environment marker (such as 'python_version>3.3') were simply ignored, leading to missing packages in the Python environment constructed by bazel. Fixes bazel-contrib#49 * Regenerate the piptool.par Required after making changes to whl.py * Pin the version of setuptools in piptool & extract whltool Some common operators in version markers (e.g., <=) are only supported in setuptools>=17.1. Rather than risk failing because the environment has an old setuptools version it's better to include it. Pinning to an exact version (currently the latest) to make things as predictable as possible. In addition, whl.py used during workspace setup also now depends on setuptools. We package this in a separate whltool.par to make this predictable as well.
1 parent 44711d8 commit f2e01f9
Copy full SHA for f2e01f9

File tree

9 files changed

+74
-18
lines changed
Filter options

9 files changed

+74
-18
lines changed

‎python/requirements.txt

Copy file name to clipboard
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,6 @@
11
pip==9.0.1
2+
setuptools==38.2.4
23
wheel==0.30.0a0
4+
5+
# For tests
6+
mock==2.0.0

‎python/whl.bzl

Copy file name to clipboardExpand all lines: python/whl.bzl
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ whl_library = repository_rule(
4444
"extras": attr.string_list(),
4545
"_script": attr.label(
4646
executable = True,
47-
default = Label("//rules_python:whl.py"),
47+
default = Label("//tools:whltool.par"),
4848
cfg = "host",
4949
),
5050
},

‎rules_python/BUILD

Copy file name to clipboardExpand all lines: rules_python/BUILD
+20-5Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,14 @@ package(default_visibility = ["//visibility:public"])
1616
licenses(["notice"]) # Apache 2.0
1717

1818
load("//python:python.bzl", "py_binary", "py_library", "py_test")
19+
load("@piptool_deps//:requirements.bzl", "requirement")
1920

2021
py_library(
2122
name = "whl",
2223
srcs = ["whl.py"],
24+
deps = [
25+
requirement("setuptools"),
26+
],
2327
)
2428

2529
py_test(
@@ -32,18 +36,29 @@ py_test(
3236
"@grpc_whl//file",
3337
"@mock_whl//file",
3438
],
35-
deps = [":whl"],
39+
deps = [
40+
":whl",
41+
requirement("mock"),
42+
],
3643
)
3744

3845
load("@subpar//:subpar.bzl", "par_binary")
39-
load("@piptool_deps//:requirements.bzl", "all_requirements")
4046

41-
# TODO(mattmoor): Bundle this tool as a PAR without any
42-
# system-installed pre-requisites. See TODOs in piptool.py.
4347
par_binary(
4448
name = "piptool",
4549
srcs = ["piptool.py"],
4650
deps = [
4751
":whl",
48-
] + all_requirements,
52+
requirement("pip"),
53+
requirement("wheel"),
54+
],
55+
)
56+
57+
par_binary(
58+
name = "whltool",
59+
srcs = ["whl.py"],
60+
main = "whl.py",
61+
deps = [
62+
":whl",
63+
],
4964
)

‎rules_python/whl.py

Copy file name to clipboardExpand all lines: rules_python/whl.py
+5-4Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import argparse
1717
import json
1818
import os
19+
import pkg_resources
1920
import re
2021
import zipfile
2122

@@ -86,10 +87,10 @@ def dependencies(self, extra=None):
8687
if requirement.get('extra') != extra:
8788
# Match the requirements for the extra we're looking for.
8889
continue
89-
if 'environment' in requirement:
90-
# TODO(mattmoor): What's the best way to support "environment"?
91-
# This typically communicates things like python version (look at
92-
# "wheel" for a good example)
90+
marker = requirement.get('environment')
91+
if marker and not pkg_resources.evaluate_marker(marker):
92+
# The current environment does not match the provided PEP 508 marker,
93+
# so ignore this requirement.
9394
continue
9495
requires = requirement.get('requires', [])
9596
for entry in requires:

‎rules_python/whl_test.py

Copy file name to clipboardExpand all lines: rules_python/whl_test.py
+41-6Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
import os
1616
import unittest
1717

18+
from mock import patch
19+
1820
from rules_python import whl
1921

2022

@@ -54,32 +56,65 @@ def test_whl_with_METADATA_file(self):
5456
self.assertEqual(set(wheel.dependencies()), set())
5557
self.assertEqual('pypi__futures_2_2_0', wheel.repository_name())
5658

57-
def test_mock_whl(self):
59+
@patch('platform.python_version', return_value='2.7.13')
60+
def test_mock_whl(self, *args):
5861
td = TestData('mock_whl/file/mock-2.0.0-py2.py3-none-any.whl')
5962
wheel = whl.Wheel(td)
6063
self.assertEqual(wheel.name(), 'mock')
6164
self.assertEqual(wheel.distribution(), 'mock')
6265
self.assertEqual(wheel.version(), '2.0.0')
6366
self.assertEqual(set(wheel.dependencies()),
64-
set(['pbr', 'six']))
67+
set(['funcsigs', 'pbr', 'six']))
6568
self.assertEqual('pypi__mock_2_0_0', wheel.repository_name())
69+
70+
@patch('platform.python_version', return_value='3.3.0')
71+
def test_mock_whl_3_3(self, *args):
72+
td = TestData('mock_whl/file/mock-2.0.0-py2.py3-none-any.whl')
73+
wheel = whl.Wheel(td)
74+
self.assertEqual(set(wheel.dependencies()),
75+
set(['pbr', 'six']))
76+
77+
@patch('platform.python_version', return_value='2.7.13')
78+
def test_mock_whl_extras(self, *args):
79+
td = TestData('mock_whl/file/mock-2.0.0-py2.py3-none-any.whl')
80+
wheel = whl.Wheel(td)
6681
self.assertEqual(['docs', 'test'], wheel.extras())
67-
self.assertEqual(set(wheel.dependencies(extra='docs')), set())
82+
self.assertEqual(set(wheel.dependencies(extra='docs')), set(['sphinx']))
6883
self.assertEqual(set(wheel.dependencies(extra='test')), set(['unittest2']))
6984

70-
def test_google_cloud_language_whl(self):
85+
@patch('platform.python_version', return_value='3.0.0')
86+
def test_mock_whl_extras_3_0(self, *args):
87+
td = TestData('mock_whl/file/mock-2.0.0-py2.py3-none-any.whl')
88+
wheel = whl.Wheel(td)
89+
self.assertEqual(['docs', 'test'], wheel.extras())
90+
self.assertEqual(set(wheel.dependencies(extra='docs')), set(['sphinx', 'Pygments', 'jinja2']))
91+
self.assertEqual(set(wheel.dependencies(extra='test')), set(['unittest2']))
92+
93+
@patch('platform.python_version', return_value='2.7.13')
94+
def test_google_cloud_language_whl(self, *args):
7195
td = TestData('google_cloud_language_whl/file/' +
7296
'google_cloud_language-0.29.0-py2.py3-none-any.whl')
7397
wheel = whl.Wheel(td)
7498
self.assertEqual(wheel.name(), 'google-cloud-language')
7599
self.assertEqual(wheel.distribution(), 'google_cloud_language')
76100
self.assertEqual(wheel.version(), '0.29.0')
101+
expected_deps = ['google-gax', 'google-cloud-core',
102+
'googleapis-common-protos[grpc]', 'enum34']
77103
self.assertEqual(set(wheel.dependencies()),
78-
set(['google-gax', 'google-cloud-core',
79-
'googleapis-common-protos[grpc]']))
104+
set(expected_deps))
80105
self.assertEqual('pypi__google_cloud_language_0_29_0',
81106
wheel.repository_name())
82107
self.assertEqual([], wheel.extras())
83108

109+
@patch('platform.python_version', return_value='3.4.0')
110+
def test_google_cloud_language_whl_3_4(self, *args):
111+
td = TestData('google_cloud_language_whl/file/' +
112+
'google_cloud_language-0.29.0-py2.py3-none-any.whl')
113+
wheel = whl.Wheel(td)
114+
expected_deps = ['google-gax', 'google-cloud-core',
115+
'googleapis-common-protos[grpc]']
116+
self.assertEqual(set(wheel.dependencies()),
117+
set(expected_deps))
118+
84119
if __name__ == '__main__':
85120
unittest.main()

‎tools/BUILD

Copy file name to clipboardExpand all lines: tools/BUILD
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,4 @@ package(default_visibility = ["//visibility:public"])
1616
licenses(["notice"]) # Apache 2.0
1717

1818
# This is generated and updated by ./update_tools.sh
19-
exports_files(["piptool.par"])
19+
exports_files(["piptool.par", "whltool.par"])

‎tools/piptool.par

Copy file name to clipboard
482 KB
Binary file not shown.

‎tools/whltool.par

Copy file name to clipboard
492 KB
Binary file not shown.

‎update_tools.sh

Copy file name to clipboardExpand all lines: update_tools.sh
+2-1Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,6 @@
1616

1717
set -euo pipefail
1818

19-
bazel build //rules_python:piptool.par
19+
bazel build //rules_python:piptool.par //rules_python:whltool.par
2020
cp bazel-bin/rules_python/piptool.par tools/piptool.par
21+
cp bazel-bin/rules_python/whltool.par tools/whltool.par

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.