Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Noarch variant blog post #2332

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 75 additions & 0 deletions blog/2024-10-15-python-noarch-variants.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
---
authors:
- isuruf
tags: [infrastructure]
---

# Noarch variant packages for Python packages on conda-forge

We introduce noarch variants for python packages on conda-forge
that have compiled extensions but with pure python reference
implementations to make life easier for early adopters of
new python variants.

<!-- truncate -->

jaimergp marked this conversation as resolved.
Show resolved Hide resolved
conda-forge packages have always been batteries included. When
a package has some build options turned off by default to reduce
dependencies, we have enabled these options to give the most
functionality and performance to our users.

In the Python world, some packages are written in C/C++/Cython
to get the most performance out of a package. However these packages
sometimes have a reference implementation written in Python. The Python
reference implementation is a good way to check the C/C++/Cython
code against a much simpler python implementation and is also
useful for platforms like PyPy where the C/C++/Cython implementation
can be slower than the Python reference implementation due to the
emulation of the Python C/C++ API by PyPy. For eg: for the Cython
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would just spell this out (particularly for non-native English readers)

Suggested change
emulation of the Python C/C++ API by PyPy. For eg: for the Cython
emulation of the Python C/C++ API by PyPy. For example for the Cython

package, setting `CYTHON_NO_COMPILE` environment variable
when building the Cython wheel itself, it will use the Python reference
implementation. The only way to figure out if a package has a Python
reference implementation is to look at `setup.py` on packages that
provide such a file to see if `extensions` are built always or
with a switch.
Comment on lines +32 to +34
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As some projects are moving away from setup.py, these details may be elsewhere

Also suggested a more succinct rewording

Suggested change
reference implementation is to look at `setup.py` on packages that
provide such a file to see if `extensions` are built always or
with a switch.
reference implementation is to look at the library's source code
to see if `extensions` are optional.


To support platforms like PyPy, Some packages build wheels with
compiled extensions for the platforms that are
known to be more performant with the compiled extension, but also
provide a universal pure Python wheel for the other platforms.
This also provides a way for new Python versions and variants
like the free-threading Python build to use these packages by the
early adopters of these Python versions.

On conda-forge we usually have compiled Python packages, but provide
no reference implementation. This makes early adopters of new Python
versions to wait for the conda-forge bot managed by @conda-forge/bot
team to start the migration and rebuild the packages. For eg: the
Comment on lines +45 to +47
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
no reference implementation. This makes early adopters of new Python
versions to wait for the conda-forge bot managed by @conda-forge/bot
team to start the migration and rebuild the packages. For eg: the
no reference implementation. This means early adopters of new Python
versions need to wait for the conda-forge bot managed by @conda-forge/bot
team to start the migration and rebuild the packages. For example the

free-threading Python 3.13 build is still not under way because
conda-forge has decided to wait until the default (GIL enabled)
Python 3.13 build has migrated enough and upstream packages have added
support for free-threading builds.
Comment on lines +48 to +51
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There might be a cleaner way to write this. Tried a first pass below

Suggested change
free-threading Python 3.13 build is still not under way because
conda-forge has decided to wait until the default (GIL enabled)
Python 3.13 build has migrated enough and upstream packages have added
support for free-threading builds.
free-threading Python 3.13 build is still paused as
conda-forge has decided to focus on the default (GIL enabled)
Python 3.13 build first while upstream packages work on
supporting free-threading.

Another issue is that some packages have cyclic dependencies at build
or test time and this requires manual handling to reduce dependencies
before the migration and add the dependencies later on.
Comment on lines +53 to +54
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
or test time and this requires manual handling to reduce dependencies
before the migration and add the dependencies later on.
or test time and this requires some manual handling.


We have been adding `noarch: python` variants for some feedstocks
so that the compiled extension has higher priority and the pure
Python extension has lower priority which makes the conda solver
use the `noarch: python` variant. One issue is that the linter
might not like selectors on noarch recipes. We added an option

```yaml
linter:
skip:
- lint_noarch_selectors
```

to `conda-forge.yml` that will make the linter skip this warning/error.

We list some PRs here as a reference for conda-forge maintainers who
want to help out with this effort.

- [coverage](https:/conda-forge/coverage-feedstock/pull/123)
- [cython](https:/conda-forge/cython-feedstock/pull/147)
- [aiohttp](https:/conda-forge/aiohttp-feedstock/pull/99)
Comment on lines +70 to +75
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be nice for readers to include an example from a simple one in the blogpost itself. Perhaps could use a diff format to highlight relevant changes