Home Explore Blog Models CI



nixpkgs

25th chunk of `doc/languages-frameworks/python.section.md`
b9e5868438759f5c56a1ccd5f71e39769b4571797c4f05240000000100000fd2
### Are Python interpreters built deterministically? {#deterministic-builds}

The Python interpreters are now built deterministically. Minor modifications had
to be made to the interpreters in order to generate deterministic bytecode. This
has security implications and is relevant for those using Python in a
`nix-shell`.

When the environment variable `DETERMINISTIC_BUILD` is set, all bytecode will
have timestamp 1. The [`buildPythonPackage`](#buildpythonpackage-function) function sets `DETERMINISTIC_BUILD=1`
and [PYTHONHASHSEED=0](https://docs.python.org/3.13/using/cmdline.html#envvar-PYTHONHASHSEED).
Both are also exported in `nix-shell`.

### How to provide automatic tests to Python packages? {#automatic-tests}

It is recommended to test packages as part of the build process.
Source distributions (`sdist`) often include test files, but not always.

The best practice today is to pass a test hook (e.g. pytestCheckHook, unittestCheckHook) into nativeCheckInputs.
This will reconfigure the checkPhase to make use of that particular test framework.
Occasionally packages don't make use of a common test framework, which may then require a custom checkPhase.

#### Common issues {#common-issues}

* Tests that attempt to access `$HOME` can be fixed by using `writableTmpDirAsHomeHook` in
  `nativeCheckInputs`, which sets up a writable temporary directory as the home directory. Alternatively,
  you can achieve the same effect manually (e.g. in `preCheck`) with: `export HOME=$(mktemp -d)`.
* Compiling with Cython causes tests to fail with a `ModuleNotLoadedError`.
  This can be fixed with two changes in the derivation: 1) replacing `pytest` with
  `pytestCheckHook` and 2) adding a `preCheck` containing `cd $out` to run
  tests within the built output.

## Contributing {#contributing}

### Contributing guidelines {#contributing-guidelines}

The following rules are desired to be respected:

* Python libraries are called from `python-packages.nix` and packaged with
  [`buildPythonPackage`](#buildpythonpackage-function). The expression of a library should be in
  `pkgs/development/python-modules/<name>/default.nix`.
* Python applications live outside of `python-packages.nix` and are packaged
  with [`buildPythonApplication`](#buildpythonapplication-function).
* Make sure libraries build for all Python interpreters.
  If it fails to build on some Python versions, consider disabling them by setting `disable = pythonAtLeast "3.x"` along with a comment.
* The two parameters, `pyproject` and `build-system` are set to avoid the legacy setuptools/distutils build.
* Only unversioned attributes (e.g. `pydantic`, but not `pypdantic_1`) can be included in `dependencies`,
  since due to `PYTHONPATH` limitations we can only ever support a single version for libraries
  without running into duplicate module name conflicts.
* The version restrictions of `dependencies` can be relaxed by [`pythonRelaxDepsHook`](#using-pythonrelaxdepshook).
* Make sure the tests are enabled using for example [`pytestCheckHook`](#using-pytestcheckhook) and, in the case of
  libraries, are passing for all interpreters. If certain tests fail they can be
  disabled individually. Try to avoid disabling the tests altogether. In any
  case, when you disable tests, leave a comment explaining not only _what_ the failure
  is but _why_ the test failure can be ignored for safe distribution with nixpkgs.
* `pythonImportsCheck` is set. This is still a good smoke test even if `pytestCheckHook` is set.
* `meta.platforms` takes the default value in many cases.
  It does not need to be set explicitly unless the package requires a specific platform.
* The file is formatted with `nixfmt-rfc-style`.
* Commit names of Python libraries must reflect that they are Python
  libraries (e.g. `python3Packages.numpy: 1.11 -> 1.12` rather than `numpy: 1.11 -> 1.12`).
  See also [`pkgs/README.md`](https://github.com/NixOS/nixpkgs/blob/master/pkgs/README.md#commit-conventions).
* Attribute names in `python-packages.nix` as well as `pname`s should match the

Title: Nixpkgs Python: Deterministic Builds, Testing, and Contribution Guidelines
Summary
This document covers key aspects of Python package management and contribution in Nixpkgs. It explains that Python interpreters are now built deterministically, generating bytecode with a fixed timestamp and hash seed, which has security implications. The text then details best practices for providing automatic tests for Python packages, recommending the use of test hooks like `pytestCheckHook` within `nativeCheckInputs`, and offers solutions for common testing issues such as `$HOME` access and Cython `ModuleNotLoadedError`s. Finally, it outlines comprehensive contributing guidelines for Python packages, specifying conventions for libraries vs. applications, multi-interpreter compatibility, dependency management (including the use of `pythonRelaxDepsHook`), mandatory testing with `pytestCheckHook` and `pythonImportsCheck`, formatting, and commit message conventions.