diff --git a/lib/matplotlib/__init__.py b/lib/matplotlib/__init__.py index 934d848e470a..8d6c0a2f9623 100644 --- a/lib/matplotlib/__init__.py +++ b/lib/matplotlib/__init__.py @@ -105,6 +105,18 @@ import six +import sys +if sys.version_info < (3, 5): # noqa: E402 + raise ImportError(""" +Matplotlib 3.0+ does not support Python 2.x, 3.0, 3.1, 3.2, 3.3, or 3.4. +Beginning with Matplotlib 3.0, Python 3.5 and above is required. + +See Matplotlib `INSTALL.rst` file for more information: + + https://github.com/matplotlib/matplotlib/blob/master/INSTALL.rst + +""") + import atexit from collections import MutableMapping import contextlib @@ -121,21 +133,9 @@ import re import shutil import stat -import sys import tempfile import warnings -if sys.version_info < (3, 5): # noqa: E402 - raise ImportError(""" -Matplotlib 3.0+ does not support Python 2.x, 3.0, 3.1, 3.2, 3.3, or 3.4. -Beginning with Matplotlib 3.0, Python 3.5 and above is required. - -See Matplotlib `INSTALL.rst` file for more information: - - https://github.com/matplotlib/matplotlib/blob/master/INSTALL.rst - -""") - # cbook must import matplotlib only within function # definitions, so it is safe to import from it here. from . import cbook diff --git a/setup.py b/setup.py index 9a16373ee303..1745a67d099b 100644 --- a/setup.py +++ b/setup.py @@ -14,6 +14,17 @@ import sys +if sys.version_info < (3, 5): + error = """ +Matplotlib 3.0+ does not support Python 2.x, 3.0, 3.1, 3.2, 3.3, or 3.4. +Beginning with Matplotlib 3.0, Python 3.5 and above is required. + +This may be due to an out of date pip. + +Make sure you have pip >= 9.0.1. +""" + sys.exit(error) + # distutils is breaking our sdists for files in symlinked dirs. # distutils will copy if os.link is not available, so this is a hack # to force copying @@ -108,9 +119,7 @@ 'Intended Audience :: Science/Research', 'License :: OSI Approved :: Python Software Foundation License', 'Programming Language :: Python', - 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.6', 'Topic :: Scientific/Engineering :: Visualization', diff --git a/setupext.py b/setupext.py index b8586d682a4e..7c7cbfea68f7 100644 --- a/setupext.py +++ b/setupext.py @@ -1,6 +1,3 @@ -# NOTE: This file must remain Python 2 compatible for the forseeable future, -# to ensure that we error out properly for people with outdated setuptools -# and/or pip. from __future__ import print_function, absolute_import from importlib import import_module @@ -14,18 +11,15 @@ import os import platform import re +import shutil import subprocess from subprocess import check_output import sys import warnings from textwrap import fill -import shutil import versioneer -PY3min = (sys.version_info[0] >= 3) - - def _get_xdg_cache_dir(): """ Return the XDG cache directory. @@ -60,16 +54,10 @@ def _get_xdg_cache_dir(): LOCAL_FREETYPE_HASH = _freetype_hashes.get(LOCAL_FREETYPE_VERSION, 'unknown') if sys.platform != 'win32': - if not PY3min: - from commands import getstatusoutput - else: - from subprocess import getstatusoutput + from subprocess import getstatusoutput -if PY3min: - import configparser -else: - import ConfigParser as configparser +import configparser # matplotlib build options, which can be altered using setup.cfg @@ -83,10 +71,7 @@ def _get_xdg_cache_dir(): setup_cfg = os.environ.get('MPLSETUPCFG', 'setup.cfg') if os.path.exists(setup_cfg): - if PY3min: - config = configparser.ConfigParser() - else: - config = configparser.SafeConfigParser() + config = configparser.ConfigParser() config.read(setup_cfg) if config.has_option('status', 'suppress'): @@ -567,11 +552,7 @@ def _try_managers(*managers): for manager in managers: pkg_name = self.pkg_names.get(manager, None) if pkg_name: - try: - # `shutil.which()` can be used when Python 2.7 support - # is dropped. It is available in Python 3.3+ - _ = check_output(["which", manager], - stderr=subprocess.STDOUT) + if shutil.which(manager) is not None: if manager == 'port': pkgconfig = 'pkgconfig' else: @@ -580,8 +561,6 @@ def _try_managers(*managers): 'and pkg-config with `{1} install {3}`' .format(self.name, manager, pkg_name, pkgconfig)) - except subprocess.CalledProcessError: - pass message = None if sys.platform == "win32": @@ -812,15 +791,6 @@ def check(self): except ImportError: msgs += [bad_pytest] - if PY3min: - msgs += ['using unittest.mock'] - else: - try: - import mock - msgs += ['using mock %s' % mock.__version__] - except ImportError: - msgs += [msg_template.format(package='mock')] - return ' / '.join(msgs) def get_packages(self): @@ -937,19 +907,12 @@ class Numpy(SetupPackage): @staticmethod def include_dirs_hook(): - if PY3min: - import builtins - if hasattr(builtins, '__NUMPY_SETUP__'): - del builtins.__NUMPY_SETUP__ - import imp - import numpy - imp.reload(numpy) - else: - import __builtin__ - if hasattr(__builtin__, '__NUMPY_SETUP__'): - del __builtin__.__NUMPY_SETUP__ - import numpy - reload(numpy) + import builtins + if hasattr(builtins, '__NUMPY_SETUP__'): + del builtins.__NUMPY_SETUP__ + import imp + import numpy + imp.reload(numpy) ext = Extension('test', []) ext.include_dirs.append(numpy.get_include()) @@ -990,10 +953,10 @@ def add_flags(self, ext): ext.define_macros.append(('__STDC_FORMAT_MACROS', 1)) def get_setup_requires(self): - return ['numpy>=1.7.1'] + return ['numpy>=1.10.0'] def get_install_requires(self): - return ['numpy>=1.7.1'] + return ['numpy>=1.10.0'] class LibAgg(SetupPackage): @@ -1146,11 +1109,7 @@ def do_custom_build(self): if (tarball_cache_path is not None and os.path.isfile(tarball_cache_path)): if get_file_hash(tarball_cache_path) == LOCAL_FREETYPE_HASH: - try: - os.makedirs('build') - except OSError: - # Don't care if it exists. - pass + os.makedirs('build', exist_ok=True) try: shutil.copy(tarball_cache_path, tarball_path) print('Using cached tarball: {}' @@ -1160,10 +1119,7 @@ def do_custom_build(self): pass if not os.path.isfile(tarball_path): - if PY3min: - from urllib.request import urlretrieve - else: - from urllib import urlretrieve + from urllib.request import urlretrieve if not os.path.exists('build'): os.makedirs('build') @@ -1193,11 +1149,7 @@ def do_custom_build(self): "You can download the file by " "alternative means and copy it " " to '{0}'".format(tarball_path)) - try: - os.makedirs(tarball_cache_dir) - except OSError: - # Don't care if it exists. - pass + os.makedirs(tarball_cache_dir, exist_ok=True) try: shutil.copy(tarball_path, tarball_cache_path) print('Cached tarball at: {}'.format(tarball_cache_path)) @@ -1474,7 +1426,7 @@ def check(self): def runtime_check(self): """ Checks whether TkAgg runtime dependencies are met """ - pkg_name = 'tkinter' if PY3min else 'Tkinter' + pkg_name = 'tkinter' try: import_module(pkg_name) except ImportError: