diff --git a/.coveragerc b/.coveragerc deleted file mode 100644 index 232c70dea..000000000 --- a/.coveragerc +++ /dev/null @@ -1,10 +0,0 @@ -[run] -source = gstools -omit = *docs*, *examples*, *tests*, */gstools/covmodel/plot.py, */gstools/field/plot.py - -[report] -exclude_lines = - pragma: no cover - if __name__ == '__main__': - def __repr__ - def __str__ diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 65b8ab6f1..34b0f1b82 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -14,6 +14,29 @@ on: workflow_dispatch: jobs: + format_check: + name: format check + runs-on: ubuntu-latest + strategy: + fail-fast: false + + steps: + - uses: actions/checkout@v2 + + - name: Set up Python 3.8 + uses: actions\setup-python@v2 + with: + python-version: 3.8 + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install black + + - name: black check + run: | + python -m black --check . + build_wheels: name: wheels on ${{ matrix.os }} runs-on: ${{ matrix.os }} @@ -31,8 +54,7 @@ jobs: uses: joerick/cibuildwheel@v1.10.0 env: CIBW_BUILD: cp36-* cp37-* cp38-* cp39-* - CIBW_BEFORE_BUILD: pip install numpy==1.19.* cython==0.29.* setuptools - CIBW_TEST_REQUIRES: pytest + CIBW_TEST_EXTRAS: test CIBW_TEST_COMMAND: pytest -v {project}/tests with: output-dir: dist @@ -61,17 +83,12 @@ jobs: python-version: ${{ matrix.python-version }} - name: Install dependencies + env: + GSTOOLS_BUILD_PARALLEL: 1 run: | python -m pip install --upgrade pip - pip install -r requirements_setup.txt - pip install -r requirements.txt - pip install -r requirements_test.txt - pip install coveralls>=3.0.0 - - - name: Build sdist - run: | - python setup.py sdist -d dist - python setup.py --openmp build_ext --inplace + pip install build coveralls>=3.0.0 + pip install --editable .[test] - name: Run tests env: @@ -80,6 +97,11 @@ jobs: python -m pytest --cov gstools --cov-report term-missing -v tests/ python -m coveralls --service=github + - name: Build sdist + run: | + # PEP 517 package builder from pypa + python -m build --sdist --outdir dist . + - uses: actions/upload-artifact@v2 if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.9' with: diff --git a/.readthedocs.yml b/.readthedocs.yml new file mode 100644 index 000000000..f88c11ac0 --- /dev/null +++ b/.readthedocs.yml @@ -0,0 +1,14 @@ +version: 2 + +sphinx: + configuration: docs/source/conf.py + +formats: all + +python: + version: 3.7 + install: + - method: pip + path: . + extra_requirements: + - doc diff --git a/MANIFEST.in b/MANIFEST.in index 2f67477f9..12d5af66b 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,9 +1,8 @@ -include README.md -include MANIFEST.in -include setup.py -include setup.cfg -recursive-include gstools *.py *.pyx *.c -recursive-include tests *.py -recursive-include docs/source * -include docs/Makefile docs/requirements.txt -include LICENSE +prune * +graft tests +graft docs +recursive-include gstools *.py *.pyx +recursive-exclude gstools *.c *.cpp +include LICENSE pyproject.toml setup.py setup.cfg +include *.md +global-exclude __pycache__ *.py[cod] .* diff --git a/docs/requirements.txt b/docs/requirements.txt deleted file mode 100644 index c5a6a232c..000000000 --- a/docs/requirements.txt +++ /dev/null @@ -1,3 +0,0 @@ --r requirements_doc.txt --r ../requirements_setup.txt --r ../requirements.txt diff --git a/docs/requirements_doc.txt b/docs/requirements_doc.txt deleted file mode 100755 index 9bb751acc..000000000 --- a/docs/requirements_doc.txt +++ /dev/null @@ -1,7 +0,0 @@ -numpydoc -sphinx-gallery -matplotlib -pyvista -pykrige -meshzoo -m2r2 diff --git a/docs/source/index.rst b/docs/source/index.rst index 763a01cea..bb06049af 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -61,24 +61,24 @@ To get the latest development version you can install it directly from GitHub: If something went wrong during installation, try the :code:`-I` `flag from pip `_. -To enable the OpenMP support, you have to provide a C compiler, Cython and OpenMP. -To get all other dependencies, it is recommended to first install gstools once -in the standard way just decribed. -Simply use the following commands: +To enable the OpenMP support, you have to provide a C compiler and OpenMP. +Parallel support is controlled by an environment variable ``GSTOOLS_BUILD_PARALLEL``, +that can be ``0`` or ``1`` (interpreted as ``0`` if not present). +GSTools then needs to be installed from source: .. code-block:: none - pip install gstools - pip install -I --no-deps --global-option="--openmp" gstools + export GSTOOLS_BUILD_PARALLEL=1 + pip install --no-binary=gstools gstools + +Note, that the ``--no-binary=gstools`` option forces pip to not use a wheel for GSTools. -Or for the development version: +For the development version, you can do almost the same: .. code-block:: none + export GSTOOLS_BUILD_PARALLEL=1 pip install git+git://github.com/GeoStat-Framework/GSTools.git@develop - pip install -I --no-deps --global-option="--openmp" git+git://github.com/GeoStat-Framework/GSTools.git@develop - -The flags :code:`-I --no-deps` force pip to reinstall gstools but not the dependencies. Citation diff --git a/examples/08_geo_coordinates/01_dwd_krige.py b/examples/08_geo_coordinates/01_dwd_krige.py index e1f789176..bac4b31cb 100755 --- a/examples/08_geo_coordinates/01_dwd_krige.py +++ b/examples/08_geo_coordinates/01_dwd_krige.py @@ -44,14 +44,14 @@ def get_dwd_temperature(date="2020-06-09 12:00:00"): sites = obs.DWDObservationStations( parameter_set=obs.DWDObservationParameterSet.TEMPERATURE_AIR, period=obs.DWDObservationPeriod.RECENT, - **settings + **settings, ) ids, lat, lon = sites.all().loc[:, ["STATION_ID", "LAT", "LON"]].values.T observations = obs.DWDObservationData( station_ids=ids, parameters=obs.DWDObservationParameter.HOURLY.TEMPERATURE_AIR_200, periods=obs.DWDObservationPeriod.RECENT, - **settings + **settings, ) temp = observations.all().VALUE.values sel = np.isfinite(temp) diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 000000000..b510e86ea --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,40 @@ +[build-system] +requires = [ + "setuptools>=42", + "wheel", + "setuptools_scm[toml]>=3.5", + "numpy>=1.14.5,<2.0", + "Cython>=0.28.3,<3.0", +] +build-backend = "setuptools.build_meta" + +[tool.setuptools_scm] +write_to = "gstools/_version.py" +write_to_template = "__version__ = '{version}'" +local_scheme = "no-local-version" +fallback_version = "0.0.0.dev0" + +[tool.coverage.run] +source = ["gstools"] +omit = [ + "*docs*", + "*examples*", + "*tests*", + "*/gstools/covmodel/plot.py", + "*/gstools/field/plot.py", +] + +[tool.coverage.report] +exclude_lines = [ + "pragma: no cover", + "def __repr__", + "def __str__", +] + +[tool.black] +line-length = 79 +target-version = [ + "py36", + "py37", + "py38", +] diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 0f47ca293..000000000 --- a/requirements.txt +++ /dev/null @@ -1,6 +0,0 @@ -numpy>=1.14.5 -scipy>=1.1.0 -hankel>=1.0.2 -emcee>=3.0.0 -pyevtk>=1.1.1 -meshio>=4.0.3, <5.0 diff --git a/requirements_setup.txt b/requirements_setup.txt deleted file mode 100755 index 7f373eac5..000000000 --- a/requirements_setup.txt +++ /dev/null @@ -1,4 +0,0 @@ -setuptools>=41.0.1 -setuptools_scm>=3.5.0 -cython>=0.28.3 -numpy>=1.14.5 diff --git a/requirements_test.txt b/requirements_test.txt deleted file mode 100755 index be10813ec..000000000 --- a/requirements_test.txt +++ /dev/null @@ -1,2 +0,0 @@ -pytest-cov>=2.8.0 -pytest>=5.3.0 diff --git a/setup.cfg b/setup.cfg index f48fdadb8..53e4bbf0b 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,3 +1,72 @@ [metadata] -description-file = README.md +name = gstools +description = GSTools: A geostatistical toolbox. +long_description = file: README.md +long_description_content_type = text/markdown +url = https://github.com/GeoStat-Framework/GSTools +author = Sebastian Müller, Lennart Schüler +author_email = info@geostat-framework.org +maintainer = Sebastian Müller, Lennart Schüler +maintainer_email = info@geostat-framework.org +license = LGPL-3.0 license_file = LICENSE +platforms = any +classifiers = + Development Status :: 5 - Production/Stable + Intended Audience :: Developers + Intended Audience :: End Users/Desktop + Intended Audience :: Science/Research + License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3) + Natural Language :: English + Operating System :: Unix + Programming Language :: Python + Programming Language :: Python :: 3 + Programming Language :: Python :: 3 :: Only + Programming Language :: Python :: 3.6 + Programming Language :: Python :: 3.7 + Programming Language :: Python :: 3.8 + Programming Language :: Python :: 3.9 + Topic :: Scientific/Engineering + Topic :: Utilities +project_urls = + Documentation = https://gstools.readthedocs.io + Source = https://github.com/GeoStat-Framework/GSTools + Tracker = https://github.com/GeoStat-Framework/GSTools/issues + Changelog = https://github.com/GeoStat-Framework/GSTools/blob/develop/CHANGELOG.md + Conda-Forge = https://anaconda.org/conda-forge/gstools + +[options] +packages = find: +install_requires = + emcee>=3.0.0,<4 + hankel>=1.0.2,<2 + meshio>=4.0.3,<5.0 + numpy>=1.14.5,<2 + pyevtk>=1.1.1,<2 + scipy>=1.1.0,<2 +python_requires = >=3.6 +zip_safe = False + +[options.packages.find] +exclude = + tests* + docs* + +[options.extras_require] +doc = + m2r2 + matplotlib>=3 + meshzoo + numpydoc>=1.1 + pykrige>=1.5 + pyvista + sphinx>=3 + sphinx-gallery>=0.8 + sphinx-rtd-theme>=0.5 +plotting = + matplotlib + pyvista +test = + coverage[toml]>=5.2.1 + pytest>=6.0 + pytest-cov>=2.11.0 diff --git a/setup.py b/setup.py index 9c0d6a769..06149506a 100644 --- a/setup.py +++ b/setup.py @@ -10,7 +10,7 @@ from distutils.ccompiler import new_compiler from distutils.sysconfig import customize_compiler -from setuptools import setup, find_packages, Distribution, Extension +from setuptools import setup, Extension from Cython.Build import cythonize import numpy as np @@ -19,9 +19,9 @@ # openmp finder ############################################################### -# This code is adapted for a large part from the scikit-learn openmp helpers, +# This code is adapted for a large part from the scikit-learn openmp_helpers.py # which can be found at: -# https://github.com/scikit-learn/scikit-learn/blob/master/sklearn/_build_utils/openmp_helpers.py +# https://github.com/scikit-learn/scikit-learn/blob/0.24.0/sklearn/_build_utils CCODE = """ @@ -49,17 +49,6 @@ def get_openmp_flag(compiler): if sys.platform == "darwin" and ("icc" in compiler or "icl" in compiler): return ["-openmp"] if sys.platform == "darwin" and "openmp" in os.getenv("CPPFLAGS", ""): - # -fopenmp can't be passed as compile flag when using Apple-clang. - # OpenMP support has to be enabled during preprocessing. - # - # For example, our macOS wheel build jobs use the following environment - # variables to build with Apple-clang and the brew installed "libomp": - # - # export CPPFLAGS="$CPPFLAGS -Xpreprocessor -fopenmp" - # export CFLAGS="$CFLAGS -I/usr/local/opt/libomp/include" - # export CXXFLAGS="$CXXFLAGS -I/usr/local/opt/libomp/include" - # export LDFLAGS="$LDFLAGS -L/usr/local/opt/libomp/lib -lomp" - # export DYLD_LIBRARY_PATH=/usr/local/opt/libomp/lib return [] # Default flag for GCC and clang: return ["-fopenmp"] @@ -120,7 +109,9 @@ def check_openmp_support(): # openmp ###################################################################### -USE_OPENMP = bool("--openmp" in sys.argv) +# you can set GSTOOLS_BUILD_PARALLEL=0 or GSTOOLS_BUILD_PARALLEL=1 +GS_PARALLEL = os.getenv("GSTOOLS_BUILD_PARALLEL") +USE_OPENMP = bool(int(GS_PARALLEL)) if GS_PARALLEL else False if USE_OPENMP: # just check if wanted @@ -135,18 +126,6 @@ def check_openmp_support(): FLAGS = [] -# add the "--openmp" to the global options -# enables calles like: -# python3 setup.py --openmp build_ext --inplace -# pip install --global-option="--openmp" gstools -class MPDistribution(Distribution): - """Distribution with --openmp as global option.""" - - global_options = Distribution.global_options + [ - ("openmp", None, "Flag to use openmp in the build") - ] - - # cython extensions ########################################################### @@ -181,82 +160,12 @@ class MPDistribution(Distribution): ) EXT_MODULES = cythonize(CY_MODULES) # annotate=True -# This is an important part. By setting this compiler directive, cython will -# embed signature information in docstrings. Sphinx then knows how to extract -# and use those signatures. -# python setup.py build_ext --inplace --> then sphinx build +# embed signatures for sphinx for ext_m in EXT_MODULES: ext_m.cython_directives = {"embedsignature": True} -# setup ####################################################################### -with open(os.path.join(HERE, "README.md"), encoding="utf-8") as f: - README = f.read() -with open(os.path.join(HERE, "requirements.txt"), encoding="utf-8") as f: - REQ = f.read().splitlines() -with open(os.path.join(HERE, "requirements_setup.txt"), encoding="utf-8") as f: - REQ_SETUP = f.read().splitlines() -with open(os.path.join(HERE, "requirements_test.txt"), encoding="utf-8") as f: - REQ_TEST = f.read().splitlines() -with open( - os.path.join(HERE, "docs", "requirements_doc.txt"), encoding="utf-8" -) as f: - REQ_DOC = f.read().splitlines() - -REQ_DEV = REQ_SETUP + REQ_TEST + REQ_DOC +# setup ####################################################################### -DOCLINE = __doc__.split("\n")[0] -CLASSIFIERS = [ - "Development Status :: 5 - Production/Stable", - "Intended Audience :: Developers", - "Intended Audience :: End Users/Desktop", - "Intended Audience :: Science/Research", - "License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)", - "Natural Language :: English", - "Operating System :: Unix", - "Programming Language :: Python", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3 :: Only", - "Topic :: Scientific/Engineering", - "Topic :: Utilities", -] -setup( - name="gstools", - description=DOCLINE, - long_description=README, - long_description_content_type="text/markdown", - maintainer="Sebastian Müller, Lennart Schüler", - maintainer_email="info@geostat-framework.org", - author="Sebastian Müller, Lennart Schüler", - author_email="info@geostat-framework.org", - url="https://github.com/GeoStat-Framework/GSTools", - license="LGPLv3", - classifiers=CLASSIFIERS, - platforms=["Windows", "Linux", "Solaris", "Mac OS-X", "Unix"], - include_package_data=True, - python_requires=">=3.6", - use_scm_version={ - "relative_to": __file__, - "write_to": "gstools/_version.py", - "write_to_template": "__version__ = '{version}'", - "local_scheme": "no-local-version", - "fallback_version": "0.0.0.dev0", - }, - setup_requires=REQ_SETUP, - install_requires=REQ, - extras_require={ - "plotting": ["pyvista", "matplotlib"], - "doc": REQ_DOC, - "test": REQ_TEST, - "dev": REQ_DEV, - }, - packages=find_packages(exclude=["tests*", "docs*"]), - ext_modules=EXT_MODULES, - include_dirs=[np.get_include()], - distclass=MPDistribution, -) +setup(ext_modules=EXT_MODULES, include_dirs=[np.get_include()])