The Contributing Guidelines for Python Discord projects can be found on our website.
A Python 3.11 interpreter and make
are required. A virtual environment is also recommended. Once that is set up, install the project's dependencies with make setup
.
This also installs a git pre-commit hook so that the linter runs upon a commit.
Manual invocation is still possible with make lint
.
Use docker compose up
to start snekbox in development mode. The optional --build
argument can be passed to force the image to be rebuilt.
You must use compose v2, accessed via docker compose
(no hyphen).
The container has all development dependencies. The repository on the host is mounted within the container; changes made to local files will also affect the container.
To build a normal container that can be used in production, run make build
.
Refer to the README for how to run the container normally.
Tests are run through coverage.py using unittest. To run the tests within a development container, run make test
.
To see a coverage report, run make report
.
The report cannot be generated on Windows directly due to the difference in file separators in the paths. Instead, launch a shell in the container (see below) and use coverage report
.
A bash shell can be launched in the development container using make devsh
. This creates a new container which will get deleted once the shell session ends.
NsJail can be invoked in a more direct manner that does not require using a web server or its API. See python -m snekbox --help
. Example usage:
python -m snekbox 'print("hello world!")' --time_limit 0 --- -m timeit
With this command, NsJail uses the same configuration normally used through the web API.
pip-tools is used to compile required Python packages and all their transitive
dependencies. All files are located in the requirements
directory. The *.in
files are the input files and the *.pip
files are the compiled outputs.
To add or change a dependency, modify the appropriate *.in
file(s) and then run make upgrade
to recompile. The make command compiles the files in a certain order. When adding a new *.in
file, it should also be included in the make command. Furthermore, the new file should be constrained by the files compiled before it, and the files compiled after it should be constrained by the new file.
Updating NsJail mainly involves two steps:
- Change the version used by the
git clone
command in the Dockerfile - Use
python -m scripts.protoc
to generate new Python code from the config protobuf
Other things to look out for are breaking changes to NsJail's config format, its command-line interface, or its logging format. Additionally, dependencies may have to be adjusted in the Dockerfile to get a new version to build or run.
Python interpreters are built using pyenv via the scripts/build_python.sh
helper script. This script accepts a pyenv version specifier (pyenv install --list
) and builds the interpreter in a version-specific directory under /snekbin/python
. In the image, each minor version of a Python interpreter should have its own build stage and the resulting /snekbin/python
directory can be copied from that stage into the base
stage.
When updating a patch version (e.g. 3.11.3 to 3.11.4), edit the existing build stage in the image for the minor version (3.11); do not add a new build stage. To have access to a new version, pyenv likely needs to be updated. To do so, change the tag in the git clone
command in the image, but only for the build stage that needs access to the new version. Updating pyenv for all build stages will just cause unnecessary build cache invalidations.
To change the default interpreter used by NsJail, update the target of the /snekbin/python/default
symlink created in the base
stage.