Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modernise setup scripts #484

Merged
merged 18 commits into from
Sep 26, 2024
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci-wheels.yml
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ jobs:
name: "Publish to Test PyPI"
runs-on: ubuntu-latest
# upload to Test PyPI for every commit on main branch
if: github.event_name == 'push' && github.event.ref == 'refs/heads/main'
if: github.event_name == 'push'
steps:
- uses: actions/download-artifact@v3
with:
Expand Down
15 changes: 7 additions & 8 deletions cf_units/tests/test_coding_standards.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,6 @@ def test_python_versions():

# Places that are checked:
pyproject_toml_file = REPO_DIR / "pyproject.toml"
setup_cfg_file = REPO_DIR / "setup.cfg"
tox_file = REPO_DIR / "tox.ini"
ci_locks_file = workflows_dir / "ci-locks.yml"
ci_tests_file = workflows_dir / "ci-tests.yml"
Expand All @@ -137,19 +136,19 @@ def test_python_versions():
text_searches: list[tuple[Path, str]] = [
(
pyproject_toml_file,
"target-version = ["
+ ", ".join([f'"py{p}"' for p in supported_strip])
+ "]",
),
(
setup_cfg_file,
"\n ".join(
[
f"Programming Language :: Python :: {ver}"
f'"Programming Language :: Python :: {ver}",'
for ver in supported
]
),
),
(
pyproject_toml_file,
"target-version = ["
+ ", ".join([f'"py{p}"' for p in supported_strip])
+ "]",
),
(
tox_file,
"[testenv:py{" + ",".join(supported_strip) + "}-lock]",
Expand Down
67 changes: 66 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,70 @@ requires = [
"setuptools_scm[toml]>=7.0",
"wheel",
"oldest-supported-numpy",
"Cython>=3.0"
"Cython>=3.0",
]
# Defined by PEP 517
build-backend = "setuptools.build_meta"

[project]
name = "cf-units"
authors = [
{name = "cf-units Contributors", email = "[email protected]"}
]
classifiers = [
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Science/Research",
"License :: OSI Approved :: BSD License",
"Operating System :: OS Independent",
"Programming Language :: Python",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: Implementation :: CPython",
"Topic :: Scientific/Engineering",
"Topic :: Scientific/Engineering :: Atmospheric Science",
"Topic :: Scientific/Engineering :: Oceanography",
]
dependencies = [
"antlr4-python3-runtime ==4.11.1", # To update this, see cf_units/_udunits2_parser/README.md
"cftime >=1.2",
"jinja2",
"numpy ==1.26.4"
# udunits2 cannot be installed with pip, and it is expected to be
# installed separately.
]
description = "Units of measure as required by the Climate and Forecast (CF) metadata conventions"
dynamic = [
"version",
]
keywords = [
"units",
"cf",
"cf-metadata",
"netcdf",
"science",
"earth-science",
"oceanography",
"meteorology",
"climate",
"python",
]
license.file = "LICENSE"
readme = "README.md"
requires-python = ">=3.9"

[project.optional-dependencies]
docs = ["sphinx"]
test = ["codecov", "cython", "jinja2", "pip", "pytest", "pytest-cov"]
all = ["pre-commit", "sphinx", "codecov", "cython", "jinja2", "pip", "pytest", "pytest-cov"]

[project.urls]
Code = "https://github.com/SciTools/cf-units"
Discussions = "https://github.com/SciTools/cf-units/discussions"
Issues = "https://github.com/SciTools/cf-units/issues"
Documentation = "https://cf-units.readthedocs.io"

[tool.coverage.run]
branch = true
plugins = [
Expand Down Expand Up @@ -41,6 +100,12 @@ doctest_optionflags = "NORMALIZE_WHITESPACE ELLIPSIS NUMBER"
minversion = "6.0"
testpaths = "cf_units"

[tool.setuptools]
license-files = ["LICENSE"]

[tool.setuptools.packages.find]
include = ["cf_units"]

[tool.setuptools_scm]
write_to = "cf_units/_version.py"
local_scheme = "dirty-tag"
Expand Down
66 changes: 0 additions & 66 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -1,66 +1,3 @@
[metadata]
author = SciTools Developers
classifiers =
Development Status :: 5 - Production/Stable
Intended Audience :: Science/Research
License :: OSI Approved :: BSD License
Operating System :: OS Independent
Programming Language :: Python :: 3 :: Only
Programming Language :: Python :: 3.10
Programming Language :: Python :: 3.11
Programming Language :: Python :: 3.12
Topic :: Scientific/Engineering
description = Units of measure as required by the Climate and Forecast (CF) metadata conventions
download_url = https://github.com/SciTools/cf-units
keywords =
units
cf
netcdf
science
oceanography
meteorology
climate
license = BSD
license_files = LICENSE
long_description = file: README.md
long_description_content_type = text/markdown
name = cf-units
project_urls =
Code = https://github.com/SciTools/cf-units
Discussions = https://github.com/SciTools/cf-units/discussions
Issues = https://github.com/SciTools/cf-units/issues
url = https://github.com/SciTools/cf-units
version = attr: cf_units.__version__

[options]
include_package_data = True
install_requires =
antlr4-python3-runtime ==4.11.1 # To update this, see cf_units/_udunits2_parser/README.md
cftime >=1.2
jinja2
numpy ==1.26.4
# udunits2 cannot be installed with pip, and it is expected to be
# installed separately.
packages = find_namespace:
python_requires =
>=3.9
zip_safe = False

[options.extras_require]
docs =
sphinx
test =
codecov
cython
jinja2
pip
pytest
pytest-cov
all =
pre-commit
%(docs)s
%(test)s

[flake8]
# References:
# https://flake8.readthedocs.io/en/latest/user/configuration.html
Expand Down Expand Up @@ -93,6 +30,3 @@ exclude =
doc,
etc,
cf_units/_udunits2_parser/parser/*

[aliases]
test = pytest
41 changes: 20 additions & 21 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
"""Setup routines to enable cf-units' Cython elements.

All other setup configuration is in `pyproject.toml`.
"""

import sys
from distutils.sysconfig import get_config_var
from os import environ
Expand All @@ -6,7 +11,8 @@

from setuptools import Command, Extension, setup

# Default to using cython, but use the .c files if it doesn't exist
# Default to using cython, but use the .c files if it doesn't exist.
# Supports the widest possible range of developer setups.
try:
from Cython.Build import cythonize
except ImportError:
Expand Down Expand Up @@ -40,27 +46,14 @@ def run(self):
path.unlink()


def get_include_dirs():
include_dirs = []
include_dir = environ.get("UDUNITS2_INCDIR")
if include_dir is None:
include_dir = get_config_var("INCLUDEDIR")
if include_dir is not None:
include_dirs.append(include_dir)
return include_dirs


def get_library_dirs():
library_dirs = []
library_dir = environ.get("UDUNITS2_LIBDIR")
if library_dir is None:
library_dir = get_config_var("LIBDIR")
if library_dir is not None:
library_dirs.append(library_dir)
return library_dirs
def get_dirs(env_var: str, config_var: str):
"""Get a directory from an environment variable or a distutils config variable."""
result = environ.get(env_var) or get_config_var(config_var)
return [result] if result else []


def get_package_data():
"""Find and correctly package the UDUNITS2 XML files for a wheel build."""
package_data = {}
# Determine whether we're building a wheel.
if "bdist_wheel" in sys.argv:
Expand Down Expand Up @@ -99,6 +92,7 @@ def get_package_data():


def numpy_build_ext(pars):
"""Make the NumPy headers available for the Cython layer."""
from setuptools.command.build_ext import build_ext as _build_ext

class build_ext(_build_ext):
Expand Down Expand Up @@ -126,12 +120,16 @@ def _set_builtin(name, value):
sys.argv.remove(FLAG_COVERAGE)
print('enable: "linetrace" Cython compiler directive')

library_dirs = get_library_dirs()
include_dirs = get_dirs("UDUNITS2_INCDIR", "INCLUDEDIR")
library_dirs = get_dirs("UDUNITS2_LIBDIR", "LIBDIR")

# Some of the complexity MUST remain in setup.py due to its dynamic nature. To
# reduce confusion, the Extension is 100% defined here, rather than splitting
# between setup.py and pyproject.toml `ext-modules`.
udunits_ext = Extension(
f"{PACKAGE}._udunits2",
[str(Path(f"{PACKAGE}") / f"_udunits2.{'pyx' if cythonize else 'c'}")],
include_dirs=get_include_dirs(),
include_dirs=include_dirs,
library_dirs=library_dirs,
libraries=["udunits2"],
define_macros=DEFINE_MACROS,
Expand All @@ -141,6 +139,7 @@ def _set_builtin(name, value):
)

if cythonize:
# https://docs.cython.org/en/latest/src/userguide/source_files_and_compilation.html#distributing-cython-modules
[udunits_ext] = cythonize(
udunits_ext,
compiler_directives=COMPILER_DIRECTIVES,
Expand Down
Loading