mupen64plus / mupen64plus-ui-python

A frontend for Mupen64Plus
http://m64py.sourceforge.net/
GNU General Public License v3.0
247 stars 67 forks source link

Build with setuptools-69+ fails: `AttributeError: module 'distutils' has no attribute 'dep_util'.` #227

Closed mgorny closed 10 months ago

mgorny commented 11 months ago

setuptools 69.0.0 has removed the distutils.dep_util module, making it impossible to build m64py if it's installed:

$ python -m build -nw
* Getting build dependencies for wheel...
running egg_info
writing src/m64py.egg-info/PKG-INFO
writing dependency_links to src/m64py.egg-info/dependency_links.txt
writing top-level names to src/m64py.egg-info/top_level.txt
reading manifest template 'MANIFEST.in'
adding license file 'LICENSES'
adding license file 'COPYING'
adding license file 'AUTHORS'
writing manifest file 'src/m64py.egg-info/SOURCES.txt'
* Building wheel...
running bdist_wheel
running build
running build_qt
Traceback (most recent call last):
  File "/usr/lib/python3.12/site-packages/pyproject_hooks/_in_process/_in_process.py", line 353, in <module>
    main()
  File "/usr/lib/python3.12/site-packages/pyproject_hooks/_in_process/_in_process.py", line 335, in main
    json_out['return_val'] = hook(**hook_input['kwargs'])
                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/pyproject_hooks/_in_process/_in_process.py", line 251, in build_wheel
    return _build_backend().build_wheel(wheel_directory, config_settings,
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/setuptools/build_meta.py", line 404, in build_wheel
    return self._build_with_temp_dir(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/setuptools/build_meta.py", line 389, in _build_with_temp_dir
    self.run_setup()
  File "/usr/lib/python3.12/site-packages/setuptools/build_meta.py", line 480, in run_setup
    super(_BuildMetaLegacyBackend, self).run_setup(setup_script=setup_script)
  File "/usr/lib/python3.12/site-packages/setuptools/build_meta.py", line 311, in run_setup
    exec(code, locals())
  File "<string>", line 391, in <module>
  File "/usr/lib/python3.12/site-packages/setuptools/__init__.py", line 103, in setup
    return distutils.core.setup(**attrs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/setuptools/_distutils/core.py", line 185, in setup
    return run_commands(dist)
           ^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/setuptools/_distutils/core.py", line 201, in run_commands
    dist.run_commands()
  File "/usr/lib/python3.12/site-packages/setuptools/_distutils/dist.py", line 969, in run_commands
    self.run_command(cmd)
  File "/usr/lib/python3.12/site-packages/setuptools/dist.py", line 963, in run_command
    super().run_command(command)
  File "/usr/lib/python3.12/site-packages/setuptools/_distutils/dist.py", line 988, in run_command
    cmd_obj.run()
  File "/usr/lib/python3.12/site-packages/wheel/bdist_wheel.py", line 368, in run
    self.run_command("build")
  File "/usr/lib/python3.12/site-packages/setuptools/_distutils/cmd.py", line 318, in run_command
    self.distribution.run_command(command)
  File "/usr/lib/python3.12/site-packages/setuptools/dist.py", line 963, in run_command
    super().run_command(command)
  File "/usr/lib/python3.12/site-packages/setuptools/_distutils/dist.py", line 988, in run_command
    cmd_obj.run()
  File "<string>", line 381, in run
  File "/usr/lib/python3.12/site-packages/setuptools/_distutils/cmd.py", line 318, in run_command
    self.distribution.run_command(command)
  File "/usr/lib/python3.12/site-packages/setuptools/dist.py", line 963, in run_command
    super().run_command(command)
  File "/usr/lib/python3.12/site-packages/setuptools/_distutils/dist.py", line 988, in run_command
    cmd_obj.run()
  File "<string>", line 92, in run
  File "<string>", line 66, in compile_ts
AttributeError: module 'distutils' has no attribute 'dep_util'. Did you mean: 'dir_util'?

ERROR Backend subprocess exited when trying to invoke build_wheel
FireBurn commented 11 months ago

This gets things working for me, but I've no idea if it's the correct solution:

--- a/setup.py  2023-11-30 12:24:55.116974040 +0000
+++ b/setup.py  2023-11-30 12:25:05.515000577 +0000
@@ -14,6 +14,7 @@
 import distutils.command.build as distutils_build
 import distutils.command.clean as distutils_clean
 import setuptools
+import setuptools.modified

 # Add the src folder to the path
 sys.path.insert(0, os.path.realpath("src"))
@@ -39,7 +39,7 @@
     def compile_rc(self, qrc_file):
         import PyQt5
         py_file = os.path.splitext(qrc_file)[0] + "_rc.py"
-        if not distutils.dep_util.newer(qrc_file, py_file):
+        if not setuptools.modified.newer(qrc_file, py_file):
             return
         origpath = os.getenv("PATH")
         path = origpath.split(os.pathsep)
@@ -54,7 +54,7 @@
     def compile_ui(self, ui_file):
         from PyQt5 import uic
         py_file = os.path.splitext(ui_file)[0] + "_ui.py"
-        if not distutils.dep_util.newer(ui_file, py_file):
+        if not setuptools.modified.newer(ui_file, py_file):
             return
         with open(py_file, "w") as a_file:
             uic.compileUi(ui_file, a_file, from_imports=True)
@@ -62,7 +62,7 @@
     def compile_ts(self, ts_file):
         import PyQt5
         qm_file = os.path.splitext(ts_file)[0] + ".qm"
-        if not distutils.dep_util.newer(ts_file, qm_file):
+        if not setuptools.modified.newer(ts_file, qm_file):
             return
         origpath = os.getenv("PATH")
         path = origpath.split(os.pathsep)
mgorny commented 11 months ago

@FireBurn, thanks. Unfortunately, this won't work for older setuptools version. Could you perhaps do something like:

try:
    from setuptools.modified import newer
except ImportError:
    from distutils.dep_util import newer

update the code below to just call newer() and submit a PR?