From 0cb467431976ffba7c2cb31020756c1ba764fa4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20S=C3=A1nchez=20Medina?= Date: Thu, 23 May 2024 01:36:15 -0700 Subject: [PATCH] doc: autogenerate python interpreter table (#313408) * doc: autogenerate python interpreter table This serves as a practical example on generating documentation by inspection of the evaluated Nixpkgs tree. Co-authored-by: Valentin Gagarin --- doc/default.nix | 10 +++- doc/doc-support/python-interpreter-table.nix | 63 ++++++++++++++++++++ doc/languages-frameworks/python.section.md | 11 +--- 3 files changed, 73 insertions(+), 11 deletions(-) create mode 100644 doc/doc-support/python-interpreter-table.nix diff --git a/doc/default.nix b/doc/default.nix index ca4091dc222c..14c828b02a06 100644 --- a/doc/default.nix +++ b/doc/default.nix @@ -105,7 +105,15 @@ in pkgs.stdenv.mkDerivation { ln -s ${optionsDoc.optionsJSON}/share/doc/nixos/options.json ./config-options.json ''; - buildPhase = '' + buildPhase = let + pythonInterpreterTable = pkgs.callPackage ./doc-support/python-interpreter-table.nix {}; + pythonSection = with lib.strings; replaceStrings + [ "@python-interpreter-table@" ] + [ pythonInterpreterTable ] + (readFile ./languages-frameworks/python.section.md); + in '' + cp ${builtins.toFile "python.section.md" pythonSection} ./languages-frameworks/python.section.md + cat \ ./functions/library.md.in \ ${lib-docs}/index.md \ diff --git a/doc/doc-support/python-interpreter-table.nix b/doc/doc-support/python-interpreter-table.nix new file mode 100644 index 000000000000..6f2b3422f672 --- /dev/null +++ b/doc/doc-support/python-interpreter-table.nix @@ -0,0 +1,63 @@ +# For debugging, run in this directory: +# nix eval --impure --raw --expr 'import ./python-interpreter-table.nix {}' +{ pkgs ? (import ../.. { config = { }; overlays = []; }) }: +let + lib = pkgs.lib; + inherit (lib.attrsets) attrNames filterAttrs; + inherit (lib.lists) elem filter map naturalSort reverseList; + inherit (lib.strings) concatStringsSep; + + isPythonInterpreter = name: + /* NB: Package names that don't follow the regular expression: + - `python-cosmopolitan` is not part of `pkgs.pythonInterpreters`. + - `_prebuilt` interpreters are used for bootstrapping internally. + - `python3Minimal` contains python packages, left behind conservatively. + - `rustpython` lacks `pythonVersion` and `implementation`. + */ + (lib.strings.match "(pypy|python)([[:digit:]]*)" name) != null; + + interpreterName = pname: + let + cuteName = { + cpython = "CPython"; + pypy = "PyPy"; + }; + interpreter = pkgs.${pname}; + in + "${cuteName.${interpreter.implementation}} ${interpreter.pythonVersion}"; + + interpreters = reverseList (naturalSort ( + filter isPythonInterpreter (attrNames pkgs.pythonInterpreters) + )); + + aliases = pname: + attrNames ( + filterAttrs (name: value: + isPythonInterpreter name + && name != pname + && interpreterName name == interpreterName pname + ) pkgs + ); + + result = map (pname: { + inherit pname; + aliases = aliases pname; + interpreter = interpreterName pname; + }) interpreters; + + toMarkdown = data: + let + line = package: '' + | ${package.pname} | ${join ", " package.aliases or [ ]} | ${package.interpreter} | + ''; + in + join "" (map line data); + + join = lib.strings.concatStringsSep; + +in +'' + | Package | Aliases | Interpeter | + |---------|---------|------------| + ${toMarkdown result} +'' diff --git a/doc/languages-frameworks/python.section.md b/doc/languages-frameworks/python.section.md index 6fcae4b6520d..4c4ecf0fa278 100644 --- a/doc/languages-frameworks/python.section.md +++ b/doc/languages-frameworks/python.section.md @@ -4,16 +4,7 @@ ### Interpreters {#interpreters} -| Package | Aliases | Interpreter | -|------------|-----------------|-------------| -| python27 | python2, python | CPython 2.7 | -| python39 | | CPython 3.9 | -| python310 | | CPython 3.10 | -| python311 | python3 | CPython 3.11 | -| python312 | | CPython 3.12 | -| python313 | | CPython 3.13 | -| pypy27 | pypy2, pypy | PyPy2.7 | -| pypy39 | pypy3 | PyPy 3.9 | +@python-interpreter-table@ The Nix expressions for the interpreters can be found in `pkgs/development/interpreters/python`.