lib/generators: uninline recursion depth tracking#168327
lib/generators: uninline recursion depth tracking#168327K900 wants to merge 2 commits intoNixOS:masterfrom K900:fix-recursive-insanity
Conversation
|
Fixed the tests. |
|
Perhaps relevant for #167388? |
lib/strings.nix
Outdated
There was a problem hiding this comment.
I think this might be more useful with the arguments round the other way? I could imagine myself currying repeat 3 more than repeat "str".
|
The problem is quite simple, if Currently preparing a patch to fix this. |
|
The same can also happen with |
|
Well, this issue only applies to "magic" attributes that are used within |
|
Yes, but more of those could be added at the same time. |
Closes NixOS#168327 The issue reported there can be demonstrated with the following expression: → nix-instantiate --eval -E "with import ./. {}; pkgs.lib.options.showDefs [ { file = \"foo\"; value = pkgs.rust.packages.stable.buildRustPackages; } ]" error: attempt to call something which is not a function but a string at /home/ma27/Projects/nixpkgs/lib/trivial.nix:442:35: 441| isFunction = f: builtins.isFunction f || 442| (f ? __functor && isFunction (f.__functor f)); | ^ 443| Basically, if a `__functor` is in an attribute-set at depth-limit, `__functor` will be set to `"<unevaluated>"`. This however breaks `lib.isFunction` which checks for a `__functor` by invoking `__functor` with `f` itself. The same issue - "magic" attributes being shadowed by `withRecursion` - also applies to others such as `__pretty`/`__functionArgs`/`__toString`. Since these attributes have a low-risk of causing a stack overflow (because these are flat attr-sets or even functions), ignoring them in `withRecursion` seems like a valid solution.
|
First of all, people should be careful with that, there's no convention that prevents people from using Second, if the new magic attribute affects pretty logic, you'd have to touch However don't get me wrong, I understand your point! I'll file a PR with my change anyways as an alternative, but it'd be understandable from my PoV if your's gets merged in favor of mine :) Another option is btw to special-case each |
|
Am I correct in assuming that you want to keep |
Can you elaborate what you exactly mean with "combinator crimes", please?
tl;dr yes, recursion limits and pretty-printing are actually two different things and thus were separated, see also the discussion in #131205 (and the linked tickets). |
|
We can make |
|
@Ma27 try the latest commit |
|
I think @infinisil added that originally? |
lib/strings.nix
Outdated
There was a problem hiding this comment.
We shouldn’t introduce a new stdlib function in an unrelated commit.
There was a problem hiding this comment.
Could always inline this, but it sounds like something that's both simple, slightly non-trivial and generally useful. Maybe I can split this off into a separate commit or even PR instead?
There was a problem hiding this comment.
A separate PR sounds reasonable. But even just having a separate commit is better than bunching a new library function with some other changes.
lib/generators.nix
Outdated
There was a problem hiding this comment.
This is a breaking API change of an exposed library function, we can’t do that.
There was a problem hiding this comment.
You need to keep the API the same; e.g. making some of the options no-ops should also work.
There was a problem hiding this comment.
That's not really viable here unfortunately - the old version took an object to be inspected, and the new one takes a function to be wrapped. I guess we can make a withRecursionLimit', or even a _withRecursionLimit'?
There was a problem hiding this comment.
As I said, I don’t think we should break the API without good cause.
There was a problem hiding this comment.
Or rather we shouldn’t break the API, period :)
There was a problem hiding this comment.
Yes, what I'm saying is, keep the old function as it is, introduce the new one without exposing it.
lib/strings.nix
Outdated
There was a problem hiding this comment.
The example should probably contain a string that is longer than one character.
|
Updated. Split |
Avoids weird issues when recursing into magic attributes like __functor and __pretty by counting recursions only when actually necessary.
@Profpatsch I added it originally it in #131205 and also filed a PR #168374 to fix it using However, @K900 brought some valid concerns up regarding my solution, so I'd leave it up to you to decide :) (sorry for my late replies, was sick recently and had a lot of other stuff to take care of after that) |
|
Force-pushed again to fix some weird mismerge - my local copy of nixpkgs was behind the laptop I wrote the "generator crimes" PoC on. |
As cute as it is, it breaks in "interesting" ways when combined with nixpkgs' magic __functor attribute and friends.
This has notably caused pretty-printing
pkgs.rustto fail, making at least two users (me included) extremely confused.There's probably a better approach here involving more nasty self-recursion and a wrapper, but let's cross that bridge when we come to it.
To reproduce:
pkgs.lib.options.showDefs [ { file = "foo"; value = pkgs.rust.packages.stable.buildRustPackages; } ].Description of changes
Removed the
withRecursivewrapper, moved all the step-counting intotoPretty, lowered the default depth to a more reasonable amount.Ping @Profpatsch and @Ma27 as originators of the function.
Things done
sandbox = trueset innix.conf? (See Nix manual)nix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD". Note: all changes have to be committed, also see nixpkgs-review usage./result/bin/)nixos/doc/manual/md-to-db.shto update generated release notes