Add types.is_set() to test whether an arbitrary object is a set as defined by new_sets.bzl. (#181)

* Add sets.is_set() to test whether an arbitrary object is a set.

Since using sets requires special API, it can be useful to determine
whether an object is a set so special handling can be used.
For example, if a method wants to be able to take a list or a set.
This commit is contained in:
TechSY730 2019-09-17 09:21:44 -05:00 committed by c-parsons
parent 58068fe0cc
commit 3154dbbc41
4 changed files with 39 additions and 1 deletions

View File

@ -40,7 +40,9 @@ bzl_library(
bzl_library( bzl_library(
name = "new_sets", name = "new_sets",
srcs = ["new_sets.bzl"], srcs = ["new_sets.bzl"],
deps = [":dicts"], deps = [
":dicts",
],
) )
bzl_library( bzl_library(

View File

@ -18,6 +18,9 @@
if you pass it an sequence: `sets.make([1, 2, 3])`. This returns a struct containing all of the if you pass it an sequence: `sets.make([1, 2, 3])`. This returns a struct containing all of the
values as keys in a dictionary - this means that all passed in values must be hashable. The values as keys in a dictionary - this means that all passed in values must be hashable. The
values in the set can be retrieved using `sets.to_list(my_set)`. values in the set can be retrieved using `sets.to_list(my_set)`.
An arbitrary object can be tested whether it is a set generated by `sets.make()` or not with the
`types.is_set()` method in types.bzl.
""" """
load(":dicts.bzl", "dicts") load(":dicts.bzl", "dicts")
@ -33,6 +36,8 @@ def _make(elements = None):
Returns: Returns:
A set containing the passed in values. A set containing the passed in values.
""" """
# If you change the structure of a set, you need to also update the _is_set method
# in types.bzl.
elements = elements if elements else [] elements = elements if elements else []
return struct(_values = {e: None for e in elements}) return struct(_values = {e: None for e in elements})
@ -233,4 +238,5 @@ sets = struct(
remove = _remove, remove = _remove,
repr = _repr, repr = _repr,
str = _repr, str = _repr,
# is_set is declared in types.bzl
) )

View File

@ -21,6 +21,7 @@ _a_string_type = type("")
_a_tuple_type = type(()) _a_tuple_type = type(())
_an_int_type = type(1) _an_int_type = type(1)
_a_depset_type = type(depset()) _a_depset_type = type(depset())
_a_struct_type = type(struct())
def _a_function(): def _a_function():
pass pass
@ -126,6 +127,17 @@ def _is_depset(v):
""" """
return type(v) == _a_depset_type return type(v) == _a_depset_type
def _is_set(v):
"""Returns True if v is a set created by sets.make().
Args:
v: The value whose type should be checked.
Returns:
True if v was created by sets.make(), False otherwise.
"""
return type(v) == _a_struct_type and hasattr(v, "_values") and _is_dict(v._values)
types = struct( types = struct(
is_list = _is_list, is_list = _is_list,
is_string = _is_string, is_string = _is_string,
@ -136,4 +148,5 @@ types = struct(
is_dict = _is_dict, is_dict = _is_dict,
is_function = _is_function, is_function = _is_function,
is_depset = _is_depset, is_depset = _is_depset,
is_set = _is_set,
) )

View File

@ -15,6 +15,7 @@
load("//lib:types.bzl", "types") load("//lib:types.bzl", "types")
load("//lib:unittest.bzl", "asserts", "unittest") load("//lib:unittest.bzl", "asserts", "unittest")
load("//lib:new_sets.bzl", "sets")
def _a_function(): def _a_function():
"""A dummy function for testing.""" """A dummy function for testing."""
@ -215,6 +216,21 @@ def _is_depset_test(ctx):
is_depset_test = unittest.make(_is_depset_test) is_depset_test = unittest.make(_is_depset_test)
def _is_set_test(ctx):
"""Unit test for types.is_set."""
env = unittest.begin(ctx)
asserts.true(env, types.is_set(sets.make()))
asserts.true(env, types.is_set(sets.make([1])))
asserts.false(env, types.is_set(None))
asserts.false(env, types.is_set({}))
asserts.false(env, types.is_set(struct(foo = 1)))
asserts.false(env, types.is_set(struct(_values = "not really values")))
return unittest.end(env)
is_set_test = unittest.make(_is_set_test)
def types_test_suite(): def types_test_suite():
"""Creates the test targets and test suite for types.bzl tests.""" """Creates the test targets and test suite for types.bzl tests."""
unittest.suite( unittest.suite(
@ -228,4 +244,5 @@ def types_test_suite():
is_dict_test, is_dict_test,
is_function_test, is_function_test,
is_depset_test, is_depset_test,
is_set_test,
) )