On aarch64-linux (an RPi3) with hardware.bluetooth
enabled and working bluetooth, I tried to build a python with bluetooth support (a dependency requires socket.AF_BLUETOOTH
, and I found the issue below).
Based on cpython/default.nix
, it seems like this should work:
$ nix shell "$(
nix eval --raw --apply 'py: py.override { bluezSupport = true; }' github:nixos/nixpkgs#python3
)" -c python -c 'import socket; print(socket.AF_BLUETOOTH)'
AttributeError: module 'socket' has no attribute 'AF_BLUETOOTH'
But obviously it doesn’t. python3Full
seems to be basically defined as the same override I’m using above, but does work (I realize the override is a noop here):
$ nix shell "$(
nix eval --raw --apply 'py: py.override {}' github:nixos/nixpkgs#python3Full
)" -c python -c 'import socket; print(socket.AF_BLUETOOTH)'
AddressFamily.AF_BLUETOOTH
Why is that? Shouldn’t python3.override { bluezSupport = true; }
be basically the same thing as python3Full
(at least with regards to bluetooth support)?
EDIT: See below – it only seems to have the broken behavior when I use .withPackages
.
Related:
1 Like
Hmmm, now getting a there is no substituter that can build it
error with my nix shell $(nix eval)
business.
I think this should do the same thing:
$ nix-shell \
-I nixpkgs=flake:github:nixos/nixpkgs \
-p '(import <nixpkgs> {}).python3Full.override { }' \
--command 'python -c "import socket; print(socket.AF_BLUETOOTH)"'
31
$ nix-shell \
-I nixpkgs=flake:github:nixos/nixpkgs \
-p '(import <nixpkgs> {}).python3.override { bluezSupport = true; }' \
--command 'python -c "import socket; print(socket.AF_BLUETOOTH)"'
31
Hmm, so now it seems to be working (with nix-shell).
Huh, no idea why this wasn’t working before, I’m sure user error on my end.
{
description = "A very basic flake";
inputs.nixpkgs.url = "github:nixos/nixpkgs/2459917e66c70c80e16c315d62b3533c9239a2fa";
outputs = {
self,
nixpkgs,
}: let
system = "aarch64-linux";
pkgs = import nixpkgs {inherit system;};
in {
packages.${system} = {
py-override = pkgs.python3.override {bluezSupport = true;};
py-full = pkgs.python3Full;
};
apps.${system} = let
makeApp = package: let
script = pkgs.writeShellScriptBin "run" ''
echo ${package}
${self.packages.${system}.${package}}/bin/python -c '
import socket
print(socket.AF_BLUETOOTH)
'
'';
in {
type = "app";
program = "${script}/bin/run";
};
in {
py-override = makeApp "py-override";
py-full = makeApp "py-full";
};
};
}
$ nix run .#py-override; nix run .#py-full
py-override
31
py-full
31
Ah, figured it out – the withPackages
seems to break things!
Why is that?
{
description = "A very basic flake";
inputs.nixpkgs.url = "github:nixos/nixpkgs/2459917e66c70c80e16c315d62b3533c9239a2fa";
outputs = {
self,
nixpkgs,
}: let
system = "aarch64-linux";
pkgs = import nixpkgs {inherit system;};
in {
packages.${system} = {
py-override = (pkgs.python3.override {bluezSupport = true;}).withPackages (_: []);
py-full = pkgs.python3Full.withPackages (_: []);
};
apps.${system} = let
makeApp = package: let
script = pkgs.writeShellScriptBin "run" ''
echo ${package}
${self.packages.${system}.${package}}/bin/python -c '
import socket
print(socket.AF_BLUETOOTH)
'
'';
in {
type = "app";
program = "${script}/bin/run";
};
in {
py-override = makeApp "py-override";
py-full = makeApp "py-full";
};
};
}
$ nix run .#py-override; nix run .#py-full
py-override
Traceback (most recent call last):
File "<string>", line 3, in <module>
AttributeError: module 'socket' has no attribute 'AF_BLUETOOTH'
py-full
31
Indeed this was the issue: Python: withPackages and overrides does not result in correct `passthru` · Issue #64334 · NixOS/nixpkgs · GitHub
Adding self
to the override seems to be the key. Because there needs to be a value to assign self = ...
to, adding a let
seems to do the trick:
python = pkgs.python3.override {
bluezSupport = true;
self = python;
};
in python.withPackages (ps:
with ps; [ ... ]
);