Skip to content

Starlark rules should be able to identify when attributes are not provided #14434

@nacl

Description

@nacl

Description of the feature request:

When creating bazel rules, I sometimes want to be able to identify when a rule attribute is provided. Usually, the default is good enough, but there are some cases where there isn't a consistent way to provide defaults that cannot otherwise be interpreted as something meaningful. In particular, attr.bool, attr.int, and attr.string come to mind -- they only allow for their exact types (bool, int and str respectively). As an example, if I create a rule with an int attribute that defaults to None, I see something like:

ERROR: Traceback (most recent call last):
	File "/Users/.../defs.bzl", line 9, column 27, in <toplevel>
		"int": attr.int(
Error in int: in call to int(), parameter 'default' got value of type 'NoneType', want 'int'

Defaulting to None is the obvious thing that comes to my mind. In its absence, rule authors need to implement custom behavior to identify integers or strings that can be translated as "not provided". In the case of bools, this is not possible, and users would have to resort to using ints.

The other attrs are not as strongly affected -- they AFAICT either already accept None (attr.label), or empty sequences or dictionaries (everything else). In each of these cases, there is no strong need to specify a new "not provided"-style default, since None already is this, or empty sequences can usually just be skipped.

It would be nice if there was a consistent way to identify that an attribute is not provided. None is intuitively suitable for this purpose, but others options would be acceptable.

An option for this could be to support None in rule attributes more broadly. For example, Bazel currently accepts None as a valid input for at least some of the built-in attributes like tags and features. Also, when provided to rules as arguments, None is implicitly converted to the "null" value for the type in question (e.g. False, 0, "", []).

Feature requests: what underlying problem are you trying to solve with this feature?

I'd like rules to be more consistently readable by end-users and reduce the overall use of magic values. The meaning of None is usually apparent from its presence, and would be a good choice to represent this.

Having an obvious way to say "not provided" would have also been very useful in preventing issues like bazelbuild/rules_pkg#486 from occurring -- if None was an option for attr.int from the beginning, it likely would have been used.

What operating system are you running Bazel on?

macOS Big Sur 11.16.1, x86_64.

What's the output of bazel info release?

2021/12/15 10:11:44 Using unreleased version at commit 4c6e324dfab9444fc51b9fb3f5074a01889725e1
development version

(Same behavior occurs with Bazel 4.2.2, also downloaded via bazelisk)

If bazel info release returns "development version" or "(@Non-Git)", tell us how you built Bazel.

Downloaded with bazelisk using:

USE_BAZEL_VERSION=4c6e324dfab9444fc51b9fb3f5074a01889725e1 bazelisk info release

(That hash was last_green at the time)

What's the output of git remote get-url origin ; git rev-parse master ; git rev-parse HEAD ?

N/A

Have you found anything relevant by searching the web?

Any other information, logs, or outputs that you want to share?

Got an example below. To reproduce the failure mentioned earlier in this ticket, uncomment the default argument to the int attribute:

https://gist.github.com/nacl/1b469f75ffbf704ab1955955687d7e00

Metadata

Metadata

Assignees

No one assigned

    Labels

    P4This is either out of scope or we don't have bandwidth to review a PR. (No assignee)staleIssues or PRs that are stale (no activity for 30 days)team-Loading-APIBUILD file and macro processing: labels, package(), visibility, globtype: feature request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions