Skip to content

Commit

Permalink
Bug 1752927: Avoid distutils deprecation warning on every Mach call r…
Browse files Browse the repository at this point in the history
…=ahal

Python 3.10 prints a warning when it sees `distutils` used, so let's
avoid using `distutils` in the "common Mach code" that runs on every
Mach call.

Note that this change will also fix the `SetuptoolsDeprecationWarning`
that shipped on `setuptools>=58.3.0`, since our usage of `distutils` was
calling a `setup.py install` under the hood.

Differential Revision: https://phabricator.services.mozilla.com/D137499
  • Loading branch information
Mitchell Hentges committed Feb 4, 2022
1 parent 951485d commit b3b0d2b
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 37 deletions.
10 changes: 0 additions & 10 deletions mach
Original file line number Diff line number Diff line change
Expand Up @@ -77,16 +77,6 @@ def main(args):
""").strip())
sys.exit(1)

try:
import distutils
except ModuleNotFoundError:
print(dedent("""
Mach needs the Python "distutils" module, but it's not available on your
machine. This error is most common on Debian Linux (or derivatives), and can be
fixed by installing a package named something like `python3-distutils`.
""").strip())
sys.exit(1)

# XCode python sets __PYVENV_LAUNCHER__, which overrides the executable
# used when a python subprocess is created. This is an issue when we want
# to run using our virtualenv python executables.
Expand Down
37 changes: 23 additions & 14 deletions python/mach/mach/site.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import subprocess
import sys
from collections import OrderedDict
from distutils import dist
import sysconfig
from pathlib import Path
import tempfile
from contextlib import contextmanager
Expand Down Expand Up @@ -743,15 +743,24 @@ def __init__(self, prefix):

@functools.lru_cache(maxsize=None)
def site_packages_dir(self):
normalized_venv_root = os.path.normpath(self.prefix)
# macOS uses a different default sysconfig scheme based on whether it's using the
# system Python or running in a virtualenv.
# Manually define the scheme (following the implementation in
# "sysconfig._get_default_scheme()") so that we're always following the
# code path for a virtualenv directory structure.
if os.name == "posix":
scheme = "posix_prefix"
else:
scheme = os.name

distribution = dist.Distribution({"script_args": "--no-user-cfg"})
installer = distribution.get_command_obj("install")
installer.prefix = normalized_venv_root
installer.finalize_options()
sysconfig_paths = sysconfig.get_paths(scheme)
data_path = Path(sysconfig_paths["data"])
purelib_path = Path(sysconfig_paths["purelib"])
relative_purelib_path = purelib_path.relative_to(data_path)

normalized_venv_root = os.path.normpath(self.prefix)
# Path to virtualenv's "site-packages" directory
path = installer.install_purelib
path = os.path.join(normalized_venv_root, relative_purelib_path)
local_folder = os.path.join(normalized_venv_root, "local")
# Hack around https://github.com/pypa/virtualenv/issues/2208
if path.startswith(local_folder):
Expand Down Expand Up @@ -789,11 +798,11 @@ def pip_install_with_constraints(self, pip_args):
return self.pip_install(["--constraint", constraints_path] + pip_args)

def pip_install(self, pip_install_args, **kwargs):
# distutils will use the architecture of the running Python instance when building
# packages. However, it's possible for the Xcode Python to be a universal binary
# (x86_64 and arm64) without the associated macOS SDK supporting arm64, thereby
# causing a build failure. To avoid this, we explicitly influence the build to
# only target a single architecture - our current architecture.
# setuptools will use the architecture of the running Python instance when
# building packages. However, it's possible for the Xcode Python to be a universal
# binary (x86_64 and arm64) without the associated macOS SDK supporting arm64,
# thereby causing a build failure. To avoid this, we explicitly influence the
# build to only target a single architecture - our current architecture.
kwargs.setdefault("env", os.environ.copy()).setdefault(
"ARCHFLAGS", "-arch {}".format(platform.machine())
)
Expand Down Expand Up @@ -1080,8 +1089,8 @@ def _deprioritize_venv_packages(virtualenv):
# Additionally, when removing the existing "site-packages" folder's entry, we have
# to do it in a case-insensitive way because, on Windows:
# * Python adds it as <venv>/lib/site-packages
# * While distutils tells us it's <venv>/Lib/site-packages
# * (note: on-disk, it's capitalized, so distutils is slightly more accurate).
# * While sysconfig tells us it's <venv>/Lib/site-packages
# * (note: on-disk, it's capitalized, so sysconfig is slightly more accurate).
for line in (
"import sys; sys.path = [p for p in sys.path if "
f"p.lower() != {repr(site_packages_dir)}.lower()]",
Expand Down
12 changes: 6 additions & 6 deletions python/mozboot/mozboot/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

from pathlib import Path

from distutils.version import LooseVersion
from packaging.version import Version
from mozboot import rust
from mozboot.util import (
get_mach_virtualenv_binary,
Expand Down Expand Up @@ -143,10 +143,10 @@
# Upgrade Mercurial older than this.
# This should match the OLDEST_NON_LEGACY_VERSION in
# version-control-tools/hgext/configwizard/__init__.py.
MODERN_MERCURIAL_VERSION = LooseVersion("4.9")
MODERN_MERCURIAL_VERSION = Version("4.9")

# Upgrade rust older than this.
MODERN_RUST_VERSION = LooseVersion(MINIMUM_RUST_VERSION)
MODERN_RUST_VERSION = Version(MINIMUM_RUST_VERSION)


class BaseBootstrapper(object):
Expand Down Expand Up @@ -619,7 +619,7 @@ def _parse_version_impl(self, path: Path, name, env, version_param):
"""Execute the given path, returning the version.
Invokes the path argument with the --version switch
and returns a LooseVersion representing the output
and returns a Version representing the output
if successful. If not, returns None.
An optional name argument gives the expected program
Expand Down Expand Up @@ -653,7 +653,7 @@ def _parse_version_impl(self, path: Path, name, env, version_param):
print("ERROR! Unable to identify %s version." % name)
return None

