Skip to content

Remove most visible dependencies on distutils. #21061

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,11 @@
import shutil
import subprocess

from setuptools import setup, find_packages, Extension
from setuptools import setup, find_packages, Distribution, Extension
import setuptools.command.build_ext
import setuptools.command.build_py
import setuptools.command.sdist

from distutils.errors import CompileError
from distutils.dist import Distribution

import setupext
from setupext import print_raw, print_status

Expand All @@ -61,7 +58,10 @@ def has_flag(self, flagname):
f.write('int main (int argc, char **argv) { return 0; }')
try:
self.compile([f.name], extra_postargs=[flagname])
except CompileError:
except Exception as exc:
# https://github.com/pypa/setuptools/issues/2698
if type(exc).__name__ != "CompileError":
raise
return False
return True

Expand Down Expand Up @@ -263,7 +263,7 @@ def make_release_tree(self, base_dir, files):
package_data.setdefault(key, [])
package_data[key] = list(set(val + package_data[key]))

setup( # Finally, pass this all along to distutils to do the heavy lifting.
setup( # Finally, pass this all along to setuptools to do the heavy lifting.
name="matplotlib",
description="Python plotting package",
author="John D. Hunter, Michael Droettboom",
Expand Down
34 changes: 28 additions & 6 deletions setupext.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import configparser
from distutils import ccompiler, sysconfig
from distutils.core import Extension
from distutils import sysconfig
import functools
import hashlib
from io import BytesIO
Expand All @@ -16,6 +15,8 @@
import textwrap
import urllib.request

from setuptools import Distribution, Extension

_log = logging.getLogger(__name__)


Expand Down Expand Up @@ -523,16 +524,37 @@ def add_libagg_flags_and_sources(ext):
os.path.join("extern", "agg24-svn", "src", x) for x in agg_sources)


# First compile checkdep_freetype2.c, which aborts the compilation either
# with "foo.h: No such file or directory" if the header is not found, or an
# appropriate error message if the header indicates a too-old version.
def get_ccompiler():
"""
Return a new CCompiler instance.

CCompiler used to be constructible via `distutils.ccompiler.new_compiler`,
but this API was removed as part of the distutils deprecation. Instead,
we trick setuptools into instantiating it by creating a dummy Distribution
with a list of extension modules that claims to be truthy, but is actually
empty, and then running the Distribution's build_ext command. (If using
a plain empty ext_modules, build_ext would early-return without doing
anything.)
"""

class L(list):
def __bool__(self):
return True

build_ext = Distribution({"ext_modules": L()}).get_command_obj("build_ext")
build_ext.finalize_options()
build_ext.run()
return build_ext.compiler


class FreeType(SetupPackage):
name = "freetype"

@classmethod
def add_flags(cls, ext):
# checkdep_freetype2.c immediately aborts the compilation either with
# "foo.h: No such file or directory" if the header is not found, or an
# appropriate error message if the header indicates a too-old version.
ext.sources.insert(0, 'src/checkdep_freetype2.c')
if options.get('system_freetype'):
pkg_config_setup_extension(
Expand Down Expand Up @@ -636,7 +658,7 @@ def do_custom_build(self, env):
f.truncate()
f.write(vcxproj)

cc = ccompiler.new_compiler()
cc = get_ccompiler()
cc.initialize() # Get msbuild in the %PATH% of cc.spawn.
cc.spawn(["msbuild", str(sln_path),
"/t:Clean;Build",
Expand Down