Description: Remove references to distutils Python 3.12 removed distutils from the standard library, per PEP 632. Although the setuptools package continues to provide distutils, upstream made a patch to remove the dependency on it. This is that patch. . What follows is the original git commit message: . credentials: eliminate distutils deprecation warnings . While removing any usage of the deprecated `distutils` package, ("The distutils package is deprecated and slated for removal in Python 3.12.") this internal utility can be removed straightaway because the `shutil.which` replacement for `distutils.spawn.find_executable` already honors the `PATHEXT` environment variable in windows systems. . See https://docs.python.org/3/library/shutil.html#shutil.which Author: NingĂș <47453810+n1ngu@users.noreply.github.com> Author: A. Karl Kornel Origin: upstream, https://github.com/docker/docker-py/commit/42789818bed5d86b487a030e2e60b02bf0cfa284 Bug: https://bugs.launchpad.net/ubuntu/+source/python-docker/+bug/2061929 Last-Update: 2024-04-17 --- This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ --- a/docker/credentials/store.py +++ b/docker/credentials/store.py @@ -1,11 +1,11 @@ import errno import json +import shutil import subprocess from . import constants from . import errors from .utils import create_environment_dict -from .utils import find_executable class Store: @@ -15,7 +15,7 @@ and erasing credentials using `program`. """ self.program = constants.PROGRAM_PREFIX + program - self.exe = find_executable(self.program) + self.exe = shutil.which(self.program) self.environment = environment if self.exe is None: raise errors.InitializationError( --- a/docker/credentials/utils.py +++ b/docker/credentials/utils.py @@ -1,32 +1,4 @@ -import distutils.spawn import os -import sys - - -def find_executable(executable, path=None): - """ - As distutils.spawn.find_executable, but on Windows, look up - every extension declared in PATHEXT instead of just `.exe` - """ - if sys.platform != 'win32': - return distutils.spawn.find_executable(executable, path) - - if path is None: - path = os.environ['PATH'] - - paths = path.split(os.pathsep) - extensions = os.environ.get('PATHEXT', '.exe').split(os.pathsep) - base, ext = os.path.splitext(executable) - - if not os.path.isfile(executable): - for p in paths: - for ext in extensions: - f = os.path.join(p, base + ext) - if os.path.isfile(f): - return f - return None - else: - return executable def create_environment_dict(overrides): --- a/tests/integration/credentials/store_test.py +++ b/tests/integration/credentials/store_test.py @@ -1,9 +1,9 @@ import os import random +import shutil import sys import pytest -from distutils.spawn import find_executable from docker.credentials import ( CredentialsNotFound, Store, StoreError, DEFAULT_LINUX_STORE, @@ -22,9 +22,9 @@ def setup_method(self): self.tmp_keys = [] if sys.platform.startswith('linux'): - if find_executable('docker-credential-' + DEFAULT_LINUX_STORE): + if shutil.which('docker-credential-' + DEFAULT_LINUX_STORE): self.store = Store(DEFAULT_LINUX_STORE) - elif find_executable('docker-credential-pass'): + elif shutil.which('docker-credential-pass'): self.store = Store('pass') else: raise Exception('No supported docker-credential store in PATH')