openlang

tryEval passed a package I had broken on purpose

Wrote a small sweep over an overlay that wraps each package in builtins.tryEval and lists the ones that fail. It reported everything as fine, including one I had broken on purpose with a throw in its dependency list.

The manual is clear about it once you read the whole entry. tryEval evaluates shallowly. A package is an attribute set, so reaching that form is enough to succeed, and nothing inside it gets forced.

let
  pkg = { name = "demo"; deps = throw "broken on purpose"; };
in {
  shallow = (builtins.tryEval pkg).success;
  deep = (builtins.tryEval (builtins.deepSeq pkg pkg)).success;
}

With --strict that gives shallow = true and deep = false. The rest of the entry matters as well. It only catches throw and assert, so an abort or a type error from a builtin stops the whole sweep instead of marking one package. The sweep as written answered a narrower question than its name suggests, and I'm not yet sure what the right thing to force is for real packages.

后续讨论 4

顺着彼此的依据读下去
  1. 固定链接

    Would deepSeq on a real package even be a good idea? A derivation's attribute set points at its dependencies, which are derivations with attribute sets of their own, and so on through a big part of the package set. Forcing all of that to check one package sounds like it checks far more than you asked, and then fails for reasons that belong to some other package.

  2. 固定链接

    It would, which is why I've moved to forcing drvPath instead. (builtins.tryEval pkg.drvPath).success makes the evaluator instantiate the derivation, which needs what its inputs need for their own instantiation and nothing that only lives in other attributes. My broken package now shows up as failing. The check has a limit, though. It forces only what instantiation reads, so a throw hiding in something that never reaches the derivation, a passthru attribute for example, still passes.

  3. 固定链接

    Settle what the sweep reports first. "Every listed package can be instantiated" needs drvPath. "Every name in the overlay evaluates to something" is answered by the shallow version, and the two reports look identical in a list.

同一个问题的其他角度

  1. Launching the consumer on a stopped event

    Got a question about a supervisor rule that treats a stopped process as a finished one, and a tiny repro makes the problem ob…

    回复 17最近活动 bashpython
  2. What does a --hash line actually pin?

    A requirements file with --hash on every line installs cleanly on my laptop and fails with a hash mismatch in a fresh Linux c…

    回复 8最近活动 python
  3. After the Kotlin DSL move, subprojects can no longer find implementation

    Moving an old multi-project build from the Groovy DSL to the Kotlin DSL. The root build.gradle had this block. The root I con…

    回复 2最近活动 kotlingroovy