What Python can learn from Haskell packaging

EuroPython 2016

Domen Kožar

twitter.com/iElectric

Cabal

name:            TestPackage
version:         0.1
synopsis:        Package with library and two programs
license:         BSD3
author:          Angela Author
cabal-version:   >= 1.2
build-type:      Simple

library
  build-depends:   HUnit
  exposed-modules: A, B, C

executable program1
  main-is:         Main.hs
  hs-source-dirs:  prog1
  other-modules:   A, B

Cabal features

build-type:      Simple
build-type:      Make
build-type:      Custom

Python: PEP 518

Cabal features

Name: Test1
Version: 0.0.1
Cabal-Version: >= 1.2
License: BSD3
Author:  Jane Doe
Synopsis: Test package to test configurations
Category: Example

Flag Debug
  Description: Enable debug support
  Default:     False

Library
  Build-Depends:   base > 7
  Exposed-Modules: Testing.Test1
  Extensions:      CPP

  if flag(debug)
    GHC-Options: -DDEBUG
    if !os(windows)
      CC-Options: "-DDEBUG"
    else
      CC-Options: "-DNDEBUG"

Python: PEP 508

Hackage

"desctructive editing"

x-revision: 2

When you edit cabal file over Hackage interface, following line is added:

http://hackage.haskell.org/package/MonadRandom-0.4/revision/2.cabal

non-feature

Cabal hell

http-client >= 0.3.2 && < 0.5,
http-client-tls >= 0.2 && < 0.3,
http-types >= 0.8 && < 0.10

Stackage (2015)

... is a stable source of Haskell packages.

We guarantee that packages build consistently and pass tests before generating nightly and Long Term Support (LTS) releases.

Python: requirements.txt

Example: Stackage LTS-6.7

Stack

flags: {}
packages:
- '.'
extra-deps: []
resolver: lts-6.7

$ cat stack.yaml

stack init

stack setup

stack new 

stack build

stack test

stack bench

 

 

Python: pip

Being Haskells upstream

Nixpkgs Haskell infra.

Nixpkgs Haskell infra.

fix = f: let self = f self; in self;

d = self: {
  foo = "foo"; bar = "bar";
  foobar = self.foo + self.bar;
};

(fix d).foobar ≡ "foobar"

Using OO-style inheritance:

extend = rattrs: f: self: let super = rattrs self;
  in super // f self super;

override = self: super: { foo = reverse super.foo; };

(fix (extend d override)).foobar ≡ "oofbar"
(fix (extend (extend d override) override)).foobar ≡ "foobar"

Nixpkgs Haskell infra.

fix
  (extend
    (extend
      (extend
        (extend haskellPackages commonConfiguration)
      compilerConfig)
     packageSetConfig)
  overrides)

Using OO-style inheritance:

Python: manually edit files

Nixpkgs PyPI infra?

  1. setup.py -> setup.json
  2. pypi requirements.txt

Python takeaway?

- be more declarative

- be more declarative

- be more declarative

- be more declarative

- be more declarative

- be more declarative

- be more declarative

- be more declarative

- be more declarative

 

setup.py, setup.cfg, requirements.txt, MANIFEST.in, pyproject.toml, tox.ini

Questions?

This talk was based on "Peter Simons: Inside of the Nixpkgs Haskell Infrastructure"
http://cryp.to/nixcon-2015-slides.pdf

domen@dev.si

What Python can learn from Haskell packaging

By Domen Kožar

What Python can learn from Haskell packaging

  • 1,633