Python Nix表达式构建报错[Errno 13] Permission denied如何解决
错误触发原因
- 直接原因:Nix的
/nix/store路径是全局只读的,你构建自定义markdown-it-py 1.1.0时,pip检测到构建环境中已经存在来自nixpkgs官方源的旧版本markdown-it-py 1.0.0,尝试卸载旧版本修改/nix/store内容,触发权限不足报错。 - 根本原因:你的配置存在依赖版本冲突:
- 你在jupyter-book的Nix表达式中单独定义了1.1.0版本的
markdown-it-py,但jupytext的依赖声明中用的是python3Packages.markdown-it-py(即nixpkgs自带的1.0.0版本) - 你自定义的
markdown-it-py依赖python3Packages.mdit-py-plugins,而这个包本身依赖官方源的旧版本markdown-it-py 1.0.0,导致两个版本同时被引入构建环境。
- 你在jupyter-book的Nix表达式中单独定义了1.1.0版本的
修复方案
推荐通过Nix overlay全局覆盖Python包版本,确保所有依赖都使用同一版本的相关包,避免冲突:
- 修改flake.nix,新增overlay覆盖需要自定义版本的Python包:
{ description = "Introduction to Computational Literary Analysis, a Textbook"; outputs = { self, nixpkgs }: let system = "x86_64-linux"; # 定义覆盖Python包的overlay pythonOverlay = final: prev: { python3Packages = prev.python3Packages.overrideScope (pyFinal: pyPrev: { attrs = pyPrev.buildPythonPackage rec { pname = "attrs"; version = "20.3.0"; src = pyPrev.fetchPypi { inherit pname version; sha256 = "007pchhxk2nh6m2rgflkkij9xjwysq3fl7xr72cy8i4pw76s6al3"; }; doCheck = false; }; click = pyPrev.buildPythonPackage rec { pname = "click"; version = "7.1"; src = pyPrev.fetchPypi { inherit pname version; sha256 = "1qk0x1bh6pmn2al9kq6cbgvm7pchnzl6ahf4zzpbjljl5lpmabs8"; }; }; markdown-it-py = pyPrev.buildPythonPackage rec { pname = "markdown-it-py"; version = "1.1.0"; src = pyPrev.fetchFromGitHub { owner = "executablebooks"; repo = "markdown-it-py"; rev = "1d27af1da41fd3b00da8307040e6e274925437b2"; sha256 = "priZH3ZbJxLm4drYt5Br5BWe+OSf4ZM0tpU7zPKw+UA="; }; propagatedBuildInputs = [ pyFinal.attrs pyFinal.mdit-py-plugins ]; doCheck = false; }; }); }; # 导入nixpkgs时应用overlay pkgs = import nixpkgs { inherit system; overlays = [ pythonOverlay ]; }; in { jupyterBook = pkgs.callPackage ./jupyter-book.nix {}; myPython = (pkgs.python3.withPackages (ps: with ps; [ jupyter jupyterlab self.jupyterBook pandas nltk ])); defaultPackage.${system} = self.myPython; }; }
- 简化jupyter-book.nix,删除原本单独定义的attrs20、click、markdown-it-py等包,直接使用overlay覆盖后的python3Packages中的对应版本:
{ python3Packages, fetchFromGitHub }: let inherit (python3Packages) buildPythonPackage fetchPypi; jupytext = buildPythonPackage rec { pname = "jupytext"; version = "1.10.3"; src = fetchPypi { inherit pname version; sha256 = "09f0ra3ndq4sxb0q3pjx713pfyc731y6fkzx93481mc7qm2cym5x"; }; propagatedBuildInputs = with python3Packages; [ toml pyyaml markdown-it-py ]; }; sphinxExternalTOC = buildPythonPackage rec { pname = "sphinx-external-toc"; version = "0.2.2"; src = fetchPypi { pname = "sphinx_external_toc"; inherit version; sha256 = "a72c5861f670f1c7a1b92f2159fc9c7c5370e079cad1e3a7be4b269fa8048e8a"; }; propagatedBuildInputs = with python3Packages; [ sphinx attrs click pyyaml ]; }; sphinxComments = buildPythonPackage rec { pname = "sphinx-comments"; version = "0.0.3"; src = fetchPypi { inherit version pname; sha256 = "00170afff27019fad08e421da1ae49c681831fb2759786f07c826e89ac94cf21"; }; propagatedBuildInputs = with python3Packages; [ sphinx ]; }; in buildPythonPackage rec { pname = "jupyter-book"; version = "0.11.2"; src = fetchPypi { inherit version pname; sha256 = "e32298e03c19f514c745062891143693c5e001a098bae9d59d2e4434b2099c54"; }; propagatedBuildInputs = with python3Packages; [ attrs linkify-it-py sphinx sphinxComments sphinxExternalTOC jupytext ]; }
这种方案会让所有Python包的依赖树都使用你指定版本的attrs、click、markdown-it-py,不会出现多版本冲突,pip也就不会尝试卸载只读路径下的旧版本包。
内容的提问来源于stack exchange,提问作者Jonathan
相关产品推荐
相关产品推荐

