docs/Nixpkgs/Languages-And-Frameworks/python.section/index.html

5685 lines
201 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!doctype html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="description" content="Aux Documentation">
<meta name="author" content="Nixpkgs Aux, and Lix Contributors">
<link rel="canonical" href="https://docs.auxolotl.org/Nixpkgs/Languages-And-Frameworks/python.section/">
<link rel="prev" href="../pkg-config.section/">
<link rel="next" href="../qt.section/">
<link rel="icon" href="../../../assets/aux-logo.svg">
<meta name="generator" content="mkdocs-1.6.0, mkdocs-material-9.5.29">
<title>Python - Aux Docs</title>
<link rel="stylesheet" href="../../../assets/stylesheets/main.76a95c52.min.css">
<link rel="stylesheet" href="../../../assets/stylesheets/palette.06af60db.min.css">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.bunny.net/css?family=IBM+Plex+Sans:300,300i,400,400i,700,700i%7CIBM+Plex+Mono:400,400i,700,700i&display=fallback">
<style>:root{--md-text-font:"IBM Plex Sans";--md-code-font:"IBM Plex Mono"}</style>
<script>__md_scope=new URL("../../..",location),__md_hash=e=>[...e].reduce((e,_)=>(e<<5)-e+_.charCodeAt(0),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
<meta property="og:type" content="website" >
<meta property="og:title" content="Python {#python} - Aux Docs" >
<meta property="og:description" content="Aux Documentation" >
<meta property="og:image" content="https://docs.auxolotl.org/assets/images/social/Nixpkgs/Languages-And-Frameworks/python.section.png" >
<meta property="og:image:type" content="image/png" >
<meta property="og:image:width" content="1200" >
<meta property="og:image:height" content="630" >
<meta property="og:url" content="https://docs.auxolotl.org/Nixpkgs/Languages-And-Frameworks/python.section/" >
<meta name="twitter:card" content="summary_large_image" >
<meta name="twitter:title" content="Python {#python} - Aux Docs" >
<meta name="twitter:description" content="Aux Documentation" >
<meta name="twitter:image" content="https://docs.auxolotl.org/assets/images/social/Nixpkgs/Languages-And-Frameworks/python.section.png" >
</head>
<body dir="ltr" data-md-color-scheme="default" data-md-color-primary="indigo" data-md-color-accent="blue">
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" for="__drawer"></label>
<div data-md-component="skip">
<a href="#python" class="md-skip">
Skip to content
</a>
</div>
<div data-md-component="announce">
</div>
<header class="md-header" data-md-component="header">
<nav class="md-header__inner md-grid" aria-label="Header">
<a href="../../.." title="Aux Docs" class="md-header__button md-logo" aria-label="Aux Docs" data-md-component="logo">
<img src="../../../assets/aux-logo.svg" alt="logo">
</a>
<label class="md-header__button md-icon" for="__drawer">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3V6m0 5h18v2H3v-2m0 5h18v2H3v-2Z"/></svg>
</label>
<div class="md-header__title" data-md-component="header-title">
<div class="md-header__ellipsis">
<div class="md-header__topic">
<span class="md-ellipsis">
Aux Docs
</span>
</div>
<div class="md-header__topic" data-md-component="header-topic">
<span class="md-ellipsis">
Python
</span>
</div>
</div>
</div>
<form class="md-header__option" data-md-component="palette">
<input class="md-option" data-md-color-media="(prefers-color-scheme: light)" data-md-color-scheme="default" data-md-color-primary="indigo" data-md-color-accent="blue" aria-label="Dark Mode" type="radio" name="__palette" id="__palette_0">
<label class="md-header__button md-icon" title="Dark Mode" for="__palette_1" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="m17.75 4.09-2.53 1.94.91 3.06-2.63-1.81-2.63 1.81.91-3.06-2.53-1.94L12.44 4l1.06-3 1.06 3 3.19.09m3.5 6.91-1.64 1.25.59 1.98-1.7-1.17-1.7 1.17.59-1.98L15.75 11l2.06-.05L18.5 9l.69 1.95 2.06.05m-2.28 4.95c.83-.08 1.72 1.1 1.19 1.85-.32.45-.66.87-1.08 1.27C15.17 23 8.84 23 4.94 19.07c-3.91-3.9-3.91-10.24 0-14.14.4-.4.82-.76 1.27-1.08.75-.53 1.93.36 1.85 1.19-.27 2.86.69 5.83 2.89 8.02a9.96 9.96 0 0 0 8.02 2.89m-1.64 2.02a12.08 12.08 0 0 1-7.8-3.47c-2.17-2.19-3.33-5-3.49-7.82-2.81 3.14-2.7 7.96.31 10.98 3.02 3.01 7.84 3.12 10.98.31Z"/></svg>
</label>
<input class="md-option" data-md-color-media="(prefers-color-scheme: dark)" data-md-color-scheme="slate" data-md-color-primary="indigo" data-md-color-accent="blue" aria-label="Light Mode" type="radio" name="__palette" id="__palette_1">
<label class="md-header__button md-icon" title="Light Mode" for="__palette_0" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 7a5 5 0 0 1 5 5 5 5 0 0 1-5 5 5 5 0 0 1-5-5 5 5 0 0 1 5-5m0 2a3 3 0 0 0-3 3 3 3 0 0 0 3 3 3 3 0 0 0 3-3 3 3 0 0 0-3-3m0-7 2.39 3.42C13.65 5.15 12.84 5 12 5c-.84 0-1.65.15-2.39.42L12 2M3.34 7l4.16-.35A7.2 7.2 0 0 0 5.94 8.5c-.44.74-.69 1.5-.83 2.29L3.34 7m.02 10 1.76-3.77a7.131 7.131 0 0 0 2.38 4.14L3.36 17M20.65 7l-1.77 3.79a7.023 7.023 0 0 0-2.38-4.15l4.15.36m-.01 10-4.14.36c.59-.51 1.12-1.14 1.54-1.86.42-.73.69-1.5.83-2.29L20.64 17M12 22l-2.41-3.44c.74.27 1.55.44 2.41.44.82 0 1.63-.17 2.37-.44L12 22Z"/></svg>
</label>
</form>
<script>var media,input,key,value,palette=__md_get("__palette");if(palette&&palette.color){"(prefers-color-scheme)"===palette.color.media&&(media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']"),palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent"));for([key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script>
<label class="md-header__button md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.516 6.516 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5Z"/></svg>
</label>
<div class="md-search" data-md-component="search" role="dialog">
<label class="md-search__overlay" for="__search"></label>
<div class="md-search__inner" role="search">
<form class="md-search__form" name="search">
<input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required>
<label class="md-search__icon md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.516 6.516 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5Z"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11h12Z"/></svg>
</label>
<nav class="md-search__options" aria-label="Search">
<button type="reset" class="md-search__icon md-icon" title="Clear" aria-label="Clear" tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41Z"/></svg>
</button>
</nav>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" tabindex="0" data-md-scrollfix>
<div class="md-search-result" data-md-component="search-result">
<div class="md-search-result__meta">
Initializing search
</div>
<ol class="md-search-result__list" role="presentation"></ol>
</div>
</div>
</div>
</div>
</div>
<div class="md-header__source">
<a href="https://git.auxolotl.org/auxolotl/docs" title="Go to repository" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M16.777 0a2.9 2.9 0 1 1-2.529 4.322H12.91a4.266 4.266 0 0 0-4.265 4.195v2.118a7.076 7.076 0 0 1 4.147-1.42l.118-.002h1.338a2.9 2.9 0 0 1 5.43 1.422 2.9 2.9 0 0 1-5.43 1.422H12.91a4.266 4.266 0 0 0-4.265 4.195v2.319A2.9 2.9 0 0 1 7.222 24 2.9 2.9 0 0 1 5.8 18.57V8.589a7.109 7.109 0 0 1 6.991-7.108l.118-.001h1.338A2.9 2.9 0 0 1 16.778 0ZM7.223 19.905a1.194 1.194 0 1 0 0 2.389 1.194 1.194 0 0 0 0-2.389Zm9.554-10.464a1.194 1.194 0 1 0 0 2.389 1.194 1.194 0 0 0 0-2.39Zm0-7.735a1.194 1.194 0 1 0 0 2.389 1.194 1.194 0 0 0 0-2.389Z"/></svg>
</div>
<div class="md-source__repository">
auxolotl/docs
</div>
</a>
</div>
</nav>
</header>
<div class="md-container" data-md-component="container">
<nav class="md-tabs" aria-label="Tabs" data-md-component="tabs">
<div class="md-grid">
<ul class="md-tabs__list">
<li class="md-tabs__item">
<a href="../../.." class="md-tabs__link">
Aux Documentation Hub
</a>
</li>
<li class="md-tabs__item">
<a href="../../../TODO/" class="md-tabs__link">
TODO
</a>
</li>
<li class="md-tabs__item">
<a href="../../../Aux/" class="md-tabs__link">
Aux
</a>
</li>
<li class="md-tabs__item">
<a href="../../../Lix/" class="md-tabs__link">
Lix
</a>
</li>
<li class="md-tabs__item">
<a href="../../../NixOS/appstream/" class="md-tabs__link">
NixOS
</a>
</li>
<li class="md-tabs__item md-tabs__item--active">
<a href="../../" class="md-tabs__link">
Nixpkgs
</a>
</li>
</ul>
</div>
</nav>
<main class="md-main" data-md-component="main">
<div class="md-main__inner md-grid">
<div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary md-nav--lifted" aria-label="Navigation" data-md-level="0">
<label class="md-nav__title" for="__drawer">
<a href="../../.." title="Aux Docs" class="md-nav__button md-logo" aria-label="Aux Docs" data-md-component="logo">
<img src="../../../assets/aux-logo.svg" alt="logo">
</a>
Aux Docs
</label>
<div class="md-nav__source">
<a href="https://git.auxolotl.org/auxolotl/docs" title="Go to repository" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M16.777 0a2.9 2.9 0 1 1-2.529 4.322H12.91a4.266 4.266 0 0 0-4.265 4.195v2.118a7.076 7.076 0 0 1 4.147-1.42l.118-.002h1.338a2.9 2.9 0 0 1 5.43 1.422 2.9 2.9 0 0 1-5.43 1.422H12.91a4.266 4.266 0 0 0-4.265 4.195v2.319A2.9 2.9 0 0 1 7.222 24 2.9 2.9 0 0 1 5.8 18.57V8.589a7.109 7.109 0 0 1 6.991-7.108l.118-.001h1.338A2.9 2.9 0 0 1 16.778 0ZM7.223 19.905a1.194 1.194 0 1 0 0 2.389 1.194 1.194 0 0 0 0-2.389Zm9.554-10.464a1.194 1.194 0 1 0 0 2.389 1.194 1.194 0 0 0 0-2.39Zm0-7.735a1.194 1.194 0 1 0 0 2.389 1.194 1.194 0 0 0 0-2.389Z"/></svg>
</div>
<div class="md-source__repository">
auxolotl/docs
</div>
</a>
</div>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../.." class="md-nav__link">
<span class="md-ellipsis">
Aux Documentation Hub
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../../TODO/" class="md-nav__link">
<span class="md-ellipsis">
TODO
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../../../Aux/" class="md-nav__link">
<span class="md-ellipsis">
Aux
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../../../Lix/" class="md-nav__link">
<span class="md-ellipsis">
Lix
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../../../NixOS/appstream/" class="md-nav__link">
<span class="md-ellipsis">
NixOS
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
<li class="md-nav__item md-nav__item--active md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_6" checked>
<div class="md-nav__link md-nav__container">
<a href="../../" class="md-nav__link ">
<span class="md-ellipsis">
Nixpkgs
</span>
</a>
<label class="md-nav__link " for="__nav_6" id="__nav_6_label" tabindex="">
<span class="md-nav__icon md-icon"></span>
</label>
</div>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_6_label" aria-expanded="true">
<label class="md-nav__title" for="__nav_6">
<span class="md-nav__icon md-icon"></span>
Nixpkgs
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../options/" class="md-nav__link">
<span class="md-ellipsis">
Options
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../../Build-Helpers/" class="md-nav__link">
<span class="md-ellipsis">
Build Helpers
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../../Development/" class="md-nav__link">
<span class="md-ellipsis">
Development
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../../Functions/" class="md-nav__link">
<span class="md-ellipsis">
Functions
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../../Hooks/" class="md-nav__link">
<span class="md-ellipsis">
Hooks
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
<li class="md-nav__item md-nav__item--active md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_6_7" checked>
<div class="md-nav__link md-nav__container">
<a href="../" class="md-nav__link ">
<span class="md-ellipsis">
Languages And Frameworks
</span>
</a>
<label class="md-nav__link " for="__nav_6_7" id="__nav_6_7_label" tabindex="0">
<span class="md-nav__icon md-icon"></span>
</label>
</div>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_6_7_label" aria-expanded="true">
<label class="md-nav__title" for="__nav_6_7">
<span class="md-nav__icon md-icon"></span>
Languages And Frameworks
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../agda.section/" class="md-nav__link">
<span class="md-ellipsis">
Agda
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../android.section/" class="md-nav__link">
<span class="md-ellipsis">
Android
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../beam.section/" class="md-nav__link">
<span class="md-ellipsis">
BEAM Languages (Erlang, Elixir &amp; LFE)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../bower.section/" class="md-nav__link">
<span class="md-ellipsis">
Bower
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../chicken.section/" class="md-nav__link">
<span class="md-ellipsis">
CHICKEN
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../coq.section/" class="md-nav__link">
<span class="md-ellipsis">
Coq and coq packages
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../crystal.section/" class="md-nav__link">
<span class="md-ellipsis">
Crystal
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../cuda.section/" class="md-nav__link">
<span class="md-ellipsis">
CUDA
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../cuelang.section/" class="md-nav__link">
<span class="md-ellipsis">
Cue (Cuelang)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../dart.section/" class="md-nav__link">
<span class="md-ellipsis">
Dart
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../dhall.section/" class="md-nav__link">
<span class="md-ellipsis">
Dhall
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../dlang.section/" class="md-nav__link">
<span class="md-ellipsis">
D (Dlang)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../dotnet.section/" class="md-nav__link">
<span class="md-ellipsis">
Dotnet
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../emscripten.section/" class="md-nav__link">
<span class="md-ellipsis">
Emscripten
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../gnome.section/" class="md-nav__link">
<span class="md-ellipsis">
GNOME
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../go.section/" class="md-nav__link">
<span class="md-ellipsis">
Go
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../gradle.section/" class="md-nav__link">
<span class="md-ellipsis">
Gradle
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../hare.section/" class="md-nav__link">
<span class="md-ellipsis">
Hare
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../haskell.section/" class="md-nav__link">
<span class="md-ellipsis">
Haskell
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../hy.section/" class="md-nav__link">
<span class="md-ellipsis">
Hy
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../idris.section/" class="md-nav__link">
<span class="md-ellipsis">
Idris
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../idris2.section/" class="md-nav__link">
<span class="md-ellipsis">
Idris2
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../ios.section/" class="md-nav__link">
<span class="md-ellipsis">
iOS
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../java.section/" class="md-nav__link">
<span class="md-ellipsis">
Java
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../javascript.section/" class="md-nav__link">
<span class="md-ellipsis">
Javascript
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../julia.section/" class="md-nav__link">
<span class="md-ellipsis">
Julia
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../lisp.section/" class="md-nav__link">
<span class="md-ellipsis">
lisp-modules
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../lua.section/" class="md-nav__link">
<span class="md-ellipsis">
Lua
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../maven.section/" class="md-nav__link">
<span class="md-ellipsis">
Maven
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../nim.section/" class="md-nav__link">
<span class="md-ellipsis">
Nim
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../ocaml.section/" class="md-nav__link">
<span class="md-ellipsis">
OCaml
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../octave.section/" class="md-nav__link">
<span class="md-ellipsis">
Octave
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../perl.section/" class="md-nav__link">
<span class="md-ellipsis">
Perl
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../php.section/" class="md-nav__link">
<span class="md-ellipsis">
PHP
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../pkg-config.section/" class="md-nav__link">
<span class="md-ellipsis">
pkg-config
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--active">
<input class="md-nav__toggle md-toggle" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc">
<span class="md-ellipsis">
Python
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<a href="./" class="md-nav__link md-nav__link--active">
<span class="md-ellipsis">
Python
</span>
</a>
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
Table of contents
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#reference" class="md-nav__link">
<span class="md-ellipsis">
Reference
</span>
</a>
<nav class="md-nav" aria-label="Reference">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#interpreters" class="md-nav__link">
<span class="md-ellipsis">
Interpreters
</span>
</a>
<nav class="md-nav" aria-label="Interpreters">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#missing-tkinter-module-standard-library" class="md-nav__link">
<span class="md-ellipsis">
Missing tkinter module standard library
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#attributes-on-interpreters-packages" class="md-nav__link">
<span class="md-ellipsis">
Attributes on interpreters packages
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#building-packages-and-applications" class="md-nav__link">
<span class="md-ellipsis">
Building packages and applications
</span>
</a>
<nav class="md-nav" aria-label="Building packages and applications">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#buildpythonpackage-function" class="md-nav__link">
<span class="md-ellipsis">
buildPythonPackage function
</span>
</a>
<nav class="md-nav" aria-label="buildPythonPackage function">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#buildpythonpackage-parameters" class="md-nav__link">
<span class="md-ellipsis">
buildPythonPackage parameters
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#overriding-python-packages" class="md-nav__link">
<span class="md-ellipsis">
Overriding Python packages
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#buildpythonapplication-function" class="md-nav__link">
<span class="md-ellipsis">
buildPythonApplication function
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#topythonapplication-function" class="md-nav__link">
<span class="md-ellipsis">
toPythonApplication function
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#topythonmodule-function" class="md-nav__link">
<span class="md-ellipsis">
toPythonModule function
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#python.buildenv-function" class="md-nav__link">
<span class="md-ellipsis">
python.buildEnv function
</span>
</a>
<nav class="md-nav" aria-label="python.buildEnv function">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#python.buildenv-arguments" class="md-nav__link">
<span class="md-ellipsis">
python.buildEnv arguments
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#python.withpackages-function" class="md-nav__link">
<span class="md-ellipsis">
python.withPackages function
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#setup-hooks" class="md-nav__link">
<span class="md-ellipsis">
Setup hooks
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#user-guide" class="md-nav__link">
<span class="md-ellipsis">
User Guide
</span>
</a>
<nav class="md-nav" aria-label="User Guide">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#using-python" class="md-nav__link">
<span class="md-ellipsis">
Using Python
</span>
</a>
<nav class="md-nav" aria-label="Using Python">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#overview" class="md-nav__link">
<span class="md-ellipsis">
Overview
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#installing-python-and-packages" class="md-nav__link">
<span class="md-ellipsis">
Installing Python and packages
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#ad-hoc-temporary-python-environment-with-nix-shell" class="md-nav__link">
<span class="md-ellipsis">
Ad-hoc temporary Python environment with nix-shell
</span>
</a>
<nav class="md-nav" aria-label="Ad-hoc temporary Python environment with nix-shell">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#running-python-scripts-and-using-nix-shell-as-shebang" class="md-nav__link">
<span class="md-ellipsis">
Running Python scripts and using nix-shell as shebang
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#load-environment-from-.nix-expression" class="md-nav__link">
<span class="md-ellipsis">
Load environment from .nix expression
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#installing-environments-globally-on-the-system" class="md-nav__link">
<span class="md-ellipsis">
Installing environments globally on the system
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#environment-defined-in-etcnixosconfiguration.nix" class="md-nav__link">
<span class="md-ellipsis">
Environment defined in /etc/nixos/configuration.nix
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#developing-with-python" class="md-nav__link">
<span class="md-ellipsis">
Developing with Python
</span>
</a>
<nav class="md-nav" aria-label="Developing with Python">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#python-library-packages-in-nixpkgs" class="md-nav__link">
<span class="md-ellipsis">
Python library packages in Nixpkgs
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#handling-dependencies" class="md-nav__link">
<span class="md-ellipsis">
Handling dependencies
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#testing-python-packages" class="md-nav__link">
<span class="md-ellipsis">
Testing Python Packages
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#using-pytest" class="md-nav__link">
<span class="md-ellipsis">
Using pytest
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#using-pytestcheckhook" class="md-nav__link">
<span class="md-ellipsis">
Using pytestCheckHook
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#using-pythonimportscheck" class="md-nav__link">
<span class="md-ellipsis">
Using pythonImportsCheck
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#using-pythonrelaxdepshook" class="md-nav__link">
<span class="md-ellipsis">
Using pythonRelaxDepsHook
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#using-unittestcheckhook" class="md-nav__link">
<span class="md-ellipsis">
Using unittestCheckHook
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#using-sphinxhook" class="md-nav__link">
<span class="md-ellipsis">
Using sphinxHook
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#organising-your-packages" class="md-nav__link">
<span class="md-ellipsis">
Organising your packages
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#including-a-derivation-using-callpackage" class="md-nav__link">
<span class="md-ellipsis">
Including a derivation using callPackage
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#faq" class="md-nav__link">
<span class="md-ellipsis">
FAQ
</span>
</a>
<nav class="md-nav" aria-label="FAQ">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#how-to-solve-circular-dependencies" class="md-nav__link">
<span class="md-ellipsis">
How to solve circular dependencies?
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#how-to-override-a-python-package" class="md-nav__link">
<span class="md-ellipsis">
How to override a Python package?
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#python-setup.py-bdist_wheel-cannot-create-.whl" class="md-nav__link">
<span class="md-ellipsis">
python setup.py bdist_wheel cannot create .whl
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#install_data-data_files-problems" class="md-nav__link">
<span class="md-ellipsis">
install_data / data_files problems
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#rationale-of-non-existent-global-site-packages" class="md-nav__link">
<span class="md-ellipsis">
Rationale of non-existent global site-packages
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#how-to-consume-python-modules-using-pip-in-a-virtual-environment-like-i-am-used-to-on-other-operating-systems" class="md-nav__link">
<span class="md-ellipsis">
How to consume Python modules using pip in a virtual environment like I am used to on other Operating Systems?
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#how-to-override-a-python-package-from-configuration.nix" class="md-nav__link">
<span class="md-ellipsis">
How to override a Python package from configuration.nix?
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#how-to-override-a-python-package-using-overlays" class="md-nav__link">
<span class="md-ellipsis">
How to override a Python package using overlays?
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#how-to-override-a-python-package-for-all-python-versions-using-extensions" class="md-nav__link">
<span class="md-ellipsis">
How to override a Python package for all Python versions using extensions?
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#how-to-use-intels-mkl-with-numpy-and-scipy" class="md-nav__link">
<span class="md-ellipsis">
How to use Intels MKL with numpy and scipy?
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#what-inputs-do-setup_requires-install_requires-and-tests_require-map-to" class="md-nav__link">
<span class="md-ellipsis">
What inputs do setup_requires, install_requires and tests_require map to?
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#optimizations" class="md-nav__link">
<span class="md-ellipsis">
How to enable interpreter optimizations?
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#python-optional-dependencies" class="md-nav__link">
<span class="md-ellipsis">
How to add optional dependencies?
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#tools" class="md-nav__link">
<span class="md-ellipsis">
How to contribute a Python package to nixpkgs?
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#deterministic-builds" class="md-nav__link">
<span class="md-ellipsis">
Are Python interpreters built deterministically?
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#automatic-tests" class="md-nav__link">
<span class="md-ellipsis">
How to provide automatic tests to Python packages?
</span>
</a>
<nav class="md-nav" aria-label="How to provide automatic tests to Python packages?">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#common-issues" class="md-nav__link">
<span class="md-ellipsis">
Common issues
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#contributing" class="md-nav__link">
<span class="md-ellipsis">
Contributing
</span>
</a>
<nav class="md-nav" aria-label="Contributing">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#contributing-guidelines" class="md-nav__link">
<span class="md-ellipsis">
Contributing guidelines
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#python-package-set-maintenance" class="md-nav__link">
<span class="md-ellipsis">
Package set maintenance
</span>
</a>
<nav class="md-nav" aria-label="Package set maintenance">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#python-package-bulk-updates" class="md-nav__link">
<span class="md-ellipsis">
Updating packages in bulk
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#python-cpython-update-schedule" class="md-nav__link">
<span class="md-ellipsis">
CPython Update Schedule
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../qt.section/" class="md-nav__link">
<span class="md-ellipsis">
Qt
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../r.section/" class="md-nav__link">
<span class="md-ellipsis">
R
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../ruby.section/" class="md-nav__link">
<span class="md-ellipsis">
Ruby
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../rust.section/" class="md-nav__link">
<span class="md-ellipsis">
Rust
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../scheme.section/" class="md-nav__link">
<span class="md-ellipsis">
Scheme
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../swift.section/" class="md-nav__link">
<span class="md-ellipsis">
Swift
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../texlive.section/" class="md-nav__link">
<span class="md-ellipsis">
TeX Live
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../titanium.section/" class="md-nav__link">
<span class="md-ellipsis">
Titanium
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../vim.section/" class="md-nav__link">
<span class="md-ellipsis">
Vim
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../../Library-Reference/asserts/" class="md-nav__link">
<span class="md-ellipsis">
Library Reference
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../../Module-System/module-system.chapter/" class="md-nav__link">
<span class="md-ellipsis">
Module System
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../../Packages/" class="md-nav__link">
<span class="md-ellipsis">
Packages
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../../Standard-Environment/" class="md-nav__link">
<span class="md-ellipsis">
Standard Environment
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../../Using-Nixpkgs/" class="md-nav__link">
<span class="md-ellipsis">
Using Nixpkgs
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
Table of contents
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#reference" class="md-nav__link">
<span class="md-ellipsis">
Reference
</span>
</a>
<nav class="md-nav" aria-label="Reference">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#interpreters" class="md-nav__link">
<span class="md-ellipsis">
Interpreters
</span>
</a>
<nav class="md-nav" aria-label="Interpreters">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#missing-tkinter-module-standard-library" class="md-nav__link">
<span class="md-ellipsis">
Missing tkinter module standard library
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#attributes-on-interpreters-packages" class="md-nav__link">
<span class="md-ellipsis">
Attributes on interpreters packages
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#building-packages-and-applications" class="md-nav__link">
<span class="md-ellipsis">
Building packages and applications
</span>
</a>
<nav class="md-nav" aria-label="Building packages and applications">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#buildpythonpackage-function" class="md-nav__link">
<span class="md-ellipsis">
buildPythonPackage function
</span>
</a>
<nav class="md-nav" aria-label="buildPythonPackage function">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#buildpythonpackage-parameters" class="md-nav__link">
<span class="md-ellipsis">
buildPythonPackage parameters
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#overriding-python-packages" class="md-nav__link">
<span class="md-ellipsis">
Overriding Python packages
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#buildpythonapplication-function" class="md-nav__link">
<span class="md-ellipsis">
buildPythonApplication function
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#topythonapplication-function" class="md-nav__link">
<span class="md-ellipsis">
toPythonApplication function
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#topythonmodule-function" class="md-nav__link">
<span class="md-ellipsis">
toPythonModule function
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#python.buildenv-function" class="md-nav__link">
<span class="md-ellipsis">
python.buildEnv function
</span>
</a>
<nav class="md-nav" aria-label="python.buildEnv function">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#python.buildenv-arguments" class="md-nav__link">
<span class="md-ellipsis">
python.buildEnv arguments
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#python.withpackages-function" class="md-nav__link">
<span class="md-ellipsis">
python.withPackages function
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#setup-hooks" class="md-nav__link">
<span class="md-ellipsis">
Setup hooks
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#user-guide" class="md-nav__link">
<span class="md-ellipsis">
User Guide
</span>
</a>
<nav class="md-nav" aria-label="User Guide">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#using-python" class="md-nav__link">
<span class="md-ellipsis">
Using Python
</span>
</a>
<nav class="md-nav" aria-label="Using Python">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#overview" class="md-nav__link">
<span class="md-ellipsis">
Overview
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#installing-python-and-packages" class="md-nav__link">
<span class="md-ellipsis">
Installing Python and packages
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#ad-hoc-temporary-python-environment-with-nix-shell" class="md-nav__link">
<span class="md-ellipsis">
Ad-hoc temporary Python environment with nix-shell
</span>
</a>
<nav class="md-nav" aria-label="Ad-hoc temporary Python environment with nix-shell">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#running-python-scripts-and-using-nix-shell-as-shebang" class="md-nav__link">
<span class="md-ellipsis">
Running Python scripts and using nix-shell as shebang
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#load-environment-from-.nix-expression" class="md-nav__link">
<span class="md-ellipsis">
Load environment from .nix expression
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#installing-environments-globally-on-the-system" class="md-nav__link">
<span class="md-ellipsis">
Installing environments globally on the system
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#environment-defined-in-etcnixosconfiguration.nix" class="md-nav__link">
<span class="md-ellipsis">
Environment defined in /etc/nixos/configuration.nix
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#developing-with-python" class="md-nav__link">
<span class="md-ellipsis">
Developing with Python
</span>
</a>
<nav class="md-nav" aria-label="Developing with Python">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#python-library-packages-in-nixpkgs" class="md-nav__link">
<span class="md-ellipsis">
Python library packages in Nixpkgs
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#handling-dependencies" class="md-nav__link">
<span class="md-ellipsis">
Handling dependencies
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#testing-python-packages" class="md-nav__link">
<span class="md-ellipsis">
Testing Python Packages
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#using-pytest" class="md-nav__link">
<span class="md-ellipsis">
Using pytest
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#using-pytestcheckhook" class="md-nav__link">
<span class="md-ellipsis">
Using pytestCheckHook
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#using-pythonimportscheck" class="md-nav__link">
<span class="md-ellipsis">
Using pythonImportsCheck
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#using-pythonrelaxdepshook" class="md-nav__link">
<span class="md-ellipsis">
Using pythonRelaxDepsHook
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#using-unittestcheckhook" class="md-nav__link">
<span class="md-ellipsis">
Using unittestCheckHook
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#using-sphinxhook" class="md-nav__link">
<span class="md-ellipsis">
Using sphinxHook
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#organising-your-packages" class="md-nav__link">
<span class="md-ellipsis">
Organising your packages
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#including-a-derivation-using-callpackage" class="md-nav__link">
<span class="md-ellipsis">
Including a derivation using callPackage
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#faq" class="md-nav__link">
<span class="md-ellipsis">
FAQ
</span>
</a>
<nav class="md-nav" aria-label="FAQ">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#how-to-solve-circular-dependencies" class="md-nav__link">
<span class="md-ellipsis">
How to solve circular dependencies?
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#how-to-override-a-python-package" class="md-nav__link">
<span class="md-ellipsis">
How to override a Python package?
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#python-setup.py-bdist_wheel-cannot-create-.whl" class="md-nav__link">
<span class="md-ellipsis">
python setup.py bdist_wheel cannot create .whl
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#install_data-data_files-problems" class="md-nav__link">
<span class="md-ellipsis">
install_data / data_files problems
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#rationale-of-non-existent-global-site-packages" class="md-nav__link">
<span class="md-ellipsis">
Rationale of non-existent global site-packages
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#how-to-consume-python-modules-using-pip-in-a-virtual-environment-like-i-am-used-to-on-other-operating-systems" class="md-nav__link">
<span class="md-ellipsis">
How to consume Python modules using pip in a virtual environment like I am used to on other Operating Systems?
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#how-to-override-a-python-package-from-configuration.nix" class="md-nav__link">
<span class="md-ellipsis">
How to override a Python package from configuration.nix?
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#how-to-override-a-python-package-using-overlays" class="md-nav__link">
<span class="md-ellipsis">
How to override a Python package using overlays?
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#how-to-override-a-python-package-for-all-python-versions-using-extensions" class="md-nav__link">
<span class="md-ellipsis">
How to override a Python package for all Python versions using extensions?
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#how-to-use-intels-mkl-with-numpy-and-scipy" class="md-nav__link">
<span class="md-ellipsis">
How to use Intels MKL with numpy and scipy?
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#what-inputs-do-setup_requires-install_requires-and-tests_require-map-to" class="md-nav__link">
<span class="md-ellipsis">
What inputs do setup_requires, install_requires and tests_require map to?
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#optimizations" class="md-nav__link">
<span class="md-ellipsis">
How to enable interpreter optimizations?
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#python-optional-dependencies" class="md-nav__link">
<span class="md-ellipsis">
How to add optional dependencies?
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#tools" class="md-nav__link">
<span class="md-ellipsis">
How to contribute a Python package to nixpkgs?
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#deterministic-builds" class="md-nav__link">
<span class="md-ellipsis">
Are Python interpreters built deterministically?
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#automatic-tests" class="md-nav__link">
<span class="md-ellipsis">
How to provide automatic tests to Python packages?
</span>
</a>
<nav class="md-nav" aria-label="How to provide automatic tests to Python packages?">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#common-issues" class="md-nav__link">
<span class="md-ellipsis">
Common issues
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#contributing" class="md-nav__link">
<span class="md-ellipsis">
Contributing
</span>
</a>
<nav class="md-nav" aria-label="Contributing">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#contributing-guidelines" class="md-nav__link">
<span class="md-ellipsis">
Contributing guidelines
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#python-package-set-maintenance" class="md-nav__link">
<span class="md-ellipsis">
Package set maintenance
</span>
</a>
<nav class="md-nav" aria-label="Package set maintenance">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#python-package-bulk-updates" class="md-nav__link">
<span class="md-ellipsis">
Updating packages in bulk
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#python-cpython-update-schedule" class="md-nav__link">
<span class="md-ellipsis">
CPython Update Schedule
</span>
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content" data-md-component="content">
<article class="md-content__inner md-typeset">
<h1 id="python">Python</h1>
<h2 id="reference">Reference</h2>
<h3 id="interpreters">Interpreters</h3>
<table>
<thead>
<tr>
<th>Package</th>
<th>Aliases</th>
<th>Interpeter</th>
</tr>
</thead>
<tbody>
<tr>
<td>python313</td>
<td></td>
<td>CPython 3.13</td>
</tr>
<tr>
<td>python312</td>
<td>python3</td>
<td>CPython 3.12</td>
</tr>
<tr>
<td>python311</td>
<td></td>
<td>CPython 3.11</td>
</tr>
<tr>
<td>python310</td>
<td></td>
<td>CPython 3.10</td>
</tr>
<tr>
<td>python39</td>
<td></td>
<td>CPython 3.9</td>
</tr>
<tr>
<td>python27</td>
<td>python, python2</td>
<td>CPython 2.7</td>
</tr>
<tr>
<td>pypy310</td>
<td></td>
<td>PyPy 3.10</td>
</tr>
<tr>
<td>pypy39</td>
<td>pypy3</td>
<td>PyPy 3.9</td>
</tr>
<tr>
<td>pypy27</td>
<td>pypy, pypy2</td>
<td>PyPy 2.7</td>
</tr>
</tbody>
</table>
<p>The Nix expressions for the interpreters can be found in
<code>pkgs/development/interpreters/python</code>.</p>
<p>All packages depending on any Python interpreter get appended
<code>out/{python.sitePackages}</code> to <code>$PYTHONPATH</code> if such directory
exists.</p>
<h4 id="missing-tkinter-module-standard-library">Missing <code>tkinter</code> module standard library</h4>
<p>To reduce closure size the <code>Tkinter</code>/<code>tkinter</code> is available as a separate package, <code>pythonPackages.tkinter</code>.</p>
<h4 id="attributes-on-interpreters-packages">Attributes on interpreters packages</h4>
<p>Each interpreter has the following attributes:</p>
<ul>
<li><code>libPrefix</code>. Name of the folder in <code>${python}/lib/</code> for corresponding interpreter.</li>
<li><code>interpreter</code>. Alias for <code>${python}/bin/${executable}</code>.</li>
<li><code>buildEnv</code>. Function to build python interpreter environments with extra packages bundled together. See <a href="#python.buildenv-function"></a> for usage and documentation.</li>
<li><code>withPackages</code>. Simpler interface to <code>buildEnv</code>. See <a href="#python.withpackages-function"></a> for usage and documentation.</li>
<li><code>sitePackages</code>. Alias for <code>lib/${libPrefix}/site-packages</code>.</li>
<li><code>executable</code>. Name of the interpreter executable, e.g. <code>python3.10</code>.</li>
<li><code>pkgs</code>. Set of Python packages for that specific interpreter. The package set can be modified by overriding the interpreter and passing <code>packageOverrides</code>.</li>
</ul>
<h3 id="building-packages-and-applications">Building packages and applications</h3>
<p>Python libraries and applications that use tools to follow PEP 517 (e.g. <code>setuptools</code> or <code>hatchling</code>, etc.) or
previous tools such as <code>distutils</code> are typically built with respectively the <a href="#buildpythonpackage-function"><code>buildPythonPackage</code></a> and
<a href="#buildpythonapplication-function"><code>buildPythonApplication</code></a> functions. These two functions also support installing a <code>wheel</code>.</p>
<p>All Python packages reside in <code>pkgs/top-level/python-packages.nix</code> and all
applications elsewhere. In case a package is used as both a library and an
application, then the package should be in <code>pkgs/top-level/python-packages.nix</code>
since only those packages are made available for all interpreter versions. The
preferred location for library expressions is in
<code>pkgs/development/python-modules</code>. It is important that these packages are
called from <code>pkgs/top-level/python-packages.nix</code> and not elsewhere, to guarantee
the right version of the package is built.</p>
<p>Based on the packages defined in <code>pkgs/top-level/python-packages.nix</code> an
attribute set is created for each available Python interpreter. The available
sets are</p>
<ul>
<li><code>pkgs.python27Packages</code></li>
<li><code>pkgs.python3Packages</code></li>
<li><code>pkgs.python39Packages</code></li>
<li><code>pkgs.python310Packages</code></li>
<li><code>pkgs.python311Packages</code></li>
<li><code>pkgs.python312Packages</code></li>
<li><code>pkgs.python313Packages</code></li>
<li><code>pkgs.pypyPackages</code></li>
</ul>
<p>and the aliases</p>
<ul>
<li><code>pkgs.python2Packages</code> pointing to <code>pkgs.python27Packages</code></li>
<li><code>pkgs.python3Packages</code> pointing to <code>pkgs.python311Packages</code></li>
<li><code>pkgs.pythonPackages</code> pointing to <code>pkgs.python2Packages</code></li>
</ul>
<h4 id="buildpythonpackage-function"><code>buildPythonPackage</code> function</h4>
<p>The <code>buildPythonPackage</code> function has its name binding in
<code>pkgs/development/interpreters/python/python-packages-base.nix</code> and is
implemented in <code>pkgs/development/interpreters/python/mk-python-derivation.nix</code>
using setup hooks.</p>
<p>The following is an example:</p>
<div class="highlight"><pre><span></span><code><span class="p">{</span> lib
<span class="p">,</span> buildPythonPackage
<span class="p">,</span> fetchPypi <span class="s2">&quot;build-system</span>
<span class="s2">, setuptools</span>
<span class="s2">, setuptools-scm &quot;</span>dependencies
<span class="p">,</span> attrs
<span class="p">,</span> pluggy
<span class="p">,</span> py
<span class="p">,</span> setuptools
<span class="p">,</span> six <span class="s2">&quot;tests</span>
<span class="s2">, hypothesis</span>
<span class="s2"> }:</span>
<span class="s2">buildPythonPackage rec {</span>
<span class="s2"> pname = &quot;</span>pytest<span class="s2">&quot;;</span>
<span class="s2"> version = &quot;</span><span class="mf">3.3.1</span><span class="s2">&quot;;</span>
<span class="s2"> pyproject = true;</span>
<span class="s2"> src = fetchPypi {</span>
<span class="s2"> inherit pname version;</span>
<span class="s2"> hash = &quot;</span><span class="l">sha256-z4Q23FnYaVNG/NOrKW3kZCXsqwDWQJbOvnn7Ueyy65M</span><span class="o">=</span><span class="s2">&quot;;</span>
<span class="s2"> };</span>
<span class="s2"> postPatch = &#39;&#39;</span>
<span class="s2"> # don&#39;t test bash builtins</span>
<span class="s2"> rm testing/test_argcomplete.py</span>
<span class="s2"> &#39;&#39;;</span>
<span class="s2"> build-system = [</span>
<span class="s2"> setuptools</span>
<span class="s2"> setuptools-scm</span>
<span class="s2"> ];</span>
<span class="s2"> dependencies = [</span>
<span class="s2"> attrs</span>
<span class="s2"> py</span>
<span class="s2"> setuptools</span>
<span class="s2"> six</span>
<span class="s2"> pluggy</span>
<span class="s2"> ];</span>
<span class="s2"> nativeCheckInputs = [</span>
<span class="s2"> hypothesis</span>
<span class="s2"> ];</span>
<span class="s2"> meta = {</span>
<span class="s2"> changelog = &quot;</span><span class="l">https://github.com/pytest-dev/pytest/releases/tag/$</span><span class="p">{</span>version<span class="p">}</span><span class="s2">&quot;;</span>
<span class="s2"> description = &quot;</span>Framework for writing tests<span class="s2">&quot;;</span>
<span class="s2"> homepage = &quot;</span><span class="l">https://github.com/pytest-dev/pytest</span><span class="s2">&quot;;</span>
<span class="s2"> license = lib.licenses.mit;</span>
<span class="s2"> maintainers = with lib.maintainers; [ domenkozar lovek323 madjar lsix ];</span>
<span class="s2"> };</span>
<span class="s2">}</span>
</code></pre></div>
<p>The <code>buildPythonPackage</code> mainly does four things:</p>
<ul>
<li>In the <a href="#build-phase"><code>buildPhase</code></a>, it calls <code>${python.pythonOnBuildForHost.interpreter} -m build --wheel</code> to
build a wheel binary zipfile.</li>
<li>In the <a href="#ssec-install-phase"><code>installPhase</code></a>, it installs the wheel file using <code>${python.pythonOnBuildForHost.interpreter} -m installer *.whl</code>.</li>
<li>In the <a href="#var-stdenv-postFixup"><code>postFixup</code></a> phase, the <code>wrapPythonPrograms</code> bash function is called to
wrap all programs in the <code>$out/bin/*</code> directory to include <code>$PATH</code>
environment variable and add dependent libraries to script's <code>sys.path</code>.</li>
<li>In the <a href="#ssec-installCheck-phase"><code>installCheck</code></a> phase, <code>${python.interpreter} -m pytest</code> is run.</li>
</ul>
<p>By default tests are run because <a href="#var-stdenv-doCheck"><code>doCheck = true</code></a>. Test dependencies, like
e.g. the test runner, should be added to <a href="#var-stdenv-nativeCheckInputs"><code>nativeCheckInputs</code></a>.</p>
<p>By default <code>meta.platforms</code> is set to the same value
as the interpreter unless overridden otherwise.</p>
<h5 id="buildpythonpackage-parameters"><code>buildPythonPackage</code> parameters</h5>
<p>All parameters from <a href="#sec-using-stdenv"><code>stdenv.mkDerivation</code></a> function are still supported. The
following are specific to <code>buildPythonPackage</code>:</p>
<ul>
<li><code>catchConflicts ? true</code>: If <code>true</code>, abort package build if a package name
appears more than once in dependency tree. Default is <code>true</code>.</li>
<li><code>disabled ? false</code>: If <code>true</code>, package is not built for the particular Python
interpreter version.</li>
<li><code>dontWrapPythonPrograms ? false</code>: Skip wrapping of Python programs.</li>
<li><code>permitUserSite ? false</code>: Skip setting the <code>PYTHONNOUSERSITE</code> environment
variable in wrapped programs.</li>
<li><code>pyproject</code>: Whether the pyproject format should be used. When set to <code>true</code>,
<code>pypaBuildHook</code> will be used, and you can add the required build dependencies
from <code>build-system.requires</code> to <code>build-system</code>. Note that the pyproject
format falls back to using <code>setuptools</code>, so you can use <code>pyproject = true</code>
even if the package only has a <code>setup.py</code>. When set to <code>false</code>, you can
use the existing <a href="#setup-hooks">hooks</a> or provide your own logic to build the
package. This can be useful for packages that don't support the pyproject
format. When unset, the legacy <code>setuptools</code> hooks are used for backwards
compatibility.</li>
<li><code>makeWrapperArgs ? []</code>: A list of strings. Arguments to be passed to
<a href="#fun-makeWrapper"><code>makeWrapper</code></a>, which wraps generated binaries. By default, the arguments to
<a href="#fun-makeWrapper"><code>makeWrapper</code></a> set <code>PATH</code> and <code>PYTHONPATH</code> environment variables before calling
the binary. Additional arguments here can allow a developer to set environment
variables which will be available when the binary is run. For example,
<code>makeWrapperArgs = ["--set FOO BAR" "--set BAZ QUX"]</code>.</li>
<li><code>namePrefix</code>: Prepends text to <code>${name}</code> parameter. In case of libraries, this
defaults to <code>"python3.8-"</code> for Python 3.8, etc., and in case of applications to <code>""</code>.</li>
<li><code>pypaBuildFlags ? []</code>: A list of strings. Arguments to be passed to <code>python -m build --wheel</code>.</li>
<li><code>pythonPath ? []</code>: List of packages to be added into <code>$PYTHONPATH</code>. Packages
in <code>pythonPath</code> are not propagated (contrary to <a href="#var-stdenv-propagatedBuildInputs"><code>propagatedBuildInputs</code></a>).</li>
<li><code>preShellHook</code>: Hook to execute commands before <code>shellHook</code>.</li>
<li><code>postShellHook</code>: Hook to execute commands after <code>shellHook</code>.</li>
<li><code>removeBinByteCode ? true</code>: Remove bytecode from <code>/bin</code>. Bytecode is only
created when the filenames end with <code>.py</code>.</li>
<li><code>setupPyGlobalFlags ? []</code>: List of flags passed to <code>setup.py</code> command.</li>
<li><code>setupPyBuildFlags ? []</code>: List of flags passed to <code>setup.py build_ext</code> command.</li>
</ul>
<p>The <a href="#sec-using-stdenv"><code>stdenv.mkDerivation</code></a> function accepts various parameters for describing
build inputs (see "Specifying dependencies"). The following are of special
interest for Python packages, either because these are primarily used, or
because their behaviour is different:</p>
<ul>
<li><code>nativeBuildInputs ? []</code>: Build-time only dependencies. Typically executables.</li>
<li><code>build-system ? []</code>: Build-time only Python dependencies. Items listed in <code>build-system.requires</code>/<code>setup_requires</code>.</li>
<li><code>buildInputs ? []</code>: Build and/or run-time dependencies that need to be
compiled for the host machine. Typically non-Python libraries which are being
linked.</li>
<li><code>nativeCheckInputs ? []</code>: Dependencies needed for running the <a href="#ssec-check-phase"><code>checkPhase</code></a>. These
are added to <a href="#var-stdenv-nativeBuildInputs"><code>nativeBuildInputs</code></a> when <a href="#var-stdenv-doCheck"><code>doCheck = true</code></a>. Items listed in
<code>tests_require</code> go here.</li>
<li><code>dependencies ? []</code>: Aside from propagating dependencies,
<code>buildPythonPackage</code> also injects code into and wraps executables with the
paths included in this list. Items listed in <code>install_requires</code> go here.</li>
<li><code>optional-dependencies ? { }</code>: Optional feature flagged dependencies. Items listed in <code>extras_requires</code> go here.</li>
</ul>
<p>Aside from propagating dependencies,
<code>buildPythonPackage</code> also injects code into and wraps executables with the
paths included in this list. Items listed in <code>extras_requires</code> go here.</p>
<h5 id="overriding-python-packages">Overriding Python packages</h5>
<p>The <code>buildPythonPackage</code> function has a <code>overridePythonAttrs</code> method that can be
used to override the package. In the following example we create an environment
where we have the <code>blaze</code> package using an older version of <code>pandas</code>. We
override first the Python interpreter and pass <code>packageOverrides</code> which contains
the overrides for packages in the package set.</p>
<div class="highlight"><pre><span></span><code><span class="k">with</span> <span class="nb">import</span> <span class="l">&lt;nixpkgs&gt;</span> <span class="p">{};</span>
<span class="p">(</span><span class="k">let</span>
<span class="ss">python</span> <span class="o">=</span> <span class="k">let</span>
<span class="ss">packageOverrides</span> <span class="o">=</span> self<span class="p">:</span> super<span class="p">:</span> <span class="p">{</span>
<span class="ss">pandas</span> <span class="o">=</span> super<span class="o">.</span>pandas<span class="o">.</span>overridePythonAttrs<span class="p">(</span>old<span class="p">:</span> <span class="k">rec</span> <span class="p">{</span>
<span class="ss">version</span> <span class="o">=</span> <span class="s2">&quot;0.19.1&quot;</span><span class="p">;</span>
<span class="ss">src</span> <span class="o">=</span> fetchPypi <span class="p">{</span>
<span class="ss">pname</span> <span class="o">=</span> <span class="s2">&quot;pandas&quot;</span><span class="p">;</span>
<span class="k">inherit</span> version<span class="p">;</span>
<span class="ss">hash</span> <span class="o">=</span> <span class="s2">&quot;sha256-JQn+rtpy/OA2deLszSKEuxyttqBzcAil50H+JDHUdCE=&quot;</span><span class="p">;</span>
<span class="p">};</span>
<span class="p">});</span>
<span class="p">};</span>
<span class="k">in</span> pkgs<span class="o">.</span>python3<span class="o">.</span>override <span class="p">{</span><span class="k">inherit</span> packageOverrides<span class="p">;</span> <span class="ss">self</span> <span class="o">=</span> python<span class="p">;};</span>
<span class="k">in</span> python<span class="o">.</span>withPackages<span class="p">(</span>ps<span class="p">:</span> <span class="p">[</span> ps<span class="o">.</span>blaze <span class="p">]))</span><span class="o">.</span>env
</code></pre></div>
<p>The next example shows a non trivial overriding of the <code>blas</code> implementation to
be used through out all of the Python package set:</p>
<div class="highlight"><pre><span></span><code><span class="p">{</span>
<span class="ss">python3MyBlas</span> <span class="o">=</span> pkgs<span class="o">.</span>python3<span class="o">.</span>override <span class="p">{</span>
<span class="ss">packageOverrides</span> <span class="o">=</span> self<span class="p">:</span> super<span class="p">:</span> <span class="p">{</span>
<span class="c1"># We need toPythonModule for the package set to evaluate this</span>
<span class="ss">blas</span> <span class="o">=</span> super<span class="o">.</span>toPythonModule<span class="p">(</span>super<span class="o">.</span>pkgs<span class="o">.</span>blas<span class="o">.</span>override <span class="p">{</span>
<span class="ss">blasProvider</span> <span class="o">=</span> super<span class="o">.</span>pkgs<span class="o">.</span>mkl<span class="p">;</span>
<span class="p">});</span>
<span class="ss">lapack</span> <span class="o">=</span> super<span class="o">.</span>toPythonModule<span class="p">(</span>super<span class="o">.</span>pkgs<span class="o">.</span>lapack<span class="o">.</span>override <span class="p">{</span>
<span class="ss">lapackProvider</span> <span class="o">=</span> super<span class="o">.</span>pkgs<span class="o">.</span>mkl<span class="p">;</span>
<span class="p">});</span>
<span class="p">};</span>
<span class="p">};</span>
<span class="p">}</span>
</code></pre></div>
<p>This is particularly useful for numpy and scipy users who want to gain speed with other blas implementations.
Note that using <code>scipy = super.scipy.override { blas = super.pkgs.mkl; };</code> will likely result in
compilation issues, because scipy dependencies need to use the same blas implementation as well.</p>
<h4 id="buildpythonapplication-function"><code>buildPythonApplication</code> function</h4>
<p>The <a href="#buildpythonapplication-function"><code>buildPythonApplication</code></a> function is practically the same as
<a href="#buildpythonpackage-function"><code>buildPythonPackage</code></a>. The main purpose of this function is to build a Python
package where one is interested only in the executables, and not importable
modules. For that reason, when adding this package to a <a href="#python.buildenv-function"><code>python.buildEnv</code></a>, the
modules won't be made available.</p>
<p>Another difference is that <a href="#buildpythonpackage-function"><code>buildPythonPackage</code></a> by default prefixes the names of
the packages with the version of the interpreter. Because this is irrelevant for
applications, the prefix is omitted.</p>
<p>When packaging a Python application with <a href="#buildpythonapplication-function"><code>buildPythonApplication</code></a>, it should be
called with <code>callPackage</code> and passed <code>python3</code> or <code>python3Packages</code> (possibly
specifying an interpreter version), like this:</p>
<div class="highlight"><pre><span></span><code><span class="p">{</span> lib
<span class="p">,</span> python3Packages
<span class="p">,</span> fetchPypi
<span class="p">}:</span>
python3Packages<span class="o">.</span>buildPythonApplication <span class="k">rec</span> <span class="p">{</span>
<span class="ss">pname</span> <span class="o">=</span> <span class="s2">&quot;luigi&quot;</span><span class="p">;</span>
<span class="ss">version</span> <span class="o">=</span> <span class="s2">&quot;2.7.9&quot;</span><span class="p">;</span>
<span class="ss">pyproject</span> <span class="o">=</span> <span class="no">true</span><span class="p">;</span>
<span class="ss">src</span> <span class="o">=</span> fetchPypi <span class="p">{</span>
<span class="k">inherit</span> pname version<span class="p">;</span>
<span class="ss">hash</span> <span class="o">=</span> <span class="s2">&quot;sha256-Pe229rT0aHwA98s+nTHQMEFKZPo/yw6sot8MivFDvAw=&quot;</span><span class="p">;</span>
<span class="p">};</span>
<span class="ss">build-system</span> <span class="o">=</span> <span class="k">with</span> python3Packages<span class="p">;</span> <span class="p">[</span>
setuptools
<span class="p">];</span>
<span class="ss">dependencies</span> <span class="o">=</span> <span class="k">with</span> python3Packages<span class="p">;</span> <span class="p">[</span>
tornado
python-daemon
<span class="p">];</span>
<span class="ss">meta</span> <span class="o">=</span> <span class="p">{</span>
<span class="c1"># ...</span>
<span class="p">};</span>
<span class="p">}</span>
</code></pre></div>
<p>This is then added to <code>all-packages.nix</code> just as any other application would be.</p>
<div class="highlight"><pre><span></span><code><span class="p">{</span>
<span class="ss">luigi</span> <span class="o">=</span> callPackage <span class="l">../applications/networking/cluster/luigi</span> <span class="p">{</span> <span class="p">};</span>
<span class="p">}</span>
</code></pre></div>
<p>Since the package is an application, a consumer doesn't need to care about
Python versions or modules, which is why they don't go in <code>python3Packages</code>.</p>
<h4 id="topythonapplication-function"><code>toPythonApplication</code> function</h4>
<p>A distinction is made between applications and libraries, however, sometimes a
package is used as both. In this case the package is added as a library to
<code>python-packages.nix</code> and as an application to <code>all-packages.nix</code>. To reduce
duplication the <code>toPythonApplication</code> can be used to convert a library to an
application.</p>
<p>The Nix expression shall use <a href="#buildpythonpackage-function"><code>buildPythonPackage</code></a> and be called from
<code>python-packages.nix</code>. A reference shall be created from <code>all-packages.nix</code> to
the attribute in <code>python-packages.nix</code>, and the <code>toPythonApplication</code> shall be
applied to the reference:</p>
<div class="highlight"><pre><span></span><code><span class="p">{</span>
<span class="ss">youtube-dl</span> <span class="o">=</span> <span class="k">with</span> python3Packages<span class="p">;</span> toPythonApplication youtube-dl<span class="p">;</span>
<span class="p">}</span>
</code></pre></div>
<h4 id="topythonmodule-function"><code>toPythonModule</code> function</h4>
<p>In some cases, such as bindings, a package is created using
<a href="#sec-using-stdenv"><code>stdenv.mkDerivation</code></a> and added as attribute in <code>all-packages.nix</code>. The Python
bindings should be made available from <code>python-packages.nix</code>. The
<code>toPythonModule</code> function takes a derivation and makes certain Python-specific
modifications.</p>
<div class="highlight"><pre><span></span><code><span class="p">{</span>
<span class="ss">opencv</span> <span class="o">=</span> toPythonModule <span class="p">(</span>pkgs<span class="o">.</span>opencv<span class="o">.</span>override <span class="p">{</span>
<span class="ss">enablePython</span> <span class="o">=</span> <span class="no">true</span><span class="p">;</span>
<span class="ss">pythonPackages</span> <span class="o">=</span> self<span class="p">;</span>
<span class="p">});</span>
<span class="p">}</span>
</code></pre></div>
<p>Do pay attention to passing in the right Python version!</p>
<h4 id="python.buildenv-function"><code>python.buildEnv</code> function</h4>
<p>Python environments can be created using the low-level <code>pkgs.buildEnv</code> function.
This example shows how to create an environment that has the Pyramid Web Framework.
Saving the following as <code>default.nix</code></p>
<div class="highlight"><pre><span></span><code><span class="k">with</span> <span class="nb">import</span> <span class="l">&lt;nixpkgs&gt;</span> <span class="p">{};</span>
python3<span class="o">.</span>buildEnv<span class="o">.</span>override <span class="p">{</span>
<span class="ss">extraLibs</span> <span class="o">=</span> <span class="p">[</span> python3Packages<span class="o">.</span>pyramid <span class="p">];</span>
<span class="ss">ignoreCollisions</span> <span class="o">=</span> <span class="no">true</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div>
<p>and running <code>nix-build</code> will create</p>
<div class="highlight"><pre><span></span><code>/nix/store/cf1xhjwzmdki7fasgr4kz6di72ykicl5-python-2.7.8-env
</code></pre></div>
<p>with wrapped binaries in <code>bin/</code>.</p>
<p>You can also use the <code>env</code> attribute to create local environments with needed
packages installed. This is somewhat comparable to <code>virtualenv</code>. For example,
running <code>nix-shell</code> with the following <code>shell.nix</code></p>
<div class="highlight"><pre><span></span><code><span class="k">with</span> <span class="nb">import</span> <span class="l">&lt;nixpkgs&gt;</span> <span class="p">{};</span>
<span class="p">(</span>python3<span class="o">.</span>buildEnv<span class="o">.</span>override <span class="p">{</span>
<span class="ss">extraLibs</span> <span class="o">=</span> <span class="k">with</span> python3Packages<span class="p">;</span> <span class="p">[</span>
numpy
requests
<span class="p">];</span>
<span class="p">})</span><span class="o">.</span>env
</code></pre></div>
<p>will drop you into a shell where Python will have the
specified packages in its path.</p>
<h5 id="python.buildenv-arguments"><code>python.buildEnv</code> arguments</h5>
<ul>
<li><code>extraLibs</code>: List of packages installed inside the environment.</li>
<li><code>postBuild</code>: Shell command executed after the build of environment.</li>
<li><code>ignoreCollisions</code>: Ignore file collisions inside the environment (default is <code>false</code>).</li>
<li><code>permitUserSite</code>: Skip setting the <code>PYTHONNOUSERSITE</code> environment variable in
wrapped binaries in the environment.</li>
</ul>
<h4 id="python.withpackages-function"><code>python.withPackages</code> function</h4>
<p>The <a href="#python.withpackages-function"><code>python.withPackages</code></a> function provides a simpler interface to the <a href="#python.buildenv-function"><code>python.buildEnv</code></a> functionality.
It takes a function as an argument that is passed the set of python packages and returns the list
of the packages to be included in the environment. Using the <a href="#python.withpackages-function"><code>withPackages</code></a> function, the previous
example for the Pyramid Web Framework environment can be written like this:</p>
<div class="highlight"><pre><span></span><code><span class="k">with</span> <span class="nb">import</span> <span class="l">&lt;nixpkgs&gt;</span> <span class="p">{};</span>
python<span class="o">.</span>withPackages <span class="p">(</span>ps<span class="p">:</span> <span class="p">[</span> ps<span class="o">.</span>pyramid <span class="p">])</span>
</code></pre></div>
<p><a href="#python.withpackages-function"><code>withPackages</code></a> passes the correct package set for the specific interpreter
version as an argument to the function. In the above example, <code>ps</code> equals
<code>pythonPackages</code>. But you can also easily switch to using python3:</p>
<div class="highlight"><pre><span></span><code><span class="k">with</span> <span class="nb">import</span> <span class="l">&lt;nixpkgs&gt;</span> <span class="p">{};</span>
python3<span class="o">.</span>withPackages <span class="p">(</span>ps<span class="p">:</span> <span class="p">[</span> ps<span class="o">.</span>pyramid <span class="p">])</span>
</code></pre></div>
<p>Now, <code>ps</code> is set to <code>python3Packages</code>, matching the version of the interpreter.</p>
<p>As <a href="#python.withpackages-function"><code>python.withPackages</code></a> uses <a href="#python.buildenv-function"><code>python.buildEnv</code></a> under the hood, it also
supports the <code>env</code> attribute. The <code>shell.nix</code> file from the previous section can
thus be also written like this:</p>
<div class="highlight"><pre><span></span><code><span class="k">with</span> <span class="nb">import</span> <span class="l">&lt;nixpkgs&gt;</span> <span class="p">{};</span>
<span class="p">(</span>python3<span class="o">.</span>withPackages <span class="p">(</span>ps<span class="p">:</span> <span class="k">with</span> ps<span class="p">;</span> <span class="p">[</span>
numpy
requests
<span class="p">]))</span><span class="o">.</span>env
</code></pre></div>
<p>In contrast to <a href="#python.buildenv-function"><code>python.buildEnv</code></a>, <a href="#python.withpackages-function"><code>python.withPackages</code></a> does not support the
more advanced options such as <code>ignoreCollisions = true</code> or <code>postBuild</code>. If you
need them, you have to use <a href="#python.buildenv-function"><code>python.buildEnv</code></a>.</p>
<p>Python 2 namespace packages may provide <code>__init__.py</code> that collide. In that case
<a href="#python.buildenv-function"><code>python.buildEnv</code></a> should be used with <code>ignoreCollisions = true</code>.</p>
<h4 id="setup-hooks">Setup hooks</h4>
<p>The following are setup hooks specifically for Python packages. Most of these
are used in <a href="#buildpythonpackage-function"><code>buildPythonPackage</code></a>.</p>
<ul>
<li><code>eggUnpackhook</code> to move an egg to the correct folder so it can be installed
with the <code>eggInstallHook</code></li>
<li><code>eggBuildHook</code> to skip building for eggs.</li>
<li><code>eggInstallHook</code> to install eggs.</li>
<li><code>pypaBuildHook</code> to build a wheel using
<a href="https://pypa-build.readthedocs.io/en/latest/index.html"><code>pypa/build</code></a> and
PEP 517/518. Note a build system (e.g. <code>setuptools</code> or <code>flit</code>) should still
be added as <code>build-system</code>.</li>
<li><code>pypaInstallHook</code> to install wheels.</li>
<li><code>pytestCheckHook</code> to run tests with <code>pytest</code>. See <a href="#using-pytestcheckhook">example usage</a>.</li>
<li><code>pythonCatchConflictsHook</code> to fail if the package depends on two different versions of the same dependency.</li>
<li><code>pythonImportsCheckHook</code> to check whether importing the listed modules works.</li>
<li><code>pythonRelaxDepsHook</code> will relax Python dependencies restrictions for the package.
See <a href="#using-pythonrelaxdepshook">example usage</a>.</li>
<li><code>pythonRemoveBinBytecode</code> to remove bytecode from the <code>/bin</code> folder.</li>
<li><code>setuptoolsBuildHook</code> to build a wheel using <code>setuptools</code>.</li>
<li><code>setuptoolsCheckHook</code> to run tests with <code>python setup.py test</code>.</li>
<li><code>sphinxHook</code> to build documentation and manpages using Sphinx.</li>
<li><code>venvShellHook</code> to source a Python 3 <code>venv</code> at the <code>venvDir</code> location. A
<code>venv</code> is created if it does not yet exist. <code>postVenvCreation</code> can be used to
to run commands only after venv is first created.</li>
<li><code>wheelUnpackHook</code> to move a wheel to the correct folder so it can be installed
with the <code>pipInstallHook</code>.</li>
<li><code>unittestCheckHook</code> will run tests with <code>python -m unittest discover</code>. See <a href="#using-unittestcheckhook">example usage</a>.</li>
</ul>
<h2 id="user-guide">User Guide</h2>
<h3 id="using-python">Using Python</h3>
<h4 id="overview">Overview</h4>
<p>Several versions of the Python interpreter are available on Nix, as well as a
high amount of packages. The attribute <code>python3</code> refers to the default
interpreter, which is currently CPython 3.11. The attribute <code>python</code> refers to
CPython 2.7 for backwards-compatibility. It is also possible to refer to
specific versions, e.g. <code>python311</code> refers to CPython 3.11, and <code>pypy</code> refers to
the default PyPy interpreter.</p>
<p>Python is used a lot, and in different ways. This affects also how it is
packaged. In the case of Python on Nix, an important distinction is made between
whether the package is considered primarily an application, or whether it should
be used as a library, i.e., of primary interest are the modules in
<code>site-packages</code> that should be importable.</p>
<p>In the Nixpkgs tree Python applications can be found throughout, depending on
what they do, and are called from the main package set. Python libraries,
however, are in separate sets, with one set per interpreter version.</p>
<p>The interpreters have several common attributes. One of these attributes is
<code>pkgs</code>, which is a package set of Python libraries for this specific
interpreter. E.g., the <code>toolz</code> package corresponding to the default interpreter
is <code>python3.pkgs.toolz</code>, and the CPython 3.11 version is <code>python311.pkgs.toolz</code>.
The main package set contains aliases to these package sets, e.g.
<code>pythonPackages</code> refers to <code>python.pkgs</code> and <code>python311Packages</code> to
<code>python311.pkgs</code>.</p>
<h4 id="installing-python-and-packages">Installing Python and packages</h4>
<p>The Nix and NixOS manuals explain how packages are generally installed. In the
case of Python and Nix, it is important to make a distinction between whether the
package is considered an application or a library.</p>
<p>Applications on Nix are typically installed into your user profile imperatively
using <code>nix-env -i</code>, and on NixOS declaratively by adding the package name to
<code>environment.systemPackages</code> in <code>/etc/nixos/configuration.nix</code>. Dependencies
such as libraries are automatically installed and should not be installed
explicitly.</p>
<p>The same goes for Python applications. Python applications can be installed in
your profile, and will be wrapped to find their exact library dependencies,
without impacting other applications or polluting your user environment.</p>
<p>But Python libraries you would like to use for development cannot be installed,
at least not individually, because they won't be able to find each other
resulting in import errors. Instead, it is possible to create an environment
with <a href="#python.buildenv-function"><code>python.buildEnv</code></a> or <a href="#python.withpackages-function"><code>python.withPackages</code></a> where the interpreter and other
executables are wrapped to be able to find each other and all of the modules.</p>
<p>In the following examples we will start by creating a simple, ad-hoc environment
with a nix-shell that has <code>numpy</code> and <code>toolz</code> in Python 3.11; then we will create
a re-usable environment in a single-file Python script; then we will create a
full Python environment for development with this same environment.</p>
<p>Philosophically, this should be familiar to users who are used to a <code>venv</code> style
of development: individual projects create their own Python environments without
impacting the global environment or each other.</p>
<h4 id="ad-hoc-temporary-python-environment-with-nix-shell">Ad-hoc temporary Python environment with <code>nix-shell</code></h4>
<p>The simplest way to start playing with the way nix wraps and sets up Python
environments is with <code>nix-shell</code> at the cmdline. These environments create a
temporary shell session with a Python and a <em>precise</em> list of packages (plus
their runtime dependencies), with no other Python packages in the Python
interpreter's scope.</p>
<p>To create a Python 3.11 session with <code>numpy</code> and <code>toolz</code> available, run:</p>
<div class="highlight"><pre><span></span><code>$<span class="w"> </span>nix-shell<span class="w"> </span>-p<span class="w"> </span><span class="s1">&#39;python311.withPackages(ps: with ps; [ numpy toolz ])&#39;</span>
</code></pre></div>
<p>By default <code>nix-shell</code> will start a <code>bash</code> session with this interpreter in our
<code>PATH</code>, so if we then run:</p>
<p>```Python console
[nix-shell:~/src/nixpkgs]$ python3
Python 3.11.3 (main, Apr 4 2023, 22:36:41) [GCC 12.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.</p>
<blockquote>
<blockquote>
<blockquote>
<p>import numpy; import toolz
<div class="highlight"><pre><span></span><code>Note that no other modules are in scope, even if they were imperatively
installed into our user environment as a dependency of a Python application:
```Python console
&gt;&gt;&gt; import requests
Traceback (most recent call last):
File &quot;&lt;stdin&gt;&quot;, line 1, in &lt;module&gt;
ModuleNotFoundError: No module named &#39;requests&#39;
</code></pre></div></p>
</blockquote>
</blockquote>
</blockquote>
<p>We can add as many additional modules onto the <code>nix-shell</code> as we need, and we
will still get 1 wrapped Python interpreter. We can start the interpreter
directly like so:</p>
<div class="highlight"><pre><span></span><code>$<span class="w"> </span>nix-shell<span class="w"> </span>-p<span class="w"> </span><span class="s2">&quot;python311.withPackages (ps: with ps; [ numpy toolz requests ])&quot;</span><span class="w"> </span>--run<span class="w"> </span>python3
this<span class="w"> </span>derivation<span class="w"> </span>will<span class="w"> </span>be<span class="w"> </span>built:
<span class="w"> </span>/nix/store/r19yf5qgfiakqlhkgjahbg3zg79549n4-python3-3.11.2-env.drv
building<span class="w"> </span><span class="s1">&#39;/nix/store/r19yf5qgfiakqlhkgjahbg3zg79549n4-python3-3.11.2-env.drv&#39;</span>...
created<span class="w"> </span><span class="m">273</span><span class="w"> </span>symlinks<span class="w"> </span><span class="k">in</span><span class="w"> </span>user<span class="w"> </span>environment
Python<span class="w"> </span><span class="m">3</span>.11.2<span class="w"> </span><span class="o">(</span>main,<span class="w"> </span>Feb<span class="w"> </span><span class="m">7</span><span class="w"> </span><span class="m">2023</span>,<span class="w"> </span><span class="m">13</span>:52:42<span class="o">)</span><span class="w"> </span><span class="o">[</span>GCC<span class="w"> </span><span class="m">12</span>.2.0<span class="o">]</span><span class="w"> </span>on<span class="w"> </span>linux
Type<span class="w"> </span><span class="s2">&quot;help&quot;</span>,<span class="w"> </span><span class="s2">&quot;copyright&quot;</span>,<span class="w"> </span><span class="s2">&quot;credits&quot;</span><span class="w"> </span>or<span class="w"> </span><span class="s2">&quot;license&quot;</span><span class="w"> </span><span class="k">for</span><span class="w"> </span>more<span class="w"> </span>information.
&gt;&gt;&gt;<span class="w"> </span>import<span class="w"> </span>requests
&gt;&gt;&gt;
</code></pre></div>
<p>Notice that this time it built a new Python environment, which now includes
<code>requests</code>. Building an environment just creates wrapper scripts that expose the
selected dependencies to the interpreter while re-using the actual modules. This
means if any other env has installed <code>requests</code> or <code>numpy</code> in a different
context, we don't need to recompile them -- we just recompile the wrapper script
that sets up an interpreter pointing to them. This matters much more for "big"
modules like <code>pytorch</code> or <code>tensorflow</code>.</p>
<p>Module names usually match their names on <a href="https://pypi.org/">pypi.org</a>, but
normalized according to PEP 503/508. (e.g. Foo__Bar.baz -&gt; foo-bar-baz)
You can use the <a href="https://nixos.org/nixos/packages.html">Nixpkgs search website</a>
to find them as well (along with non-python packages).</p>
<p>At this point we can create throwaway experimental Python environments with
arbitrary dependencies. This is a good way to get a feel for how the Python
interpreter and dependencies work in Nix and NixOS, but to do some actual
development, we'll want to make it a bit more persistent.</p>
<h5 id="running-python-scripts-and-using-nix-shell-as-shebang">Running Python scripts and using <code>nix-shell</code> as shebang</h5>
<p>Sometimes, we have a script whose header looks like this:</p>
<div class="highlight"><pre><span></span><code><span class="ch">#!/usr/bin/env python3</span>
<span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="nn">np</span>
<span class="n">a</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">])</span>
<span class="n">b</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">([</span><span class="mi">3</span><span class="p">,</span><span class="mi">4</span><span class="p">])</span>
<span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;The dot product of </span><span class="si">{</span><span class="n">a</span><span class="si">}</span><span class="s2"> and </span><span class="si">{</span><span class="n">b</span><span class="si">}</span><span class="s2"> is: </span><span class="si">{</span><span class="n">np</span><span class="o">.</span><span class="n">dot</span><span class="p">(</span><span class="n">a</span><span class="p">,</span><span class="w"> </span><span class="n">b</span><span class="p">)</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
</code></pre></div>
<p>Executing this script requires a <code>python3</code> that has <code>numpy</code>. Using what we learned
in the previous section, we could startup a shell and just run it like so:</p>
<div class="highlight"><pre><span></span><code>$ nix-shell -p &#39;python311.withPackages (ps: with ps; [ numpy ])&#39; --run &#39;python3 foo.py&#39;
The dot product of [1 2] and [3 4] is: 11
</code></pre></div>
<p>But if we maintain the script ourselves, and if there are more dependencies, it
may be nice to encode those dependencies in source to make the script re-usable
without that bit of knowledge. That can be done by using <code>nix-shell</code> as a
<a href="https://en.wikipedia.org/wiki/Shebang_(Unix)">shebang</a>, like so:</p>
<div class="highlight"><pre><span></span><code><span class="ch">#!/usr/bin/env nix-shell</span>
<span class="c1">#!nix-shell -i python3 -p &quot;python3.withPackages(ps: [ ps.numpy ])&quot;</span>
<span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="nn">np</span>
<span class="n">a</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">])</span>
<span class="n">b</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">([</span><span class="mi">3</span><span class="p">,</span><span class="mi">4</span><span class="p">])</span>
<span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;The dot product of </span><span class="si">{</span><span class="n">a</span><span class="si">}</span><span class="s2"> and </span><span class="si">{</span><span class="n">b</span><span class="si">}</span><span class="s2"> is: </span><span class="si">{</span><span class="n">np</span><span class="o">.</span><span class="n">dot</span><span class="p">(</span><span class="n">a</span><span class="p">,</span><span class="w"> </span><span class="n">b</span><span class="p">)</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
</code></pre></div>
<p>Then we execute it, without requiring any environment setup at all!</p>
<div class="highlight"><pre><span></span><code>$<span class="w"> </span>./foo.py
The<span class="w"> </span>dot<span class="w"> </span>product<span class="w"> </span>of<span class="w"> </span><span class="o">[</span><span class="m">1</span><span class="w"> </span><span class="m">2</span><span class="o">]</span><span class="w"> </span>and<span class="w"> </span><span class="o">[</span><span class="m">3</span><span class="w"> </span><span class="m">4</span><span class="o">]</span><span class="w"> </span>is:<span class="w"> </span><span class="m">11</span>
</code></pre></div>
<p>If the dependencies are not available on the host where <code>foo.py</code> is executed, it
will build or download them from a Nix binary cache prior to starting up, prior
that it is executed on a machine with a multi-user nix installation.</p>
<p>This provides a way to ship a self bootstrapping Python script, akin to a
statically linked binary, where it can be run on any machine (provided nix is
installed) without having to assume that <code>numpy</code> is installed globally on the
system.</p>
<p>By default it is pulling the import checkout of Nixpkgs itself from our nix
channel, which is nice as it cache aligns with our other package builds, but we
can make it fully reproducible by pinning the <code>nixpkgs</code> import:</p>
<div class="highlight"><pre><span></span><code><span class="ch">#!/usr/bin/env nix-shell</span>
<span class="c1">#!nix-shell -i python3 -p &quot;python3.withPackages (ps: [ ps.numpy ])&quot;</span>
<span class="c1">#!nix-shell -I nixpkgs=https://github.com/NixOS/nixpkgs/archive/e51209796c4262bfb8908e3d6d72302fe4e96f5f.tar.gz</span>
<span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="nn">np</span>
<span class="n">a</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">])</span>
<span class="n">b</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">([</span><span class="mi">3</span><span class="p">,</span><span class="mi">4</span><span class="p">])</span>
<span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;The dot product of </span><span class="si">{</span><span class="n">a</span><span class="si">}</span><span class="s2"> and </span><span class="si">{</span><span class="n">b</span><span class="si">}</span><span class="s2"> is: </span><span class="si">{</span><span class="n">np</span><span class="o">.</span><span class="n">dot</span><span class="p">(</span><span class="n">a</span><span class="p">,</span><span class="w"> </span><span class="n">b</span><span class="p">)</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
</code></pre></div>
<p>This will execute with the exact same versions of Python 3.10, numpy, and system
dependencies a year from now as it does today, because it will always use
exactly git commit <code>e51209796c4262bfb8908e3d6d72302fe4e96f5f</code> of Nixpkgs for all
of the package versions.</p>
<p>This is also a great way to ensure the script executes identically on different
servers.</p>
<h5 id="load-environment-from-.nix-expression">Load environment from <code>.nix</code> expression</h5>
<p>We've now seen how to create an ad-hoc temporary shell session, and how to
create a single script with Python dependencies, but in the course of normal
development we're usually working in an entire package repository.</p>
<p>As explained <a href="https://nixos.org/manual/nix/stable/command-ref/nix-shell">in the <code>nix-shell</code> section</a> of the Nix manual, <code>nix-shell</code> can also load an expression from a <code>.nix</code> file.
Say we want to have Python 3.11, <code>numpy</code> and <code>toolz</code>, like before,
in an environment. We can add a <code>shell.nix</code> file describing our dependencies:</p>
<div class="highlight"><pre><span></span><code><span class="k">with</span> <span class="nb">import</span> <span class="l">&lt;nixpkgs&gt;</span> <span class="p">{};</span>
<span class="p">(</span>python311<span class="o">.</span>withPackages <span class="p">(</span>ps<span class="p">:</span> <span class="k">with</span> ps<span class="p">;</span> <span class="p">[</span>
numpy
toolz
<span class="p">]))</span><span class="o">.</span>env
</code></pre></div>
<p>And then at the command line, just typing <code>nix-shell</code> produces the same
environment as before. In a normal project, we'll likely have many more
dependencies; this can provide a way for developers to share the environments
with each other and with CI builders.</p>
<p>What's happening here?</p>
<ol>
<li>We begin with importing the Nix Packages collections. <code>import &lt;nixpkgs&gt;</code>
imports the <code>&lt;nixpkgs&gt;</code> function, <code>{}</code> calls it and the <code>with</code> statement
brings all attributes of <code>nixpkgs</code> in the local scope. These attributes form
the main package set.</li>
<li>Then we create a Python 3.11 environment with the <a href="#python.withpackages-function"><code>withPackages</code></a> function, as before.</li>
<li>The <a href="#python.withpackages-function"><code>withPackages</code></a> function expects us to provide a function as an argument
that takes the set of all Python packages and returns a list of packages to
include in the environment. Here, we select the packages <code>numpy</code> and <code>toolz</code>
from the package set.</li>
</ol>
<p>To combine this with <code>mkShell</code> you can:</p>
<div class="highlight"><pre><span></span><code><span class="k">with</span> <span class="nb">import</span> <span class="l">&lt;nixpkgs&gt;</span> <span class="p">{};</span>
<span class="k">let</span>
<span class="ss">pythonEnv</span> <span class="o">=</span> python311<span class="o">.</span>withPackages <span class="p">(</span>ps<span class="p">:</span> <span class="p">[</span>
ps<span class="o">.</span>numpy
ps<span class="o">.</span>toolz
<span class="p">]);</span>
<span class="k">in</span> mkShell <span class="p">{</span>
<span class="ss">packages</span> <span class="o">=</span> <span class="p">[</span>
pythonEnv
black
mypy
libffi
openssl
<span class="p">];</span>
<span class="p">}</span>
</code></pre></div>
<p>This will create a unified environment that has not just our Python interpreter
and its Python dependencies, but also tools like <code>black</code> or <code>mypy</code> and libraries
like <code>libffi</code> the <code>openssl</code> in scope. This is generic and can span any number of
tools or languages across the Nixpkgs ecosystem.</p>
<h5 id="installing-environments-globally-on-the-system">Installing environments globally on the system</h5>
<p>Up to now, we've been creating environments scoped to an ad-hoc shell session,
or a single script, or a single project. This is generally advisable, as it
avoids pollution across contexts.</p>
<p>However, sometimes we know we will often want a Python with some basic packages,
and want this available without having to enter into a shell or build context.
This can be useful to have things like vim/emacs editors and plugins or shell
tools "just work" without having to set them up, or when running other software
that expects packages to be installed globally.</p>
<p>To create your own custom environment, create a file in <code>~/.config/nixpkgs/overlays/</code>
that looks like this:</p>
<div class="highlight"><pre><span></span><code><span class="c1"># ~/.config/nixpkgs/overlays/myEnv.nix</span>
self<span class="p">:</span> super<span class="p">:</span> <span class="p">{</span>
<span class="ss">myEnv</span> <span class="o">=</span> super<span class="o">.</span>buildEnv <span class="p">{</span>
<span class="ss">name</span> <span class="o">=</span> <span class="s2">&quot;myEnv&quot;</span><span class="p">;</span>
<span class="ss">paths</span> <span class="o">=</span> <span class="p">[</span>
<span class="c1"># A Python 3 interpreter with some packages</span>
<span class="p">(</span>self<span class="o">.</span>python3<span class="o">.</span>withPackages <span class="p">(</span>
ps<span class="p">:</span> <span class="k">with</span> ps<span class="p">;</span> <span class="p">[</span>
pyflakes
pytest
black
<span class="p">]</span>
<span class="p">))</span>
<span class="c1"># Some other packages we&#39;d like as part of this env</span>
self<span class="o">.</span>mypy
self<span class="o">.</span>black
self<span class="o">.</span>ripgrep
self<span class="o">.</span>tmux
<span class="p">];</span>
<span class="p">};</span>
<span class="p">}</span>
</code></pre></div>
<p>You can then build and install this to your profile with:</p>
<div class="highlight"><pre><span></span><code>nix-env<span class="w"> </span>-iA<span class="w"> </span>myEnv
</code></pre></div>
<p>One limitation of this is that you can only have 1 Python env installed
globally, since they conflict on the <code>python</code> to load out of your <code>PATH</code>.</p>
<p>If you get a conflict or prefer to keep the setup clean, you can have <code>nix-env</code>
atomically <em>uninstall</em> all other imperatively installed packages and replace
your profile with just <code>myEnv</code> by using the <code>--replace</code> flag.</p>
<h5 id="environment-defined-in-etcnixosconfiguration.nix">Environment defined in <code>/etc/nixos/configuration.nix</code></h5>
<p>For the sake of completeness, here's how to install the environment system-wide
on NixOS.</p>
<div class="highlight"><pre><span></span><code><span class="p">{</span> <span class="c1"># ...</span>
environment<span class="o">.</span><span class="ss">systemPackages</span> <span class="o">=</span> <span class="k">with</span> pkgs<span class="p">;</span> <span class="p">[</span>
<span class="p">(</span>python310<span class="o">.</span>withPackages<span class="p">(</span>ps<span class="p">:</span> <span class="k">with</span> ps<span class="p">;</span> <span class="p">[</span> numpy toolz <span class="p">]))</span>
<span class="p">];</span>
<span class="p">}</span>
</code></pre></div>
<h3 id="developing-with-python">Developing with Python</h3>
<p>Above, we were mostly just focused on use cases and what to do to get started
creating working Python environments in nix.</p>
<p>Now that you know the basics to be up and running, it is time to take a step
back and take a deeper look at how Python packages are packaged on Nix.</p>
<h4 id="python-library-packages-in-nixpkgs">Python library packages in Nixpkgs</h4>
<p>With Nix all packages are built by functions. The main function in Nix for
building Python libraries is <a href="#buildpythonpackage-function"><code>buildPythonPackage</code></a>. Let's see how we can build the
<code>toolz</code> package.</p>
<div class="highlight"><pre><span></span><code><span class="p">{</span> lib
<span class="p">,</span> buildPythonPackage
<span class="p">,</span> fetchPypi
<span class="p">,</span> setuptools
<span class="p">}:</span>
buildPythonPackage <span class="k">rec</span> <span class="p">{</span>
<span class="ss">pname</span> <span class="o">=</span> <span class="s2">&quot;toolz&quot;</span><span class="p">;</span>
<span class="ss">version</span> <span class="o">=</span> <span class="s2">&quot;0.10.0&quot;</span><span class="p">;</span>
<span class="ss">pyproject</span> <span class="o">=</span> <span class="no">true</span><span class="p">;</span>
<span class="ss">src</span> <span class="o">=</span> fetchPypi <span class="p">{</span>
<span class="k">inherit</span> pname version<span class="p">;</span>
<span class="ss">hash</span> <span class="o">=</span> <span class="s2">&quot;sha256-CP3V73yWSArRHBLUct4hrNMjWZlvaaUlkpm1QP66RWA=&quot;</span><span class="p">;</span>
<span class="p">};</span>
<span class="ss">build-system</span> <span class="o">=</span> <span class="p">[</span>
setuptools
<span class="p">];</span>
<span class="c1"># has no tests</span>
<span class="ss">doCheck</span> <span class="o">=</span> <span class="no">false</span><span class="p">;</span>
<span class="ss">pythonImportsCheck</span> <span class="o">=</span> <span class="p">[</span>
<span class="s2">&quot;toolz.itertoolz&quot;</span>
<span class="s2">&quot;toolz.functoolz&quot;</span>
<span class="s2">&quot;toolz.dicttoolz&quot;</span>
<span class="p">];</span>
<span class="ss">meta</span> <span class="o">=</span> <span class="p">{</span>
<span class="ss">changelog</span> <span class="o">=</span> <span class="s2">&quot;https://github.com/pytoolz/toolz/releases/tag/</span><span class="si">${</span>version<span class="si">}</span><span class="s2">&quot;</span><span class="p">;</span>
<span class="ss">homepage</span> <span class="o">=</span> <span class="s2">&quot;https://github.com/pytoolz/toolz&quot;</span><span class="p">;</span>
<span class="ss">description</span> <span class="o">=</span> <span class="s2">&quot;List processing tools and functional utilities&quot;</span><span class="p">;</span>
<span class="ss">license</span> <span class="o">=</span> lib<span class="o">.</span>licenses<span class="o">.</span>bsd3<span class="p">;</span>
<span class="p">};</span>
<span class="p">}</span>
</code></pre></div>
<p>What happens here? The function <a href="#buildpythonpackage-function"><code>buildPythonPackage</code></a> is called and as argument
it accepts a set. In this case the set is a recursive set, <code>rec</code>. One of the
arguments is the name of the package, which consists of a basename (generally
following the name on PyPI) and a version. Another argument, <code>src</code> specifies the
source, which in this case is fetched from PyPI using the helper function
<code>fetchPypi</code>. The argument <code>doCheck</code> is used to set whether tests should be run
when building the package. Since there are no tests, we rely on <a href="#using-pythonimportscheck"><code>pythonImportsCheck</code></a>
to test whether the package can be imported. Furthermore, we specify some meta
information. The output of the function is a derivation.</p>
<p>An expression for <code>toolz</code> can be found in the Nixpkgs repository. As explained
in the introduction of this Python section, a derivation of <code>toolz</code> is available
for each interpreter version, e.g. <code>python311.pkgs.toolz</code> refers to the <code>toolz</code>
derivation corresponding to the CPython 3.11 interpreter.</p>
<p>The above example works when you're directly working on
<code>pkgs/top-level/python-packages.nix</code> in the Nixpkgs repository. Often though,
you will want to test a Nix expression outside of the Nixpkgs tree.</p>
<p>The following expression creates a derivation for the <code>toolz</code> package,
and adds it along with a <code>numpy</code> package to a Python environment.</p>
<div class="highlight"><pre><span></span><code><span class="k">with</span> <span class="nb">import</span> <span class="l">&lt;nixpkgs&gt;</span> <span class="p">{};</span>
<span class="p">(</span> <span class="k">let</span>
<span class="ss">my_toolz</span> <span class="o">=</span> python311<span class="o">.</span>pkgs<span class="o">.</span>buildPythonPackage <span class="k">rec</span> <span class="p">{</span>
<span class="ss">pname</span> <span class="o">=</span> <span class="s2">&quot;toolz&quot;</span><span class="p">;</span>
<span class="ss">version</span> <span class="o">=</span> <span class="s2">&quot;0.10.0&quot;</span><span class="p">;</span>
<span class="ss">pyproject</span> <span class="o">=</span> <span class="no">true</span><span class="p">;</span>
<span class="ss">src</span> <span class="o">=</span> fetchPypi <span class="p">{</span>
<span class="k">inherit</span> pname version<span class="p">;</span>
<span class="ss">hash</span> <span class="o">=</span> <span class="s2">&quot;sha256-CP3V73yWSArRHBLUct4hrNMjWZlvaaUlkpm1QP66RWA=&quot;</span><span class="p">;</span>
<span class="p">};</span>
<span class="ss">build-system</span> <span class="o">=</span> <span class="p">[</span>
python311<span class="o">.</span>pkgs<span class="o">.</span>setuptools
<span class="p">];</span>
<span class="c1"># has no tests</span>
<span class="ss">doCheck</span> <span class="o">=</span> <span class="no">false</span><span class="p">;</span>
<span class="ss">meta</span> <span class="o">=</span> <span class="p">{</span>
<span class="ss">homepage</span> <span class="o">=</span> <span class="s2">&quot;https://github.com/pytoolz/toolz/&quot;</span><span class="p">;</span>
<span class="ss">description</span> <span class="o">=</span> <span class="s2">&quot;List processing tools and functional utilities&quot;</span><span class="p">;</span>
<span class="c1"># [...]</span>
<span class="p">};</span>
<span class="p">};</span>
<span class="k">in</span> python311<span class="o">.</span>withPackages <span class="p">(</span>ps<span class="p">:</span> <span class="k">with</span> ps<span class="p">;</span> <span class="p">[</span>
numpy
my_toolz
<span class="p">])</span>
<span class="p">)</span><span class="o">.</span>env
</code></pre></div>
<p>Executing <code>nix-shell</code> will result in an environment in which you can use
Python 3.11 and the <code>toolz</code> package. As you can see we had to explicitly mention
for which Python version we want to build a package.</p>
<p>So, what did we do here? Well, we took the Nix expression that we used earlier
to build a Python environment, and said that we wanted to include our own
version of <code>toolz</code>, named <code>my_toolz</code>. To introduce our own package in the scope
of <a href="#python.withpackages-function"><code>withPackages</code></a> we used a <code>let</code> expression. You can see that we used
<code>ps.numpy</code> to select numpy from the nixpkgs package set (<code>ps</code>). We did not take
<code>toolz</code> from the Nixpkgs package set this time, but instead took our own version
that we introduced with the <code>let</code> expression.</p>
<h4 id="handling-dependencies">Handling dependencies</h4>
<p>Our example, <code>toolz</code>, does not have any dependencies on other Python packages or system libraries.
<a href="#buildpythonpackage-function"><code>buildPythonPackage</code></a> uses the the following arguments in the following circumstances:</p>
<ul>
<li><code>dependencies</code> - For Python runtime dependencies.</li>
<li><code>build-system</code> - For Python build-time requirements.</li>
<li><a href="#var-stdenv-buildInputs"><code>buildInputs</code></a> - For non-Python build-time requirements.</li>
<li><a href="#var-stdenv-nativeCheckInputs"><code>nativeCheckInputs</code></a> - For test dependencies</li>
</ul>
<p>Dependencies can belong to multiple arguments, for example if something is both a build time requirement &amp; a runtime dependency.</p>
<p>The following example shows which arguments are given to <a href="#buildpythonpackage-function"><code>buildPythonPackage</code></a> in
order to build <a href="https://github.com/blaze/datashape"><code>datashape</code></a>.</p>
<div class="highlight"><pre><span></span><code><span class="p">{</span> lib
<span class="p">,</span> buildPythonPackage
<span class="p">,</span> fetchPypi <span class="s2">&quot;build dependencies</span>
<span class="s2">, setuptools &quot;</span>dependencies
<span class="p">,</span> numpy<span class="p">,</span> multipledispatch<span class="p">,</span> python-dateutil <span class="s2">&quot;tests</span>
<span class="s2">, pytestCheckHook</span>
<span class="s2">}:</span>
<span class="s2">buildPythonPackage rec {</span>
<span class="s2"> pname = &quot;</span>datashape<span class="s2">&quot;;</span>
<span class="s2"> version = &quot;</span><span class="mf">0.4.7</span><span class="s2">&quot;;</span>
<span class="s2"> pyproject = true;</span>
<span class="s2"> src = fetchPypi {</span>
<span class="s2"> inherit pname version;</span>
<span class="s2"> hash = &quot;</span><span class="l">sha256-FLLvdm1MllKrgTGC6Gb0k0deZeVYvtCCLji/B7uhong</span><span class="o">=</span><span class="s2">&quot;;</span>
<span class="s2"> };</span>
<span class="s2"> build-system = [</span>
<span class="s2"> setuptools</span>
<span class="s2"> ];</span>
<span class="s2"> dependencies = [</span>
<span class="s2"> multipledispatch</span>
<span class="s2"> numpy</span>
<span class="s2"> python-dateutil</span>
<span class="s2"> ];</span>
<span class="s2"> nativeCheckInputs = [</span>
<span class="s2"> pytestCheckHook</span>
<span class="s2"> ];</span>
<span class="s2"> meta = {</span>
<span class="s2"> changelog = &quot;</span><span class="l">https://github.com/blaze/datashape/releases/tag/$</span><span class="p">{</span>version<span class="p">}</span><span class="s2">&quot;;</span>
<span class="s2"> homepage = &quot;</span><span class="l">https://github.com/ContinuumIO/datashape</span><span class="s2">&quot;;</span>
<span class="s2"> description = &quot;</span>Data description language<span class="s2">&quot;;</span>
<span class="s2"> license = lib.licenses.bsd2;</span>
<span class="s2"> };</span>
<span class="s2">}</span>
</code></pre></div>
<p>We can see several runtime dependencies, <code>numpy</code>, <code>multipledispatch</code>, and
<code>python-dateutil</code>. Furthermore, we have <a href="#var-stdenv-nativeCheckInputs"><code>nativeCheckInputs</code></a> with <code>pytestCheckHook</code>.
<code>pytestCheckHook</code> is a test runner hook and is only used during the <a href="#ssec-check-phase"><code>checkPhase</code></a> and is
therefore not added to <code>dependencies</code>.</p>
<p>In the previous case we had only dependencies on other Python packages to consider.
Occasionally you have also system libraries to consider. E.g., <code>lxml</code> provides
Python bindings to <code>libxml2</code> and <code>libxslt</code>. These libraries are only required
when building the bindings and are therefore added as <a href="#var-stdenv-buildInputs"><code>buildInputs</code></a>.</p>
<div class="highlight"><pre><span></span><code><span class="p">{</span> lib
<span class="p">,</span> buildPythonPackage
<span class="p">,</span> fetchPypi
<span class="p">,</span> setuptools
<span class="p">,</span> libxml2
<span class="p">,</span> libxslt
<span class="p">}:</span>
buildPythonPackage <span class="k">rec</span> <span class="p">{</span>
<span class="ss">pname</span> <span class="o">=</span> <span class="s2">&quot;lxml&quot;</span><span class="p">;</span>
<span class="ss">version</span> <span class="o">=</span> <span class="s2">&quot;3.4.4&quot;</span><span class="p">;</span>
<span class="ss">pyproject</span> <span class="o">=</span> <span class="no">true</span><span class="p">;</span>
<span class="ss">src</span> <span class="o">=</span> fetchPypi <span class="p">{</span>
<span class="k">inherit</span> pname version<span class="p">;</span>
<span class="ss">hash</span> <span class="o">=</span> <span class="s2">&quot;sha256-s9NiusRxFydHzaNRMjjxFcvWxfi45jGb9ql6eJJyQJk=&quot;</span><span class="p">;</span>
<span class="p">};</span>
<span class="ss">build-system</span> <span class="o">=</span> <span class="p">[</span>
setuptools
<span class="p">];</span>
<span class="ss">buildInputs</span> <span class="o">=</span> <span class="p">[</span>
libxml2
libxslt
<span class="p">];</span>
<span class="c1"># tests are meant to be ran &quot;in-place&quot; in the same directory as src</span>
<span class="ss">doCheck</span> <span class="o">=</span> <span class="no">false</span><span class="p">;</span>
<span class="ss">pythonImportsCheck</span> <span class="o">=</span> <span class="p">[</span>
<span class="s2">&quot;lxml&quot;</span>
<span class="s2">&quot;lxml.etree&quot;</span>
<span class="p">];</span>
<span class="ss">meta</span> <span class="o">=</span> <span class="p">{</span>
<span class="ss">changelog</span> <span class="o">=</span> <span class="s2">&quot;https://github.com/lxml/lxml/releases/tag/lxml-</span><span class="si">${</span>version<span class="si">}</span><span class="s2">&quot;</span><span class="p">;</span>
<span class="ss">description</span> <span class="o">=</span> <span class="s2">&quot;Pythonic binding for the libxml2 and libxslt libraries&quot;</span><span class="p">;</span>
<span class="ss">homepage</span> <span class="o">=</span> <span class="s2">&quot;https://lxml.de&quot;</span><span class="p">;</span>
<span class="ss">license</span> <span class="o">=</span> lib<span class="o">.</span>licenses<span class="o">.</span>bsd3<span class="p">;</span>
<span class="ss">maintainers</span> <span class="o">=</span> <span class="k">with</span> lib<span class="o">.</span>maintainers<span class="p">;</span> <span class="p">[</span> sjourdois <span class="p">];</span>
<span class="p">};</span>
<span class="p">}</span>
</code></pre></div>
<p>In this example <code>lxml</code> and Nix are able to work out exactly where the relevant
files of the dependencies are. This is not always the case.</p>
<p>The example below shows bindings to The Fastest Fourier Transform in the West,
commonly known as FFTW. On Nix we have separate packages of FFTW for the
different types of floats (<code>"single"</code>, <code>"double"</code>, <code>"long-double"</code>). The
bindings need all three types, and therefore we add all three as <a href="#var-stdenv-buildInputs"><code>buildInputs</code></a>.
The bindings don't expect to find each of them in a different folder, and
therefore we have to set <code>LDFLAGS</code> and <code>CFLAGS</code>.</p>
<div class="highlight"><pre><span></span><code><span class="p">{</span> lib
<span class="p">,</span> buildPythonPackage
<span class="p">,</span> fetchPypi <span class="s2">&quot;build dependencies</span>
<span class="s2">, setuptools &quot;</span>dependencies
<span class="p">,</span> fftw
<span class="p">,</span> fftwFloat
<span class="p">,</span> fftwLongDouble
<span class="p">,</span> numpy
<span class="p">,</span> scipy
<span class="p">}:</span>
buildPythonPackage <span class="k">rec</span> <span class="p">{</span>
<span class="ss">pname</span> <span class="o">=</span> <span class="s2">&quot;pyfftw&quot;</span><span class="p">;</span>
<span class="ss">version</span> <span class="o">=</span> <span class="s2">&quot;0.9.2&quot;</span><span class="p">;</span>
<span class="ss">pyproject</span> <span class="o">=</span> <span class="no">true</span><span class="p">;</span>
<span class="ss">src</span> <span class="o">=</span> fetchPypi <span class="p">{</span>
<span class="k">inherit</span> pname version<span class="p">;</span>
<span class="ss">hash</span> <span class="o">=</span> <span class="s2">&quot;sha256-9ru2r6kwhUCaskiFoaPNuJCfCVoUL01J40byvRt4kHQ=&quot;</span><span class="p">;</span>
<span class="p">};</span>
<span class="ss">build-system</span> <span class="o">=</span> <span class="p">[</span>
setuptools
<span class="p">];</span>
<span class="ss">buildInputs</span> <span class="o">=</span> <span class="p">[</span>
fftw
fftwFloat
fftwLongDouble
<span class="p">];</span>
<span class="ss">dependencies</span> <span class="o">=</span> <span class="p">[</span>
numpy
scipy
<span class="p">];</span>
<span class="ss">preConfigure</span> <span class="o">=</span> <span class="s s-Multiline">&#39;&#39;</span>
<span class="s s-Multiline"> export LDFLAGS=&quot;-L</span><span class="si">${</span>fftw<span class="o">.</span>dev<span class="si">}</span><span class="s s-Multiline">/lib -L</span><span class="si">${</span>fftwFloat<span class="o">.</span>out<span class="si">}</span><span class="s s-Multiline">/lib -L</span><span class="si">${</span>fftwLongDouble<span class="o">.</span>out<span class="si">}</span><span class="s s-Multiline">/lib&quot;</span>
<span class="s s-Multiline"> export CFLAGS=&quot;-I</span><span class="si">${</span>fftw<span class="o">.</span>dev<span class="si">}</span><span class="s s-Multiline">/include -I</span><span class="si">${</span>fftwFloat<span class="o">.</span>dev<span class="si">}</span><span class="s s-Multiline">/include -I</span><span class="si">${</span>fftwLongDouble<span class="o">.</span>dev<span class="si">}</span><span class="s s-Multiline">/include&quot;</span>
<span class="s s-Multiline"> &#39;&#39;</span><span class="p">;</span>
<span class="c1"># Tests cannot import pyfftw. pyfftw works fine though.</span>
<span class="ss">doCheck</span> <span class="o">=</span> <span class="no">false</span><span class="p">;</span>
<span class="ss">pythonImportsCheck</span> <span class="o">=</span> <span class="p">[</span> <span class="s2">&quot;pyfftw&quot;</span> <span class="p">];</span>
<span class="ss">meta</span> <span class="o">=</span> <span class="p">{</span>
<span class="ss">changelog</span> <span class="o">=</span> <span class="s2">&quot;https://github.com/pyFFTW/pyFFTW/releases/tag/v</span><span class="si">${</span>version<span class="si">}</span><span class="s2">&quot;</span><span class="p">;</span>
<span class="ss">description</span> <span class="o">=</span> <span class="s2">&quot;Pythonic wrapper around FFTW, the FFT library, presenting a unified interface for all the supported transforms&quot;</span><span class="p">;</span>
<span class="ss">homepage</span> <span class="o">=</span> <span class="s2">&quot;http://hgomersall.github.com/pyFFTW&quot;</span><span class="p">;</span>
<span class="ss">license</span> <span class="o">=</span> <span class="k">with</span> lib<span class="o">.</span>licenses<span class="p">;</span> <span class="p">[</span> bsd2 bsd3 <span class="p">];</span>
<span class="p">};</span>
<span class="p">}</span>
</code></pre></div>
<p>Note also the line <a href="#var-stdenv-doCheck"><code>doCheck = false;</code></a>, we explicitly disabled running the test-suite.</p>
<h4 id="testing-python-packages">Testing Python Packages</h4>
<p>It is highly encouraged to have testing as part of the package build. This
helps to avoid situations where the package was able to build and install,
but is not usable at runtime.
Your package should provide its own <a href="#ssec-check-phase"><code>checkPhase</code></a>.</p>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>The <a href="#ssec-check-phase"><code>checkPhase</code></a> for python maps to the <code>installCheckPhase</code> on a
normal derivation. This is due to many python packages not behaving well
to the pre-installed version of the package. Version info, and natively
compiled extensions generally only exist in the install directory, and
thus can cause issues when a test suite asserts on that behavior.</p>
</div>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>Tests should only be disabled if they don't agree with nix
(e.g. external dependencies, network access, flakey tests), however,
as many tests should be enabled as possible. Failing tests can still be
a good indication that the package is not in a valid state.</p>
</div>
<h4 id="using-pytest">Using pytest</h4>
<p>Pytest is the most common test runner for python repositories. A trivial
test run would be:</p>
<div class="highlight"><pre><span></span><code><span class="p">{</span>
<span class="ss">nativeCheckInputs</span> <span class="o">=</span> <span class="p">[</span> pytest <span class="p">];</span>
<span class="ss">checkPhase</span> <span class="o">=</span> <span class="s s-Multiline">&#39;&#39;</span>
<span class="s s-Multiline"> runHook preCheck</span>
<span class="s s-Multiline"> pytest</span>
<span class="s s-Multiline"> runHook postCheck</span>
<span class="s s-Multiline"> &#39;&#39;</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div>
<p>However, many repositories' test suites do not translate well to nix's build
sandbox, and will generally need many tests to be disabled.</p>
<p>To filter tests using pytest, one can do the following:</p>
<div class="highlight"><pre><span></span><code><span class="p">{</span>
<span class="ss">nativeCheckInputs</span> <span class="o">=</span> <span class="p">[</span> pytest <span class="p">];</span>
<span class="c1"># avoid tests which need additional data or touch network</span>
<span class="ss">checkPhase</span> <span class="o">=</span> <span class="s s-Multiline">&#39;&#39;</span>
<span class="s s-Multiline"> runHook preCheck</span>
<span class="s s-Multiline"> pytest tests/ --ignore=tests/integration -k &#39;not download and not update&#39; --ignore=tests/test_failing.py</span>
<span class="s s-Multiline"> runHook postCheck</span>
<span class="s s-Multiline"> &#39;&#39;</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div>
<p><code>--ignore</code> will tell pytest to ignore that file or directory from being
collected as part of a test run. This is useful is a file uses a package
which is not available in nixpkgs, thus skipping that test file is much
easier than having to create a new package.</p>
<p><code>-k</code> is used to define a predicate for test names. In this example, we are
filtering out tests which contain <code>download</code> or <code>update</code> in their test case name.
Only one <code>-k</code> argument is allowed, and thus a long predicate should be concatenated
with “\” and wrapped to the next line.</p>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>In pytest==6.0.1, the use of “\” to continue a line (e.g. <code>-k 'not download \'</code>) has
been removed, in this case, it's recommended to use <code>pytestCheckHook</code>.</p>
</div>
<h4 id="using-pytestcheckhook">Using pytestCheckHook</h4>
<p><code>pytestCheckHook</code> is a convenient hook which will set up (or configure)
a <a href="#ssec-check-phase"><code>checkPhase</code></a> to run <code>pytest</code>. This is also beneficial
when a package may need many items disabled to run the test suite.
Most packages use <code>pytest</code> or <code>unittest</code>, which is compatible with <code>pytest</code>,
so you will most likely use <code>pytestCheckHook</code>.</p>
<p>Using the example above, the analogous <code>pytestCheckHook</code> usage would be:</p>
<div class="highlight"><pre><span></span><code><span class="p">{</span>
<span class="ss">nativeCheckInputs</span> <span class="o">=</span> <span class="p">[</span>
pytestCheckHook
<span class="p">];</span>
<span class="c1"># requires additional data</span>
<span class="ss">pytestFlagsArray</span> <span class="o">=</span> <span class="p">[</span>
<span class="s2">&quot;tests/&quot;</span>
<span class="s2">&quot;--ignore=tests/integration&quot;</span>
<span class="p">];</span>
<span class="ss">disabledTests</span> <span class="o">=</span> <span class="p">[</span>
<span class="c1"># touches network</span>
<span class="s2">&quot;download&quot;</span>
<span class="s2">&quot;update&quot;</span>
<span class="p">];</span>
<span class="ss">disabledTestPaths</span> <span class="o">=</span> <span class="p">[</span>
<span class="s2">&quot;tests/test_failing.py&quot;</span>
<span class="p">];</span>
<span class="p">}</span>
</code></pre></div>
<p>This is especially useful when tests need to be conditionally disabled,
for example:</p>
<div class="highlight"><pre><span></span><code><span class="p">{</span>
<span class="ss">disabledTests</span> <span class="o">=</span> <span class="p">[</span>
<span class="c1"># touches network</span>
<span class="s2">&quot;download&quot;</span>
<span class="s2">&quot;update&quot;</span>
<span class="p">]</span> <span class="o">++</span> lib<span class="o">.</span>optionals <span class="p">(</span>pythonAtLeast <span class="s2">&quot;3.8&quot;</span><span class="p">)</span> <span class="p">[</span>
<span class="c1"># broken due to python3.8 async changes</span>
<span class="s2">&quot;async&quot;</span>
<span class="p">]</span> <span class="o">++</span> lib<span class="o">.</span>optionals stdenv<span class="o">.</span>isDarwin <span class="p">[</span>
<span class="c1"># can fail when building with other packages</span>
<span class="s2">&quot;socket&quot;</span>
<span class="p">];</span>
<span class="p">}</span>
</code></pre></div>
<p>Trying to concatenate the related strings to disable tests in a regular
<a href="#ssec-check-phase"><code>checkPhase</code></a> would be much harder to read. This also enables us to comment on
why specific tests are disabled.</p>
<h4 id="using-pythonimportscheck">Using pythonImportsCheck</h4>
<p>Although unit tests are highly preferred to validate correctness of a package, not
all packages have test suites that can be run easily, and some have none at all.
To help ensure the package still works, <a href="#using-pythonimportscheck"><code>pythonImportsCheck</code></a> can attempt to import
the listed modules.</p>
<div class="highlight"><pre><span></span><code><span class="p">{</span>
<span class="ss">pythonImportsCheck</span> <span class="o">=</span> <span class="p">[</span>
<span class="s2">&quot;requests&quot;</span>
<span class="s2">&quot;urllib&quot;</span>
<span class="p">];</span>
<span class="p">}</span>
</code></pre></div>
<p>roughly translates to:</p>
<div class="highlight"><pre><span></span><code><span class="p">{</span>
<span class="ss">postCheck</span> <span class="o">=</span> <span class="s s-Multiline">&#39;&#39;</span>
<span class="s s-Multiline"> PYTHONPATH=$out/</span><span class="si">${</span>python<span class="o">.</span>sitePackages<span class="si">}</span><span class="s s-Multiline">:$PYTHONPATH</span>
<span class="s s-Multiline"> python -c &quot;import requests; import urllib&quot;</span>
<span class="s s-Multiline"> &#39;&#39;</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div>
<p>However, this is done in its own phase, and not dependent on whether <a href="#var-stdenv-doCheck"><code>doCheck = true;</code></a>.</p>
<p>This can also be useful in verifying that the package doesn't assume commonly
present packages (e.g. <code>setuptools</code>).</p>
<h4 id="using-pythonrelaxdepshook">Using pythonRelaxDepsHook</h4>
<p>It is common for upstream to specify a range of versions for its package
dependencies. This makes sense, since it ensures that the package will be built
with a subset of packages that is well tested. However, this commonly causes
issues when packaging in Nixpkgs, because the dependencies that this package
may need are too new or old for the package to build correctly. We also cannot
package multiple versions of the same package since this may cause conflicts
in <code>PYTHONPATH</code>.</p>
<p>One way to side step this issue is to relax the dependencies. This can be done
by either removing the package version range or by removing the package
declaration entirely. This can be done using the <code>pythonRelaxDepsHook</code> hook. For
example, given the following <code>requirements.txt</code> file:</p>
<div class="highlight"><pre><span></span><code>pkg1&lt;1.0
pkg2
pkg3&gt;=1.0,&lt;=2.0
</code></pre></div>
<p>we can do:</p>
<div class="highlight"><pre><span></span><code><span class="p">{</span>
<span class="ss">pythonRelaxDeps</span> <span class="o">=</span> <span class="p">[</span>
<span class="s2">&quot;pkg1&quot;</span>
<span class="s2">&quot;pkg3&quot;</span>
<span class="p">];</span>
<span class="ss">pythonRemoveDeps</span> <span class="o">=</span> <span class="p">[</span>
<span class="s2">&quot;pkg2&quot;</span>
<span class="p">];</span>
<span class="p">}</span>
</code></pre></div>
<p>which would result in the following <code>requirements.txt</code> file:</p>
<div class="highlight"><pre><span></span><code>pkg1
pkg3
</code></pre></div>
<p>Another option is to pass <code>true</code>, that will relax/remove all dependencies, for
example:</p>
<div class="highlight"><pre><span></span><code><span class="p">{</span>
<span class="ss">pythonRelaxDeps</span> <span class="o">=</span> <span class="no">true</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div>
<p>which would result in the following <code>requirements.txt</code> file:</p>
<div class="highlight"><pre><span></span><code>pkg1
pkg2
pkg3
</code></pre></div>
<p>In general you should always use <code>pythonRelaxDeps</code>, because <code>pythonRemoveDeps</code>
will convert build errors into runtime errors. However <code>pythonRemoveDeps</code> may
still be useful in exceptional cases, and also to remove dependencies wrongly
declared by upstream (for example, declaring <code>black</code> as a runtime dependency
instead of a dev dependency).</p>
<p>Keep in mind that while the examples above are done with <code>requirements.txt</code>,
<code>pythonRelaxDepsHook</code> works by modifying the resulting wheel file, so it should
work with any of the <a href="#setup-hooks">existing hooks</a>.</p>
<p>The <code>pythonRelaxDepsHook</code> has no effect on build time dependencies, such as
those specified in <code>build-system</code>. If a package requires incompatible build
time dependencies, they should be removed in <code>postPatch</code> through
<code>substituteInPlace</code> or similar.</p>
<h4 id="using-unittestcheckhook">Using unittestCheckHook</h4>
<p><code>unittestCheckHook</code> is a hook which will set up (or configure) a <a href="#ssec-check-phase"><code>checkPhase</code></a> to run <code>python -m unittest discover</code>:</p>
<div class="highlight"><pre><span></span><code><span class="p">{</span>
<span class="ss">nativeCheckInputs</span> <span class="o">=</span> <span class="p">[</span>
unittestCheckHook
<span class="p">];</span>
<span class="ss">unittestFlagsArray</span> <span class="o">=</span> <span class="p">[</span>
<span class="s2">&quot;-s&quot;</span> <span class="s2">&quot;tests&quot;</span> <span class="s2">&quot;-v&quot;</span>
<span class="p">];</span>
<span class="p">}</span>
</code></pre></div>
<p><code>pytest</code> is compatible with <code>unittest</code>, so in most cases you can use <code>pytestCheckHook</code> instead.</p>
<h4 id="using-sphinxhook">Using sphinxHook</h4>
<p>The <code>sphinxHook</code> is a helpful tool to build documentation and manpages
using the popular Sphinx documentation generator.
It is setup to automatically find common documentation source paths and
render them using the default <code>html</code> style.</p>
<div class="highlight"><pre><span></span><code><span class="p">{</span>
<span class="ss">outputs</span> <span class="o">=</span> <span class="p">[</span>
<span class="s2">&quot;out&quot;</span>
<span class="s2">&quot;doc&quot;</span>
<span class="p">];</span>
<span class="ss">nativeBuildInputs</span> <span class="o">=</span> <span class="p">[</span>
sphinxHook
<span class="p">];</span>
<span class="p">}</span>
</code></pre></div>
<p>The hook will automatically build and install the artifact into the
<code>doc</code> output, if it exists. It also provides an automatic diversion
for the artifacts of the <code>man</code> builder into the <code>man</code> target.</p>
<div class="highlight"><pre><span></span><code><span class="p">{</span>
<span class="ss">outputs</span> <span class="o">=</span> <span class="p">[</span>
<span class="s2">&quot;out&quot;</span>
<span class="s2">&quot;doc&quot;</span>
<span class="s2">&quot;man&quot;</span>
<span class="p">];</span>
<span class="c1"># Use multiple builders</span>
<span class="ss">sphinxBuilders</span> <span class="o">=</span> <span class="p">[</span>
<span class="s2">&quot;singlehtml&quot;</span>
<span class="s2">&quot;man&quot;</span>
<span class="p">];</span>
<span class="p">}</span>
</code></pre></div>
<p>Overwrite <code>sphinxRoot</code> when the hook is unable to find your
documentation source root.</p>
<div class="highlight"><pre><span></span><code><span class="p">{</span>
<span class="c1"># Configure sphinxRoot for uncommon paths</span>
<span class="ss">sphinxRoot</span> <span class="o">=</span> <span class="s2">&quot;weird/docs/path&quot;</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div>
<p>The hook is also available to packages outside the python ecosystem by
referencing it using <code>sphinxHook</code> from top-level.</p>
<h3 id="organising-your-packages">Organising your packages</h3>
<p>So far we discussed how you can use Python on Nix, and how you can develop with
it. We've looked at how you write expressions to package Python packages, and we
looked at how you can create environments in which specified packages are
available.</p>
<p>At some point you'll likely have multiple packages which you would
like to be able to use in different projects. In order to minimise unnecessary
duplication we now look at how you can maintain a repository with your
own packages. The important functions here are <code>import</code> and <code>callPackage</code>.</p>
<h3 id="including-a-derivation-using-callpackage">Including a derivation using <code>callPackage</code></h3>
<p>Earlier we created a Python environment using <a href="#python.withpackages-function"><code>withPackages</code></a>, and included the
<code>toolz</code> package via a <code>let</code> expression.
Let's split the package definition from the environment definition.</p>
<p>We first create a function that builds <code>toolz</code> in <code>~/path/to/toolz/release.nix</code></p>
<div class="highlight"><pre><span></span><code><span class="p">{</span> lib
<span class="p">,</span> buildPythonPackage
<span class="p">,</span> fetchPypi
<span class="p">,</span> setuptools
<span class="p">}:</span>
buildPythonPackage <span class="k">rec</span> <span class="p">{</span>
<span class="ss">pname</span> <span class="o">=</span> <span class="s2">&quot;toolz&quot;</span><span class="p">;</span>
<span class="ss">version</span> <span class="o">=</span> <span class="s2">&quot;0.10.0&quot;</span><span class="p">;</span>
<span class="ss">pyproject</span> <span class="o">=</span> <span class="no">true</span><span class="p">;</span>
<span class="ss">src</span> <span class="o">=</span> fetchPypi <span class="p">{</span>
<span class="k">inherit</span> pname version<span class="p">;</span>
<span class="ss">hash</span> <span class="o">=</span> <span class="s2">&quot;sha256-CP3V73yWSArRHBLUct4hrNMjWZlvaaUlkpm1QP66RWA=&quot;</span><span class="p">;</span>
<span class="p">};</span>
<span class="ss">build-system</span> <span class="o">=</span> <span class="p">[</span>
setuptools
<span class="p">];</span>
<span class="ss">meta</span> <span class="o">=</span> <span class="p">{</span>
<span class="ss">changelog</span> <span class="o">=</span> <span class="s2">&quot;https://github.com/pytoolz/toolz/releases/tag/</span><span class="si">${</span>version<span class="si">}</span><span class="s2">&quot;</span><span class="p">;</span>
<span class="ss">homepage</span> <span class="o">=</span> <span class="s2">&quot;https://github.com/pytoolz/toolz/&quot;</span><span class="p">;</span>
<span class="ss">description</span> <span class="o">=</span> <span class="s2">&quot;List processing tools and functional utilities&quot;</span><span class="p">;</span>
<span class="ss">license</span> <span class="o">=</span> lib<span class="o">.</span>licenses<span class="o">.</span>bsd3<span class="p">;</span>
<span class="p">};</span>
<span class="p">}</span>
</code></pre></div>
<p>It takes an argument <a href="#buildpythonpackage-function"><code>buildPythonPackage</code></a>. We now call this function using
<code>callPackage</code> in the definition of our environment</p>
<div class="highlight"><pre><span></span><code><span class="k">with</span> <span class="nb">import</span> <span class="l">&lt;nixpkgs&gt;</span> <span class="p">{};</span>
<span class="p">(</span> <span class="k">let</span>
<span class="ss">toolz</span> <span class="o">=</span> callPackage <span class="l">/path/to/toolz/release.nix</span> <span class="p">{</span>
<span class="ss">buildPythonPackage</span> <span class="o">=</span> python3Packages<span class="o">.</span>buildPythonPackage<span class="p">;</span>
<span class="p">};</span>
<span class="k">in</span> python3<span class="o">.</span>withPackages <span class="p">(</span>ps<span class="p">:</span> <span class="p">[</span>
ps<span class="o">.</span>numpy
toolz
<span class="p">])</span>
<span class="p">)</span><span class="o">.</span>env
</code></pre></div>
<p>Important to remember is that the Python version for which the package is made
depends on the <code>python</code> derivation that is passed to <a href="#buildpythonpackage-function"><code>buildPythonPackage</code></a>. Nix
tries to automatically pass arguments when possible, which is why generally you
don't explicitly define which <code>python</code> derivation should be used. In the above
example we use <a href="#buildpythonpackage-function"><code>buildPythonPackage</code></a> that is part of the set <code>python3Packages</code>,
and in this case the <code>python3</code> interpreter is automatically used.</p>
<h2 id="faq">FAQ</h2>
<h3 id="how-to-solve-circular-dependencies">How to solve circular dependencies?</h3>
<p>Consider the packages <code>A</code> and <code>B</code> that depend on each other. When packaging <code>B</code>,
a solution is to override package <code>A</code> not to depend on <code>B</code> as an input. The same
should also be done when packaging <code>A</code>.</p>
<h3 id="how-to-override-a-python-package">How to override a Python package?</h3>
<p>We can override the interpreter and pass <code>packageOverrides</code>. In the following
example we rename the <code>pandas</code> package and build it.</p>
<div class="highlight"><pre><span></span><code><span class="k">with</span> <span class="nb">import</span> <span class="l">&lt;nixpkgs&gt;</span> <span class="p">{};</span>
<span class="p">(</span><span class="k">let</span>
<span class="ss">python</span> <span class="o">=</span> <span class="k">let</span>
<span class="ss">packageOverrides</span> <span class="o">=</span> self<span class="p">:</span> super<span class="p">:</span> <span class="p">{</span>
<span class="ss">pandas</span> <span class="o">=</span> super<span class="o">.</span>pandas<span class="o">.</span>overridePythonAttrs<span class="p">(</span>old<span class="p">:</span> <span class="p">{</span><span class="ss">name</span><span class="o">=</span><span class="s2">&quot;foo&quot;</span><span class="p">;});</span>
<span class="p">};</span>
<span class="k">in</span> pkgs<span class="o">.</span>python310<span class="o">.</span>override <span class="p">{</span>
<span class="k">inherit</span> packageOverrides<span class="p">;</span>
<span class="p">};</span>
<span class="k">in</span> python<span class="o">.</span>withPackages <span class="p">(</span>ps<span class="p">:</span> <span class="p">[</span>
ps<span class="o">.</span>pandas
<span class="p">]))</span><span class="o">.</span>env
</code></pre></div>
<p>Using <code>nix-build</code> on this expression will build an environment that contains the
package <code>pandas</code> but with the new name <code>foo</code>.</p>
<p>All packages in the package set will use the renamed package. A typical use case
is to switch to another version of a certain package. For example, in the
Nixpkgs repository we have multiple versions of <code>django</code> and <code>scipy</code>. In the
following example we use a different version of <code>scipy</code> and create an
environment that uses it. All packages in the Python package set will now use
the updated <code>scipy</code> version.</p>
<div class="highlight"><pre><span></span><code><span class="k">with</span> <span class="nb">import</span> <span class="l">&lt;nixpkgs&gt;</span> <span class="p">{};</span>
<span class="p">(</span> <span class="k">let</span>
<span class="ss">packageOverrides</span> <span class="o">=</span> self<span class="p">:</span> super<span class="p">:</span> <span class="p">{</span>
<span class="ss">scipy</span> <span class="o">=</span> super<span class="o">.</span>scipy_0_17<span class="p">;</span>
<span class="p">};</span>
<span class="k">in</span> <span class="p">(</span>pkgs<span class="o">.</span>python310<span class="o">.</span>override <span class="p">{</span>
<span class="k">inherit</span> packageOverrides<span class="p">;</span>
<span class="p">})</span><span class="o">.</span>withPackages <span class="p">(</span>ps<span class="p">:</span> <span class="p">[</span>
ps<span class="o">.</span>blaze
<span class="p">])</span>
<span class="p">)</span><span class="o">.</span>env
</code></pre></div>
<p>The requested package <code>blaze</code> depends on <code>pandas</code> which itself depends on <code>scipy</code>.</p>
<p>If you want the whole of Nixpkgs to use your modifications, then you can use
<code>overlays</code> as explained in this manual. In the following example we build a
<code>inkscape</code> using a different version of <code>numpy</code>.</p>
<div class="highlight"><pre><span></span><code><span class="k">let</span>
<span class="ss">pkgs</span> <span class="o">=</span> <span class="nb">import</span> <span class="l">&lt;nixpkgs&gt;</span> <span class="p">{};</span>
<span class="ss">newpkgs</span> <span class="o">=</span> <span class="nb">import</span> pkgs<span class="o">.</span>path <span class="p">{</span> <span class="ss">overlays</span> <span class="o">=</span> <span class="p">[</span> <span class="p">(</span>self<span class="p">:</span> super<span class="p">:</span> <span class="p">{</span>
<span class="ss">python310</span> <span class="o">=</span> <span class="k">let</span>
<span class="ss">packageOverrides</span> <span class="o">=</span> python-self<span class="p">:</span> python-super<span class="p">:</span> <span class="p">{</span>
<span class="ss">numpy</span> <span class="o">=</span> python-super<span class="o">.</span>numpy_1_18<span class="p">;</span>
<span class="p">};</span>
<span class="k">in</span> super<span class="o">.</span>python310<span class="o">.</span>override <span class="p">{</span><span class="k">inherit</span> packageOverrides<span class="p">;};</span>
<span class="p">}</span> <span class="p">)</span> <span class="p">];</span> <span class="p">};</span>
<span class="k">in</span> newpkgs<span class="o">.</span>inkscape
</code></pre></div>
<h3 id="python-setup.py-bdist_wheel-cannot-create-.whl"><code>python setup.py bdist_wheel</code> cannot create .whl</h3>
<p>Executing <code>python setup.py bdist_wheel</code> in a <code>nix-shell</code>fails with</p>
<div class="highlight"><pre><span></span><code>ValueError: ZIP does not support timestamps before 1980
</code></pre></div>
<p>This is because files from the Nix store (which have a timestamp of the UNIX
epoch of January 1, 1970) are included in the .ZIP, but .ZIP archives follow the
DOS convention of counting timestamps from 1980.</p>
<p>The command <code>bdist_wheel</code> reads the <code>SOURCE_DATE_EPOCH</code> environment variable,
which <code>nix-shell</code> sets to 1. Unsetting this variable or giving it a value
corresponding to 1980 or later enables building wheels.</p>
<p>Use 1980 as timestamp:</p>
<div class="highlight"><pre><span></span><code>nix-shell<span class="w"> </span>--run<span class="w"> </span><span class="s2">&quot;SOURCE_DATE_EPOCH=315532800 python3 setup.py bdist_wheel&quot;</span>
</code></pre></div>
<p>or the current time:</p>
<div class="highlight"><pre><span></span><code>nix-shell<span class="w"> </span>--run<span class="w"> </span><span class="s2">&quot;SOURCE_DATE_EPOCH=</span><span class="k">$(</span>date<span class="w"> </span>+%s<span class="k">)</span><span class="s2"> python3 setup.py bdist_wheel&quot;</span>
</code></pre></div>
<p>or unset <code>SOURCE_DATE_EPOCH</code>:</p>
<div class="highlight"><pre><span></span><code>nix-shell<span class="w"> </span>--run<span class="w"> </span><span class="s2">&quot;unset SOURCE_DATE_EPOCH; python3 setup.py bdist_wheel&quot;</span>
</code></pre></div>
<h3 id="install_data-data_files-problems"><code>install_data</code> / <code>data_files</code> problems</h3>
<p>If you get the following error:</p>
<div class="highlight"><pre><span></span><code>could not create &#39;/nix/store/6l1bvljpy8gazlsw2aw9skwwp4pmvyxw-python-2.7.8/etc&#39;:
Permission denied
</code></pre></div>
<p>This is a <a href="https://github.com/pypa/setuptools/issues/130">known bug</a> in
<code>setuptools</code>. Setuptools <code>install_data</code> does not respect <code>--prefix</code>. An example
of such package using the feature is <code>pkgs/tools/X11/xpra/default.nix</code>.</p>
<p>As workaround install it as an extra <code>preInstall</code> step:</p>
<div class="highlight"><pre><span></span><code><span class="si">${</span><span class="nv">python</span><span class="p">.pythonOnBuildForHost.interpreter</span><span class="si">}</span><span class="w"> </span>setup.py<span class="w"> </span>install_data<span class="w"> </span>--install-dir<span class="o">=</span><span class="nv">$out</span><span class="w"> </span>--root<span class="o">=</span><span class="nv">$out</span>
sed<span class="w"> </span>-i<span class="w"> </span><span class="s1">&#39;/ = data\_files/d&#39;</span><span class="w"> </span>setup.py
</code></pre></div>
<h3 id="rationale-of-non-existent-global-site-packages">Rationale of non-existent global site-packages</h3>
<p>On most operating systems a global <code>site-packages</code> is maintained. This however
becomes problematic if you want to run multiple Python versions or have multiple
versions of certain libraries for your projects. Generally, you would solve such
issues by creating virtual environments using <code>virtualenv</code>.</p>
<p>On Nix each package has an isolated dependency tree which, in the case of
Python, guarantees the right versions of the interpreter and libraries or
packages are available. There is therefore no need to maintain a global <code>site-packages</code>.</p>
<p>If you want to create a Python environment for development, then the recommended
method is to use <code>nix-shell</code>, either with or without the <a href="#python.buildenv-function"><code>python.buildEnv</code></a>
function.</p>
<h3 id="how-to-consume-python-modules-using-pip-in-a-virtual-environment-like-i-am-used-to-on-other-operating-systems">How to consume Python modules using pip in a virtual environment like I am used to on other Operating Systems?</h3>
<p>While this approach is not very idiomatic from Nix perspective, it can still be
useful when dealing with pre-existing projects or in situations where it's not
feasible or desired to write derivations for all required dependencies.</p>
<p>This is an example of a <code>default.nix</code> for a <code>nix-shell</code>, which allows to consume
a virtual environment created by <code>venv</code>, and install Python modules through
<code>pip</code> the traditional way.</p>
<p>Create this <code>default.nix</code> file, together with a <code>requirements.txt</code> and
execute <code>nix-shell</code>.</p>
<div class="highlight"><pre><span></span><code><span class="k">with</span> <span class="nb">import</span> <span class="l">&lt;nixpkgs&gt;</span> <span class="p">{</span> <span class="p">};</span>
<span class="k">let</span>
<span class="ss">pythonPackages</span> <span class="o">=</span> python3Packages<span class="p">;</span>
<span class="k">in</span> pkgs<span class="o">.</span>mkShell <span class="k">rec</span> <span class="p">{</span>
<span class="ss">name</span> <span class="o">=</span> <span class="s2">&quot;impurePythonEnv&quot;</span><span class="p">;</span>
<span class="ss">venvDir</span> <span class="o">=</span> <span class="s2">&quot;./.venv&quot;</span><span class="p">;</span>
<span class="ss">buildInputs</span> <span class="o">=</span> <span class="p">[</span>
<span class="c1"># A Python interpreter including the &#39;venv&#39; module is required to bootstrap</span>
<span class="c1"># the environment.</span>
pythonPackages<span class="o">.</span>python
<span class="c1"># This executes some shell code to initialize a venv in $venvDir before</span>
<span class="c1"># dropping into the shell</span>
pythonPackages<span class="o">.</span>venvShellHook
<span class="c1"># Those are dependencies that we would like to use from nixpkgs, which will</span>
<span class="c1"># add them to PYTHONPATH and thus make them accessible from within the venv.</span>
pythonPackages<span class="o">.</span>numpy
pythonPackages<span class="o">.</span>requests
<span class="c1"># In this particular example, in order to compile any binary extensions they may</span>
<span class="c1"># require, the Python modules listed in the hypothetical requirements.txt need</span>
<span class="c1"># the following packages to be installed locally:</span>
taglib
openssl
git
libxml2
libxslt
libzip
zlib
<span class="p">];</span>
<span class="c1"># Run this command, only after creating the virtual environment</span>
<span class="ss">postVenvCreation</span> <span class="o">=</span> <span class="s s-Multiline">&#39;&#39;</span>
<span class="s s-Multiline"> unset SOURCE_DATE_EPOCH</span>
<span class="s s-Multiline"> pip install -r requirements.txt</span>
<span class="s s-Multiline"> &#39;&#39;</span><span class="p">;</span>
<span class="c1"># Now we can execute any commands within the virtual environment.</span>
<span class="c1"># This is optional and can be left out to run pip manually.</span>
<span class="ss">postShellHook</span> <span class="o">=</span> <span class="s s-Multiline">&#39;&#39;</span>
<span class="s s-Multiline"> # allow pip to install wheels</span>
<span class="s s-Multiline"> unset SOURCE_DATE_EPOCH</span>
<span class="s s-Multiline"> &#39;&#39;</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div>
<p>In case the supplied venvShellHook is insufficient, or when Python 2 support is
needed, you can define your own shell hook and adapt to your needs like in the
following example:</p>
<div class="highlight"><pre><span></span><code><span class="k">with</span> <span class="nb">import</span> <span class="l">&lt;nixpkgs&gt;</span> <span class="p">{</span> <span class="p">};</span>
<span class="k">let</span>
<span class="ss">venvDir</span> <span class="o">=</span> <span class="s2">&quot;./.venv&quot;</span><span class="p">;</span>
<span class="ss">pythonPackages</span> <span class="o">=</span> python3Packages<span class="p">;</span>
<span class="k">in</span> pkgs<span class="o">.</span>mkShell <span class="k">rec</span> <span class="p">{</span>
<span class="ss">name</span> <span class="o">=</span> <span class="s2">&quot;impurePythonEnv&quot;</span><span class="p">;</span>
<span class="ss">buildInputs</span> <span class="o">=</span> <span class="p">[</span>
pythonPackages<span class="o">.</span>python
<span class="c1"># Needed when using python 2.7</span>
<span class="c1"># pythonPackages.virtualenv</span>
<span class="c1"># ...</span>
<span class="p">];</span>
<span class="c1"># This is very close to how venvShellHook is implemented, but</span>
<span class="c1"># adapted to use &#39;virtualenv&#39;</span>
<span class="ss">shellHook</span> <span class="o">=</span> <span class="s s-Multiline">&#39;&#39;</span>
<span class="s s-Multiline"> SOURCE_DATE_EPOCH=$(date +%s)</span>
<span class="s s-Multiline"> if [ -d &quot;</span><span class="si">${</span>venvDir<span class="si">}</span><span class="s s-Multiline">&quot; ]; then</span>
<span class="s s-Multiline"> echo &quot;Skipping venv creation, &#39;${venvDir}&#39; already exists&quot;</span>
<span class="s s-Multiline"> else</span>
<span class="s s-Multiline"> echo &quot;Creating new venv environment in path: &#39;${venvDir}&#39;&quot;</span>
<span class="s s-Multiline"> # Note that the module venv was only introduced in python 3, so for 2.7</span>
<span class="s s-Multiline"> # this needs to be replaced with a call to virtualenv</span>
<span class="s s-Multiline"> </span><span class="si">${</span>pythonPackages<span class="o">.</span>python<span class="o">.</span>interpreter<span class="si">}</span><span class="s s-Multiline"> -m venv &quot;</span><span class="si">${</span>venvDir<span class="si">}</span><span class="s s-Multiline">&quot;</span>
<span class="s s-Multiline"> fi</span>
<span class="s s-Multiline"> # Under some circumstances it might be necessary to add your virtual</span>
<span class="s s-Multiline"> # environment to PYTHONPATH, which you can do here too;</span>
<span class="s s-Multiline"> # PYTHONPATH=$PWD/</span><span class="si">${</span>venvDir<span class="si">}</span><span class="s s-Multiline">/</span><span class="si">${</span>pythonPackages<span class="o">.</span>python<span class="o">.</span>sitePackages<span class="si">}</span><span class="s s-Multiline">/:$PYTHONPATH</span>
<span class="s s-Multiline"> source &quot;</span><span class="si">${</span>venvDir<span class="si">}</span><span class="s s-Multiline">/bin/activate&quot;</span>
<span class="s s-Multiline"> # As in the previous example, this is optional.</span>
<span class="s s-Multiline"> pip install -r requirements.txt</span>
<span class="s s-Multiline"> &#39;&#39;</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div>
<p>Note that the <code>pip install</code> is an imperative action. So every time <code>nix-shell</code>
is executed it will attempt to download the Python modules listed in
requirements.txt. However these will be cached locally within the <code>virtualenv</code>
folder and not downloaded again.</p>
<h3 id="how-to-override-a-python-package-from-configuration.nix">How to override a Python package from <code>configuration.nix</code>?</h3>
<p>If you need to change a package's attribute(s) from <code>configuration.nix</code> you could do:</p>
<div class="highlight"><pre><span></span><code><span class="p">{</span>
nixpkgs<span class="o">.</span>config<span class="o">.</span><span class="ss">packageOverrides</span> <span class="o">=</span> super<span class="p">:</span> <span class="p">{</span>
<span class="ss">python3</span> <span class="o">=</span> super<span class="o">.</span>python3<span class="o">.</span>override <span class="p">{</span>
<span class="ss">packageOverrides</span> <span class="o">=</span> python-self<span class="p">:</span> python-super<span class="p">:</span> <span class="p">{</span>
<span class="ss">twisted</span> <span class="o">=</span> python-super<span class="o">.</span>twisted<span class="o">.</span>overridePythonAttrs <span class="p">(</span>oldAttrs<span class="p">:</span> <span class="p">{</span>
<span class="ss">src</span> <span class="o">=</span> super<span class="o">.</span>fetchPypi <span class="p">{</span>
<span class="ss">pname</span> <span class="o">=</span> <span class="s2">&quot;Twisted&quot;</span><span class="p">;</span>
<span class="ss">version</span> <span class="o">=</span> <span class="s2">&quot;19.10.0&quot;</span><span class="p">;</span>
<span class="ss">hash</span> <span class="o">=</span> <span class="s2">&quot;sha256-c5S6fycq5yKnTz2Wnc9Zm8TvCTvDkgOHSKSQ8XJKUV0=&quot;</span><span class="p">;</span>
<span class="ss">extension</span> <span class="o">=</span> <span class="s2">&quot;tar.bz2&quot;</span><span class="p">;</span>
<span class="p">};</span>
<span class="p">});</span>
<span class="p">};</span>
<span class="p">};</span>
<span class="p">};</span>
<span class="p">}</span>
</code></pre></div>
<p><code>python3Packages.twisted</code> is now globally overridden.
All packages and also all NixOS services that reference <code>twisted</code>
(such as <code>services.buildbot-worker</code>) now use the new definition.
Note that <code>python-super</code> refers to the old package set and <code>python-self</code>
to the new, overridden version.</p>
<p>To modify only a Python package set instead of a whole Python derivation, use
this snippet:</p>
<div class="highlight"><pre><span></span><code><span class="p">{</span>
<span class="ss">myPythonPackages</span> <span class="o">=</span> python3Packages<span class="o">.</span>override <span class="p">{</span>
<span class="ss">overrides</span> <span class="o">=</span> self<span class="p">:</span> super<span class="p">:</span> <span class="p">{</span>
<span class="ss">twisted</span> <span class="o">=</span> <span class="l">&lt;...&gt;</span><span class="p">;</span>
<span class="p">};</span>
<span class="p">};</span>
<span class="p">}</span>
</code></pre></div>
<h3 id="how-to-override-a-python-package-using-overlays">How to override a Python package using overlays?</h3>
<p>Use the following overlay template:</p>
<div class="highlight"><pre><span></span><code>self<span class="p">:</span> super<span class="p">:</span> <span class="p">{</span>
<span class="ss">python</span> <span class="o">=</span> super<span class="o">.</span>python<span class="o">.</span>override <span class="p">{</span>
<span class="ss">packageOverrides</span> <span class="o">=</span> python-self<span class="p">:</span> python-super<span class="p">:</span> <span class="p">{</span>
<span class="ss">twisted</span> <span class="o">=</span> python-super<span class="o">.</span>twisted<span class="o">.</span>overrideAttrs <span class="p">(</span>oldAttrs<span class="p">:</span> <span class="p">{</span>
<span class="ss">src</span> <span class="o">=</span> super<span class="o">.</span>fetchPypi <span class="p">{</span>
<span class="ss">pname</span> <span class="o">=</span> <span class="s2">&quot;Twisted&quot;</span><span class="p">;</span>
<span class="ss">version</span> <span class="o">=</span> <span class="s2">&quot;19.10.0&quot;</span><span class="p">;</span>
<span class="ss">hash</span> <span class="o">=</span> <span class="s2">&quot;sha256-c5S6fycq5yKnTz2Wnc9Zm8TvCTvDkgOHSKSQ8XJKUV0=&quot;</span><span class="p">;</span>
<span class="ss">extension</span> <span class="o">=</span> <span class="s2">&quot;tar.bz2&quot;</span><span class="p">;</span>
<span class="p">};</span>
<span class="p">});</span>
<span class="p">};</span>
<span class="p">};</span>
<span class="p">}</span>
</code></pre></div>
<h3 id="how-to-override-a-python-package-for-all-python-versions-using-extensions">How to override a Python package for all Python versions using extensions?</h3>
<p>The following overlay overrides the call to <a href="#buildpythonpackage-function"><code>buildPythonPackage</code></a> for the
<code>foo</code> package for all interpreters by appending a Python extension to the
<code>pythonPackagesExtensions</code> list of extensions.</p>
<div class="highlight"><pre><span></span><code>final<span class="p">:</span> prev<span class="p">:</span> <span class="p">{</span>
<span class="ss">pythonPackagesExtensions</span> <span class="o">=</span> prev<span class="o">.</span>pythonPackagesExtensions <span class="o">++</span> <span class="p">[</span>
<span class="p">(</span>
python-final<span class="p">:</span> python-prev<span class="p">:</span> <span class="p">{</span>
<span class="ss">foo</span> <span class="o">=</span> python-prev<span class="o">.</span>foo<span class="o">.</span>overridePythonAttrs <span class="p">(</span>oldAttrs<span class="p">:</span> <span class="p">{</span>
<span class="c1"># ...</span>
<span class="p">});</span>
<span class="p">}</span>
<span class="p">)</span>
<span class="p">];</span>
<span class="p">}</span>
</code></pre></div>
<h3 id="how-to-use-intels-mkl-with-numpy-and-scipy">How to use Intels MKL with numpy and scipy?</h3>
<p>MKL can be configured using an overlay. See the section "<a href="#sec-overlays-alternatives-blas-lapack">Using overlays to
configure alternatives</a>".</p>
<h3 id="what-inputs-do-setup_requires-install_requires-and-tests_require-map-to">What inputs do <code>setup_requires</code>, <code>install_requires</code> and <code>tests_require</code> map to?</h3>
<p>In a <code>setup.py</code> or <code>setup.cfg</code> it is common to declare dependencies:</p>
<ul>
<li><code>setup_requires</code> corresponds to <code>build-system</code></li>
<li><code>install_requires</code> corresponds to <code>dependencies</code></li>
<li><code>tests_require</code> corresponds to <a href="#var-stdenv-nativeCheckInputs"><code>nativeCheckInputs</code></a></li>
</ul>
<h3 id="optimizations">How to enable interpreter optimizations?</h3>
<p>The Python interpreters are by default not built with optimizations enabled, because
the builds are in that case not reproducible. To enable optimizations, override the
interpreter of interest, e.g using</p>
<div class="highlight"><pre><span></span><code><span class="k">let</span>
<span class="ss">pkgs</span> <span class="o">=</span> <span class="nb">import</span> <span class="l">./.</span> <span class="p">{};</span>
<span class="ss">mypython</span> <span class="o">=</span> pkgs<span class="o">.</span>python3<span class="o">.</span>override <span class="p">{</span>
<span class="ss">enableOptimizations</span> <span class="o">=</span> <span class="no">true</span><span class="p">;</span>
<span class="ss">reproducibleBuild</span> <span class="o">=</span> <span class="no">false</span><span class="p">;</span>
<span class="ss">self</span> <span class="o">=</span> mypython<span class="p">;</span>
<span class="p">};</span>
<span class="k">in</span> mypython
</code></pre></div>
<h3 id="python-optional-dependencies">How to add optional dependencies?</h3>
<p>Some packages define optional dependencies for additional features. With
<code>setuptools</code> this is called <code>extras_require</code> and <code>flit</code> calls it
<code>extras-require</code>, while PEP 621 calls these <code>optional-dependencies</code>.</p>
<div class="highlight"><pre><span></span><code><span class="p">{</span>
<span class="ss">optional-dependencies</span> <span class="o">=</span> <span class="p">{</span>
<span class="ss">complete</span> <span class="o">=</span> <span class="p">[</span> distributed <span class="p">];</span>
<span class="p">};</span>
<span class="p">}</span>
</code></pre></div>
<p>and letting the package requiring the extra add the list to its dependencies</p>
<div class="highlight"><pre><span></span><code><span class="p">{</span>
<span class="ss">dependencies</span> <span class="o">=</span> <span class="p">[</span>
<span class="c1"># ...</span>
<span class="p">]</span> <span class="o">++</span> dask<span class="o">.</span>optional-dependencies<span class="o">.</span>complete<span class="p">;</span>
<span class="p">}</span>
</code></pre></div>
<p>This method is using <code>passthru</code>, meaning that changing <code>optional-dependencies</code> of a package won't cause it to rebuild.</p>
<p>Note this method is preferred over adding parameters to builders, as that can
result in packages depending on different variants and thereby causing
collisions.</p>
<h3 id="tools">How to contribute a Python package to nixpkgs?</h3>
<p>Packages inside nixpkgs must use the <a href="#buildpythonpackage-function"><code>buildPythonPackage</code></a> or <a href="#buildpythonapplication-function"><code>buildPythonApplication</code></a> function directly,
because we can only provide security support for non-vendored dependencies.</p>
<p>We recommend <a href="https://github.com/nix-community/nix-init">nix-init</a> for creating new python packages within nixpkgs,
as it already prefetches the source, parses dependencies for common formats and prefills most things in <code>meta</code>.</p>
<p>See also <a href="#contributing">contributing section</a>.</p>
<h3 id="deterministic-builds">Are Python interpreters built deterministically?</h3>
<p>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
<code>nix-shell</code>.</p>
<p>When the environment variable <code>DETERMINISTIC_BUILD</code> is set, all bytecode will
have timestamp 1. The <a href="#buildpythonpackage-function"><code>buildPythonPackage</code></a> function sets <code>DETERMINISTIC_BUILD=1</code>
and <a href="https://docs.python.org/3.11/using/cmdline.html#envvar-PYTHONHASHSEED">PYTHONHASHSEED=0</a>.
Both are also exported in <code>nix-shell</code>.</p>
<h3 id="automatic-tests">How to provide automatic tests to Python packages?</h3>
<p>It is recommended to test packages as part of the build process.
Source distributions (<code>sdist</code>) often include test files, but not always.</p>
<p>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.</p>
<h4 id="common-issues">Common issues</h4>
<ul>
<li>Non-working tests can often be deselected. Most Python modules
do follow the standard test protocol where the pytest runner can be used.
<code>pytest</code> supports the <code>-k</code> and <code>--ignore</code> parameters to ignore test
methods or classes as well as whole files. For <code>pytestCheckHook</code> these are
conveniently exposed as <code>disabledTests</code> and <code>disabledTestPaths</code> respectively.</li>
</ul>
<div class="highlight"><pre><span></span><code>buildPythonPackage <span class="p">{</span>
<span class="c1"># ...</span>
<span class="ss">nativeCheckInputs</span> <span class="o">=</span> <span class="p">[</span>
pytestCheckHook
<span class="p">];</span>
<span class="ss">disabledTests</span> <span class="o">=</span> <span class="p">[</span>
<span class="s2">&quot;function_name&quot;</span>
<span class="s2">&quot;other_function&quot;</span>
<span class="p">];</span>
<span class="ss">disabledTestPaths</span> <span class="o">=</span> <span class="p">[</span>
<span class="s2">&quot;this/file.py&quot;</span>
<span class="p">];</span>
<span class="p">}</span>
</code></pre></div>
<ul>
<li>Tests that attempt to access <code>$HOME</code> can be fixed by using the following
work-around before running tests (e.g. <code>preCheck</code>): <code>export HOME=$(mktemp -d)</code></li>
<li>Compiling with Cython causes tests to fail with a <code>ModuleNotLoadedError</code>.
This can be fixed with two changes in the derivation: 1) replacing <code>pytest</code> with
<code>pytestCheckHook</code> and 2) adding a <code>preCheck</code> containing <code>cd $out</code> to run
tests within the built output.</li>
</ul>
<h2 id="contributing">Contributing</h2>
<h3 id="contributing-guidelines">Contributing guidelines</h3>
<p>The following rules are desired to be respected:</p>
<ul>
<li>Python libraries are called from <code>python-packages.nix</code> and packaged with
<a href="#buildpythonpackage-function"><code>buildPythonPackage</code></a>. The expression of a library should be in
<code>pkgs/development/python-modules/&lt;name&gt;/default.nix</code>.</li>
<li>Python applications live outside of <code>python-packages.nix</code> and are packaged
with <a href="#buildpythonapplication-function"><code>buildPythonApplication</code></a>.</li>
<li>Make sure libraries build for all Python interpreters.
If it fails to build on some Python versions, consider disabling them by setting <code>disable = pythonAtLeast "3.x"</code> along with a comment.</li>
<li>The two parameters, <code>pyproject</code> and <code>build-system</code> are set to avoid the legacy setuptools/distutils build.</li>
<li>Only unversioned attributes (e.g. <code>pydantic</code>, but not <code>pypdantic_1</code>) can be included in <code>dependencies</code>,
since due to <code>PYTHONPATH</code> limitations we can only ever support a single version for libraries
without running into duplicate module name conflicts.</li>
<li>The version restrictions of <code>dependencies</code> can be relaxed by <a href="#using-pythonrelaxdepshook"><code>pythonRelaxDepsHook</code></a>.</li>
<li>Make sure the tests are enabled using for example <a href="#using-pytestcheckhook"><code>pytestCheckHook</code></a> 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 why.</li>
<li><code>pythonImportsCheck</code> is set. This is still a good smoke test even if <code>pytestCheckHook</code> is set.</li>
<li><code>meta.platforms</code> takes the default value in many cases.
It does not need to be set explicitly unless the package requires a specific platform.</li>
<li>The file is formatted with <code>nixfmt-rfc-style</code>.</li>
<li>Commit names of Python libraries should reflect that they are Python
libraries, so write for example <code>python311Packages.numpy: 1.11 -&gt; 1.12</code>.
It is highly recommended to specify the current default version to enable
automatic build by ofborg.
Note that <code>pythonPackages</code> is an alias for <code>python27Packages</code>.</li>
<li>Attribute names in <code>python-packages.nix</code> as well as <code>pname</code>s should match the
library's name on PyPI, but be normalized according to <a href="https://www.python.org/dev/peps/pep-0503/#normalized-names">PEP
0503</a>. This means
that characters should be converted to lowercase and <code>.</code> and <code>_</code> should be
replaced by a single <code>-</code> (foo-bar-baz instead of Foo__Bar.baz).
If necessary, <code>pname</code> has to be given a different value within <code>fetchPypi</code>.</li>
<li>Packages from sources such as GitHub and GitLab that do not exist on PyPI
should not use a name that is already used on PyPI. When possible, they should
use the package repository name prefixed with the owner (e.g. organization) name
and using a <code>-</code> as delimiter.</li>
<li>Attribute names in <code>python-packages.nix</code> should be sorted alphanumerically to
avoid merge conflicts and ease locating attributes.</li>
</ul>
<p>This list is useful for reviewers as well as for self-checking when submitting packages.</p>
<h2 id="python-package-set-maintenance">Package set maintenance</h2>
<p>The whole Python package set has a lot of packages that do not see regular
updates, because they either are a very fragile component in the Python
ecosystem, like for example the <code>hypothesis</code> package, or packages that have
no maintainer, so maintenance falls back to the package set maintainers.</p>
<h3 id="python-package-bulk-updates">Updating packages in bulk</h3>
<p>There is a tool to update alot of python libraries in bulk, it exists at
<code>maintainers/scripts/update-python-libraries</code> with this repository.</p>
<p>It can quickly update minor or major versions for all packages selected
and create update commits, and supports the <code>fetchPypi</code>, <code>fetchurl</code> and
<code>fetchFromGitHub</code> fetchers. When updating lots of packages that are
hosted on GitHub, exporting a <code>GITHUB_API_TOKEN</code> is highly recommended.</p>
<p>Updating packages in bulk leads to lots of breakages, which is why a
stabilization period on the <code>python-updates</code> branch is required.</p>
<p>If a package is fragile and often breaks during these bulks updates, it
may be reasonable to set <code>passthru.skipBulkUpdate = true</code> in the
derivation. This decision should not be made on a whim and should
always be supported by a qualifying comment.</p>
<p>Once the branch is sufficiently stable it should normally be merged
into the <code>staging</code> branch.</p>
<p>An exemplary call to update all python libraries between minor versions
would be:</p>
<div class="highlight"><pre><span></span><code>$ maintainers/scripts/update-python-libraries --target minor --commit --use-pkgs-prefix pkgs/development/python-modules/**/default.nix
</code></pre></div>
<h2 id="python-cpython-update-schedule">CPython Update Schedule</h2>
<p>With <a href="https://www.python.org/dev/peps/pep-0602/">PEP 602</a>, CPython now
follows a yearly release cadence. In nixpkgs, all supported interpreters
are made available, but only the most recent two
interpreters package sets are built; this is a compromise between being
the latest interpreter, and what the majority of the Python packages support.</p>
<p>New CPython interpreters are released in October. Generally, it takes some
time for the majority of active Python projects to support the latest stable
interpreter. To help ease the migration for Nixpkgs users
between Python interpreters the schedule below will be used:</p>
<table>
<thead>
<tr>
<th>When</th>
<th>Event</th>
</tr>
</thead>
<tbody>
<tr>
<td>After YY.11 Release</td>
<td>Bump CPython package set window. The latest and previous latest stable should now be built.</td>
</tr>
<tr>
<td>After YY.05 Release</td>
<td>Bump default CPython interpreter to latest stable.</td>
</tr>
</tbody>
</table>
<p>In practice, this means that the Python community will have had a stable interpreter
for ~2 months before attempting to update the package set. And this will
allow for ~7 months for Python applications to support the latest interpreter.</p>
</article>
</div>
<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script>
</div>
</main>
<footer class="md-footer">
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-copyright">
<div class="md-copyright__highlight">
Licenced MIT
</div>
Made with
<a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener">
Material for MkDocs
</a>
</div>
<div class="md-social">
<a href="https://git.auxolotl.org/auxolotl/docs" target="_blank" rel="noopener" title="Aux Docs Repo" class="md-social__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M16.777 0a2.9 2.9 0 1 1-2.529 4.322H12.91a4.266 4.266 0 0 0-4.265 4.195v2.118a7.076 7.076 0 0 1 4.147-1.42l.118-.002h1.338a2.9 2.9 0 0 1 5.43 1.422 2.9 2.9 0 0 1-5.43 1.422H12.91a4.266 4.266 0 0 0-4.265 4.195v2.319A2.9 2.9 0 0 1 7.222 24 2.9 2.9 0 0 1 5.8 18.57V8.589a7.109 7.109 0 0 1 6.991-7.108l.118-.001h1.338A2.9 2.9 0 0 1 16.778 0ZM7.223 19.905a1.194 1.194 0 1 0 0 2.389 1.194 1.194 0 0 0 0-2.389Zm9.554-10.464a1.194 1.194 0 1 0 0 2.389 1.194 1.194 0 0 0 0-2.39Zm0-7.735a1.194 1.194 0 1 0 0 2.389 1.194 1.194 0 0 0 0-2.389Z"/></svg>
</a>
<a href="https://forum.aux.computer/" target="_blank" rel="noopener" title="Aux Forum" class="md-social__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12.103 0C18.666 0 24 5.485 24 11.997c0 6.51-5.33 11.99-11.9 11.99L0 24V11.79C0 5.28 5.532 0 12.103 0zm.116 4.563a7.395 7.395 0 0 0-6.337 3.57 7.247 7.247 0 0 0-.148 7.22L4.4 19.61l4.794-1.074a7.424 7.424 0 0 0 8.136-1.39 7.256 7.256 0 0 0 1.737-7.997 7.375 7.375 0 0 0-6.84-4.585h-.008z"/></svg>
</a>
<a href="https://wiki.auxolotl.org/" target="_blank" rel="noopener" title="Aux Wiki" class="md-social__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M17.801 13.557c.148.098.288.202.417.313 1.854 1.6 3.127 4.656 2.582 7.311-1.091-.255-5.747-1.055-7.638-3.383-.91-1.12-1.366-2.081-1.569-2.885a5.65 5.65 0 0 0 .034-.219c.089.198.197.35.313.466.24.24.521.335.766.372.304.046.594-.006.806-.068l.001.001c.05-.015.433-.116.86-.342.325-.173 2.008-.931 3.428-1.566Zm-7.384 1.435C9.156 16.597 6.6 18.939.614 18.417c.219-1.492 1.31-3.019 2.51-4.11.379-.345.906-.692 1.506-1.009.286.168.598.332.939.486 2.689 1.221 3.903 1.001 4.89.573a1.3 1.3 0 0 0 .054-.025 6.156 6.156 0 0 0-.096.66Zm4.152-.462c.38-.341.877-.916 1.383-1.559-.389-.15-.866-.371-1.319-.591-.598-.29-1.305-.283-2.073-.315a4.685 4.685 0 0 1-.804-.103c.014-.123.027-.246.038-.369.062.104.673.057.871.057.354 0 1.621.034 3.074-.574 1.452-.608 2.55-1.706 3.022-3.225.474-1.52.22-3.091-.168-3.952-.169.709-1.453 2.381-1.926 2.871-.473.489-2.381 2.296-2.972 2.921-.7.74-.688.793-1.332 1.302-.202.19-.499.402-.563.53.027-.338.039-.675.027-.997a7.653 7.653 0 0 0-.032-.523c.322-.059.567-.522.567-.861 0-.224-.106-.247-.271-.229.075-.894.382-3.923 1.254-4.281.218.109.831.068.649-.295-.182-.364-.825-.074-1.081.266-.28.374-.956 2.046-.92 4.324-.113.014-.174.033-.322.033-.171 0-.321-.04-.433-.05.034-2.275-.714-3.772-.84-4.169-.12-.375-.491-.596-.781-.596-.146 0-.272.056-.333.179-.182.363.459.417.677.308.706.321 1.156 3.519 1.254 4.277-.125-.006-.199.035-.199.233 0 .311.17.756.452.843a.442.442 0 0 0-.007.03s-.287.99-.413 2.189a4.665 4.665 0 0 1-.718-.225c-.714-.286-1.355-.583-2.019-.566-.664.018-1.366.023-1.804-.036-.438-.058-.649-.15-.649-.15s-.234.365.257 1.075c.42.607 1.055 1.047 1.644 1.18.589.134 1.972.18 2.785-.377.16-.109.317-.228.459-.34a8.717 8.717 0 0 0-.013.626c-.289.753-.571 1.993-.268 3.338 0-.001.701-.842.787-2.958.006-.144.009-.271.01-.383.052-.248.103-.518.148-.799.072.135.151.277.234.413.511.842 1.791 1.37 2.383 1.49.091.019.187.032.285.038Zm-1.12.745c-.188.055-.445.1-.713.059-.21-.031-.45-.11-.655-.316-.169-.168-.312-.419-.401-.789a9.837 9.837 0 0 0 .039-.82l.049-.243c.563.855 1.865 1.398 2.476 1.522.036.008.072.014.109.02l-.013.009c-.579.415-.76.503-.891.558Zm6.333-2.818c-.257.114-4.111 1.822-5.246 2.363.98-.775 3.017-3.59 3.699-4.774 1.062.661 1.468 1.109 1.623 1.441.101.217.09.38.096.515a.57.57 0 0 1-.172.455Zm-9.213 1.62a1.606 1.606 0 0 1-.19.096c-.954.414-2.126.61-4.728-.571-2.023-.918-3.024-2.157-3.371-2.666.476.161 1.471.473 2.157.524.282.021.703.068 1.167.125.021.209.109.486.345.829l.001.001c.451.651 1.134 1.119 1.765 1.262.622.141 2.083.182 2.942-.407a3.12 3.12 0 0 0 .132-.093l.001.179a6.052 6.052 0 0 0-.221.721Zm5.512-1.271a17.49 17.49 0 0 1-1.326-.589c.437.042 1.054.083 1.692.108-.121.162-.244.323-.366.481Zm.932-1.26c-.12.17-.245.343-.373.517-.241.018-.478.03-.709.038a29.05 29.05 0 0 1-.741-.048c.608-.065 1.228-.252 1.823-.507Zm.22-.315c-.809.382-1.679.648-2.507.648-.472 0-.833.018-1.139.039v.001c-.324-.031-.665-.039-1.019-.054a3.555 3.555 0 0 1-.152-.009c.102-.002.192-.006.249-.006.363 0 1.662.034 3.151-.589 1.508-.632 2.645-1.773 3.136-3.351.37-1.186.31-2.402.086-3.312.458-.336.86-.651 1.147-.91.501-.451.743-.733.848-.869.199.206.714.864.685 2.138-.036 1.611-.606 3.187-1.501 4.154a9.099 9.099 0 0 1-1.321 1.132 11.978 11.978 0 0 0-.644-.422l-.089-.055-.051.091c-.184.332-.5.825-.879 1.374ZM4.763 5.817c-.157 1.144.113 2.323.652 3.099.539.776 2.088 2.29 3.614 2.505.991.14 2.055.134 2.055.134s-.593-.576-1.114-1.66c-.521-1.085-.948-2.104-1.734-2.786-.785-.681-1.601-1.416-2.045-1.945-.444-.53-.59-.86-.59-.86s-.656.175-.838 1.513Zm14.301 4.549a9.162 9.162 0 0 0 1.3-1.12c.326-.352.611-.782.845-1.265 1.315.145 2.399.371 2.791.434 0 0-.679 1.971-3.945 3.022l-.016-.035c-.121-.26-.385-.594-.975-1.036Zm-11.634.859a8.537 8.537 0 0 1-.598-.224c-1.657-.693-2.91-1.944-3.449-3.678-.498-1.601-.292-3.251.091-4.269.225.544.758 1.34 1.262 2.01a3.58 3.58 0 0 0-.172.726c-.163 1.197.123 2.428.687 3.24.416.599 1.417 1.62 2.555 2.193-.128.002-.253.003-.376.002Zm-1.758-.077c-.958-.341-1.901-.787-2.697-1.368C-.07 7.559 0 6.827 0 6.827s1.558-.005 3.088.179c.03.126.065.251.104.377.557 1.791 1.851 3.086 3.562 3.803l.047.019a4.254 4.254 0 0 1-.267-.026h-.001c-.401-.053-.595-.135-.595-.135l-.157-.069-.092.144-.017.029Zm6.807-1.59c.086.017.136.058.136.145 0 .197-.242.5-.597.597l-.01-.161a.887.887 0 0 0 .283-.243c.078-.099.142-.217.188-.338Zm-1.591.006c.033.1.076.197.129.282.061.097.134.18.217.24l-.021.083c-.276-.093-.424-.293-.424-.466 0-.078.035-.119.099-.139Zm-.025-.664c-.275-.816-.795-2.022-1.505-2.179-.296.072-.938.096-.691-.145.246-.24 1.085-.048 1.283.217.145.194.744.806 1.011 1.737l.032.227a.324.324 0 0 0-.13.143Zm1.454-.266c.251-.99.889-1.639 1.039-1.841.197-.265 1.036-.457 1.283-.217.247.241-.395.217-.691.145-.69.152-1.2 1.296-1.481 2.109a.364.364 0 0 0-.067-.059.37.37 0 0 0-.092-.043l.009-.094Zm4.802-2.708a9.875 9.875 0 0 1-.596.705c-.304.315-1.203 1.176-1.963 1.916.647-.955 1.303-1.806 2.184-2.376.123-.08.249-.161.375-.245Z"/></svg>
</a>
</div>
</div>
</div>
</footer>
</div>
<div class="md-dialog" data-md-component="dialog">
<div class="md-dialog__inner md-typeset"></div>
</div>
<script id="__config" type="application/json">{"base": "../../..", "features": ["content.tooltips", "search.highlight", "navigation.tabs", "navigation.indexes", "navigation.prune"], "search": "../../../assets/javascripts/workers/search.b8dbb3d2.min.js", "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}}</script>
<script src="../../../assets/javascripts/bundle.fe8b6f2b.min.js"></script>
</body>
</html>