Python 3.12: help porting from `distutils` to get the expected build directory


I have the following code which works until Python 3.12 due to the removal of distutils. Is the relevant information available in any other way (i.e., where compiled module artifacts should go for wheels to find)? Note that the project is way too complicated for any build; CMake has to drive things on its own and generates (knowing what is supposed to be available from a set of -D flags is not feasible).

import setuptools # importing this suppresses deprecation methods
# XXX(python-3.12): figure out what replaces this kind of access after
# `distutils` is removed.
from distutils.dist import Distribution
from distutils.command import build

d = Distribution()
b =



I managed to reverse engineer things to this. Why the version gaps are different on different platforms? No idea.

import sys
import sysconfig

justver = None
if sys.platform == 'linux':
    justver = (3, 6)
elif sys.platform == 'nt':
    justver = (3, 10)
elif sys.platform == 'darwin':
    justver = (3, 9)

if justver is not None and sys.version_info[:1] <= justver:
    tag = '{}.{}'.format(sys.version_info.major, sys.version_info.minor)
    tag = sys.implementation.cache_tag

print('build/lib.{}-{}'.format(sysconfig.get_platform(), tag))

[Maybe @abravalheri or @FFY00 can help with this question.]

There is one thing I have not understood… Who/what is creating the build directory that you are trying to find? Is it setuptools or something else?

distutils and setuptools use a combination of plat_name (which is not exactly sysconfig.get_platform()) and sys.implementation.cache_tag to derive the name of the build directory.

I think the best way to obtain the name of the directory is inside of the finalize_options or run method of the command object you are trying to write/customize. You can have a look on the example in Recommended way to add custom build steps · pypa/setuptools · Discussion #3762 · GitHub.

The bdist_wheel object will have a bdist_dir attribute when creating wheels.

The project is built by CMake. I’m just trying to put the build artifacts in a place that bdist_wheel can find them.

Yeah, I saw some nt-only conditionals in there…the comments didn’t help say why, but this at least agrees across the versions I’m testing (3.6+).

I’m not customizing any command object; I’m completely skipping the build_lib command because I need to run CMake before I can provide all of the information to setup() (e.g., what [xyz] bits will be available). I suppose I could instantiate a bdist_wheel object, but that’s a new configure-time dependency (currently we are stdlib only until you actually make a wheel).