-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Python bindings: add Value
type
#17
Open
roberth
wants to merge
39
commits into
tweag:python-bindings
Choose a base branch
from
roberth:python-bindings
base: python-bindings
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
39 commits
Select commit
Hold shift + click to select a range
2c1d537
ci: Always run with sandbox, even on Darwin
infinisil ae07006
python: Initialise bindings from Pythonix
infinisil 80e5b4d
python: Fixes for Nix changes
infinisil e3020bf
python: Integrate incremental and CI build
infinisil 7751140
python: Fix for IFD
infinisil afa4916
python: Format using clang-format
infinisil 26cb4f0
python: Rename pythonnix namespace to nix::python
infinisil 36a74d1
python: Add exampleEnv to try out the bindings
infinisil e4df267
python: Install the bindings in hopefully the correct location
infinisil 402a16d
WIP: Start writing documentation and example
infinisil 47bd4a4
Remove .cache from .gitignore
infinisil 3fab794
Always include config.h
infinisil 2fce5fd
Release the GIL for Nix evaluation
infinisil e11273f
Don't release GIL lock because it would segfault
infinisil a10ae63
Allow getting exact throw error messages
infinisil e460074
Readd .cache to .gitignore
infinisil 8a9d1fe
Add ThrownNixError subclass
infinisil 6be7198
python: Add clang-tools to dev env
infinisil 813cbc4
python: Properly release and reacquire GIL
infinisil fe03f3d
python: Detect stack overflow from recursive data structure
infinisil 7e46ddb
Insert some TODO's
infinisil b69d933
python: Handle null's in expressions correctly
infinisil af8d911
python: Fix boolean to nix conversion
infinisil bb06d43
python: Add test for Null conversion
infinisil cd1442a
python: Use assertRaises for tests
infinisil 1e76e28
python: We don't need to install the bindings into a subdirectly
infinisil 724d1d8
Remove python from manual build again
infinisil 56a0ab0
Very simple Nix source filtering
infinisil 75696bd
Fix the buildPythonApplication example
infinisil b9dc4e4
Fix some unset variable problems with vars-and-functions.sh
infinisil 090ee61
assertEquals -> assertEqual
infinisil 22432b3
Alternate approach to calling init.sh
infinisil 1df5ea8
Don't depend on all files for the python bindings
infinisil 754e342
Make buildPythonApplication test work
infinisil 29d3a70
Fix dev shell
infinisil e412e35
Add debugging capability to dev shell
infinisil c87a1b4
Convert from eval to callExprString API
infinisil 7cc4ac2
python: Use global EvalState for now
roberth 6e7eff4
python: Add nix.evalExprString() and value.toPythonStrict()
roberth File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
build | ||
# For clang-tools | ||
.cache |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
# This Makefile is only used for development of the Python bindings, it is not | ||
# used in the Nix build. | ||
# The reason this exists is to make it easier to develop the Python bindings in | ||
# tandem with the main Nix. | ||
# The default `make` (defaults to `make build`) calls the main Nix projects | ||
# `make install` before calling the Python bindings' `meson compile`, therefore | ||
# ensuring that the needed Nix dynamic libraries are up-to-date | ||
|
||
builddir=build | ||
|
||
.PHONY: build | ||
build: nix-install setup-done | ||
meson compile -C $(builddir) | ||
|
||
.PHONY: test | ||
test: nix-install setup-done | ||
meson test -C $(builddir) -v | ||
|
||
.PHONY: clean | ||
clean: | ||
rm -rf $(builddir) | ||
|
||
# We include the main Nix projects Makefile.config file to know the $(libdir) | ||
# variable, which is where Nix is installed in, which we can then use to setup | ||
# the meson build | ||
include ../Makefile.config | ||
|
||
# We need the file to exist though | ||
../Makefile.config: | ||
@# Throw a good error message in case ./configure hasn't been run yet | ||
@[[ -e ../config.status ]] || ( echo "The main Nix project needs to be configured first, see https://nixos.org/manual/nix/stable/contributing/hacking.html" && exit 1 ) | ||
@# If ./configure is done, we can create the file ourselves | ||
$(MAKE) -C .. Makefile.config | ||
|
||
.PHONY: setup | ||
setup: nix-install | ||
@# Make meson be able to find the locally-installed Nix | ||
PKG_CONFIG_PATH=$(libdir)/pkgconfig:$$PKG_CONFIG_PATH meson setup $(builddir) | ||
|
||
.PHONY: setup-done | ||
setup-done: | ||
@# A better error message in case the build directory doesn't exist yet | ||
@[[ -e $(builddir) ]] || ( echo "Run 'make setup' once to configure the project build directory" && exit 1 ) | ||
|
||
.PHONY: nix-install | ||
nix-install: | ||
@# The python bindings don't technically need an _entire_ Nix installation, | ||
@# but it seems non-trivial to pick out only exactly the files it actually needs | ||
$(MAKE) -C .. install |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
# Python Bindings | ||
|
||
This directory contains experimental Python bindings to a small subset of Nix's functionality. These bindings are very fast since they link to the necessary dynamic libraries directly, without having to call the Nix CLI for every operation. | ||
|
||
Originally these bindings were created by [@Mic92](https://github.com/Mic92) and called [Pythonix](https://github.com/Mic92/pythonix). However, after Nix changed the internal library interface multiple times, therefore requiring Pythonix to be updated, it wasn't worth the third-party time investment anymore and the Pythonix repository was archived. At that point it only worked for Nix versions below 2.4. By having these bindings upstream, they can be updated right along the C++ code that defines the library interface. | ||
|
||
## Documentation | ||
|
||
See [index.md](./doc/index.md), which is also rendered in the HTML manual. | ||
|
||
To hack on these bindings, see [hacking.md](./doc/hacking.md), also rendered in the HTML manual. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This seems empty though. Let's not reference things that don't exist, or create those things first. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
{ | ||
self, | ||
system, | ||
lib, | ||
python, | ||
boost, | ||
gdb, | ||
clang-tools, | ||
pkg-config, | ||
ninja, | ||
meson, | ||
nix, | ||
mkShell, | ||
enableDebugging, | ||
recurseIntoAttrs, | ||
isShell ? false, | ||
}: | ||
let | ||
_python = python; | ||
in | ||
let | ||
python = _python.override { self = enableDebugging _python; }; | ||
# Extracts tests/init.sh | ||
testScripts = nix.overrideAttrs (old: { | ||
name = "nix-test-scripts-${old.version}"; | ||
outputs = [ "out" ]; | ||
separateDebugInfo = false; | ||
buildPhase = '' | ||
make tests/{init.sh,common/vars-and-functions.sh} | ||
''; | ||
script = '' | ||
pushd ${placeholder "out"}/libexec >/dev/null | ||
source init.sh | ||
popd >/dev/null | ||
''; | ||
passAsFile = [ "script" ]; | ||
installPhase = '' | ||
rm -rf "$out" | ||
mkdir -p "$out"/{libexec/common,share/bash} | ||
cp tests/init.sh "$out"/libexec | ||
cp tests/common/vars-and-functions.sh "$out"/libexec/common | ||
|
||
cp "$scriptPath" "$out"/share/bash/nix-test.sh | ||
''; | ||
dontFixup = true; | ||
}); | ||
in | ||
python.pkgs.buildPythonPackage { | ||
name = "nix"; | ||
format = "other"; | ||
|
||
src = builtins.path { | ||
path = ./.; | ||
filter = path: type: | ||
path == toString ./meson.build | ||
|| path == toString ./tests.py | ||
|| path == toString ./test.sh | ||
|| lib.hasPrefix (toString ./src) path; | ||
}; | ||
|
||
|
||
strictDeps = true; | ||
|
||
nativeBuildInputs = [ | ||
ninja | ||
pkg-config | ||
(meson.override { python3 = python; }) | ||
] ++ lib.optional (!isShell) nix; | ||
|
||
buildInputs = nix.propagatedBuildInputs ++ [ | ||
boost | ||
] ++ lib.optional (!isShell) nix; | ||
|
||
mesonBuildType = "release"; | ||
|
||
doInstallCheck = true; | ||
TEST_SCRIPTS = testScripts; | ||
installCheckPhase = "meson test -v"; | ||
|
||
passthru = { | ||
exampleEnv = python.withPackages (p: [ nix.python-bindings ]); | ||
tests = { | ||
example-buildPythonApplication = import ./examples/buildPythonApplication { | ||
inherit nix system testScripts; | ||
}; | ||
}; | ||
shell = mkShell { | ||
packages = [ | ||
clang-tools | ||
gdb | ||
]; | ||
TEST_SCRIPTS = testScripts; | ||
inputsFrom = [ | ||
(nix.python-bindings.override { isShell = true; }) | ||
]; | ||
}; | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Experimental Python Bindings API | ||
|
||
This is the API! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Python Bindings Hacking | ||
|
||
This is how to hack on the bindings |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
@@ -0,0 +1,32 @@ | ||||
# Experimental Python Bindings | ||||
|
||||
Nix comes with minimal experimental Python bindings that link directly to the necessary dynamic libraries, making them very fast. | ||||
|
||||
## Trying it out | ||||
|
||||
The easiest way to try out the bindings is using the provided example environment: | ||||
|
||||
``` | ||||
$ nix run github:NixOS/nix#nix.python-bindings.exampleEnv | ||||
Python 3.10.8 (main, Oct 11 2022, 11:35:05) [GCC 11.3.0] on linux | ||||
Type "help", "copyright", "credits" or "license" for more information. | ||||
>>> import nix | ||||
>>> nix.eval('"Hello ${name}!"', vars=dict(name="Python")) | ||||
'Hello Python!' | ||||
``` | ||||
|
||||
For the available functions and their interfaces, see the API section. | ||||
|
||||
## Build integration | ||||
|
||||
In the future these Python bindings will be available from Nixpkgs as `python3Packages.nix`. | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Let's not talk about the future here. |
||||
|
||||
Until then the Python bindings are only available from the Nix derivation via the `python-bindings` [passthru attribute](https://nixos.org/manual/nixpkgs/stable/#var-stdenv-passthru). Without any modifications, this derivation is built for the default Python 3 version from the Nixpkgs version used to build Nix. This Python version might not match the Python version of the project you're trying to use them in. Therefore it is recommended to override the bindings with the correct Python version using | ||||
|
||||
``` | ||||
nix.python-bindings.override { | ||||
python = myPythonVersion; | ||||
} | ||||
``` | ||||
|
||||
For complete examples, see https://github.com/NixOS/nix/tree/master/python/examples |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
{ | ||
system ? builtins.currentSystem, | ||
pkgs ? import (fetchTarball { | ||
url = "https://github.com/NixOS/nixpkgs/archive/545c7a31e5dedea4a6d372712a18e00ce097d462.tar.gz"; | ||
sha256 = "1dbsi2ccq8x0hyl8n0hisigj8q19amvj9irzfbgy4b3szb6x2y6l"; | ||
}) { | ||
config = {}; | ||
overlays = []; | ||
inherit system; | ||
}, | ||
nix ? (import ../../..).default, | ||
testScripts, | ||
}: | ||
let | ||
python = pkgs.python3; | ||
nixBindings = nix.python-bindings.override { inherit python; }; | ||
in python.pkgs.buildPythonApplication { | ||
pname = "hello-nix"; | ||
version = "0.1"; | ||
src = builtins.path { | ||
path = ./.; | ||
filter = path: type: | ||
pkgs.lib.hasPrefix (toString ./hello) path | ||
|| path == toString ./setup.py; | ||
}; | ||
propagatedBuildInputs = [ nixBindings ]; | ||
doInstallCheck = true; | ||
nativeCheckInputs = [ | ||
nix | ||
]; | ||
installCheckPhase = '' | ||
( | ||
source ${testScripts}/share/bash/nix-test.sh | ||
$out/bin/hello-nix | ||
) | ||
''; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
import nix | ||
|
||
def greet(): | ||
print("Evaluating 1 + 1 in Nix gives: " + str(nix.eval("1 + 1"))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
from setuptools import setup, find_packages | ||
|
||
setup( | ||
name="hello-nix", | ||
version="0.1", | ||
packages=find_packages(), | ||
entry_points={ | ||
'console_scripts': [ | ||
'hello-nix = hello:greet', | ||
], | ||
}, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
#pragma once | ||
|
||
#define PY_SSIZE_T_CLEAN | ||
#include <Python.h> | ||
|
||
#include "eval.hh" | ||
|
||
namespace nix::python { | ||
|
||
typedef struct { | ||
PyObject_HEAD | ||
// TODO: (performance) flatten this pointer, while making sure | ||
// initialization is correct, | ||
// or allocate these python objects with boehmgc | ||
nix::RootValue *value; | ||
|
||
inline nix::RootValue & operator *() { | ||
return *value; | ||
} | ||
} ValuePyObject; | ||
|
||
extern PyTypeObject ValuePyType; | ||
|
||
ValuePyObject *allocValuePyObject(nix::EvalState * state); | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
project('python-nix', 'cpp', | ||
version : '0.1.8', | ||
license : 'LGPL-2.0', | ||
) | ||
|
||
python_mod = import('python') | ||
py_installation = python_mod.find_installation() | ||
|
||
nix_expr_dep = dependency('nix-expr', required: true) | ||
nix_main_dep = dependency('nix-main', required: true) | ||
|
||
subdir('src') | ||
|
||
fs = import('fs') | ||
|
||
env = environment() | ||
env.prepend('PYTHONPATH', fs.parent(nix_bindings.full_path())) | ||
test('python test', find_program('bash'), args : files('test.sh'), env : env) |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I may be missing something but I don't see where it's rendered in the manual.