{ config , lib , pkgs , ... }: with lib; let cfg = config.my.programs.python; pythonVersions = map (version: "3${toString version}") (range 8 11); enabledVersions = filterAttrs (_: value: value.enable) cfg.versions; pythonPackages = version: attrNames pkgs."python${version}Packages"; commonPackages = let packageLists = map pythonPackages (attrNames enabledVersions); in foldl' intersectLists (head packageLists) (tail packageLists); versionOpts = version: { enable = mkEnableOption (toString version); pythonPackages = mkOption { default = [ ]; type = with types; listOf (enum (pythonPackages version)); }; }; in { options.my.programs.python = { versions = genAttrs pythonVersions versionOpts; defaultPackages = mkOption { default = [ ]; type = with types; listOf (enum commonPackages); }; extraPackages = mkOption { default = [ ]; type = with types; listOf package; }; }; config = { users.users.moritz.packages = ( let mkPython = version: let package = pkgs."python${version}"; finalPythonPackages = cfg.versions.${version}.pythonPackages ++ cfg.defaultPackages; getPythonPackages = ps: map (flip getAttr ps) finalPythonPackages; in package.withPackages getPythonPackages; in map mkPython (attrNames enabledVersions) ) ++ cfg.extraPackages; }; }