Skip to content

Commit

Permalink
Merge pull request #180 from bnavigator/setuptools_scm
Browse files Browse the repository at this point in the history
Use setuptools_scm instead of custom version determination code
  • Loading branch information
bnavigator committed Jul 16, 2022
2 parents e162b5f + c785268 commit 5a6858f
Show file tree
Hide file tree
Showing 9 changed files with 65 additions and 230 deletions.
3 changes: 1 addition & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ if (CMAKE_VERSION VERSION_GREATER "3.11.99")
cmake_policy(SET CMP0074 NEW)
endif()

project(slycot VERSION ${SLYCOT_VERSION} LANGUAGES NONE)
project(slycot LANGUAGES NONE)

enable_language(C)
enable_language(Fortran)
Expand All @@ -22,6 +22,5 @@ message(STATUS "NumPy included from: ${NumPy_INCLUDE_DIR}")
message(STATUS "F2PY included from: ${F2PY_INCLUDE_DIR}")
message(STATUS "LAPACK: ${LAPACK_LIBRARIES}")
message(STATUS "BLAS: ${BLAS_LIBRARIES}")
message(STATUS "Slycot version: ${SLYCOT_VERSION}")

add_subdirectory(slycot)
1 change: 0 additions & 1 deletion MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ include conda-recipe/*
include slycot/CMakeLists.txt
include slycot/tests/CMakeLists.txt
include slycot/*.py
include slycot/version.py.in
include slycot/src/*.f
include slycot/tests/*.py
graft slycot/src/SLICOT-Reference
4 changes: 3 additions & 1 deletion conda-recipe/meta.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,11 @@ requirements:
- libcblas * *netlib
- liblapack * *netlib
- python
- numpy!=1.23.0
- numpy !=1.23.0
- pip
- scikit-build >=0.14.1
- setuptools >=45
- setuptools_scm >=6.3

run:
- python {{ PY_VER }}
Expand Down
48 changes: 47 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,8 +1,54 @@
[build-system]
requires = [
"setuptools",
"setuptools>=45",
"setuptools_scm>=6.3",
"wheel",
"scikit-build>=0.14.1",
"cmake",
"numpy!=1.23.0"]
build-backend = "setuptools.build_meta"

[project]
name = "slycot"
description = "A wrapper for the SLICOT control and systems library"
readme = "README.rst"
authors = [{ name = "Enrico Avventi et al." }]
maintainers = [{ name = "Slycot developers", email = "python-control-discuss@lists.sourceforge.net"}]
license = {text = "GPL-2.0 AND BSD-3-Clause"}
classifiers = [
"Development Status :: 4 - Beta",
"Intended Audience :: Science/Research",
"Intended Audience :: Developers",
"License :: OSI Approved",
"License :: OSI Approved :: GNU General Public License v2 (GPLv2)",
"License :: OSI Approved :: BSD License",
"Programming Language :: C",
"Programming Language :: Fortran",
"Programming Language :: Python",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Topic :: Software Development",
"Topic :: Scientific/Engineering",
"Operating System :: Microsoft :: Windows",
"Operating System :: POSIX",
"Operating System :: Unix",
"Operating System :: MacOS",
]
requires-python = ">=3.7"
dependencies = [
"numpy",
]
dynamic = ["version"]

[project.urls]
homepage = "https://github.com/python-control/Slycot"


[tool.setuptools_scm]
write_to = "slycot/version.py"

[tool.pytest.ini_options]
# run the tests with compiled and installed package
addopts = "--pyargs slycot"
10 changes: 0 additions & 10 deletions setup.cfg.in

This file was deleted.

212 changes: 12 additions & 200 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,111 +8,18 @@

import builtins
import os
import sys
import subprocess
import re
import platform
try:
import configparser
except ImportError:
import ConfigParser as configparser

try:
from skbuild import setup
from skbuild.command.sdist import sdist
except ImportError:
raise ImportError('scikit-build must be installed before running setup.py')

DOCLINES = __doc__.split("\n")

CLASSIFIERS = """\
Development Status :: 4 - Beta
Intended Audience :: Science/Research
Intended Audience :: Developers
License :: OSI Approved
License :: OSI Approved :: GNU General Public License v2 (GPLv2)
Programming Language :: C
Programming Language :: Fortran
Programming Language :: Python
Programming Language :: Python :: 3.7
Programming Language :: Python :: 3.8
Programming Language :: Python :: 3.9
Programming Language :: Python :: 3.10
Topic :: Software Development
Topic :: Scientific/Engineering
Operating System :: Microsoft :: Windows
Operating System :: POSIX
Operating System :: Unix
Operating System :: MacOS
"""

# defaults
ISRELEASED = True
# assume a version set by conda, next update with git,
# otherwise count on default
VERSION = 'Unknown'


class GitError(RuntimeError):
"""Exception for git errors occuring in in git_version"""
pass


def git_version(srcdir=None):
"""Return the git version, revision and cycle
Uses rev-parse to get the revision tag to get the version number from the
latest tag and detects (approximate) revision cycles
"""
def _minimal_ext_cmd(cmd, srcdir):
# construct minimal environment
env = {}
for k in ['SYSTEMROOT', 'PATH']:
v = os.environ.get(k)
if v is not None:
env[k] = v
# LANGUAGE is used on win32
env['LANGUAGE'] = 'C'
env['LANG'] = 'C'
env['LC_ALL'] = 'C'
proc = subprocess.Popen(
cmd,
cwd=srcdir,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
env=env)
out, err = proc.communicate()
if proc.returncode:
errmsg = err.decode('ascii', errors='ignore').strip()
raise GitError("git err; return code %d, error message:\n '%s'"
% (proc.returncode, errmsg))
return out

try:
GIT_VERSION = VERSION
GIT_REVISION = 'Unknown'
GIT_CYCLE = 0
out = _minimal_ext_cmd(['git', 'rev-parse', 'HEAD'], srcdir)
GIT_REVISION = out.strip().decode('ascii')
out = _minimal_ext_cmd(['git', 'tag'], srcdir)
GIT_VERSION = out.strip().decode('ascii').split('\n')[-1][1:]
out = _minimal_ext_cmd(['git', 'describe', '--tags',
'--long', '--always'], srcdir)
try:
# don't get a good description with shallow clones
GIT_CYCLE = out.strip().decode('ascii').split('-')[1]
except IndexError:
pass
except OSError:
pass

return GIT_VERSION, GIT_REVISION, GIT_CYCLE

# 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_scm import get_version
except ImportError:
raise ImportError('setuptools_scm must be installed before running setup.py')

# This is a bit hackish: we are setting a global variable so that the main
# slycot __init__ can detect if it is being loaded by the setup routine, to
Expand All @@ -121,69 +28,6 @@ def _minimal_ext_cmd(cmd, srcdir):
builtins.__SLYCOT_SETUP__ = True


def rewrite_setup_cfg(version, gitrevision, release):
toreplace = dict(locals())
data = ''.join(open('setup.cfg.in', 'r').readlines()).split('@')
for k, v in toreplace.items():
idx = data.index(k)
data[idx] = v
cfg = open('setup.cfg', 'w')
cfg.write(''.join(data))
cfg.close()


def get_version_info(srcdir=None):
global ISRELEASED
GIT_CYCLE = 0

# Adding the git rev number needs to be done inside write_version_py(),
# otherwise the import of slycot.version messes up
# the build under Python 3.
if os.environ.get('CONDA_BUILD', False):
FULLVERSION = os.environ.get('PKG_VERSION', '???')
GIT_REVISION = os.environ.get('GIT_DESCRIBE_HASH', '')
ISRELEASED = True
rewrite_setup_cfg(FULLVERSION, GIT_REVISION, 'yes')
elif os.path.exists('.git'):
FULLVERSION, GIT_REVISION, GIT_CYCLE = git_version(srcdir)
ISRELEASED = (GIT_CYCLE == 0)
rewrite_setup_cfg(FULLVERSION, GIT_REVISION,
(ISRELEASED and 'yes') or 'no')
elif os.path.exists('setup.cfg'):
# valid distribution
setupcfg = configparser.ConfigParser(allow_no_value=True)
setupcfg.read('setup.cfg')

FULLVERSION = setupcfg.get(section='metadata', option='version')

if FULLVERSION is None:
FULLVERSION = "Unknown"

GIT_REVISION = setupcfg.get(section='metadata', option='gitrevision')

if GIT_REVISION is None:
GIT_REVISION = ""

return FULLVERSION, GIT_REVISION
else:

# try to find a version number from the dir name
dname = os.getcwd().split(os.sep)[-1]

m = re.search(r'[0-9.]+', dname)
if m:
FULLVERSION = m.group()
GIT_REVISION = ''

else:
FULLVERSION = VERSION
GIT_REVISION = "Unknown"

if not ISRELEASED:
FULLVERSION += '.' + str(GIT_CYCLE)

return FULLVERSION, GIT_REVISION

def check_submodules():
""" verify that the submodules are checked out and clean
use `git submodule update --init`; on failure
Expand Down Expand Up @@ -212,43 +56,11 @@ def run(self):
check_submodules()
sdist.run(self)

def setup_package():
src_path = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, src_path)

# Rewrite the version file everytime
VERSION, gitrevision = get_version_info(src_path)

metadata = dict(
name='slycot',
packages=['slycot', 'slycot.tests'],
cmake_languages=('C', 'Fortran'),
version=VERSION,
maintainer="Slycot developers",
maintainer_email="python-control-discuss@lists.sourceforge.net",
description=DOCLINES[0],
long_description=open('README.rst').read(),
url='https://github.com/python-control/Slycot',
author='Enrico Avventi et al.',
license='GPL-2.0',
classifiers=[_f for _f in CLASSIFIERS.split('\n') if _f],
platforms=["Windows", "Linux", "Solaris", "Mac OS-X", "Unix"],
cmdclass={"sdist": sdist_checked},
cmake_args=['-DSLYCOT_VERSION:STRING=' + VERSION,
'-DGIT_REVISION:STRING=' + gitrevision,
'-DISRELEASE:STRING=' + str(ISRELEASED),
'-DFULL_VERSION=' + VERSION + '.git' + gitrevision[:7]],
zip_safe=False,
install_requires=['numpy'],
python_requires=">=3.7"
)

try:
setup(**metadata)
finally:
del sys.path[0]
return


if __name__ == '__main__':
setup_package()
# These need to stay in setup.py
# https://scikit-build.readthedocs.io/en/latest/usage.html#setuptools-options
setup(
packages=['slycot', 'slycot.tests'],
cmdclass={'sdist': sdist_checked},
cmake_languages=('C', 'Fortran'),
use_scm_version = True,
)
4 changes: 1 addition & 3 deletions slycot/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -630,13 +630,11 @@ set(F2PYSOURCE_DEPS
src/transform.pyf src/synthesis.pyf
src/_helper.pyf)

configure_file(version.py.in version.py @ONLY)

set(PYSOURCE

__init__.py examples.py exceptions.py
analysis.py math.py synthesis.py transform.py
${CMAKE_CURRENT_BINARY_DIR}/version.py)
)

set(SLYCOT_MODULE "_wrapper")

Expand Down
3 changes: 1 addition & 2 deletions slycot/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,7 @@
from .transform import tf01md, tf01rd
from .transform import td04ad, tb01pd

# Version information
from .version import version as __version__
from .version import __version__


def test():
Expand Down
10 changes: 0 additions & 10 deletions slycot/version.py.in

This file was deleted.

0 comments on commit 5a6858f

Please sign in to comment.