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

pyproject: Use pyproject.toml for building wheels #560

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
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
3 changes: 2 additions & 1 deletion MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
include LICENSE
include *.rst
include doc/requirements.txt
include sounddevice_build.py
recursive-include _custom_build *.py
include sounddevice.py
recursive-include doc *.rst *.py
recursive-include examples *.py
1 change: 1 addition & 0 deletions VERSION
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0.5.0
Empty file added _custom_build/__init__.py
Empty file.
58 changes: 58 additions & 0 deletions _custom_build/backend.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
"""A Thin backend wrapper for setuptools.build_meta

See https://setuptools.pypa.io/en/latest/build_meta.html
"""

from setuptools import build_meta as _orig
from setuptools.build_meta import *
import sounddevice_build
import os
import platform
import shutil

sounddevice_build.main()

DARWIN = "Darwin"
WINDOWS = "Windows"
MACOSX_VERSIONS = ["maccosx_10_6_x86_64", "macosx_10_6_universal2"]


def get_platform_specific_wheel_name() -> str:
"""Return the platform specific wheel name."""
current_platform = os.environ.get("PYTHON_SOUNDDEVICE_PLATFORM", platform.system())
architecture = os.environ.get("PYTHON_SOUNDDEVICE_ARCHITECTURE", platform.architecture()[0])
oses = "any"

if current_platform == DARWIN:
oses = ".".join(MACOSX_VERSIONS)
elif current_platform == WINDOWS:
oses = "win32" if architecture == "32bit" else "win_amd64"

with open("VERSION", "r") as f:
version = f.read().strip()

return f"sounddevice-{version}-py3-none-{oses}.whl"


def prepare_meta_for_build_wheel(config_settings=None):
Copy link
Member

Choose a reason for hiding this comment

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

I guess this should be ...

Suggested change
def prepare_meta_for_build_wheel(config_settings=None):
def prepare_metadata_for_build_wheel(config_settings=None):

... but the whole function seems unnecessary, since it is imported already?

"""This function may be used in the future to customize platform specific portaudio libraries."""
return _orig.prepare_metadata_for_build_wheel(config_settings=config_settings)


def get_requires_for_build_wheel(config_settings=None):
return _orig.get_requires_for_build_wheel(config_settings=config_settings)


def build_wheel(wheel_directory, config_settings=None, metadata_directory=None):
"""Intercept the build wheel function and copy the wheel to a platform specific name.

We build the wheel as ususal for the package but intercept the output so that we can rename it.
"""

wheel_file = _orig.build_wheel(wheel_directory, config_settings=config_settings, metadata_directory=metadata_directory)
old_wheel_path = os.path.join(wheel_directory, wheel_file)
new_wheel_path = os.path.join(wheel_directory, get_platform_specific_wheel_name())

shutil.move(old_wheel_path, new_wheel_path)

return new_wheel_path
9 changes: 7 additions & 2 deletions sounddevice_build.py → _custom_build/sounddevice_build.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from cffi import FFI

ffibuilder = FFI()
ffibuilder.set_source('_sounddevice', None)
ffibuilder.set_source("_sounddevice", None)
ffibuilder.cdef("""
int Pa_GetVersion( void );
const char* Pa_GetVersionText( void );
Expand Down Expand Up @@ -314,5 +314,10 @@
int PaWasapi_IsLoopback( PaDeviceIndex device );
""")

if __name__ == '__main__':

def main():
ffibuilder.compile(verbose=True)


if __name__ == "__main__":
main()
42 changes: 40 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,41 @@
[build-system]
requires = ["setuptools >= 61.0"]
build-backend = "setuptools.build_meta"
requires = ["setuptools", "wheel", "CFFI>=1.0.0"]
build-backend = "backend"
backend-path = ["_custom_build"]

[project]
name = "sounddevice"
description = "Play and Record Sound with Python"
requires-python = ">=3.7"
readme = "README.rst"
license = { file = "LICENSE" }
keywords = ["sound", "audio", "play", "record", "playrec", "PortAudio"]
authors = [{ name = "Matthias Geier", email = "[email protected]" }]
classifiers = [
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Topic :: Multimedia :: Sound/Audio"
]
urls = { "Source" = "https://github.com/spatialaudio/python-sounddevice" }
dependencies = ["CFFI>=1.0.0"]
dynamic = ["version"]

[project.optional-dependencies]
NumPy = ["NumPy"]

[tool.setuptools]
zip-safe = false
py-modules = ["sounddevice", "_sounddevice"]
packages = ["_sounddevice_data"]

[tool.setuptools.package-data]
"_sounddevice_data"= [
"portaudio-binaries/*.dll",
"portaudio-binaries/*.dylib",
Copy link
Member

Choose a reason for hiding this comment

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

I guess this causes all wheels to contain all binaries. This should be limited.

Also, the sdist now also contains the binaries, but it shouldn't.

"portaudio-binaries/*.md"
]

[tool.setuptools.dynamic]
version = { "file" = "VERSION" }
96 changes: 0 additions & 96 deletions setup.py

This file was deleted.

1 change: 0 additions & 1 deletion sounddevice.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@
https://python-sounddevice.readthedocs.io/

"""
__version__ = '0.5.0'

import atexit as _atexit
import os as _os
Expand Down