forked from auxolotl/docs
5685 lines
201 KiB
HTML
5685 lines
201 KiB
HTML
|
||
<!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 & 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 Intel’s 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 Intel’s 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">"build-system</span>
|
||
<span class="s2">, setuptools</span>
|
||
<span class="s2">, setuptools-scm "</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">"tests</span>
|
||
<span class="s2">, hypothesis</span>
|
||
<span class="s2"> }:</span>
|
||
|
||
<span class="s2">buildPythonPackage rec {</span>
|
||
<span class="s2"> pname = "</span>pytest<span class="s2">";</span>
|
||
<span class="s2"> version = "</span><span class="mf">3.3.1</span><span class="s2">";</span>
|
||
<span class="s2"> pyproject = true;</span>
|
||
|
||
<span class="s2"> src = fetchPypi {</span>
|
||
<span class="s2"> inherit pname version;</span>
|
||
<span class="s2"> hash = "</span><span class="l">sha256-z4Q23FnYaVNG/NOrKW3kZCXsqwDWQJbOvnn7Ueyy65M</span><span class="o">=</span><span class="s2">";</span>
|
||
<span class="s2"> };</span>
|
||
|
||
<span class="s2"> postPatch = ''</span>
|
||
<span class="s2"> # don't test bash builtins</span>
|
||
<span class="s2"> rm testing/test_argcomplete.py</span>
|
||
<span class="s2"> '';</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 = "</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">";</span>
|
||
<span class="s2"> description = "</span>Framework for writing tests<span class="s2">";</span>
|
||
<span class="s2"> homepage = "</span><span class="l">https://github.com/pytest-dev/pytest</span><span class="s2">";</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"><nixpkgs></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">"0.19.1"</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">"pandas"</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">"sha256-JQn+rtpy/OA2deLszSKEuxyttqBzcAil50H+JDHUdCE="</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">"luigi"</span><span class="p">;</span>
|
||
<span class="ss">version</span> <span class="o">=</span> <span class="s2">"2.7.9"</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">"sha256-Pe229rT0aHwA98s+nTHQMEFKZPo/yw6sot8MivFDvAw="</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"><nixpkgs></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"><nixpkgs></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"><nixpkgs></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"><nixpkgs></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"><nixpkgs></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">'python311.withPackages(ps: with ps; [ numpy toolz ])'</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
|
||
>>> import requests
|
||
Traceback (most recent call last):
|
||
File "<stdin>", line 1, in <module>
|
||
ModuleNotFoundError: No module named 'requests'
|
||
</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">"python311.withPackages (ps: with ps; [ numpy toolz requests ])"</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">'/nix/store/r19yf5qgfiakqlhkgjahbg3zg79549n4-python3-3.11.2-env.drv'</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">"help"</span>,<span class="w"> </span><span class="s2">"copyright"</span>,<span class="w"> </span><span class="s2">"credits"</span><span class="w"> </span>or<span class="w"> </span><span class="s2">"license"</span><span class="w"> </span><span class="k">for</span><span class="w"> </span>more<span class="w"> </span>information.
|
||
>>><span class="w"> </span>import<span class="w"> </span>requests
|
||
>>>
|
||
</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 -> 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">"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">"</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 'python311.withPackages (ps: with ps; [ numpy ])' --run 'python3 foo.py'
|
||
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 "python3.withPackages(ps: [ ps.numpy ])"</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">"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">"</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 "python3.withPackages (ps: [ ps.numpy ])"</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">"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">"</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"><nixpkgs></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 <nixpkgs></code>
|
||
imports the <code><nixpkgs></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"><nixpkgs></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">"myEnv"</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'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">"toolz"</span><span class="p">;</span>
|
||
<span class="ss">version</span> <span class="o">=</span> <span class="s2">"0.10.0"</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">"sha256-CP3V73yWSArRHBLUct4hrNMjWZlvaaUlkpm1QP66RWA="</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">"toolz.itertoolz"</span>
|
||
<span class="s2">"toolz.functoolz"</span>
|
||
<span class="s2">"toolz.dicttoolz"</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">"https://github.com/pytoolz/toolz/releases/tag/</span><span class="si">${</span>version<span class="si">}</span><span class="s2">"</span><span class="p">;</span>
|
||
<span class="ss">homepage</span> <span class="o">=</span> <span class="s2">"https://github.com/pytoolz/toolz"</span><span class="p">;</span>
|
||
<span class="ss">description</span> <span class="o">=</span> <span class="s2">"List processing tools and functional utilities"</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"><nixpkgs></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">"toolz"</span><span class="p">;</span>
|
||
<span class="ss">version</span> <span class="o">=</span> <span class="s2">"0.10.0"</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">"sha256-CP3V73yWSArRHBLUct4hrNMjWZlvaaUlkpm1QP66RWA="</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">"https://github.com/pytoolz/toolz/"</span><span class="p">;</span>
|
||
<span class="ss">description</span> <span class="o">=</span> <span class="s2">"List processing tools and functional utilities"</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 & 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">"build dependencies</span>
|
||
<span class="s2">, setuptools "</span>dependencies
|
||
<span class="p">,</span> numpy<span class="p">,</span> multipledispatch<span class="p">,</span> python-dateutil <span class="s2">"tests</span>
|
||
<span class="s2">, pytestCheckHook</span>
|
||
<span class="s2">}:</span>
|
||
|
||
<span class="s2">buildPythonPackage rec {</span>
|
||
<span class="s2"> pname = "</span>datashape<span class="s2">";</span>
|
||
<span class="s2"> version = "</span><span class="mf">0.4.7</span><span class="s2">";</span>
|
||
<span class="s2"> pyproject = true;</span>
|
||
|
||
<span class="s2"> src = fetchPypi {</span>
|
||
<span class="s2"> inherit pname version;</span>
|
||
<span class="s2"> hash = "</span><span class="l">sha256-FLLvdm1MllKrgTGC6Gb0k0deZeVYvtCCLji/B7uhong</span><span class="o">=</span><span class="s2">";</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 = "</span><span class="l">https://github.com/blaze/datashape/releases/tag/$</span><span class="p">{</span>version<span class="p">}</span><span class="s2">";</span>
|
||
<span class="s2"> homepage = "</span><span class="l">https://github.com/ContinuumIO/datashape</span><span class="s2">";</span>
|
||
<span class="s2"> description = "</span>Data description language<span class="s2">";</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">"lxml"</span><span class="p">;</span>
|
||
<span class="ss">version</span> <span class="o">=</span> <span class="s2">"3.4.4"</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">"sha256-s9NiusRxFydHzaNRMjjxFcvWxfi45jGb9ql6eJJyQJk="</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 "in-place" 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">"lxml"</span>
|
||
<span class="s2">"lxml.etree"</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">"https://github.com/lxml/lxml/releases/tag/lxml-</span><span class="si">${</span>version<span class="si">}</span><span class="s2">"</span><span class="p">;</span>
|
||
<span class="ss">description</span> <span class="o">=</span> <span class="s2">"Pythonic binding for the libxml2 and libxslt libraries"</span><span class="p">;</span>
|
||
<span class="ss">homepage</span> <span class="o">=</span> <span class="s2">"https://lxml.de"</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">"build dependencies</span>
|
||
<span class="s2">, setuptools "</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">"pyfftw"</span><span class="p">;</span>
|
||
<span class="ss">version</span> <span class="o">=</span> <span class="s2">"0.9.2"</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">"sha256-9ru2r6kwhUCaskiFoaPNuJCfCVoUL01J40byvRt4kHQ="</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">''</span>
|
||
<span class="s s-Multiline"> export LDFLAGS="-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"</span>
|
||
<span class="s s-Multiline"> export CFLAGS="-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"</span>
|
||
<span class="s s-Multiline"> ''</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">"pyfftw"</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">"https://github.com/pyFFTW/pyFFTW/releases/tag/v</span><span class="si">${</span>version<span class="si">}</span><span class="s2">"</span><span class="p">;</span>
|
||
<span class="ss">description</span> <span class="o">=</span> <span class="s2">"Pythonic wrapper around FFTW, the FFT library, presenting a unified interface for all the supported transforms"</span><span class="p">;</span>
|
||
<span class="ss">homepage</span> <span class="o">=</span> <span class="s2">"http://hgomersall.github.com/pyFFTW"</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">''</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"> ''</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">''</span>
|
||
<span class="s s-Multiline"> runHook preCheck</span>
|
||
|
||
<span class="s s-Multiline"> pytest tests/ --ignore=tests/integration -k 'not download and not update' --ignore=tests/test_failing.py</span>
|
||
|
||
<span class="s s-Multiline"> runHook postCheck</span>
|
||
<span class="s s-Multiline"> ''</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">"tests/"</span>
|
||
<span class="s2">"--ignore=tests/integration"</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">"download"</span>
|
||
<span class="s2">"update"</span>
|
||
<span class="p">];</span>
|
||
|
||
<span class="ss">disabledTestPaths</span> <span class="o">=</span> <span class="p">[</span>
|
||
<span class="s2">"tests/test_failing.py"</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">"download"</span>
|
||
<span class="s2">"update"</span>
|
||
<span class="p">]</span> <span class="o">++</span> lib<span class="o">.</span>optionals <span class="p">(</span>pythonAtLeast <span class="s2">"3.8"</span><span class="p">)</span> <span class="p">[</span>
|
||
<span class="c1"># broken due to python3.8 async changes</span>
|
||
<span class="s2">"async"</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">"socket"</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">"requests"</span>
|
||
<span class="s2">"urllib"</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">''</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 "import requests; import urllib"</span>
|
||
<span class="s s-Multiline"> ''</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<1.0
|
||
pkg2
|
||
pkg3>=1.0,<=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">"pkg1"</span>
|
||
<span class="s2">"pkg3"</span>
|
||
<span class="p">];</span>
|
||
<span class="ss">pythonRemoveDeps</span> <span class="o">=</span> <span class="p">[</span>
|
||
<span class="s2">"pkg2"</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">"-s"</span> <span class="s2">"tests"</span> <span class="s2">"-v"</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">"out"</span>
|
||
<span class="s2">"doc"</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">"out"</span>
|
||
<span class="s2">"doc"</span>
|
||
<span class="s2">"man"</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">"singlehtml"</span>
|
||
<span class="s2">"man"</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">"weird/docs/path"</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">"toolz"</span><span class="p">;</span>
|
||
<span class="ss">version</span> <span class="o">=</span> <span class="s2">"0.10.0"</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">"sha256-CP3V73yWSArRHBLUct4hrNMjWZlvaaUlkpm1QP66RWA="</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">"https://github.com/pytoolz/toolz/releases/tag/</span><span class="si">${</span>version<span class="si">}</span><span class="s2">"</span><span class="p">;</span>
|
||
<span class="ss">homepage</span> <span class="o">=</span> <span class="s2">"https://github.com/pytoolz/toolz/"</span><span class="p">;</span>
|
||
<span class="ss">description</span> <span class="o">=</span> <span class="s2">"List processing tools and functional utilities"</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"><nixpkgs></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"><nixpkgs></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">"foo"</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"><nixpkgs></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"><nixpkgs></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">"SOURCE_DATE_EPOCH=315532800 python3 setup.py bdist_wheel"</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">"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"</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">"unset SOURCE_DATE_EPOCH; python3 setup.py bdist_wheel"</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 '/nix/store/6l1bvljpy8gazlsw2aw9skwwp4pmvyxw-python-2.7.8/etc':
|
||
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">'/ = data\_files/d'</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"><nixpkgs></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">"impurePythonEnv"</span><span class="p">;</span>
|
||
<span class="ss">venvDir</span> <span class="o">=</span> <span class="s2">"./.venv"</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 'venv' 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">''</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"> ''</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">''</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"> ''</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"><nixpkgs></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">"./.venv"</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">"impurePythonEnv"</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 'virtualenv'</span>
|
||
<span class="ss">shellHook</span> <span class="o">=</span> <span class="s s-Multiline">''</span>
|
||
<span class="s s-Multiline"> SOURCE_DATE_EPOCH=$(date +%s)</span>
|
||
|
||
<span class="s s-Multiline"> if [ -d "</span><span class="si">${</span>venvDir<span class="si">}</span><span class="s s-Multiline">" ]; then</span>
|
||
<span class="s s-Multiline"> echo "Skipping venv creation, '${venvDir}' already exists"</span>
|
||
<span class="s s-Multiline"> else</span>
|
||
<span class="s s-Multiline"> echo "Creating new venv environment in path: '${venvDir}'"</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 "</span><span class="si">${</span>venvDir<span class="si">}</span><span class="s s-Multiline">"</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 "</span><span class="si">${</span>venvDir<span class="si">}</span><span class="s s-Multiline">/bin/activate"</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"> ''</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">"Twisted"</span><span class="p">;</span>
|
||
<span class="ss">version</span> <span class="o">=</span> <span class="s2">"19.10.0"</span><span class="p">;</span>
|
||
<span class="ss">hash</span> <span class="o">=</span> <span class="s2">"sha256-c5S6fycq5yKnTz2Wnc9Zm8TvCTvDkgOHSKSQ8XJKUV0="</span><span class="p">;</span>
|
||
<span class="ss">extension</span> <span class="o">=</span> <span class="s2">"tar.bz2"</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"><...></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">"Twisted"</span><span class="p">;</span>
|
||
<span class="ss">version</span> <span class="o">=</span> <span class="s2">"19.10.0"</span><span class="p">;</span>
|
||
<span class="ss">hash</span> <span class="o">=</span> <span class="s2">"sha256-c5S6fycq5yKnTz2Wnc9Zm8TvCTvDkgOHSKSQ8XJKUV0="</span><span class="p">;</span>
|
||
<span class="ss">extension</span> <span class="o">=</span> <span class="s2">"tar.bz2"</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 Intel’s 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">"function_name"</span>
|
||
<span class="s2">"other_function"</span>
|
||
<span class="p">];</span>
|
||
|
||
<span class="ss">disabledTestPaths</span> <span class="o">=</span> <span class="p">[</span>
|
||
<span class="s2">"this/file.py"</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/<name>/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 -> 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> |