Skip to content
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: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ END_UNRELEASED_TEMPLATE
### Changed
* (gazelle) For package mode, resolve dependencies when imports are relative
to the package path. This is enabled via the
`# gazelle:experimental_allow_relative_imports` true directive ({gh-issue}`2203`).
`# gazelle:python_experimental_allow_relative_imports` true directive ({gh-issue}`2203`).
* (gazelle) Types for exposed members of `python.ParserOutput` are now all public.
* (gazelle) Removed the requirement for `__init__.py`, `__main__.py`, or `__test__.py` files to be
present in a directory to generate a `BUILD.bazel` file.
Expand Down Expand Up @@ -99,6 +99,8 @@ END_UNRELEASED_TEMPLATE
absolute imports (Python 2's behavior without `absolute_import`). Previous
behavior can be restored using the directive
`# gazelle:python_resolve_sibling_imports true`
* (pypi) Show overridden index URL of packages when downloading metadata have failed.
([#2985](https://github.com/bazel-contrib/rules_python/issues/2985)).

{#v0-0-0-added}
### Added
Expand Down
36 changes: 0 additions & 36 deletions docs/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.

load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
load("@bazel_skylib//rules:build_test.bzl", "build_test")
load("@dev_pip//:requirements.bzl", "requirement")
load("//python/private:bzlmod_enabled.bzl", "BZLMOD_ENABLED") # buildifier: disable=bzl-visibility
Expand Down Expand Up @@ -189,38 +188,3 @@ lock(
],
visibility = ["//:__subpackages__"],
)

# Temporary compatibility aliases for some other projects depending on the old
# bzl_library targets.
alias(
name = "defs",
actual = "//python:defs_bzl",
deprecation = "Use //python:defs_bzl instead; targets under //docs are internal.",
visibility = ["//visibility:public"],
)

alias(
name = "bazel_repo_tools",
actual = "//python/private:bazel_tools_bzl",
deprecation = "Use @bazel_tools//tools:bzl_srcs instead; targets under //docs are internal.",
visibility = ["//visibility:public"],
)

bzl_library(
name = "pip_install_bzl",
deprecation = "Use //python:pip_bzl or //python/pip_install:pip_repository_bzl instead; " +
"targets under //docs are internal.",
visibility = ["//visibility:public"],
deps = [
"//python:pip_bzl",
"//python/pip_install:pip_repository_bzl",
],
)

alias(
name = "requirements_parser_bzl",
actual = "//python/pip_install:pip_repository_bzl",
deprecation = "Use //python/pip_install:pip_repository_bzl instead; Both the requirements " +
"parser and targets under //docs are internal",
visibility = ["//visibility:public"],
)
4 changes: 2 additions & 2 deletions gazelle/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ Python-specific directives are as follows:
| Defines the format of the distribution name in labels to third-party deps. Useful for using Gazelle plugin with other rules with different repository conventions (e.g. `rules_pycross`). Full label is always prepended with (pip) repository name, e.g. `@pip//numpy`. |
| `# gazelle:python_label_normalization` | `snake_case` |
| Controls how distribution names in labels to third-party deps are normalized. Useful for using Gazelle plugin with other rules with different label conventions (e.g. `rules_pycross` uses PEP-503). Can be "snake_case", "none", or "pep503". |
| `# gazelle:experimental_allow_relative_imports` | `false` |
| `# gazelle:python_experimental_allow_relative_imports` | `false` |
| Controls whether Gazelle resolves dependencies for import statements that use paths relative to the current package. Can be "true" or "false".|
| `# gazelle:python_generate_pyi_deps` | `false` |
| Controls whether to generate a separate `pyi_deps` attribute for type-checking dependencies or merge them into the regular `deps` attribute. When `false` (default), type-checking dependencies are merged into `deps` for backward compatibility. When `true`, generates separate `pyi_deps`. Imports in blocks with the format `if typing.TYPE_CHECKING:`/`if TYPE_CHECKING:` and type-only stub packages (eg. boto3-stubs) are recognized as type-checking dependencies. |
Expand Down Expand Up @@ -736,7 +736,7 @@ See [Issue #3076][gh3076] for more information.
[gh3076]: https://github.com/bazel-contrib/rules_python/issues/3076


#### Directive: `experimental_allow_relative_imports`
#### Directive: `python_experimental_allow_relative_imports`
Enables experimental support for resolving relative imports in
`python_generation_mode package`.

Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# gazelle:python_generation_mode package
# gazelle:experimental_allow_relative_imports true
# gazelle:python_experimental_allow_relative_imports true
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
load("@rules_python//python:defs.bzl", "py_binary")

# gazelle:python_generation_mode package
# gazelle:experimental_allow_relative_imports true
# gazelle:python_experimental_allow_relative_imports true

py_binary(
name = "relative_imports_package_mode_bin",
Expand Down
2 changes: 1 addition & 1 deletion gazelle/python/testdata/sibling_imports_disabled/BUILD.in
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# gazelle:python_resolve_sibling_imports false
# gazelle:experimental_allow_relative_imports true
# gazelle:python_experimental_allow_relative_imports true
2 changes: 1 addition & 1 deletion gazelle/python/testdata/sibling_imports_disabled/BUILD.out
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
load("@rules_python//python:defs.bzl", "py_library", "py_test")

# gazelle:python_resolve_sibling_imports false
# gazelle:experimental_allow_relative_imports true
# gazelle:python_experimental_allow_relative_imports true

py_library(
name = "sibling_imports_disabled",
Expand Down
2 changes: 1 addition & 1 deletion gazelle/python/testdata/sibling_imports_disabled/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ disabled. It covers different types of imports in `pkg/unit_test.py`:
(not the sibling `typing.py`).
- `from .b import run` / `from .typing import A` - resolves to the sibling
`pkg/b.py` / `pkg/typing.py` (with
`gazelle:experimental_allow_relative_imports` enabled)
`gazelle:python_experimental_allow_relative_imports` enabled)
- `import test_util` - resolves to the root-level `test_util.py` instead of
the sibling `pkg/test_util.py`
- `from b import run` - resolves to the root-level `b.py` instead of the
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# gazelle:python_generation_mode file
# gazelle:python_resolve_sibling_imports false
# gazelle:experimental_allow_relative_imports true
# gazelle:python_experimental_allow_relative_imports true
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ load("@rules_python//python:defs.bzl", "py_library", "py_test")

# gazelle:python_generation_mode file
# gazelle:python_resolve_sibling_imports false
# gazelle:experimental_allow_relative_imports true
# gazelle:python_experimental_allow_relative_imports true

py_library(
name = "a",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ disabled. It covers different types of imports in `pkg/unit_test.py`:
(not the sibling `typing.py`).
- `from .b import run` / `from .typing import A` - resolves to the sibling
`pkg/b.py` / `pkg/typing.py` (with
`gazelle:experimental_allow_relative_imports` enabled)
`gazelle:python_experimental_allow_relative_imports` enabled)
- `import test_util` - resolves to the root-level `test_util.py` instead of
the sibling `pkg/test_util.py`
- `from b import run` - resolves to the root-level `b.py` instead of the
Expand Down
2 changes: 1 addition & 1 deletion gazelle/pythonconfig/pythonconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ const (
LabelNormalization = "python_label_normalization"
// ExperimentalAllowRelativeImports represents the directive that controls
// whether relative imports are allowed.
ExperimentalAllowRelativeImports = "experimental_allow_relative_imports"
ExperimentalAllowRelativeImports = "python_experimental_allow_relative_imports"
// GeneratePyiDeps represents the directive that controls whether to generate
// separate pyi_deps attribute or merge type-checking dependencies into deps.
// Defaults to false for backward compatibility.
Expand Down
26 changes: 17 additions & 9 deletions python/private/pypi/simpleapi_download.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -128,16 +128,24 @@ def simpleapi_download(

failed_sources = [pkg for pkg in attr.sources if pkg not in found_on_index]
if failed_sources:
pkg_index_urls = {
pkg: index_url_overrides.get(
normalize_name(pkg),
index_urls,
)
for pkg in failed_sources
}

_fail(
"\n".join([
"Failed to download metadata for {} for from urls: {}.".format(
failed_sources,
index_urls,
),
"If you would like to skip downloading metadata for these packages please add 'simpleapi_skip={}' to your 'pip.parse' call.".format(
render.list(failed_sources),
),
]),
"""
Failed to download metadata of the following packages from urls:
{pkg_index_urls}

If you would like to skip downloading metadata for these packages please add 'simpleapi_skip={failed_sources}' to your 'pip.parse' call.
""".format(
pkg_index_urls = render.dict(pkg_index_urls),
failed_sources = render.list(failed_sources),
),
)
return None

Expand Down
2 changes: 1 addition & 1 deletion sphinxdocs/private/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
# limitations under the License.

load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
load("//python:proto.bzl", "py_proto_library")
load("@com_google_protobuf//bazel:py_proto_library.bzl", "py_proto_library")
load("//python:py_binary.bzl", "py_binary")
load("//python:py_library.bzl", "py_library")

Expand Down
28 changes: 22 additions & 6 deletions tests/pypi/simpleapi_download/simpleapi_download_tests.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,11 @@ def _test_fail(env):
output = "",
success = False,
)
if "bar" in url:
return struct(
output = "",
success = False,
)
else:
return struct(
output = "data from {}".format(url),
Expand All @@ -99,7 +104,9 @@ def _test_fail(env):
report_progress = lambda _: None,
),
attr = struct(
index_url_overrides = {},
index_url_overrides = {
"foo": "invalid",
},
index_url = "main",
extra_index_urls = ["extra"],
sources = ["foo", "bar", "baz"],
Expand All @@ -112,16 +119,25 @@ def _test_fail(env):
)

env.expect.that_collection(fails).contains_exactly([
"""\
Failed to download metadata for ["foo"] for from urls: ["main", "extra"].
If you would like to skip downloading metadata for these packages please add 'simpleapi_skip=["foo"]' to your 'pip.parse' call.\
"""
Failed to download metadata of the following packages from urls:
{
"foo": "invalid",
"bar": ["main", "extra"],
}

If you would like to skip downloading metadata for these packages please add 'simpleapi_skip=[
"foo",
"bar",
]' to your 'pip.parse' call.
""",
])
env.expect.that_collection(calls).contains_exactly([
"extra/foo/",
"invalid/foo/",
"main/bar/",
"main/baz/",
"main/foo/",
"invalid/foo/",
"extra/bar/",
])

_tests.append(_test_fail)
Expand Down
17 changes: 10 additions & 7 deletions tests/repl/repl_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,16 @@ def setUp(self):

def run_code_in_repl(self, lines: Iterable[str], *, env=None) -> str:
"""Runs the lines of code in the REPL and returns the text output."""
return subprocess.check_output(
[self.repl],
text=True,
stderr=subprocess.STDOUT,
input="\n".join(lines),
env=env,
).strip()
try:
return subprocess.check_output(
[self.repl],
text=True,
stderr=subprocess.STDOUT,
input="\n".join(lines),
env=env,
).strip()
except subprocess.CalledProcessError as error:
raise RuntimeError(f"Failed to run the REPL:\n{error.stdout}") from error

def test_repl_version(self):
"""Validates that we can successfully execute arbitrary code on the REPL."""
Expand Down