diff options
author | Maximilian Bosch <maximilian@mbosch.me> | 2021-07-23 10:43:44 +0200 |
---|---|---|
committer | Maximilian Bosch <maximilian@mbosch.me> | 2021-08-25 23:18:26 +0200 |
commit | 55ea29fd8c7a4b130a114b0f06b3fadfaf028356 (patch) | |
tree | 328cf78611ffedb3a7a06a778596f5469eff076f /lib/tests | |
parent | 81f586e8b8d808c58116267cb9c0f45b3e61e4c8 (diff) | |
download | nixpkgs-55ea29fd8c7a4b130a114b0f06b3fadfaf028356.tar nixpkgs-55ea29fd8c7a4b130a114b0f06b3fadfaf028356.tar.gz nixpkgs-55ea29fd8c7a4b130a114b0f06b3fadfaf028356.tar.bz2 nixpkgs-55ea29fd8c7a4b130a114b0f06b3fadfaf028356.tar.lz nixpkgs-55ea29fd8c7a4b130a114b0f06b3fadfaf028356.tar.xz nixpkgs-55ea29fd8c7a4b130a114b0f06b3fadfaf028356.tar.zst nixpkgs-55ea29fd8c7a4b130a114b0f06b3fadfaf028356.zip |
lib/generators/toPretty: add evaluation-limit
When having e.g. recursive attr-set, it cannot be printed which is solved by Nix itself like this: $ nix-instantiate --eval -E 'let a.b = 1; a.c = a; in builtins.trace a 1' trace: { b = 1; c = <CYCLE>; } 1 However, `generators.toPretty` tries to evaluate something until it's done which can result in a spurious `stack-overflow`-error: $ nix-instantiate --eval -E 'with import <nixpkgs/lib>; generators.toPretty { } (mkOption { type = types.str; })' error: stack overflow (possible infinite recursion) Those attr-sets are in fact rather common, one example is shown above, a `types.<type>`-declaration is such an example. By adding an optional `depthLimit`-argument, `toPretty` will stop evaluating as soon as the limit is reached: $ nix-instantiate --eval -E 'with import ./Projects/nixpkgs-update-int/lib; generators.toPretty { depthLimit = 2; } (mkOption { type = types.str; })' |xargs -0 echo -e "{ _type = \"option\"; type = { _type = \"option-type\"; check = <function>; deprecationMessage = null; description = \"string\"; emptyValue = { }; functor = { binOp = <unevaluated>; name = <unevaluated>; payload = <unevaluated>; type = <unevaluated>; wrapped = <unevaluated>; }; getSubModules = null; getSubOptions = <function>; merge = <function>; name = \"str\"; nestedTypes = { }; substSubModules = <function>; typeMerge = <function>; }; }" Optionally, it's also possible to let `toPretty` throw an error if the limit is exceeded.
Diffstat (limited to 'lib/tests')
-rw-r--r-- | lib/tests/misc.nix | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/lib/tests/misc.nix b/lib/tests/misc.nix index 4b2e5afc1d6..110716ca691 100644 --- a/lib/tests/misc.nix +++ b/lib/tests/misc.nix @@ -529,6 +529,24 @@ runTests { }; }; + testToPrettyLimit = + let + a.b = 1; + a.c = a; + in { + expr = generators.toPretty { depthLimit = 2; } a; + expected = "{\n b = 1;\n c = {\n b = 1;\n c = {\n b = <unevaluated>;\n c = <unevaluated>;\n };\n };\n}"; + }; + + testToPrettyLimitThrow = + let + a.b = 1; + a.c = a; + in { + expr = (builtins.tryEval (generators.toPretty { depthLimit = 2; throwOnDepthLimit = true; } a)).success; + expected = false; + }; + testToPrettyMultiline = { expr = mapAttrs (const (generators.toPretty { })) rec { list = [ 3 4 [ false ] ]; |