return LooseVersion(match.group(1))
return Version(match.group(1))

def _parse_version(self, path: Path, name=None, env=None):
return self._parse_version_impl(path, name, env, "--version")
Expand Down Expand Up @@ -817,7 +817,7 @@ def ensure_rust_targets(self, rustup: Path, rust_version):

if "mobile_android" in self.application:
# Let's add the most common targets.
if rust_version < LooseVersion("1.33"):
if rust_version < Version("1.33"):
arm_target = "armv7-linux-androideabi"
else:
arm_target = "thumbv7neon-linux-androideabi"
Expand Down
8 changes: 4 additions & 4 deletions python/mozboot/mozboot/bootstrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import time
from typing import Optional
from pathlib import Path
from distutils.version import LooseVersion
from packaging.version import Version
from mach.util import (
get_state_dir,
UserError,
Expand Down Expand Up @@ -128,7 +128,7 @@


# Version 2.24 changes the "core.commitGraph" setting to be "True" by default.
MINIMUM_RECOMMENDED_GIT_VERSION = LooseVersion("2.24")
MINIMUM_RECOMMENDED_GIT_VERSION = Version("2.24")
OLD_GIT_WARNING = """
You are running an older version of git ("{old_version}").
We recommend upgrading to at least version "{minimum_recommended_version}" to improve
Expand Down Expand Up @@ -616,7 +616,7 @@ def configure_git(
)
if not match:
raise Exception("Could not find git version")
git_version = LooseVersion(match.group(1))
git_version = Version(match.group(1))

if git_version < MINIMUM_RECOMMENDED_GIT_VERSION:
print(
Expand All @@ -626,7 +626,7 @@ def configure_git(
)
)

if git_version >= LooseVersion("2.17"):
if git_version >= Version("2.17"):
# "core.untrackedCache" has a bug before 2.17
subprocess.check_call(
[git_str, "config", "core.untrackedCache", "true"], cwd=str(top_src_dir)
Expand Down
6 changes: 3 additions & 3 deletions python/mozboot/mozboot/osx.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from urllib.request import urlopen

from pathlib import Path
from distutils.version import StrictVersion
from packaging.version import Version

from mozboot.base import BaseBootstrapper
from mozfile import which
Expand Down Expand Up @@ -200,9 +200,9 @@ class OSXBootstrapper(OSXAndroidBootstrapper, BaseBootstrapper):
def __init__(self, version, **kwargs):
BaseBootstrapper.__init__(self, **kwargs)

self.os_version = StrictVersion(version)
self.os_version = Version(version)

if self.os_version < StrictVersion("10.6"):
if self.os_version < Version("10.6"):
raise Exception("OS X 10.6 or above is required.")

self.minor_version = version.split(".")[1]
Expand Down

0 comments on commit b3b0d2b

Please sign in to comment.