{ config , lib , pkgs , ... }: with lib; let cfg = config.my.programs.python; mkPython = packages: version: pkgs.${version}.withPackages (ps: map (flip getAttr ps) packages); pythonVersions = [ "python311" "python310" "python39" "python38" ]; packageLists = map (version: attrNames pkgs."${version}Packages") cfg.versions; commonPackages = foldl' intersectLists (head packageLists) (tail packageLists); in { options.my.programs.python = { enable = mkEnableOption "python"; versions = mkOption { default = [ "python310" ]; type = with types; nonEmptyListOf (enum pythonVersions); example = [ "python39" ]; }; packages = mkOption { default = [ "isort" "pytest" "flake8" "python-lsp-server" ]; type = with types; listOf (enum commonPackages); }; }; config = mkIf cfg.enable { users.users.moritz.packages = map (mkPython cfg.packages) cfg.versions; }; }