Skip to content

build: package alsaaudio as a typed Python package - #161

Open
Robolightning wants to merge 1 commit into
larsimmisch:mainfrom
StableKite:main
Open

build: package alsaaudio as a typed Python package#161
Robolightning wants to merge 1 commit into
larsimmisch:mainfrom
StableKite:main

Conversation

@Robolightning

@Robolightning Robolightning commented Apr 17, 2026

Copy link
Copy Markdown

This PR narrows the change to the part that is still not covered by #156.

#156 already made type information visible to downstream type checkers by shipping the alsaaudio-stubs companion package. This PR keeps that work intact, but changes the runtime packaging layout so that alsaaudio is a real Python package with a private native extension module.

Changes:

  • move the native extension from top-level alsaaudio to alsaaudio._alsaaudio
  • add alsaaudio/__init__.py to preserve the existing public API
  • ship alsaaudio/__init__.pyi next to the runtime package
  • add alsaaudio/py.typed
  • keep non-Linux installs stub-only instead of trying to build the ALSA extension
  • adjust constructor stubs for PCM and Mixer so stubtest passes for the C extension classes

Validation:

  • built the wheel against ALSA headers/libs from a Linux sysroot
  • installed the resulting wheel
  • verified import alsaaudio
  • verified alsaaudio.asoundlib_version()
  • verified that the public API is still exposed from alsaaudio
  • verified mypy on a downstream sample
  • verified pyright on a downstream sample
  • verified mypy.stubtest alsaaudio

@ossilator

Copy link
Copy Markdown
Collaborator

looks sensible judging by a quick inspection.

given the bullet list, it seem that this PR can be atomized into a series of self-contained commits.

@mttbernardini

Copy link
Copy Markdown
Contributor

@Robolightning I have a question, since I authored #156, which supposedly tackled the same type-stubs issue. Is the approach in there not working? It's working totally fine for me with pyright.

No "private" module trick was necessary, it follows the standard practice of providing a stubs companion package to a native module. Keen to know your thoughts :)

@Robolightning Robolightning changed the title build: package alsaaudio properly and ship typing stubs build: package alsaaudio as a typed Python package Jun 11, 2026
@Robolightning

Copy link
Copy Markdown
Author

@Robolightning I have a question, since I authored #156, which supposedly tackled the same type-stubs issue. Is the approach in there not working? It's working totally fine for me with pyright.

No "private" module trick was necessary, it follows the standard practice of providing a stubs companion package to a native module. Keen to know your thoughts :)

Thanks for pointing this out. I re-tested the current #156 approach and agree that the companion alsaaudio-stubs package does work for downstream type checking; my original wording overstated that part.

The remaining issue I am trying to address here is narrower: the runtime module is still a native top-level extension module, so there is no real Python package source for alsaaudio itself. This PR changes that layout by moving the extension to alsaaudio._alsaaudio and adding a small alsaaudio/__init__.py wrapper, while preserving the existing public API.

I also rebuilt and installed the wheel locally against ALSA headers/libs and checked import, mypy, pyright, and stubtest. The package layout works. I found one remaining stubtest issue in the constructor stubs for the C extension classes, and amended the PR with that minimal fix.

@Robolightning

Copy link
Copy Markdown
Author

looks sensible judging by a quick inspection.

given the bullet list, it seem that this PR can be atomized into a series of self-contained commits.

Thanks, that makes sense. I compared this again against current main after #156.

#156 already covers the companion-stubs approach, so I narrowed this PR to the packaging layout change that is still different: making alsaaudio a real package, moving the native extension to alsaaudio._alsaaudio, and shipping __init__.pyi/py.typed with that package.

I rebuilt the current PR wheel locally against ALSA headers/libs and verified import, mypy, pyright, and stubtest. The runtime package layout works, and the wheel no longer contains a duplicate top-level extension. I found one remaining issue in the stubs: PCM and Mixer constructor signatures need to be represented via __new__ for stubtest to accept the C extension classes. I amended the PR with only that minimal fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants