Bharel
Bharel

Reputation: 26901

Limit package to CPython - setup.cfg

I'm using pyproject.toml and setup.cfg per PEP-517.

I have my setup.cfg as follows:

[metadata]
name = Package
version = 1.0.0

[options]
py_modules = ...
python_requires = >=3

I wish to limit the package to work only on CPython, as it solves an implementation-specific issue.

I've tried using the environment markers, but unfortunately they don't work on the python_requires field:

python_requires = >=3; implementation_name == "cpython"

Is there any way to achieve what I wish without resorting to the deprecated setup.py?

Upvotes: 3

Views: 348

Answers (1)

hoefling
hoefling

Reputation: 66201

Unfortunately, you can't restrict the implementation via environment markers and the package metadata doesn't define any suitable field. However, the implementation can be restricted via the language implementation tag in wheel metadata; the format of the tag is defined in PEP 425. The CPython implementation is abbreviated with cp, python_requires = >=3 from your config implies cp3 for the full tag. Set the tag in a [bdist_wheel] section in setup.cfg:

[metadata]
...

[options]
...

[bdist_wheel]
python_tag=cp3

This is not special to bdist_wheel; any distutils subcommand can have a section in setup.cfg where one can persist its command line options. Read through Writing the Setup Configuration File for more details on that.

To answer your question from the comments:

To be honest I haven't even found the online documentation for the python-tag command. Am I missing something?

This is indeed somewhat hidden; wheel's docs don't provide a reference for the bdist_wheel's options. Usually, you list them via python setup.py bdist_wheel --help (just as with any other subcommand), but since you don't have the setup script, you can fake one:

$ python -c "from setuptools import setup; setup()" bdist_wheel --help
Options for 'bdist_wheel' command:
  ...
  --python-tag      Python implementation compatibility tag (default: 'py3')

A built wheel file will now have the cp3-none-any suffix (and the cp3-none-any tag in wheel metadata), and will be rejected by other implementations:

$ pypy3 -m pip install meowpkg-0.0.1-cp3-none-any.whl 
ERROR: meowpkg-0.0.1-cp3-none-any.whl is not a supported wheel on this platform.

This will also work with source dists since pip will always build a wheel from PEP 517-compliant sdists (and not resort to legacy setup.py install), so this is also safe to use with source dists. Example:

$ python -m build
$ pip uninstall -y wheel  # for testing only
WARNING: Skipping wheel as it is not installed.
$ pip install dist/meowpkg-0.0.1.tar.gz 
Processing ./dist/meowpkg-0.0.1.tar.gz
  Installing build dependencies ... done
  Getting requirements to build wheel ... done
    Preparing wheel metadata ... done
Building wheels for collected packages: meowpkg
  Building wheel for meowpkg (PEP 517) ... done
  Created wheel for meowpkg: filename=meowpkg-0.0.1-cp3-none-any.whl size=1005 sha256=d87571afcdeda6be74a182b9e3e1ce6035a4aea4bb173c291900a85e53232983
  Stored in directory: /home/oleg.hoefling/.cache/pip/wheels/1a/8c/43/90d6b484adcf2515d25503b0c47f14565cadf0e891a597e23e
Successfully built meowpkg
Installing collected packages: meowpkg
  Attempting uninstall: meowpkg
    Found existing installation: meowpkg 0.0.1
    Uninstalling meowpkg-0.0.1:
      Successfully uninstalled meowpkg-0.0.1
Successfully installed meowpkg-0.0.1

Upvotes: 3

Related Questions