From 3a5e582ca741a1819066078cfad26fae4f8bfe9f Mon Sep 17 00:00:00 2001 From: Vojta Tuma Date: Thu, 12 Dec 2024 16:24:07 +0100 Subject: [PATCH] Switch eccodes python to wheelchains --- setup.cfg | 20 +++++++++ setup.py | 131 +++++++++++++----------------------------------------- 2 files changed, 50 insertions(+), 101 deletions(-) diff --git a/setup.cfg b/setup.cfg index 2bd557ea..afd3c050 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,3 +1,23 @@ +[metadata] +description = "eccodes-python" +long_description = file: README.rst +long_description_content_type = text/rst +author = "European Centre for Medium-Range Weather Forecasts (ECMWF)" +author_email = "software.support@ecmwf.int" +url = "https://github.com/ecmwf/eccodes-python" +keywords = ecCodes, GRIB, BUFR +classifiers = + Development Status :: 4 - Beta + Intended Audience :: Developers + License :: OSI Approved :: Apache Software License + Programming Language :: Python :: 3.8 + Programming Language :: Python :: 3.9 + Programming Language :: Python :: 3.10 + Programming Language :: Python :: 3.11 + Programming Language :: Python :: Implementation :: CPython + Programming Language :: Python :: Implementation :: PyPy + Operating System :: OS Independent + [aliases] test = pytest diff --git a/setup.py b/setup.py index 5a435e2c..4ebc631a 100644 --- a/setup.py +++ b/setup.py @@ -1,125 +1,54 @@ -#!/usr/bin/env python -# -# (C) Copyright 2017- ECMWF. -# -# This software is licensed under the terms of the Apache Licence Version 2.0 -# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. -# -# In applying this licence, ECMWF does not waive the privileges and immunities -# granted to it by virtue of its status as an intergovernmental organisation nor -# does it submit to any jurisdiction. -# - -import io import os -import re import sys - import setuptools +from setup_utils import parse_dependencies, ext_kwargs + +# TODO this needs to be automated, in particular: +# - handle the dependency preparation, similarly to how wheelmaker/prepare_deps.sh does it +# - possibly include a buildconfig file here as well +# - wheel linux needs only to invoke uv run --python python3.11 python -m build --installer uv --wheel . +# - reqs: pythonpath to setup_utils, name, version, libdir, incdir +# - version probably directly from eccodes themselves? +# - can we restrict setuptools version without pyproject? Do we need the setuptools upperbound? See the NOTEs below +# - the whole github action needs to be redone +# - deal with the naming oddities. Name the eccodes so package `libs`? Probably rename to libs globally, and fix the findlibs invocations in odc and in eccodes +# - simplify the findlibs invocations in the codebase - -def read(path): - file_path = os.path.join(os.path.dirname(__file__), *path.split("/")) - return io.open(file_path, encoding="utf-8").read() - - -# single-sourcing the package version using method 1 of: -# https://packaging.python.org/guides/single-sourcing-package-version/ -def parse_version_from(path): - version_pattern = ( - r"^__version__ = [\"\'](.*)[\"\']" # More permissive regex pattern - ) - version_file = read(path) - version_match = re.search(version_pattern, version_file, re.M) - if version_match is None or len(version_match.groups()) > 1: - raise ValueError("couldn't parse version") - return version_match.group(1) - - -# for the binary wheel -libdir = os.path.realpath("install/lib") -incdir = os.path.realpath("install/include") -libs = ["eccodes"] - -if "--binary-wheel" in sys.argv: - sys.argv.remove("--binary-wheel") - - # https://setuptools.pypa.io/en/latest/userguide/ext_modules.html - ext_modules = [ - setuptools.Extension( - "eccodes._eccodes", - sources=["eccodes/_eccodes.cc"], - language="c++", - libraries=libs, - library_dirs=[libdir], - include_dirs=[incdir], - extra_link_args=["-Wl,-rpath," + libdir], - ) - ] - - def shared(directory): - result = [] - for path, dirs, files in os.walk(directory): - for f in files: - result.append(os.path.join(path, f)) - return result - - # Paths must be relative to package directory... - shared_files = ["versions.txt"] - shared_files += [x[len("eccodes/") :] for x in shared("eccodes/copying")] - - if os.name == "nt": - for n in os.listdir("eccodes"): - if n.endswith(".dll"): - shared_files.append(n) - -else: - ext_modules = [] - shared_files = [] - - -install_requires = ["numpy"] if sys.version_info < (3, 7): install_requires = ["numpy<1.20"] elif sys.version_info < (3, 8): install_requires = ["numpy<1.22"] elif sys.version_info < (3, 9): install_requires = ["numpy<1.25"] +else: + install_requires = ["numpy"] install_requires += ["attrs", "cffi", "findlibs"] +ext_modules = [ + setuptools.Extension( + "eccodes._eccodes", + sources=["eccodes/_eccodes.cc"], + language="c++", + libraries=["eccodes"], + library_dirs=[os.environ["LIBDIR"]], + include_dirs=[os.environ["INCDIR"]], + ) +] setuptools.setup( - name="eccodes", - version=parse_version_from("gribapi/bindings.py"), - description="Python interface to the ecCodes GRIB and BUFR decoder/encoder", - long_description=read("README.rst") + read("CHANGELOG.rst"), - author="European Centre for Medium-Range Weather Forecasts (ECMWF)", - author_email="software.support@ecmwf.int", - license="Apache License Version 2.0", - url="https://github.com/ecmwf/eccodes-python", + name=os.environ["NAME"], + version=os.environ["VERSION"], packages=setuptools.find_packages(), - include_package_data=True, - package_data={"": shared_files}, - install_requires=install_requires, + install_requires=parse_dependencies() + install_requires, + **ext_kwargs[sys.platform], + # NOTE does this work? Move to extras? tests_require=[ "pytest", "pytest-cov", "pytest-flakes", ], + # NOTE does this work? test_suite="tests", zip_safe=True, - keywords="ecCodes GRIB BUFR", - classifiers=[ - "Development Status :: 4 - Beta", - "Intended Audience :: Developers", - "License :: OSI Approved :: Apache Software License", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - "Programming Language :: Python :: Implementation :: CPython", - "Programming Language :: Python :: Implementation :: PyPy", - "Operating System :: OS Independent", - ], ext_modules=ext_modules, )