Nix flake editable python install does not reload modules

Hi folks,

I am currently working on a python project using a nix flake to manage all dependencies and buildPythonPackage to build the package. Everything seems to be going well, nix build is successfully building the library, and nix develop drops me into a dev shell with the expected dependencies and python modules.

However, I am encountering some strange behavior with my locally imported python modules. My package has a main.py module, where I import some code from other modules. When I run the main module with python3 /path/to/main.py from inside my nix develop shell, things work normally, until I make a code change. When I make a code change to any of the modules I import, those changes are not picked up until I rebuild my package (and dev shell). According to the pip build hook, my package should be installed in editable mode, meaning I would expect the code changes to be picked up instantly, without rebuild.

Even weirder: if i run the python interpreter with python3, then import the modules from inside the interpreter, I can see the code changes without a rebuild. Can anyone help explain what’s going on ??

Relevant resources:

my file structure

.
├── default.nix
├── docs
├── flake.lock
├── flake.nix
├── housefire
│   ├── __init__.py
│   ├── property_data_scrapers
│   │   ├── __init__.py
│   │   ├── main.py
│   │   ├── scraper.py
│   │   └── transformer.py
│   └── utils
│       ├── __init__.py
│       ├── env_utils.py
│       ├── format_edge_config.py
│       ├── housefire_api.py
│       ├── logger.py
│       └── scraping_utils.py
├── pyproject.toml

my flake.nix

{
  description = "Nix flake for the python build inputs to housefire";

  inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";

  outputs = { self, nixpkgs }:
    let
      supportedSystems = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" ];
      forEachSupportedSystem = f: nixpkgs.lib.genAttrs supportedSystems (system: f {
        pkgs = import nixpkgs { inherit system; };
      });
    in
    {
      packages = forEachSupportedSystem ({ pkgs }: {
        default = pkgs.python3Packages.callPackage ./default.nix { };
      });
      devShells = forEachSupportedSystem ({ pkgs }: {
        default = pkgs.mkShell {
          packages = with pkgs; [
            (
              python3.withPackages (
                ps: with ps; [
                  (callPackage ./default.nix { })
                  # extra dev dependencies
                  black
                ]
              )
            )
            (if (!pkgs.stdenv.isDarwin) then pkgs.chromium else null)
          ];

          shellHook = (pkgs.lib.optionalString (!pkgs.stdenv.isDarwin) ''
            export CHROME_PATH=${pkgs.chromium}/bin/chromium
          '');
        };
      });

      formatter = forEachSupportedSystem ({ pkgs }: pkgs.nixpkgs-fmt
      );
    };
}

my default.nix for building the package

{ buildPythonPackage
, pythonOlder
, pandas
, python-dotenv
, requests
, nodriver
, setuptools
}:

buildPythonPackage {
  pname = "housefire";
  version = "1.0.0";
  pyproject = true;

  disabled = pythonOlder "3.9";

  src = ./.;

  dependencies = [
    pandas
    python-dotenv
    requests
    nodriver
  ];

  build-system = [ setuptools ];

  meta = {
    homepage = "https://github.com/liam-murphy14/housefire";
    description = "A personal project for people to see REITs";
  };
}

my pyproject.toml

[project]
name = "housefire"
version = "1.0.0"
authors = [
    { name="Liam Murphy", email="liam.murphy137@gmail.com" },
]
description = "A personal project to help people see REITs"
requires-python = ">=3.9"
classifiers = [
    "Programming Language :: Python :: 3",
    "License :: OSI Approved :: MIT License",
    "Operating System :: OS Independent",
]

dependencies = [
    "pandas",
    "python-dotenv",
    "requests",
    "nodriver",
]

[project.urls]
Homepage = "https://github.com/liam-murphy14/housefire"
Issues = "https://github.com/liam-murphy14/housefire/issues"

[tool.setuptools]
include-package-data = true
packages = [
    'housefire',
    'housefire.property_data_scrapers',
    'housefire.utils'
]

[build-system]
requires = ["setuptools>=61.0", "wheel"]
build-backend = "setuptools.build_meta"

Thanks in advance ! Full repo here if you want more context: housefire/python_serverless_housefire at main · liam-murphy14/housefire · GitHub