8000 Add py_import rule · Pull Request #174 · bazel-contrib/rules_python · GitHub
[go: up one dir, main page]

Skip to content

Add py_import rule #174

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from Apr 22, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .bazelrc
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# This lets us glob() up all the files inside the examples to make them inputs to tests
# (Note, we cannot use `common --deleted_packages` because the bazel version command doesn't support it)
# To update these lines, run tools/bazel_integration_test/update_deleted_packages.sh
build --deleted_packages=examples/legacy_pip_import/boto,examples/legacy_pip_import/extras,examples/legacy_pip_import/helloworld,examples/pip_install,examples/pip_parse
query --deleted_packages=examples/legacy_pip_import/boto,examples/legacy_pip_import/extras,examples/legacy_pip_import/helloworld,examples/pip_install,examples/pip_parse
build --deleted_packages=examples/legacy_pip_import/boto,examples/legacy_pip_import/extras,examples/legacy_pip_import/helloworld,examples/pip_install,examples/pip_parse,examples/py_import
query --deleted_packages=examples/legacy_pip_import/boto,examples/legacy_pip_import/extras,examples/legacy_pip_import/helloworld,examples/pip_install,examples/pip_parse,examples/py_import

test --test_output=errors
5 changes: 5 additions & 0 deletions examples/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,8 @@ bazel_integration_test(
name = "pip_parse_example",
timeout = "long",
)

bazel_integration_test(
name = "py_import_example",
timeout = "long",
)
40 changes: 40 additions & 0 deletions examples/py_import/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Copyright 2020 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.

load("@pip//:requirements.bzl", "requirement")
load("@rules_python//python:defs.bzl", "py_import", "py_test")

package(default_visibility = ["//visibility:public"])

licenses(["notice"]) # Apache 2.0

# Adapt helloworld.egg so it can be depended on as if it were a
# py_library target
py_import(
name = "py_import",
# Note: this .egg file can be regenerated using zipper:
# $ third_party/ijar/zipper Cc \
# examples/py_import/helloworld.egg \
# examples/py_import/helloworld.py=examples/legacy_pip_import/helloworld/helloworld.py \
# examples/__init__.py= \
# examples/py_import/__init__.py=
srcs = ["helloworld.egg"],
deps = [requirement("futures")],
)

py_test(
name = "py_import_test",
srcs = ["py_import_test.py"],
deps = [":py_import"],
)
15 changes: 15 additions & 0 deletions examples/py_import/WORKSPACE
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
workspace(name = "py_import")

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

# Note, this relies on a pre-release of 0.3.0, and doesn't actually work with 0.2.0
# Use --override_repository=rules_python=$HOME/Projects/rules_python to test for now
http_archive(
name = "rules_python",
sha256 = "778197e26c5fbeb07ac2a2c5ae405b30f6cb7ad1f5510ea6fdac03bded96cc6f",
url = "https://github.com/bazelbuild/rules_python/releases/download/0.2.0/rules_python-0.2.0.tar.gz",
)

load("@rules_python//python:pip.bzl", "pip_install")

pip_install(requirements = "//:requirements.txt")
Binary file added examples/py_import/helloworld.egg
Binary file not shown.
41 changes: 41 additions & 0 deletions examples/py_import/py_import_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Copyright 2017-2019 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

from examples.py_import import helloworld


class HelloWorldTest(unittest.TestCase):

def test_helloworld(self):
hw = helloworld.HelloWorld()
hw.SayHello()

def test_helloworld_async(self):
hw = helloworld.HelloWorld()
hw.SayHelloAsync()
hw.Stop()

def test_helloworld_multiple(self):
hw = helloworld.HelloWorld()
hw.SayHelloAsync()
hw.SayHelloAsync()
hw.SayHelloAsync()
hw.SayHelloAsync()
hw.Stop()


if __name__ == '__main__':
unittest.main()
1 change: 1 addition & 0 deletions examples/py_import/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
futures>=3.1
Binary file added examples/py_import/some_library.egg
Binary file not shown.
50 changes: 50 additions & 0 deletions python/defs.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,56 @@ def py_test(**attrs):
# buildifier: disable=native-python
native.py_test(**_add_tags(attrs))

def _py_import_impl(ctx):
# See https://github.com/bazelbuild/bazel/blob/0.24.0/src/main/java/com/google/devtools/build/lib/bazel/rules/python/BazelPythonSemantics.java#L104 .
import_paths = [
"/".join([ctx.workspace_name, x.short_path])
for x in ctx.files.srcs
]

return [
DefaultInfo(
default_runfiles = ctx.runfiles(ctx.files.srcs, collect_default = True),
),
PyInfo(
transitive_sources = depset(transitive = [
dep[PyInfo].transitive_sources
for dep in ctx.attr.deps
]),
imports = depset(direct = import_paths, transitive = [
dep[PyInfo].imports
for dep in ctx.attr.deps
]),
),
]

py_import = rule(
doc = """This rule allows the use of Python packages as dependencies.

It imports the given `.egg` file(s), which might be checked in source files,
fetched externally as with `http_file`, or produced as outputs of other rules.

It may be used like a `py_library`, in the `deps` of other Python rules.

This is similar to [java_import](https://docs.bazel.build/versions/master/be/java.html#java_import).
""",
implementation = _py_import_impl,
attrs = {
"deps": attr.label_list(
doc = "The list of other libraries to be linked in to the " +
"binary target.",
providers = [PyInfo],
),
"srcs": attr.label_list(
doc = "The list of Python package files provided to Python targets " +
"that depend on this target. Note that currently only the .egg " +
"format is accepted. For .whl files, try the whl_library rule. " +
"We accept contributions to extend py_import to handle .whl.",
allow_files = [".egg"],
),
},
)

def py_runtime(**attrs):
"""See the Bazel core [py_runtime](https://docs.bazel.build/versions/master/be/python.html#py_runtime) documentation.

Expand Down
4 changes: 2 additions & 2 deletions tools/bazel_integration_test/bazel_integration_test.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ _ATTRS = {
It is assumed by the test runner that the bazel binary is found at label_workspace/bazel (wksp/bazel.exe on Windows)""",
),
"bazel_commands": attr.string_list(
default = ["info", "test ..."],
doc = """The list of bazel commands to run. Defaults to `["info", "test ..."]`.
default = ["info", "test --test_output=errors ..."],
doc = """The list of bazel commands to run.

Note that if a command contains a bare `--` argument, the --test_arg passed to Bazel will appear before it.
""",
Expand Down
0