Skip to content
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

Introduce types.anything #97119

Merged
merged 5 commits into from Sep 21, 2020
Merged

Introduce types.anything #97119

merged 5 commits into from Sep 21, 2020

Conversation

infinisil
Copy link
Member

Motivation for this change

This introduces the new type types.anything, which implements a safe and reasonable merge strategy if you don't care about the type. Specifically:

  • It recursively merges attribute sets together
    • Except if it's string-coercible (aka, packages and co.), then only one definition is allowed
  • It doesn't concatenate list values together (since list concatenation doesn't always make sense)
  • If it's an atomic value (not a set or a list), all definitions must be equal
  • It applies mkIf's and co. for all values

This is in contrast with the often-used types.attrs and types.unspecified, which can be problematic because they don't adhere to above points. If both this PR and #97114 are merged, I can start deprecating those in favor of this one.

Note that the doc entry for this new type is intentionally kept small, because its behavior is very natural and doesn't need a special explanation.

Ping @rycee @roberth @Profpatsch

Things done
  • Wrote a doc entry for the new type
  • Wrote tests for the new type

@edolstra
Copy link
Member

edolstra commented Sep 4, 2020

Hm, what's the use case for this? Presumably you always do care about the type of an option since you need to use it somewhere eventually.

@rycee
Copy link
Member

rycee commented Sep 4, 2020

@edolstra I don't think the anything type is very useful by itself but I would happily use, e.g., attrsOf anything instead of attrs or attrsOf unspecified. That is, when I know the type is an attribute set but not the specific content. I've encountered this mainly when defining settings-like options that gets serialized to some hierarchical configuration format. For example the programs.taskwarrier.config or programs.waybar.settings.*.modules options in Home Manager.

@infinisil
Copy link
Member Author

Yeah exactly, the intention is for this type to replace types.attrs and types.unspecified, which are currently used when the type isn't known, but as mentioned they have some surprising behavior which you wouldn't expect.

nixos/doc/manual/development/option-types.xml Outdated Show resolved Hide resolved
lib/types.nix Show resolved Hide resolved
Previously it would error out for a single function definition
This new type has unsurprising merge behavior: Only attribute sets are
merged together (recursively), and only if they don't conflict.

This is in contrast to the existing types:
- types.attrs is problematic because later definitions completely
  override attributes of earlier definitions, and it doesn't support
  mkIf and co.
- types.unspecified is very similar to types.attrs, but it has smart
  merging behavior that often doesn't make sense, and it doesn't support
  all types
@infinisil
Copy link
Member Author

Changes since the last revision:

  • I moved types.attrs to the bottom of the type list and added a warning about its problems
  • Added an example for types.anything in the docs
  • Fixed mergeEqualOption for when a single function is passed. Now it doesn't error out anymore. Also added a test case to types.anything for this

Copy link
Member

@Profpatsch Profpatsch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@roberth roberth merged commit f3893d8 into NixOS:master Sep 21, 2020
@roberth
Copy link
Member

roberth commented Sep 21, 2020

Thanks @infinisil !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants