Skip to content

For python, how to use venvShellHook with numtide / devshell #309

Open

Description

@geekodour

We can use venvShellHook with plain shell.nix with something like

let
  pkgs = import <nixpkgs> { };
  pyPackages = pkgs.python311Packages;
in pkgs.mkShell {
  name = "py";
  venvDir = "./.venv";
  buildInputs = [
    pyPackages.pip
    pyPackages.venvShellHook
    pkgs.ruff # linter
    pkgs.python311
  ];

  postShellHook = ''
    pip install poetry
    unset SOURCE_DATE_EPOCH
  '';
}

And with vanilla flake with something like:

 devShells.default = pkgs.mkShell {
        nativeBuildInputs = with pkgs; [pkgs.python311Packages.pip pkgs.python311Packages.venvShellHook];
        venvDir = "./.venv";
 };

But with numtide / devshell it seems like I cannot use venvShellHook and hence no way to have the sweet virtual env created for me as I cd into the directory.

Activity

  1. changed the title [-]How to use venvShellHook with `numtide / devshell`[/-] [+]For python, how to use venvShellHook with `numtide / devshell`[/+] on Apr 26, 2024
  2. yajo commented on Aug 2, 2024

    @yajo
    Contributor

    Did you find a solution?

  3. geekodour commented on Aug 2, 2024

    @geekodour
    Author

    @yajo my solution was not using numtide devshell but using flake devshell with flake as described here: https://fasterthanli.me/series/building-a-rust-service-with-nix/part-10

    Here's a flake i use for one of my projects:

    • It has unstable overlay (while some well respected members of the community mentioned that it's not the ideal way to use overlay for accessing unstable but works for me as of the moment)
    • Additionally uses process-compose for setting up PG (remove if not needed)
    • If we want to use something as shell hook, you must use postshellHook because shellHook will be used by venvShellHook and if you set shellHook manually it overrides it.
    • Also has a ci shell in addition to the default shell, remove if not needed
    {
      inputs = {
        nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.05";
        nixpkgs-unstable.url = "github:nixos/nixpkgs/nixos-unstable";
        flake-parts = { url = "github:hercules-ci/flake-parts"; inputs.nixpkgs-lib.follows = "nixpkgs"; };
        process-compose-flake.url = "github:Platonic-Systems/process-compose-flake";
      };
    
      outputs = inputs@{ flake-parts, ... }:
        flake-parts.lib.mkFlake { inherit inputs; } {
          imports = [
            # https://community.flake.parts/process-compose-flake
            inputs.process-compose-flake.flakeModule
          ];
          systems = [ "x86_64-linux" "aarch64-linux" ];
          perSystem = { config, pkgs, system, ... }:
            let
              pyPackages = pkgs.python311Packages;
            in
            {
              _module.args.pkgs = import inputs.nixpkgs {
                inherit system;
                overlays = [
                  (final: prev: {
                    unstable = import inputs.nixpkgs-unstable {
                      system = final.system;
                      config.allowUnfree = true;
                    };
                  })
                ];
              };
              process-compose = {
                localpg = {
                  settings.processes = {
                    postgres-server = {
                      command = ''pg_ctl -o "-p $PGPORT -h $PGHOST" -D $PGDATA start'';
                      is_daemon = true;
                      shutdown = { command = "pg_ctl -D $PGDATA stop"; };
                    };
                  };
                };
              };
    
              devShells = {
                default = pkgs.mkShell {
                  name = "custom-py-shell";
                  venvDir = "./.venv";
                  nativeBuildInputs = [ ];
                  buildInputs = [
                    pkgs.python311
                    pyPackages.pip
                    pyPackages.venvShellHook
                    pkgs.poetry
                    pkgs.just # adhoc commands
                  ];
                  packages = [
                    # debugging
                    #pkgs.memray
                    #pyPackages.objgraph
                    #pyPackages.pudb
                    pyPackages.ipython
                    pyPackages.isort
                    pyPackages.mypy
                    pkgs.ruff
                    pkgs.unstable.duckdb
                    # pg
                    pkgs.postgresql_16 # for exts: withPackages (p: [ p.pg_uuidv7 ]))
                  ];
                  postShellHook = ''
                    mkdir -p $PGDATA
                    if [ -d $PGDATA ]; then
                      initdb -U postgres $PGDATA --auth=trust >/dev/null
                    fi
                    export LD_LIBRARY_PATH="${pkgs.lib.makeLibraryPath [
                      pkgs.stdenv.cc.cc
                    ]}"
                  '';
                };
                ci = pkgs.mkShell {
                  name = "ci";
                  venvDir = "./.venv";
                  buildInputs = [
                    pkgs.poetry
                    pyPackages.venvShellHook
                  ];
                  packages = [
                    pkgs.just
                    pyPackages.isort
                    pyPackages.mypy
                    pyPackages.pytest
                    pkgs.ruff
                  ];
                  postShellHook = ''
                    export PROJECT_ROOT=$GITHUB_WORKSPACE
                  '';
                };
              };
            };
        };
    }

    Hope it helps!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions