diff options
author | Alexandre Marie <alexandre.marie@synchrotron-soleil.fr> | 2020-07-21 14:45:14 +0200 |
---|---|---|
committer | Alexandre Marie <alexandre.marie@synchrotron-soleil.fr> | 2020-07-21 14:45:14 +0200 |
commit | 328032e2317e3ac4859196bbf12bdb71795302fe (patch) | |
tree | 8cd13462beab109e3cb53410c42335b6d1e00ee6 /setup.py | |
parent | 33ed2a64c92b0311ae35456c016eb284e426afc2 (diff) |
New upstream version 0.13.0+dfsg
Diffstat (limited to 'setup.py')
-rw-r--r-- | setup.py | 131 |
1 files changed, 95 insertions, 36 deletions
@@ -1,8 +1,8 @@ -#!/usr/bin/python +#!/usr/bin/env python3 # coding: utf8 # /*########################################################################## # -# Copyright (c) 2015-2019 European Synchrotron Radiation Facility +# Copyright (c) 2015-2020 European Synchrotron Radiation Facility # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -25,10 +25,9 @@ # ###########################################################################*/ __authors__ = ["Jérôme Kieffer", "Thomas Vincent"] -__date__ = "12/02/2019" +__date__ = "06/05/2020" __license__ = "MIT" - import sys import os import platform @@ -40,30 +39,35 @@ import glob # The silx.io module seems to be loaded instead. import io - logging.basicConfig(level=logging.INFO) logger = logging.getLogger("silx.setup") - from distutils.command.clean import clean as Clean from distutils.command.build import build as _build try: from setuptools import Command from setuptools.command.build_py import build_py as _build_py - from setuptools.command.build_ext import build_ext from setuptools.command.sdist import sdist - logger.info("Use setuptools") + try: + from Cython.Build import build_ext + logger.info("Use setuptools with cython") + except ImportError: + from setuptools.command.build_ext import build_ext + logger.info("Use setuptools, cython is missing") except ImportError: try: from numpy.distutils.core import Command except ImportError: from distutils.core import Command from distutils.command.build_py import build_py as _build_py - from distutils.command.build_ext import build_ext from distutils.command.sdist import sdist - logger.info("Use distutils") - + try: + from Cython.Build import build_ext + logger.info("Use distutils with cython") + except ImportError: + from distutils.command.build_ext import build_ext + logger.info("Use distutils, cython is missing") try: import sphinx import sphinx.util.console @@ -72,8 +76,9 @@ try: except ImportError: sphinx = None - PROJECT = "silx" +if sys.version_info.major < 3: + logger.error(PROJECT + " no longer supports Python2") if "LANG" not in os.environ and sys.platform == "darwin" and sys.version_info[0] > 2: print("""WARNING: the LANG environment variable is not defined, @@ -114,36 +119,33 @@ classifiers = ["Development Status :: 4 - Beta", "Operating System :: Microsoft :: Windows", "Operating System :: POSIX", "Programming Language :: Cython", - "Programming Language :: Python :: 2.7", - "Programming Language :: Python :: 3.5", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3", "Programming Language :: Python :: Implementation :: CPython", "Topic :: Scientific/Engineering :: Physics", "Topic :: Software Development :: Libraries :: Python Modules", ] - # ########## # # version.py # # ########## # + class build_py(_build_py): """ Enhanced build_py which copies version.py to <PROJECT>._version.py """ + def find_package_modules(self, package, package_dir): modules = _build_py.find_package_modules(self, package, package_dir) if package == PROJECT: modules.append((PROJECT, '_version', 'version.py')) return modules - ######## # Test # ######## + class PyTest(Command): """Command to start tests running the script: run_tests.py""" user_options = [] @@ -162,12 +164,13 @@ class PyTest(Command): if errno != 0: raise SystemExit(errno) - # ################### # # build_doc command # # ################### # + if sphinx is None: + class SphinxExpectedCommand(Command): """Command to inform that sphinx is missing""" user_options = [] @@ -255,6 +258,55 @@ class BuildMan(Command): succeeded = succeeded and status == 0 return succeeded + @staticmethod + def _write_script(target_name, lst_lines=None): + """Write a script to a temporary file and return its name + :paran target_name: base of the script name + :param lst_lines: list of lines to be written in the script + :return: the actual filename of the script (for execution or removal) + """ + import tempfile + import stat + script_fid, script_name = tempfile.mkstemp(prefix="%s_" % target_name, text=True) + with os.fdopen(script_fid, 'wt') as script: + for line in lst_lines: + if not line.endswith("\n"): + line += "\n" + script.write(line) + # make it executable + mode = os.stat(script_name).st_mode + os.chmod(script_name, mode + stat.S_IEXEC) + return script_name + + def get_synopsis(self, module_name, env, log_output=False): + """Execute a script to retrieve the synopsis for help2man + :return: synopsis + :rtype: single line string + """ + import subprocess + script_name = None + synopsis = None + script = ["#!%s\n" % sys.executable, + "import logging", + "logging.basicConfig(level=logging.ERROR)", + "import %s as app" % module_name, + "print(app.__doc__)"] + try: + script_name = self._write_script(module_name, script) + command_line = [sys.executable, script_name] + p = subprocess.Popen(command_line, env=env, stdout=subprocess.PIPE) + status = p.wait() + if status != 0: + logger.warning("Error while getting synopsis for module '%s'.", module_name) + synopsis = p.stdout.read().decode("utf-8").strip() + if synopsis == 'None': + synopsis = None + finally: + # clean up the script + if script_name is not None: + os.remove(script_name) + return synopsis + def run(self): build = self.get_finalized_command('build') path = sys.path @@ -268,6 +320,7 @@ class BuildMan(Command): import tempfile import stat script_name = None + workdir = tempfile.mkdtemp() entry_points = self.entry_points_iterator() for target_name, module_name, function_name in entry_points: @@ -278,19 +331,22 @@ class BuildMan(Command): py3 = sys.version_info >= (3, 0) try: # create a launcher using the right python interpreter - script_fid, script_name = tempfile.mkstemp(prefix="%s_" % target_name, text=True) - script = os.fdopen(script_fid, 'wt') - script.write("#!%s\n" % sys.executable) - script.write("import %s as app\n" % module_name) - script.write("app.%s()\n" % function_name) - script.close() + script_name = os.path.join(workdir, target_name) + with open(script_name, "wt") as script: + script.write("#!%s\n" % sys.executable) + script.write("import %s as app\n" % module_name) + script.write("app.%s()\n" % function_name) # make it executable mode = os.stat(script_name).st_mode os.chmod(script_name, mode + stat.S_IEXEC) # execute help2man man_file = "build/man/%s.1" % target_name - command_line = ["help2man", script_name, "-o", man_file] + command_line = ["help2man", "-N", script_name, "-o", man_file] + + synopsis = self.get_synopsis(module_name, env) + if synopsis: + command_line += ["-n", synopsis] if not py3: # Before Python 3.4, ArgParser --version was using # stderr to print the version @@ -313,9 +369,11 @@ class BuildMan(Command): # clean up the script if script_name is not None: os.remove(script_name) + os.rmdir(workdir) if sphinx is not None: + class BuildDocCommand(BuildDoc): """Command to build documentation using sphinx. @@ -351,6 +409,7 @@ if sphinx is not None: sys.path.pop(0) class BuildDocAndGenerateScreenshotCommand(BuildDocCommand): + def run(self): old = os.environ.get('DIRECTIVE_SNAPSHOT_QT') os.environ['DIRECTIVE_SNAPSHOT_QT'] = 'True' @@ -364,17 +423,18 @@ else: BuildDocCommand = SphinxExpectedCommand BuildDocAndGenerateScreenshotCommand = SphinxExpectedCommand - # ################### # # test_doc command # # ################### # if sphinx is not None: + class TestDocCommand(BuildDoc): """Command to test the documentation using sphynx doctest. http://www.sphinx-doc.org/en/1.4.8/ext/doctest.html """ + def run(self): # make sure the python path is pointing to the newly built # code so that the documentation is built on this and not a @@ -394,11 +454,11 @@ if sphinx is not None: else: TestDocCommand = SphinxExpectedCommand - # ############################# # # numpy.distutils Configuration # # ############################# # + def configuration(parent_package='', top_path=None): """Recursive construction of package info to be used in setup(). @@ -529,10 +589,10 @@ class BuildExt(build_ext): # Cytonize from Cython.Build import cythonize patched_exts = cythonize( - [ext], - compiler_directives={'embedsignature': True, + [ext], + compiler_directives={'embedsignature': True, 'language_level': 3}, - force=self.force_cython + force=self.force_cython ) ext.sources = patched_exts[0].sources @@ -634,7 +694,6 @@ class BuildExt(build_ext): self.patch_extension(ext) build_ext.build_extensions(self) - ################################################################################ # Clean command ################################################################################ @@ -700,7 +759,6 @@ class CleanCommand(Clean): except OSError: pass - ################################################################################ # Debian source tree ################################################################################ @@ -764,11 +822,11 @@ class sdist_debian(sdist): self.archive_files = [debian_arch] print("Building debian .orig.tar.gz in %s" % self.archive_files[0]) - # ##### # # setup # # ##### # + def get_project_configuration(dry_run): """Returns project arguments for setup""" # Use installed numpy version as minimal required version @@ -787,7 +845,7 @@ def get_project_configuration(dry_run): "setuptools", # for io support "h5py", - "fabio>=0.7", + "fabio>=0.9", # Python 2/3 compatibility "six", ] @@ -888,6 +946,7 @@ def get_project_configuration(dry_run): package_data=package_data, zip_safe=False, entry_points=entry_points, + python_requires='>=3.5', ) return setup_kwargs |