macOS AudioUnit APIs called from within Python extension fail to see AudioUnits

I am writing a (native, C) Python extension for macOS which uses the AudioUnit APIs, loading and using AudioUnit components. The Python extension is a dynamic library which is loaded by the Python interpreter (/usr/bin/python), with the code residing in the interpreter's memory space.

I have noticed that, when my code running within Python attempts to load AudioUnit components, it sees far fewer components than there are available on the system. The code works perfectly well when running in its own process, in a dynamic library loaded with dlopen into another test program, or a subprocess launched from the Python interpreter with os.system. For example, this code for counting the AudioUnits available on the system:
Code Block
AudioComponentDescription desc = {
0, 0, 0, 0, 0
};
AudioComponent last = nil;
int count = 0;
do {
last = AudioComponentFindNext(last, &desc);
if (last) { count += 1; }
} while (last != nil);
printf("Found %d components\n", count);

When I run it within the Python extension, it reports 111 components found, most of which are standard Apple AudioUnits. When I run this code otherwise, it reports considerably more components (300+, which includes third-party AudioUnits installed on the machine it is running on). Attempting to load AudioUnits that are not among the 111 also fails within the Python extension.

My questions are: why do the AudioToolbox APIs only see a subset of AudioUnits when called from a Python extension, and how can I mitigate this to access all AudioUnits available on the system? (I'm guessing it is not sandboxing, as in the cases I've tested, the binaries are raw MACH-O binaries, rather than app bundles with signatures or entitlements.)
I can think of two potential problems you may be running into:
  1. By using /usr/bin/python (which is part of the system), your code is running with SIP (System Integrity Protection) enabled and therefore in a more restrictive environment (certain dyld environment variables filtered out). Maybe python refuses to load / run non-system .dylibs (as otherwise they would be run with the rights of the signed system process)?

  2. I seem to recall python loading its extensions fairly restrictively (RTLD_LOCAL among other dlopen-flags, but check the source); maybe that causes havoc with proper enumeration?

macOS AudioUnit APIs called from within Python extension fail to see AudioUnits
 
 
Q