Description
It appears that setuptools is shipping a distutils hack that has begun to trigger double import warnings from the double import denier.
Easiest method to reproduce is to have setuptools>=60.0.0 and run the following two commands (from labscript_utils.ls_zprocess):
import labscript_utils # engages the double import denier, maybe other things
from distutils.version import LooseVersion
With setuptools=60.0.5, the error is
Traceback (most recent call last):
File "c:\users\naqsl\src\labscript-suite\labscript-utils\labscript_utils\double_import_denier.py", line 72, in find_spec
self._raise_error(path, fullname, tb, other_name, other_tb)
File "c:\users\naqsl\src\labscript-suite\labscript-utils\labscript_utils\double_import_denier.py", line 136, in _raise_error
raise RuntimeError(msg) from None
RuntimeError: Double import! The same file has been imported under two different names, resulting in two copies of the module. This is almost certainly a mistake. If you are running a script from within a package and want to import another submodule of that package, import it by its full path: 'import module.submodule' instead of just 'import submodule.'
Path imported: C:\Users\naqsL\Miniconda3\envs\labscript2\Lib\site-packages\setuptools\_distutils\dir_util.py
Traceback (first time imported, as setuptools._distutils.dir_util):
------------
File "<stdin>", line 1, in <module>
File "C:\Users\naqsL\Miniconda3\envs\labscript2\lib\site-packages\_distutils_hack\__init__.py", line 92, in create_module
return importlib.import_module('setuptools._distutils')
File "C:\Users\naqsL\Miniconda3\envs\labscript2\lib\importlib\__init__.py", line 127, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "C:\Users\naqsL\Miniconda3\envs\labscript2\lib\site-packages\setuptools\__init__.py", line 8, in <module>
import _distutils_hack.override # noqa: F401
File "C:\Users\naqsL\Miniconda3\envs\labscript2\lib\site-packages\_distutils_hack\override.py", line 1, in <module>
__import__('_distutils_hack').do_override()
File "C:\Users\naqsL\Miniconda3\envs\labscript2\lib\site-packages\_distutils_hack\__init__.py", line 73, in do_override
ensure_local_distutils()
File "C:\Users\naqsL\Miniconda3\envs\labscript2\lib\site-packages\_distutils_hack\__init__.py", line 60, in ensure_local_distutils
core = importlib.import_module('distutils.core')
File "C:\Users\naqsL\Miniconda3\envs\labscript2\lib\importlib\__init__.py", line 127, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "C:\Users\naqsL\Miniconda3\envs\labscript2\lib\site-packages\setuptools\_distutils\core.py", line 18, in <module>
from distutils.cmd import Command
File "C:\Users\naqsL\Miniconda3\envs\labscript2\lib\site-packages\setuptools\_distutils\cmd.py", line 9, in <module>
from distutils import util, dir_util, file_util, archive_util, dep_util
------------
Traceback (second time imported, as distutils.dir_util):
------------
File "<stdin>", line 1, in <module>
File "C:\Users\naqsL\Miniconda3\envs\labscript2\lib\site-packages\_distutils_hack\__init__.py", line 92, in create_module
return importlib.import_module('setuptools._distutils')
File "C:\Users\naqsL\Miniconda3\envs\labscript2\lib\importlib\__init__.py", line 127, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "C:\Users\naqsL\Miniconda3\envs\labscript2\lib\site-packages\setuptools\__init__.py", line 8, in <module>
import _distutils_hack.override # noqa: F401
File "C:\Users\naqsL\Miniconda3\envs\labscript2\lib\site-packages\_distutils_hack\override.py", line 1, in <module>
__import__('_distutils_hack').do_override()
File "C:\Users\naqsL\Miniconda3\envs\labscript2\lib\site-packages\_distutils_hack\__init__.py", line 73, in do_override
ensure_local_distutils()
File "C:\Users\naqsL\Miniconda3\envs\labscript2\lib\site-packages\_distutils_hack\__init__.py", line 60, in ensure_local_distutils
core = importlib.import_module('distutils.core')
File "C:\Users\naqsL\Miniconda3\envs\labscript2\lib\importlib\__init__.py", line 127, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "C:\Users\naqsL\Miniconda3\envs\labscript2\lib\site-packages\setuptools\_distutils\core.py", line 18, in <module>
from distutils.cmd import Command
File "C:\Users\naqsL\Miniconda3\envs\labscript2\lib\site-packages\setuptools\_distutils\cmd.py", line 9, in <module>
from distutils import util, dir_util, file_util, archive_util, dep_util
File "C:\Users\naqsL\Miniconda3\envs\labscript2\lib\site-packages\setuptools\_distutils\archive_util.py", line 18, in <module>
from distutils.dir_util import mkpath
------------
Under setuptools=60.9.3, (most recent release), the message changes slightly and becomes decidedly less helpful.
Traceback (most recent call last):
File "c:\users\naqsl\src\labscript-suite\labscript-utils\labscript_utils\double_import_denier.py", line 72, in find_spec
self._raise_error(path, fullname, tb, other_name, other_tb)
File "c:\users\naqsl\src\labscript-suite\labscript-utils\labscript_utils\double_import_denier.py", line 136, in _raise_error
raise RuntimeError(msg) from None
RuntimeError: Double import! The same file has been imported under two different names, resulting in two copies of the module. This is almost certainly a mistake. If you are running a script from within a package and want to import another submodule of that package, import it by its full path: 'import module.submodule' instead of just 'import submodule.'
Path imported: C:\Users\naqsL\Miniconda3\envs\labscript2\Lib\site-packages\setuptools\_distutils\__init__.py
Traceback (first time imported, as setuptools._distutils):
------------
File "<stdin>", line 1, in <module>
File "c:\users\naqsl\src\labscript-suite\labscript-utils\labscript_utils\double_import_denier.py", line 57, in find_spec
spec = importlib.util.find_spec(fullname, path)
File "C:\Users\naqsL\Miniconda3\envs\labscript2\lib\importlib\util.py", line 103, in find_spec
return _find_spec(fullname, parent_path)
File "C:\Users\naqsL\Miniconda3\envs\labscript2\lib\site-packages\_distutils_hack\__init__.py", line 90, in find_spec
return method()
File "C:\Users\naqsL\Miniconda3\envs\labscript2\lib\site-packages\_distutils_hack\__init__.py", line 101, in spec_for_distutils
mod = importlib.import_module('setuptools._distutils')
File "C:\Users\naqsL\Miniconda3\envs\labscript2\lib\importlib\__init__.py", line 127, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "C:\Users\naqsL\Miniconda3\envs\labscript2\lib\site-packages\setuptools\__init__.py", line 8, in <module>
import _distutils_hack.override # noqa: F401
File "C:\Users\naqsL\Miniconda3\envs\labscript2\lib\site-packages\_distutils_hack\override.py", line 1, in <module>
__import__('_distutils_hack').do_override()
File "C:\Users\naqsL\Miniconda3\envs\labscript2\lib\site-packages\_distutils_hack\__init__.py", line 72, in do_override
ensure_local_distutils()
File "C:\Users\naqsL\Miniconda3\envs\labscript2\lib\site-packages\_distutils_hack\__init__.py", line 55, in ensure_local_distutils
importlib.import_module('distutils')
File "C:\Users\naqsL\Miniconda3\envs\labscript2\lib\importlib\__init__.py", line 127, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "C:\Users\naqsL\Miniconda3\envs\labscript2\lib\site-packages\_distutils_hack\__init__.py", line 90, in find_spec
return method()
File "C:\Users\naqsL\Miniconda3\envs\labscript2\lib\site-packages\_distutils_hack\__init__.py", line 101, in spec_for_distutils
mod = importlib.import_module('setuptools._distutils')
File "C:\Users\naqsL\Miniconda3\envs\labscript2\lib\importlib\__init__.py", line 127, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
------------
Traceback (second time imported, as distutils):
------------
------------
While I suppose we could whitelist distutils, I think the more correct solution is to remove calls to distutils (seeing as it will be fully deprecated in python 3.12). It appears the equivalent function for this present problem is now packaging.version.Version. If we go this route, it's probably worth checking the whole suite for random distutils calls and updating them as well.