Fix Python 3.12 support by removing distutil imports

This commit is contained in:
allegroai 2024-02-29 14:12:21 +02:00
parent 17ae28a62f
commit 09c5ef99af
5 changed files with 58 additions and 8 deletions

View File

@ -19,8 +19,6 @@ import traceback
from collections import defaultdict from collections import defaultdict
from copy import deepcopy, copy from copy import deepcopy, copy
from datetime import datetime from datetime import datetime
from distutils.spawn import find_executable
from distutils.util import strtobool
from functools import partial from functools import partial
from os.path import basename from os.path import basename
from tempfile import mkdtemp, NamedTemporaryFile from tempfile import mkdtemp, NamedTemporaryFile
@ -114,6 +112,7 @@ from clearml_agent.helper.base import (
) )
from clearml_agent.helper.check_update import start_check_update_daemon from clearml_agent.helper.check_update import start_check_update_daemon
from clearml_agent.helper.console import ensure_text, print_text, decode_binary_lines from clearml_agent.helper.console import ensure_text, print_text, decode_binary_lines
from clearml_agent.helper.environment.converters import strtobool
from clearml_agent.helper.os.daemonize import daemonize_process from clearml_agent.helper.os.daemonize import daemonize_process
from clearml_agent.helper.package.base import PackageManager from clearml_agent.helper.package.base import PackageManager
from clearml_agent.helper.package.conda_api import CondaAPI from clearml_agent.helper.package.conda_api import CondaAPI
@ -140,7 +139,7 @@ from clearml_agent.helper.process import (
commit_docker, commit_docker,
terminate_process, terminate_process,
check_if_command_exists, check_if_command_exists,
terminate_all_child_processes, terminate_all_child_processes, find_executable,
) )
from clearml_agent.helper.repo import clone_repository_cached, RepoInfo, VCS, fix_package_import_diff_patch, \ from clearml_agent.helper.repo import clone_repository_cached, RepoInfo, VCS, fix_package_import_diff_patch, \
patch_add_task_init_call patch_add_task_init_call

View File

@ -14,7 +14,6 @@ import sys
import tempfile import tempfile
from abc import ABCMeta from abc import ABCMeta
from collections import OrderedDict from collections import OrderedDict
from distutils.spawn import find_executable
from functools import total_ordering from functools import total_ordering
from typing import Text, Dict, Any, Optional, AnyStr, IO, Union from typing import Text, Dict, Any, Optional, AnyStr, IO, Union
@ -38,6 +37,7 @@ use_powershell = os.getenv("CLEARML_AGENT_USE_POWERSHELL", None)
def which(cmd, path=None): def which(cmd, path=None):
from clearml_agent.helper.process import find_executable
result = find_executable(cmd, path) result = find_executable(cmd, path)
if not result: if not result:
raise ValueError('command "{}" not found'.format(cmd)) raise ValueError('command "{}" not found'.format(cmd))

View File

@ -1,5 +1,4 @@
import base64 import base64
from distutils.util import strtobool
from typing import Union, Optional, Any, TypeVar, Callable, Tuple from typing import Union, Optional, Any, TypeVar, Callable, Tuple
import six import six
@ -68,3 +67,20 @@ def or_(*converters, **kwargs):
return value return value
return wrapper return wrapper
def strtobool (val):
"""Convert a string representation of truth to true (1) or false (0).
True values are 'y', 'yes', 't', 'true', 'on', and '1'; false values
are 'n', 'no', 'f', 'false', 'off', and '0'. Raises ValueError if
'val' is anything else.
"""
val = val.lower()
if val in ('y', 'yes', 't', 'true', 'on', '1'):
return 1
elif val in ('n', 'no', 'f', 'false', 'off', '0'):
return 0
else:
raise ValueError("invalid truth value %r" % (val,))

View File

@ -5,7 +5,6 @@ import re
import os import os
import subprocess import subprocess
from collections import OrderedDict from collections import OrderedDict
from distutils.spawn import find_executable
from functools import partial from functools import partial
from itertools import chain from itertools import chain
from typing import Text, Iterable, Union, Dict, Set, Sequence, Any from typing import Text, Iterable, Union, Dict, Set, Sequence, Any
@ -22,7 +21,7 @@ from clearml_agent.errors import CommandFailedError
from clearml_agent.helper.base import ( from clearml_agent.helper.base import (
rm_tree, NonStrictAttrs, select_for_platform, is_windows_platform, ExecutionInfo, rm_tree, NonStrictAttrs, select_for_platform, is_windows_platform, ExecutionInfo,
convert_cuda_version_to_float_single_digit_str, convert_cuda_version_to_int_10_base_str, ) convert_cuda_version_to_float_single_digit_str, convert_cuda_version_to_int_10_base_str, )
from clearml_agent.helper.process import Argv, Executable, DEVNULL, CommandSequence, PathLike from clearml_agent.helper.process import Argv, Executable, DEVNULL, CommandSequence, PathLike, find_executable
from clearml_agent.helper.package.requirements import SimpleVersion from clearml_agent.helper.package.requirements import SimpleVersion
from clearml_agent.session import Session from clearml_agent.session import Session
from .base import PackageManager from .base import PackageManager

View File

@ -8,7 +8,6 @@ import subprocess
import sys import sys
from contextlib import contextmanager from contextlib import contextmanager
from copy import copy from copy import copy
from distutils.spawn import find_executable
from itertools import chain, repeat, islice from itertools import chain, repeat, islice
from os.path import devnull from os.path import devnull
from time import sleep from time import sleep
@ -492,3 +491,40 @@ def double_quote(s):
# use single quotes, and put single quotes into double quotes # use single quotes, and put single quotes into double quotes
# the string $"b is then quoted as "$"""b" # the string $"b is then quoted as "$"""b"
return '"' + s.replace('"', '"\'\"\'"') + '"' return '"' + s.replace('"', '"\'\"\'"') + '"'
def find_executable(executable, path=None):
"""Tries to find 'executable' in the directories listed in 'path'.
A string listing directories separated by 'os.pathsep'; defaults to
os.environ['PATH']. Returns the complete filename or None if not found.
"""
_, ext = os.path.splitext(executable)
if (sys.platform == 'win32') and (ext != '.exe'):
executable = executable + '.exe'
if os.path.isfile(executable):
return executable
if path is None:
path = os.environ.get('PATH', None)
if path is None:
try:
path = os.confstr("CS_PATH")
except (AttributeError, ValueError):
# os.confstr() or CS_PATH is not available
path = os.defpath
# bpo-35755: Don't use os.defpath if the PATH environment variable is
# set to an empty string
# PATH='' doesn't match, whereas PATH=':' looks in the current directory
if not path:
return None
paths = path.split(os.pathsep)
for p in paths:
f = os.path.join(p, executable)
if os.path.isfile(f):
# the file exists, we have a shot at spawn working
return f
return None