testing-cabal / testtools

Testtools - tasteful testing for python
https://testtools.readthedocs.io/en/latest/
Other
94 stars 88 forks source link

`testtools` fails to import with Python 3.12 #352

Closed jakelishman closed 11 months ago

jakelishman commented 11 months ago

At the moment, import testtools fails because of the eager import of distutils via testtools.distutilscmd, which provides the deprecated TestCommand, since distutils is removed from the Python 3.12 standard library.

setuptools still packages distutils, so a temporary workaround could be to add setuptools as a runtime dependency until TestCommand can be removed, or potentially the import of TestCommand in the root could be conditional on Python version?

Happy to provide a patch in either direction, if it would help.

jelmer commented 11 months ago

We've marked distutils support as deprecated (see NEWS); however, we haven't done any major release since then.

We could try to import from setuptools first, and fall back to importing from distutils if that doesn't work? That way at least we don't add setuptools as a runtime dependency for existing users on python < 3.12.

jakelishman commented 11 months ago

Yeah, I saw the deprecation - if the preferred solution is just to wait til the next major release to support Python 3.12 then that's a fine answer to my query.

Setuptools doesn't re-expose setuptools.distutils publicly - the setuptools Python wheel puts in a shim to the import system via its _distutils_hack package that causes import distutils to pull in the private setuptools._distutils if there's no other distutils in the import path.

Could it be acceptable to add the dependency on setuptools; python_version>=3.12 to avoid burdening prior Python versions with the extra requirement?

jelmer commented 11 months ago

AFAIK we just import Command from distutils, so I was proposing just doing:


try:
    from setuptools.command import Command
except ModuleNotFoundError:
    from distutils.command import Command

and then indeed adding a setuptools; python_version>=3.12 dependency.

jakelishman commented 11 months ago

Ah yeah, sorry I misunderstood slightly. There's also distutils.errors.DisutilsOptionError, but that's easily redirectable to setuptools.errors.OptionError by similar means (which in actuality is just a re-export of distutils.errors.DistutilsOptionError).