When I run nix-shell
against the following shell.nix
, I’m provided with a temporary executable where changes made to the source code are immediately reflected:
$ cat shell.nix
{ pkgs ? import <nixpkgs> {} }:
pkgs.python38Packages.buildPythonPackage rec {
name = "my-project";
src = ./my_project;
propagatedBuildInputs = with pkgs.python38Packages; [ pycryptodome setuptools ];
}
$ nix-shell shell.nix
# lots of output including the stack trace described by:
# https://discourse.nixos.org/t/pip-not-found-by-python39-in-nix-shell/24017/5
[nix-shell] $ my-package
hello
[nix-shell] $ vim file.py # update the string printed
[nix-shell] $ my-package
hello world
[nix-shell]$ which my-project
/tmp/tmp.m0JwP7xpRS/bin/my-project
[nix-shell]$ realpath /tmp/tmp.m0JwP7xpRS/bin/my-project
/private/tmp/tmp.m0JwP7xpRS/bin/my-project
This is working fine for development except for an ugly stack trace due to python not being able to find pip. But it doesn’t seem like the correct way to do it because it’s not using mkShell
(and throws a low-sev error). When I update the shell.nix to use mkShell
, I get the stack trace show below:
$ cat shell.nix
{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
packages = [
(pkgs.python38Packages.buildPythonPackage rec {
name = "my-project";
src = ./my_project;
propagatedBuildInputs = with pkgs.python38Packages; [ pycryptodome setuptools ];
})
];
}
$ nix-shell shell.nix
# some healthy build output then:
Executing setuptoolsBuildPhase
Traceback (most recent call last):
File "nix_run_setup", line 3, in <module>
import setuptools
File "/nix/store/cflil6pns2v38j68ifgzax6aaz2k82qr-python3.8-setuptools-65.3.0/lib/python3.8/site-packages/setuptools/__init__.py", line 16, in <module>
import setuptools.version
File "/nix/store/cflil6pns2v38j68ifgzax6aaz2k82qr-python3.8-setuptools-65.3.0/lib/python3.8/site-packages/setuptools/version.py", line 1, in <module>
import pkg_resources
File "/nix/store/cflil6pns2v38j68ifgzax6aaz2k82qr-python3.8-setuptools-65.3.0/lib/python3.8/site-packages/pkg_resources/__init__.py", line 969, in <module>
class Environment:
File "/nix/store/cflil6pns2v38j68ifgzax6aaz2k82qr-python3.8-setuptools-65.3.0/lib/python3.8/site-packages/pkg_resources/__init__.py", line 973, in Environment
self, search_path=None, platform=get_supported_platform(),
File "/nix/store/cflil6pns2v38j68ifgzax6aaz2k82qr-python3.8-setuptools-65.3.0/lib/python3.8/site-packages/pkg_resources/__init__.py", line 191, in get_supported_platform
plat = 'macosx-%s-%s' % ('.'.join(_macos_vers()[:2]), m.group(3))
File "/nix/store/cflil6pns2v38j68ifgzax6aaz2k82qr-python3.8-setuptools-65.3.0/lib/python3.8/site-packages/pkg_resources/__init__.py", line 366, in _macos_vers
version = platform.mac_ver()[0]
AttributeError: module 'platform' has no attribute 'mac_ver'
error: builder for '/nix/store/wvi05r8alvdqqki0skyicx67kxif35vx-python3.8-my-project.drv' failed with exit code 1;
last 10 log lines:
> import pkg_resources
> File "/nix/store/cflil6pns2v38j68ifgzax6aaz2k82qr-python3.8-setuptools-65.3.0/lib/python3.8/site-packages/pkg_resources/__init__.py", line 969, in <module>
> class Environment:
> File "/nix/store/cflil6pns2v38j68ifgzax6aaz2k82qr-python3.8-setuptools-65.3.0/lib/python3.8/site-packages/pkg_resources/__init__.py", line 973, in Environment
> self, search_path=None, platform=get_supported_platform(),
> File "/nix/store/cflil6pns2v38j68ifgzax6aaz2k82qr-python3.8-setuptools-65.3.0/lib/python3.8/site-packages/pkg_resources/__init__.py", line 191, in get_supported_platform
> plat = 'macosx-%s-%s' % ('.'.join(_macos_vers()[:2]), m.group(3))
> File "/nix/store/cflil6pns2v38j68ifgzax6aaz2k82qr-python3.8-setuptools-65.3.0/lib/python3.8/site-packages/pkg_resources/__init__.py", line 366, in _macos_vers
> version = platform.mac_ver()[0]
> AttributeError: module 'platform' has no attribute 'mac_ver'
For full logs, run 'nix log /nix/store/wvi05r8alvdqqki0skyicx67kxif35vx-python3.8-my-project.drv'.
error: Recipe `shell` failed on line 3 with exit code 1
I can update the python package to be a proper derivation and it will build but it will not hot-reload the executable when the source changes, so is not useful for quick tweak/checks while developing:
$ cat shell.nix
{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
packages = [
(pkgs.python38Packages.buildPythonPackage rec {
pname = "my-project";
version = "0.0.1";
format = "setuptools";
src = ./.;
propagatedBuildInputs = with pkgs.python38Packages; [ pycryptodome setuptools ];
doCheck = false;
pythonRelaxDeps = true;
})
];
}
$ nix-shell shell.nix
# lots of healthy build output including zero errors
[nix-shell] $ my-package
hello
[nix-shell] $ vim file.py # update the string printed
[nix-shell] $ my-package
hello # update not reflected :(
[nix-shell]$ which my-project
/nix/store/abc123-python3.8-my-project-0.0.1/bin/my-project
A few questions:
- what exactly is causing the first example to expose an executable from a private tmp dir?
- how can I expose a hot-reloadable executable while still using
mkShell
? - how could I tweak the first example to fix the stack trace while preserving the nice tweak/check cycle it enables?
- Is there any other guidance you could share? I’d appreciate relevant links to docs or source code because I’m confused by what’s going on here.
Thank you in advance!