Zulip Chat Archive

Stream: general

Topic: Leanblueprint broken on Nix


Niklas Halonen (Jan 10 2025 at 19:53):

Hi all, I packaged leanblueprint to nixpkgs, but as pointed out by @Yury G. Kudryashov its plasTeX integration is broken, sorry about that. I'm working on a fix but won't promise that I get it done any time soon. Here are some more details about the problem if someone wants to help with the task:

  • When creating a web version of the blueprint, plasTeX tries to use the leanblueprint python module, which it cannot find as it was built without leanblueprint as a dependency. This error is seen in the output
plasTeX version 3.1
..
ERROR: Loading package "report" raised exception ModuleNotFoundError : No
   module named 'leanblueprint'
  • Adding leanblueprint as a dependency to plasTeX would cause a cyclic dependency resulting in "error: infinite recursion encoutered".

Some possible solutions I have considered:

  • Rewriting leanblueprint to use plasTeX as a python module rather than call it from a subprocess
  • Create a wrapper for plasTeX which has leanblueprint in its PYTHONPATH
  • Creating a package which bundles leanblueprint and plastex into one

As far as I know there is no way to get leanblueprint to work on Nix right now. Please correct me if I'm wrong.

Yury G. Kudryashov (Jan 10 2025 at 23:25):

I'm setting the python path in the command line, then it works.

Yury G. Kudryashov (Jan 10 2025 at 23:26):

You can just create a wrapper around the lean blueprint command that sets the python path environment variable. On the phone, so can't give more details right now.

Niklas Halonen (Jun 20 2025 at 15:44):

I'm very sorry it took me so long, but I have finally managed to get leanblueprint to work on Nix. I did it by following this solution in NixOS discourse. It's not idiomatic and tends to be quite slow, but it gets pygrahviz (from nixpkgs, as it can't compile when installed with pip), leanblueprint and plastex all in the same Python PATH by just downloading the tool using pip.

Anyways, this Nix shell worked for me, hopefully it's useful to other Nix users in the meanwhile:

  pkgs.mkShellNoCC {
    buildInputs = with pkgs; [
      python312
      python312Packages.pip
      python312Packages.virtualenvwrapper
      python312Packages.pygraphviz
      texlive.combined.scheme-small
    ];

    shellHook = ''
      echo "Activating venv with --system-site-packages"
      export TMPDIR=/tmp  && export VENV=$(mktemp -d)
      virtualenv --system-site-packages $VENV
      source $VENV/bin/activate
      pip install -U leanblueprint
    '';
  };

I have tested it on the ExtremeValueProject formalization project (part of a course by @Kalle Kytölä that I attended), and it worked as expected.

Next, I'll try to see what I can do about the broken leanblueprint in nixpkgs.

Niklas Halonen (Jun 20 2025 at 17:30):

It seems like I previosly completely missed the obvious dependency on LaTeX which probably was the reason it was not working for me before :man_facepalming: Solving the problem didn't require an intricate pip setup like I previously thought.

It's enough to simply add e.g. pkgs.texlive.combined.scheme-basic to the shell and the old leanblueprint 0.0.10 that I PRed to nixpkgs seems to work flawlessly.

Notification Bot (Jun 20 2025 at 17:39):

Niklas Halonen has marked this topic as resolved.

Niklas Halonen (Jun 20 2025 at 17:42):

So it seems like leanblueprint from nixpkgs worked all along[^1], just requires presence of a LaTeX distribution, which it doesn't come with as it's a "very dynamic/decoupled dependency". I'm happy to help if anyone still has trouble with the tool!

Here is a PR to nixpkgs for a bump and simple tests to leanblueprint

[^1]: It does work with nix-shell, see my latest message about investigating why it's not working with the unstable nix shell command.

Niklas Halonen (Jun 22 2025 at 13:46):

I think I'm going crazy. It's still clearly not working as intended.

To experiment, I started a fresh gitpod instance (on this repository) and tried entering a Nix shell with nix shell nixpkgs#{texlive.combined.scheme-small,leanblueprint} and when I ran leanblueprint web I got the error from my original post:

plasTeX version 3.1
..
ERROR: Loading package "report" raised exception ModuleNotFoundError : No
   module named 'leanblueprint'
..
ERROR: Loading package "amssymb" raised exception ModuleNotFoundError : No
   module named 'leanblueprint'
ERROR: Loading package "amsthm" raised exception ModuleNotFoundError : No
   module named 'leanblueprint'
ERROR: Loading package "amsmath" raised exception ModuleNotFoundError : No
   module named 'leanblueprint'
ERROR: Loading package "hyperref" raised exception ModuleNotFoundError : No
   module named 'leanblueprint'
ERROR: Loading package "blueprint" raised exception ModuleNotFoundError :
   No module named 'leanblueprint'

The way nix shell works is quite different from nix-shell (the stable command; which I had begun using recently).

By starting the shell with nix-shell -p texlive.combined.scheme-small -p leanblueprint, leanblueprint works again (requires forcefully removing the blueprint/web directory as usual):

[nix-shell:/workspace/ExtremeValueProject]$ leanblueprint web
plasTeX version 3.1
..
 (loading package /nix/store/sgcr0jrj93zvl98q9dx26k1s679zhq4j-python3.12-
   plasTeX-3.1/lib/python3.12/site-packages/plasTeX/Packages/report.py
 )..
 [..]
 [ index.html [ sect0001.html ] [ sect0002.html ] [ sect0003.html ]
 [ sect0004.html ] [ sect0005.html ] [ sect0006.html ] [ sect0007.html ]
 [ sect0008.html ] [ sect0009.html ] ]

The difference between the shells seems to be to the PYTHONPATH environment variable. nix-shell sets PYTHONPATH to include all site-packages, like leanblueprint, plastexdepgraph, plastexshowmore, pygraphviz, whereas nix shell doesn't set the PYTHONPATH at all.

The goal would of course be to get leanblueprint to work independently of the environment (PYTHONPATH), but because of the dependency cycle, I'm not sure if that's directly possible. Inspecting the .leanblueprint-wrapped binary reveals the site-packages, which need to be inherited by the plastex subprocess (like how environment variables are inherited). I'm now wondering how to wrap it differently, or if I should just refactor leanblueprint to import plastex instead of running it in a shell...


Last updated: Dec 20 2025 at 21:32 UTC