From 2b6c185cbb32dc49b78a50b25c594726aaf699b9 Mon Sep 17 00:00:00 2001 From: Matt Moore Date: Fri, 22 Sep 2017 23:40:27 +0000 Subject: [PATCH] This adds support for "extras". "Extras" are additional dependencies of a given library, which are consumed by passing the "extra" name in brackets after the distribution name, for example: ``` mock[docs]==1.0.1 ``` We see this in the dependencies of several Google Cloud libraries, which depend on: `googleapis_common_protos[grpc]` I've added a simple test that the dependency structure we synthesize for this kind of thing is correct via an "extras" test that has a `requirements.txt` of: ``` google-cloud-language==0.27.0 ``` Fixes: https://github.com/bazelbuild/rules_python/issues/12 --- README.md | 4 ++ WORKSPACE | 23 ++++++- examples/extras/BUILD | 29 ++++++++ examples/extras/extras_test.py | 25 +++++++ examples/extras/requirements.txt | 1 + examples/extras/version_test.py | 26 +++++++ python/whl.bzl | 13 +++- rules_python/BUILD | 1 + rules_python/piptool.py | 114 +++++++++++++++++++++---------- rules_python/whl.py | 62 ++++++++++++----- rules_python/whl_test.py | 19 ++++++ tools/piptool.par | Bin 1349150 -> 1350077 bytes 12 files changed, 260 insertions(+), 57 deletions(-) create mode 100644 examples/extras/BUILD create mode 100644 examples/extras/extras_test.py create mode 100644 examples/extras/requirements.txt create mode 100644 examples/extras/version_test.py diff --git a/README.md b/README.md index a6a87109cb..aea05d57ab 100644 --- a/README.md +++ b/README.md @@ -106,6 +106,10 @@ for dependencies, however, it is recommended that folks stick with the `requirement` pattern in case the need arises for us to make changes to this format in the future. +["Extras"]( +https://packaging.python.org/tutorials/installing-packages/#installing-setuptools-extras) +will have a target of the extra name (in place of `pkg` above). + ## Updating `docs/` All of the content (except `BUILD`) under `docs/` is generated. To update the diff --git a/WORKSPACE b/WORKSPACE index 0f205befec..430dfe7f07 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -26,8 +26,8 @@ sass_repositories() git_repository( name = "io_bazel_skydoc", - remote = "https://github.com/bazelbuild/skydoc.git", commit = "e9be81cf5be41e4200749f5d8aa2db7955f8aacc", + remote = "https://github.com/bazelbuild/skydoc.git", ) load("@io_bazel_skydoc//skylark:skylark.bzl", "skydoc_repositories") @@ -92,6 +92,15 @@ http_file( "mock-2.0.0-py2.py3-none-any.whl"), ) +http_file( + name = "google_cloud_language_whl", + sha256 = "a2dd34f0a0ebf5705dcbe34bd41199b1d0a55c4597d38ed045bd183361a561e9", + # From https://pypi.python.org/pypi/google-cloud-language + url = ("https://pypi.python.org/packages/6e/86/" + + "cae57e4802e72d9e626ee5828ed5a646cf4016b473a4a022f1038dba3460/" + + "google_cloud_language-0.29.0-py2.py3-none-any.whl"), +) + # Imports for examples pip_import( name = "examples_helloworld", @@ -128,3 +137,15 @@ load( ) _boto_install() + +pip_import( + name = "examples_extras", + requirements = "//examples/extras:requirements.txt", +) + +load( + "@examples_extras//:requirements.bzl", + _extras_install = "pip_install", +) + +_extras_install() diff --git a/examples/extras/BUILD b/examples/extras/BUILD new file mode 100644 index 0000000000..94880ce47c --- /dev/null +++ b/examples/extras/BUILD @@ -0,0 +1,29 @@ +# Copyright 2017 The Bazel Authors. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +package(default_visibility = ["//visibility:public"]) + +licenses(["notice"]) # Apache 2.0 + +load("@examples_extras//:requirements.bzl", "requirement") +load("//python:python.bzl", "py_test") + +py_test( + name = "extras_test", + srcs = ["extras_test.py"], + deps = [ + requirement("google-cloud-language"), + # Make sure that we can resolve the "extra" dependency + requirement("googleapis-common-protos[grpc]"), + ], +) diff --git a/examples/extras/extras_test.py b/examples/extras/extras_test.py new file mode 100644 index 0000000000..3ad249d5a0 --- /dev/null +++ b/examples/extras/extras_test.py @@ -0,0 +1,25 @@ +# Copyright 2017 The Bazel Authors. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import unittest + + +# The test is the build itself, which should not work if extras are missing. +class ExtrasTest(unittest.TestCase): + def test_nothing(self): + pass + + +if __name__ == '__main__': + unittest.main() diff --git a/examples/extras/requirements.txt b/examples/extras/requirements.txt new file mode 100644 index 0000000000..743bbe7921 --- /dev/null +++ b/examples/extras/requirements.txt @@ -0,0 +1 @@ +google-cloud-language==0.27.0 diff --git a/examples/extras/version_test.py b/examples/extras/version_test.py new file mode 100644 index 0000000000..9b469b76d3 --- /dev/null +++ b/examples/extras/version_test.py @@ -0,0 +1,26 @@ +# Copyright 2017 The Bazel Authors. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import pip +import unittest + + +class VersionTest(unittest.TestCase): + + def test_version(self): + self.assertEqual(pip.__version__, '9.0.1') + + +if __name__ == '__main__': + unittest.main() diff --git a/python/whl.bzl b/python/whl.bzl index f7827ed51f..7a19947c5f 100644 --- a/python/whl.bzl +++ b/python/whl.bzl @@ -16,12 +16,17 @@ def _whl_impl(repository_ctx): """Core implementation of whl_library.""" - result = repository_ctx.execute([ + args = [ "python", repository_ctx.path(repository_ctx.attr._script), "--whl", repository_ctx.path(repository_ctx.attr.whl), "--requirements", repository_ctx.attr.requirements, - ]) + ] + + if repository_ctx.attr.extras: + args += ["--extras", ",".join(repository_ctx.attr.extras)] + + result = repository_ctx.execute(args) if result.return_code: fail("whl_library failed: %s (%s)" % (result.stdout, result.stderr)) @@ -33,6 +38,7 @@ whl_library = repository_rule( single_file = True, ), "requirements": attr.string(), + "extras": attr.string_list(), "_script": attr.label( executable = True, default = Label("//rules_python:whl.py"), @@ -64,4 +70,7 @@ Args: requirements: The name of the pip_import repository rule from which to load this .whl's dependencies. + + extras: A subset of the "extras" available from this .whl for which + requirements has the dependencies. """ diff --git a/rules_python/BUILD b/rules_python/BUILD index 08aca7e530..e0bf79667e 100644 --- a/rules_python/BUILD +++ b/rules_python/BUILD @@ -28,6 +28,7 @@ py_test( data = [ "@futures_3_1_1_whl//file", "@futures_2_2_0_whl//file", + "@google_cloud_language_whl//file", "@grpc_whl//file", "@mock_whl//file", ], diff --git a/rules_python/piptool.py b/rules_python/piptool.py index 98dfce9c48..f5d504aa87 100644 --- a/rules_python/piptool.py +++ b/rules_python/piptool.py @@ -18,6 +18,7 @@ import json import os import pkgutil +import pkg_resources import re import shutil import sys @@ -78,36 +79,7 @@ def pip_main(argv): argv = ["--disable-pip-version-check", "--cert", cert_path] + argv return pip.main(argv) - -# TODO(mattmoor): We can't easily depend on other libraries when -# being invoked as a raw .py file. Once bundled, we should be able -# to remove this fallback on a stub implementation of Wheel. -try: - from rules_python.whl import Wheel -except: - class Wheel(object): - - def __init__(self, path): - self._path = path - - def basename(self): - return os.path.basename(self._path) - - def distribution(self): - # See https://www.python.org/dev/peps/pep-0427/#file-name-convention - parts = self.basename().split('-') - return parts[0] - - def version(self): - # See https://www.python.org/dev/peps/pep-0427/#file-name-convention - parts = self.basename().split('-') - return parts[1] - - def repository_name(self): - # Returns the canonical name of the Bazel repository for this package. - canonical = 'pypi__{}_{}'.format(self.distribution(), self.version()) - # Escape any illegal characters with underscore. - return re.sub('[-.]', '_', canonical) +from rules_python.whl import Wheel parser = argparse.ArgumentParser( description='Import Python dependencies into Bazel.') @@ -124,6 +96,59 @@ def repository_name(self): parser.add_argument('--directory', action='store', help=('The directory into which to put .whl files.')) +def determine_possible_extras(whls): + """Determines the list of possible "extras" for each .whl + + The possibility of an extra is determined by looking at its + additional requirements, and determinine whether they are + satisfied by the complete list of available wheels. + + Args: + whls: a list of Wheel objects + + Returns: + a dict that is keyed by the Wheel objects in whls, and whose + values are lists of possible extras. + """ + whl_map = { + whl.distribution(): whl + for whl in whls + } + + # TODO(mattmoor): Consider memoizing if this recursion ever becomes + # expensive enough to warrant it. + def is_possible(distro, extra): + distro = distro.replace("-", "_") + # If we don't have the .whl at all, then this isn't possible. + if distro not in whl_map: + return False + whl = whl_map[distro] + # If we have the .whl, and we don't need anything extra then + # we can satisfy this dependency. + if not extra: + return True + # If we do need something extra, then check the extra's + # dependencies to make sure they are fully satisfied. + for extra_dep in whl.dependencies(extra=extra): + req = pkg_resources.Requirement.parse(extra_dep) + # Check that the dep and any extras are all possible. + if not is_possible(req.project_name, None): + return False + for e in req.extras: + if not is_possible(req.project_name, e): + return False + # If all of the dependencies of the extra are satisfiable then + # it is possible to construct this dependency. + return True + + return { + whl: [ + extra + for extra in whl.extras() + if is_possible(whl.distribution(), extra) + ] + for whl in whls + } def main(): args = parser.parse_args() @@ -140,6 +165,9 @@ def list_whls(): if fname.endswith('.whl'): yield os.path.join(root, fname) + whls = [Wheel(path) for path in list_whls()] + possible_extras = determine_possible_extras(whls) + def whl_library(wheel): # Indentation here matters. whl_library must be within the scope # of the function below. We also avoid reimporting an existing WHL. @@ -149,10 +177,25 @@ def whl_library(wheel): name = "{repo_name}", whl = "@{name}//:{path}", requirements = "@{name}//:requirements.bzl", + extras = [{extras}] )""".format(name=args.name, repo_name=wheel.repository_name(), - path=wheel.basename()) - - whls = [Wheel(path) for path in list_whls()] + path=wheel.basename(), + extras=','.join([ + '"%s"' % extra + for extra in possible_extras.get(wheel, []) + ])) + + whl_targets = ','.join([ + ','.join([ + '"%s": "@%s//:pkg"' % (whl.distribution().lower(), whl.repository_name()) + ] + [ + # For every extra that is possible from this requirements.txt + '"%s[%s]": "@%s//:%s"' % (whl.distribution().lower(), extra.lower(), + whl.repository_name(), extra) + for extra in possible_extras.get(whl, []) + ]) + for whl in whls + ]) with open(args.output, 'w') as f: f.write("""\ @@ -178,10 +221,7 @@ def requirement(name): return _requirements[name_key] """.format(input=args.input, whl_libraries='\n'.join(map(whl_library, whls)) if whls else "pass", - mappings=','.join([ - '"%s": "@%s//:pkg"' % (wheel.distribution().lower(), wheel.repository_name()) - for wheel in whls - ]))) + mappings=whl_targets)) if __name__ == '__main__': main() diff --git a/rules_python/whl.py b/rules_python/whl.py index 14d775a778..e3829bd9d6 100644 --- a/rules_python/whl.py +++ b/rules_python/whl.py @@ -70,13 +70,21 @@ def metadata(self): def name(self): return self.metadata().get('name') - def dependencies(self): + def dependencies(self, extra=None): + """Access the dependencies of this Wheel. + + Args: + extra: if specified, include the additional dependencies + of the named "extra". + + Yields: + the names of requirements from the metadata.json + """ # TODO(mattmoor): Is there a schema to follow for this? run_requires = self.metadata().get('run_requires', []) for requirement in run_requires: - if 'extra' in requirement: - # TODO(mattmoor): What's the best way to support "extras"? - # https://packaging.python.org/tutorials/installing-packages/#installing-setuptools-extras + if requirement.get('extra') != extra: + # Match the requirements for the extra we're looking for. continue if 'environment' in requirement: # TODO(mattmoor): What's the best way to support "environment"? @@ -89,6 +97,9 @@ def dependencies(self): parts = re.split('[ ><=()]', entry) yield parts[0] + def extras(self): + return self.metadata().get('extras', []) + def expand(self, directory): with zipfile.ZipFile(self.path(), 'r') as whl: whl.extractall(directory) @@ -112,6 +123,9 @@ def _parse_metadata(self, content): parser.add_argument('--directory', action='store', default='.', help='The directory into which to expand things.') +parser.add_argument('--extras', action='append', + help='The set of extras for which to generate library targets.') + def main(): args = parser.parse_args() whl = Wheel(args.whl) @@ -126,19 +140,33 @@ def main(): load("{requirements}", "requirement") py_library( - name = "pkg", - srcs = glob(["**/*.py"]), - data = glob(["**/*"], exclude=["**/*.py", "**/* *", "BUILD", "WORKSPACE"]), - # This makes this directory a top-level in the python import - # search path for anything that depends on this. - imports = ["."], - deps = [{dependencies}], - )""".format( - requirements=args.requirements, - dependencies=','.join([ - 'requirement("%s")' % d - for d in whl.dependencies() - ]))) + name = "pkg", + srcs = glob(["**/*.py"]), + data = glob(["**/*"], exclude=["**/*.py", "**/* *", "BUILD", "WORKSPACE"]), + # This makes this directory a top-level in the python import + # search path for anything that depends on this. + imports = ["."], + deps = [{dependencies}], +) +{extras}""".format( + requirements=args.requirements, + dependencies=','.join([ + 'requirement("%s")' % d + for d in whl.dependencies() + ]), + extras='\n\n'.join([ + """py_library( + name = "{extra}", + deps = [ + ":pkg",{deps} + ], +)""".format(extra=extra, + deps=','.join([ + 'requirement("%s")' % dep + for dep in whl.dependencies(extra) + ])) + for extra in args.extras or [] + ]))) if __name__ == '__main__': main() diff --git a/rules_python/whl_test.py b/rules_python/whl_test.py index e148328275..c56a4e997d 100644 --- a/rules_python/whl_test.py +++ b/rules_python/whl_test.py @@ -33,6 +33,7 @@ def test_grpc_whl(self): self.assertEqual(set(wheel.dependencies()), set(['enum34', 'futures', 'protobuf', 'six'])) self.assertEqual('pypi__grpcio_1_6_0', wheel.repository_name()) + self.assertEqual([], wheel.extras()) def test_futures_whl(self): td = TestData('futures_3_1_1_whl/file/futures-3.1.1-py2-none-any.whl') @@ -42,6 +43,7 @@ def test_futures_whl(self): self.assertEqual(wheel.version(), '3.1.1') self.assertEqual(set(wheel.dependencies()), set()) self.assertEqual('pypi__futures_3_1_1', wheel.repository_name()) + self.assertEqual([], wheel.extras()) def test_whl_with_METADATA_file(self): td = TestData('futures_2_2_0_whl/file/futures-2.2.0-py2.py3-none-any.whl') @@ -61,6 +63,23 @@ def test_mock_whl(self): self.assertEqual(set(wheel.dependencies()), set(['pbr', 'six'])) self.assertEqual('pypi__mock_2_0_0', wheel.repository_name()) + self.assertEqual(['docs', 'test'], wheel.extras()) + self.assertEqual(set(wheel.dependencies(extra='docs')), set()) + self.assertEqual(set(wheel.dependencies(extra='test')), set(['unittest2'])) + + def test_google_cloud_language_whl(self): + td = TestData('google_cloud_language_whl/file/' + + 'google_cloud_language-0.29.0-py2.py3-none-any.whl') + wheel = whl.Wheel(td) + self.assertEqual(wheel.name(), 'google-cloud-language') + self.assertEqual(wheel.distribution(), 'google_cloud_language') + self.assertEqual(wheel.version(), '0.29.0') + self.assertEqual(set(wheel.dependencies()), + set(['google-gax', 'google-cloud-core', + 'googleapis-common-protos[grpc]'])) + self.assertEqual('pypi__google_cloud_language_0_29_0', + wheel.repository_name()) + self.assertEqual([], wheel.extras()) if __name__ == '__main__': unittest.main() diff --git a/tools/piptool.par b/tools/piptool.par index 29b12897705a30a87ca4d1581b8cc4b75f8b26d5..41019234d328d7386de51298be6152601e1dd311 100755 GIT binary patch delta 20804 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 EKftbjSpWb4