diff --git a/CHANGELOG.md b/CHANGELOG.md index 556e2397e..ae2981e6a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Change Log for SD.Next -## Update for 2024-09-16 +## Update for 2024-09-17 - **flux** - avoid unet load if unchanged @@ -31,6 +31,7 @@ - correct using of `extra_networks_default_multiplier` if not scale is specified - **hf** force logout/login on token change - **backend=original** is now marked as in maintenance-only mode +- **python 3.12** improved compatibility, automatically handle `setuptools` - minor ui optimizations ## Update for 2024-09-13 diff --git a/installer.py b/installer.py index f932f04a8..0461745c4 100644 --- a/installer.py +++ b/installer.py @@ -9,12 +9,6 @@ import platform import subprocess import cProfile -try: - import pkg_resources # python 3.12 no longer has it built-in -except ImportError: - stdout = subprocess.run(f'"{sys.executable}" -m pip install setuptools', shell=True, check=False, env=os.environ, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - import pkg_resources - class Dot(dict): # dot notation access to dictionary attributes __getattr__ = dict.get @@ -22,6 +16,7 @@ class Dot(dict): # dot notation access to dictionary attributes __delattr__ = dict.__delitem__ +pkg_resources, setuptools, distutils = None, None, None # defined via ensure_base_requirements version = None current_branch = None log = logging.getLogger("sd") @@ -88,10 +83,6 @@ def setup_logging(): def get(self): return self.buffer - install('rich', 'rich', quiet=True) - install('setuptools==69.5.1', 'setuptools', quiet=True) - install('psutil', 'psutil', quiet=True) - install('requests', 'requests', quiet=True) from functools import partial, partialmethod from logging.handlers import RotatingFileHandler from rich.theme import Theme @@ -187,8 +178,8 @@ def installed(package, friendly: str = None, reload = False, quiet = False): try: if reload: try: - import imp # pylint: disable=deprecated-module - imp.reload(pkg_resources) + import importlib # pylint: disable=deprecated-module + importlib.reload(pkg_resources) except Exception: pass if friendly: @@ -278,8 +269,8 @@ def install(package, friendly: str = None, ignore: bool = False, reinstall: bool deps = '' if not no_deps else '--no-deps ' res = pip(f"install{' --upgrade' if not args.uv else ''} {deps}{package}", ignore=ignore, uv=package != "uv") try: - import imp # pylint: disable=deprecated-module - imp.reload(pkg_resources) + import importlib # pylint: disable=deprecated-module + importlib.reload(pkg_resources) except Exception: pass return res @@ -902,22 +893,38 @@ def install_submodules(force=True): def ensure_base_requirements(): + setuptools_version = '69.5.1' + + def update_setuptools(): + # print('Install base requirements') + global pkg_resources, setuptools, distutils # pylint: disable=global-statement + # python may ship with incompatible setuptools + subprocess.run(f'"{sys.executable}" -m pip install setuptools=={setuptools_version}', shell=True, check=False, env=os.environ, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + import importlib + # need to delete all references to modules to be able to reload them otherwise python will use cached version + modules = [m for m in sys.modules if m.startswith('setuptools') or m.startswith('pkg_resources') or m.startswith('distutils')] + for m in modules: + del sys.modules[m] + setuptools = importlib.import_module('setuptools') + sys.modules['setuptools'] = setuptools + distutils = importlib.import_module('distutils') + sys.modules['distutils'] = distutils + pkg_resources = importlib.import_module('pkg_resources') + sys.modules['pkg_resources'] = pkg_resources + try: - import setuptools # pylint: disable=unused-import + global pkg_resources, setuptools # pylint: disable=global-statement + import pkg_resources # pylint: disable=redefined-outer-name + import setuptools # pylint: disable=redefined-outer-name + if setuptools.__version__ != setuptools_version: + update_setuptools() except ImportError: - install('setuptools==69.5.1', 'setuptools') - try: - import setuptools # pylint: disable=unused-import - except ImportError: - pass - try: - import rich # pylint: disable=unused-import - except ImportError: - install('rich', 'rich') - try: - import rich # pylint: disable=unused-import - except ImportError: - pass + update_setuptools() + + # used by installler itself so must be installed before requirements + install('rich', 'rich', quiet=True) + install('psutil', 'psutil', quiet=True) + install('requests', 'requests', quiet=True) def install_requirements(): diff --git a/modules/loader.py b/modules/loader.py index e696d8024..b32c1af0e 100644 --- a/modules/loader.py +++ b/modules/loader.py @@ -7,10 +7,12 @@ import warnings import urllib3 from modules import timer, errors + initialized = False errors.install() logging.getLogger("DeepSpeed").disabled = True + import torch # pylint: disable=C0411 try: import intel_extension_for_pytorch as ipex # pylint: disable=import-error, unused-import diff --git a/modules/onnx_impl/execution_providers.py b/modules/onnx_impl/execution_providers.py index 641bf8720..e38199d0f 100644 --- a/modules/onnx_impl/execution_providers.py +++ b/modules/onnx_impl/execution_providers.py @@ -89,7 +89,7 @@ def get_provider() -> Tuple: def install_execution_provider(ep: ExecutionProvider): - import imp # pylint: disable=deprecated-module + import importlib # pylint: disable=deprecated-module from installer import installed, install, uninstall res = "
"
     res += uninstall(["onnxruntime", "onnxruntime-directml", "onnxruntime-gpu", "onnxruntime-training", "onnxruntime-openvino"], quiet=True)
@@ -112,5 +112,5 @@ def install_execution_provider(ep: ExecutionProvider):
     res += '

' res += 'Server restart required' log.info("Server restart required") - imp.reload(ort) + importlib.reload(ort) return res