In 2012, Guido Had No Idea NumPy Had Its Own Packaging System
In a recently resurfaced 2012 PyData panel discussion, Fernando Perez, Travis Oliphant, and David Cournapeau sat down with Guido van Rossum to discuss the scientific Python community’s needs. The conversation wandered through operator overloading (which eventually produced the @ matrix multiplication operator in Python 3.5) and import performance on supercomputers. The packaging segment is the one worth revisiting.
David Cournapeau, who maintained NumPy’s build infrastructure, explained that NumPy had written its own packaging layer on top of distutils that was “as much code as distutils itself.” NumPy had to override nearly every piece of distutils to handle Fortran compilers, C++ extensions, Cython, cross-platform compiler flags, and builds on exotic hardware like IBM Blue Gene supercomputers.
Guido’s response:
I personally wasn’t even aware that you guys had your own installer that was as big as distutils.
Fernando Perez then described the problem: compiler flags in distutils “flow in this very opaque way. You basically have to instrument the code and trace it to see when this particular method along the way all of a sudden flipped the flag inside of a structure. There is no API for that to happen.” When you’re building SciPy, a layer of Fortran, Cython, C, and C++ wrapped together, you need clear control over compilation flags and which compilers to use because they’re not all ABI compatible. Doing that through distutils was a project he no longer had “the fortitude” for.
Guido asked whether they had all this working on platforms beyond Linux. Yes, Fernando said. macOS was pervasive, Windows was widely used, and then there were “the funky Unices” on big iron machines with exotic compilers. That cross-platform support was why the codebase was so large.
Travis Oliphant admitted the whole approach was probably a mistake: “We were trying to get code reuse and benefit from the registration mechanisms that distutils was promoting. We could have gotten all that likely by just building our own system and then hooking in on those pieces.” Guido agreed: “Maybe you overloaded every single line of code in the original distutils. You didn’t benefit from it.”
Guido’s advice: build your own system. The scientific community’s needs were “so unusual compared to the larger Python community” that trying to work within distutils was wasted effort. PyPI integration was just a couple of API calls. They could reimplement that themselves.
Fernando’s reply: “By now, with all of the energy that we’ve burnt on that, we would have finished.”
The same story, told twice
Compare this with Brett Cannon’s explanation from a 2025 interview about why packaging never became a core development concern: “Basically, they’re separate because Guido doesn’t care about packaging.”
Brett described a gap that grew organically. The 2012 panel shows what that gap looked like when people tried to bridge it in real time. Guido genuinely didn’t know the scale of what NumPy had built. The scientific community genuinely didn’t know how long the distutils2 discussions had been going on. Each side thought the other was either moving too fast or not listening.
Guido also delivered what might be the most honest summary of Python packaging progress ever recorded:
Nothing ever happens in the packaging world. And then someone comes out with a terrible hack and suddenly everybody adopts it and then progress is being stalled for seven years again.
What happened next
The scientific Python community did eventually take Guido’s advice, though it took years:
- Conda (first released in 2012, the same year as this panel) became the scientific community’s answer, handling compiled dependencies that pip couldn’t
- scikit-build wrapped CMake for Python extension building
- meson-python gave SciPy a modern build backend (SciPy migrated from NumPy’s distutils to Meson in 2023)
- NumPy’s distutils was deprecated in NumPy 1.24 (2022) and removed in NumPy 2.0 (2024), twelve years after this conversation
On the standards side, PEP 517 and PEP 518 finally decoupled build backends from setuptools, letting projects use whatever build system they needed without overriding distutils from the inside.