Skip to content
Browse files

Fix infinite process recursion on Windows

  • Loading branch information...
1 parent 5f41835 commit ce1da9b07c9f89f76622a823d92f85bd00f7b172 @mdboom mdboom committed
Showing with 158 additions and 133 deletions.
  1. +137 −133 setup.py
  2. +21 −0 setupext.py
View
270 setup.py
@@ -20,17 +20,19 @@
except AttributeError:
pass
-# BEFORE importing distutils, remove MANIFEST. distutils doesn't properly
-# update it when the contents of directories change.
-if os.path.exists('MANIFEST'):
- os.remove('MANIFEST')
+# This 'if' statement is needed to prevent spawning infinite processes
+# on Windows
+if __name__ == '__main__':
+ # BEFORE importing distutils, remove MANIFEST. distutils doesn't properly
+ # update it when the contents of directories change.
+ if os.path.exists('MANIFEST'):
+ os.remove('MANIFEST')
try:
from setuptools.core import setup
except ImportError:
from distutils.core import setup
-
import setupext
from setupext import print_line, print_raw, print_message, print_status
@@ -48,6 +50,7 @@
'Required dependencies and extensions',
setupext.Numpy(),
setupext.Dateutil(),
+ setupext.Tornado(),
setupext.Pyparsing(),
setupext.CXX(),
setupext.LibAgg(),
@@ -87,90 +90,6 @@
]
-# These are distutils.setup parameters that the various packages add
-# things to.
-packages = []
-py_modules = []
-ext_modules = []
-package_data = {}
-package_dir = {'': 'lib'}
-install_requires = []
-default_backend = None
-
-
-# Go through all of the packages and figure out which ones we are
-# going to build/install.
-print_line()
-print_raw("Edit setup.cfg to change the build options")
-
-
-required_failed = []
-good_packages = []
-for package in mpl_packages:
- if isinstance(package, str):
- print_raw('')
- print_raw(package.upper())
- else:
- try:
- result = package.check()
- if result is not None:
- message = 'yes [%s]' % result
- print_status(package.name, message)
- except setupext.CheckFailed as e:
- print_status(package.name, 'no [%s]' % str(e))
- if not package.optional:
- required_failed.append(package)
- else:
- good_packages.append(package)
- if isinstance(package, setupext.OptionalBackendPackage):
- if default_backend is None:
- default_backend = package.name
-print_raw('')
-
-
-# Abort if any of the required packages can not be built.
-if required_failed:
- print_line()
- print_message(
- "The following required packages can not "
- "be built: %s" %
- ', '.join(x.name for x in required_failed))
- sys.exit(1)
-
-
-# Now collect all of the information we need to build all of the
-# packages.
-for package in good_packages:
- if isinstance(package, str):
- continue
- packages.extend(package.get_packages())
- py_modules.extend(package.get_py_modules())
- ext = package.get_extension()
- if ext is not None:
- ext_modules.append(ext)
- data = package.get_package_data()
- for key, val in data.items():
- package_data.setdefault(key, [])
- package_data[key] = list(set(val + package_data[key]))
- install_requires.extend(package.get_install_requires())
-
-# Write the default matplotlibrc file
-if default_backend is None:
- default_backend = 'svg'
-if setupext.options['backend']:
- default_backend = setupext.options['backend']
-with open('matplotlibrc.template') as fd:
- template = fd.read()
-with open('lib/matplotlib/mpl-data/matplotlibrc', 'w') as fd:
- fd.write(template % {'backend': default_backend})
-
-
-# Build in verbose mode if requested
-if setupext.options['verbose']:
- for mod in ext_modules:
- mod.extra_compile_args.append('-DVERBOSE')
-
-
classifiers = [
'Development Status :: 5 - Production/Stable',
'Intended Audience :: Science/Research',
@@ -181,47 +100,132 @@
'Topic :: Scientific/Engineering :: Visualization',
]
-
-# Finally, pass this all along to distutils to do the heavy lifting.
-distrib = setup(name="matplotlib",
- version=__version__,
- description="Python plotting package",
- author="John D. Hunter, Michael Droettboom",
- author_email="mdroe@stsci.edu",
- url="http://matplotlib.org",
- long_description="""
- matplotlib strives to produce publication quality 2D graphics
- for interactive graphing, scientific publishing, user interface
- development and web application servers targeting multiple user
- interfaces and hardcopy output formats. There is a 'pylab' mode
- which emulates matlab graphics.
- """,
- download_url="https://downloads.sourceforge.net/project/matplotlib/matplotlib/matplotlib-{0}/matplotlib-{0}.tar.gz".format(__version__),
- install_requires=['dateutils', 'tornado'],
- license="BSD",
- packages=packages,
- platforms='any',
- py_modules=py_modules,
- ext_modules=ext_modules,
- package_dir=package_dir,
- package_data=package_data,
- classifiers=classifiers,
-
- # List third-party Python packages that we require
- install_requires=install_requires,
-
- # Automatically 2to3 source on Python 3.x
- use_2to3=True,
-
- # matplotlib has C/C++ extensions, so it's not zip safe.
- # Telling setuptools this prevents it from doing an automatic
- # check for zip safety.
- zip_safe=False,
-
- # Install our nose plugin so it will always be found
- entry_points={
- 'nose.plugins.0.10': [
- 'KnownFailure = matplotlib.testing.noseclasses:KnownFailure'
- ]
- },
- )
+# One doesn't normally see `if __name__ == '__main__'` blocks in a setup.py,
+# however, this is needed on Windows to avoid creating infinite subprocesses
+# when using multiprocessing.
+if __name__ == '__main__':
+ # These are distutils.setup parameters that the various packages add
+ # things to.
+ packages = []
+ py_modules = []
+ ext_modules = []
+ package_data = {}
+ package_dir = {'': 'lib'}
+ install_requires = []
+ default_backend = None
+
+
+ # Go through all of the packages and figure out which ones we are
+ # going to build/install.
+ print_line()
+ print_raw("Edit setup.cfg to change the build options")
+
+ required_failed = []
+ good_packages = []
+ for package in mpl_packages:
+ if isinstance(package, str):
+ print_raw('')
+ print_raw(package.upper())
+ else:
+ try:
+ result = package.check()
+ if result is not None:
+ message = 'yes [%s]' % result
+ print_status(package.name, message)
+ except setupext.CheckFailed as e:
+ print_status(package.name, 'no [%s]' % str(e))
+ if not package.optional:
+ required_failed.append(package)
+ else:
+ good_packages.append(package)
+ if isinstance(package, setupext.OptionalBackendPackage):
+ if default_backend is None:
+ default_backend = package.name
+ print_raw('')
+
+
+ # Abort if any of the required packages can not be built.
+ if required_failed:
+ print_line()
+ print_message(
+ "The following required packages can not "
+ "be built: %s" %
+ ', '.join(x.name for x in required_failed))
+ sys.exit(1)
+
+
+ # Now collect all of the information we need to build all of the
+ # packages.
+ for package in good_packages:
+ if isinstance(package, str):
+ continue
+ packages.extend(package.get_packages())
+ py_modules.extend(package.get_py_modules())
+ ext = package.get_extension()
+ if ext is not None:
+ ext_modules.append(ext)
+ data = package.get_package_data()
+ for key, val in data.items():
+ package_data.setdefault(key, [])
+ package_data[key] = list(set(val + package_data[key]))
+ install_requires.extend(package.get_install_requires())
+
+ # Write the default matplotlibrc file
+ if default_backend is None:
+ default_backend = 'svg'
+ if setupext.options['backend']:
+ default_backend = setupext.options['backend']
+ with open('matplotlibrc.template') as fd:
+ template = fd.read()
+ with open('lib/matplotlib/mpl-data/matplotlibrc', 'w') as fd:
+ fd.write(template % {'backend': default_backend})
+
+
+ # Build in verbose mode if requested
+ if setupext.options['verbose']:
+ for mod in ext_modules:
+ mod.extra_compile_args.append('-DVERBOSE')
+
+
+ # Finally, pass this all along to distutils to do the heavy lifting.
+ distrib = setup(name="matplotlib",
+ version=__version__,
+ description="Python plotting package",
+ author="John D. Hunter, Michael Droettboom",
+ author_email="mdroe@stsci.edu",
+ url="http://matplotlib.org",
+ long_description="""
+ matplotlib strives to produce publication quality 2D graphics
+ for interactive graphing, scientific publishing, user interface
+ development and web application servers targeting multiple user
+ interfaces and hardcopy output formats. There is a 'pylab' mode
+ which emulates matlab graphics.
+ """,
+ license="BSD",
+ packages=packages,
+ platforms='any',
+ py_modules=py_modules,
+ ext_modules=ext_modules,
+ package_dir=package_dir,
+ package_data=package_data,
+ classifiers=classifiers,
+ download_url="https://downloads.sourceforge.net/project/matplotlib/matplotlib/matplotlib-{0}/matplotlib-{0}.tar.gz".format(__version__),
+
+ # List third-party Python packages that we require
+ install_requires=install_requires,
+
+ # Automatically 2to3 source on Python 3.x
+ use_2to3=True,
+
+ # matplotlib has C/C++ extensions, so it's not zip safe.
+ # Telling setuptools this prevents it from doing an automatic
+ # check for zip safety.
+ zip_safe=False,
+
+ # Install our nose plugin so it will always be found
+ entry_points={
+ 'nose.plugins.0.10': [
+ 'KnownFailure = matplotlib.testing.noseclasses:KnownFailure'
+ ]
+ },
+ )
View
21 setupext.py
@@ -723,6 +723,9 @@ class FreeType(SetupPackage):
name = "freetype"
def check(self):
+ if sys.platform == 'win32':
+ return "Unknown version"
+
status, output = getstatusoutput("freetype-config --version")
if status == 0:
version = output
@@ -885,6 +888,24 @@ def get_install_requires(self):
return ['python_dateutil']
+class Tornado(SetupPackage):
+ name = "tornado"
+
+ def check(self):
+ try:
+ import tornado
+ except ImportError:
+ return (
+ "tornado was not found. It is required for the WebAgg "
+ "backend. pip/easy_install may attempt to install it "
+ "after matplotlib.")
+
+ return "using tornado version %s" % tornado.__version__
+
+ def get_install_requires(self):
+ return ['tornado']
+
+
class Pyparsing(SetupPackage):
name = "pyparsing"

0 comments on commit ce1da9b

Please sign in to comment.
Something went wrong with that request. Please try again.