Remove distutils (#57040)
Summary:
[distutils](https://docs.python.org/3/library/distutils.html) is on its way out and will be deprecated-on-import for Python 3.10+ and removed in Python 3.12 (see [PEP 632](https://www.python.org/dev/peps/pep-0632/)). There's no reason for us to keep it around since all the functionality we want from it can be found in `setuptools` / `sysconfig`. `setuptools` includes a copy of most of `distutils` (which is fine to use according to the PEP), that it uses under the hood, so this PR also uses that in some places.
Fixes #56527
Pull Request resolved: https://github.com/pytorch/pytorch/pull/57040
Pulled By: driazati
Reviewed By: nikithamalgifb
Differential Revision: D28051356
fbshipit-source-id: 1ca312219032540e755593e50da0c9e23c62d720
diff --git a/setup.py b/setup.py
index a3f416f..1bfb7a7 100644
--- a/setup.py
+++ b/setup.py
@@ -21,9 +21,7 @@
# default behavior of autogoo and cmake build systems.)
#
# CC
-# the C/C++ compiler to use (NB: the CXX flag has no effect for distutils
-# compiles, because distutils always uses CC to compile, even for C++
-# files.
+# the C/C++ compiler to use
#
# Environment variables for feature toggles:
#
@@ -197,14 +195,10 @@
from setuptools import setup, Extension, find_packages
from collections import defaultdict
-from distutils import core
-from distutils.core import Distribution
-from distutils.errors import DistutilsArgError
+from setuptools.dist import Distribution
import setuptools.command.build_ext
import setuptools.command.install
-import distutils.command.clean
-import distutils.command.sdist
-import distutils.sysconfig
+import setuptools.command.sdist
import filecmp
import shutil
import subprocess
@@ -213,6 +207,7 @@
import glob
import importlib
import time
+import sysconfig
from tools.build_pytorch_libs import build_caffe2
from tools.setup_helpers.env import (IS_WINDOWS, IS_DARWIN, IS_LINUX,
@@ -261,31 +256,31 @@
def report(*args):
pass
+ # Make distutils respect --quiet too
+ setuptools.distutils.log.warn = report
+
# Constant known variables used throughout this file
cwd = os.path.dirname(os.path.abspath(__file__))
lib_path = os.path.join(cwd, "torch", "lib")
third_party_path = os.path.join(cwd, "third_party")
caffe2_build_dir = os.path.join(cwd, "build")
-# lib/pythonx.x/site-packages
-rel_site_packages = distutils.sysconfig.get_python_lib(prefix='')
-# full absolute path to the dir above
-full_site_packages = distutils.sysconfig.get_python_lib()
+
# CMAKE: full path to python library
if IS_WINDOWS:
cmake_python_library = "{}/libs/python{}.lib".format(
- distutils.sysconfig.get_config_var("prefix"),
- distutils.sysconfig.get_config_var("VERSION"))
+ sysconfig.get_config_var("prefix"),
+ sysconfig.get_config_var("VERSION"))
# Fix virtualenv builds
# TODO: Fix for python < 3.3
if not os.path.exists(cmake_python_library):
cmake_python_library = "{}/libs/python{}.lib".format(
sys.base_prefix,
- distutils.sysconfig.get_config_var("VERSION"))
+ sysconfig.get_config_var("VERSION"))
else:
cmake_python_library = "{}/{}".format(
- distutils.sysconfig.get_config_var("LIBDIR"),
- distutils.sysconfig.get_config_var("INSTSONAME"))
-cmake_python_include_dir = distutils.sysconfig.get_python_inc()
+ sysconfig.get_config_var("LIBDIR"),
+ sysconfig.get_config_var("INSTSONAME"))
+cmake_python_include_dir = sysconfig.get_path("include")
################################################################################
@@ -491,9 +486,9 @@
# Do not use clang to compile extensions if `-fstack-clash-protection` is defined
# in system CFLAGS
- system_c_flags = str(distutils.sysconfig.get_config_var('CFLAGS'))
- if IS_LINUX and '-fstack-clash-protection' in system_c_flags and 'clang' in os.environ.get('CC', ''):
- os.environ['CC'] = str(distutils.sysconfig.get_config_var('CC'))
+ c_flags = str(os.getenv('CFLAGS', ''))
+ if IS_LINUX and '-fstack-clash-protection' in c_flags and 'clang' in os.environ.get('CC', ''):
+ os.environ['CC'] = str(os.environ['CC'])
# It's an old-style class in Python 2.7...
setuptools.command.build_ext.build_ext.run(self)
@@ -547,7 +542,8 @@
filename = self.get_ext_filename(fullname)
report("\nCopying extension {}".format(ext.name))
- src = os.path.join("torch", rel_site_packages, filename)
+ relative_site_packages = sysconfig.get_path('purelib').replace(sysconfig.get_path('data'), '').lstrip(os.path.sep)
+ src = os.path.join("torch", relative_site_packages, filename)
if not os.path.exists(src):
report("{} does not exist".format(src))
del self.extensions[i]
@@ -559,10 +555,11 @@
os.makedirs(dst_dir)
self.copy_file(src, dst)
i += 1
- distutils.command.build_ext.build_ext.build_extensions(self)
+ setuptools.command.build_ext.build_ext.build_extensions(self)
+
def get_outputs(self):
- outputs = distutils.command.build_ext.build_ext.get_outputs(self)
+ outputs = setuptools.command.build_ext.build_ext.get_outputs(self)
outputs.append(os.path.join(self.build_lib, "caffe2"))
report("setup.py::get_outputs returning {}".format(outputs))
return outputs
@@ -644,7 +641,15 @@
super().run()
-class clean(distutils.command.clean.clean):
+class clean(setuptools.Command):
+ user_options = []
+
+ def initialize_options(self):
+ pass
+
+ def finalize_options(self):
+ pass
+
def run(self):
import glob
import re
@@ -665,10 +670,8 @@
except OSError:
shutil.rmtree(filename, ignore_errors=True)
- super().run()
-
-class sdist(distutils.command.sdist.sdist):
+class sdist(setuptools.command.sdist.sdist):
def run(self):
with concat_license_files():
super().run()
@@ -863,14 +866,11 @@
# Parse the command line and check the arguments
# before we proceed with building deps and setup
dist = Distribution()
- dist.script_name = sys.argv[0]
- dist.script_args = sys.argv[1:]
try:
- ok = dist.parse_command_line()
- except DistutilsArgError as msg:
- raise SystemExit(core.gen_usage(dist.script_name) + "\nerror: %s" % msg)
- if not ok:
- sys.exit()
+ dist.parse_command_line()
+ except setuptools.distutils.errors.DistutilsArgError as e:
+ print(e)
+ sys.exit(1)
if RUN_BUILD_DEPS:
build_deps()