From 44750524e0dfa61d5bdb08fbafb0121582f4e62d Mon Sep 17 00:00:00 2001 From: Greg Lucas Date: Sat, 24 Jun 2023 22:03:25 -0600 Subject: [PATCH] BLD: cleanup setup.py and pyproject.toml Simplify some of the setup.py build work now that we have removed more extension libraries. Move the static content over to pyproject.toml and migrate more content to the modern build utilities. --- .appveyor.yml | 46 ------- .circleci/config.yml | 50 +------ .github/workflows/ci-testing.yml | 62 ++++----- .github/workflows/release.yml | 115 ++++++++++++---- INSTALL | 75 ++--------- MANIFEST.in | 6 +- docs/source/reference/matplotlib.rst | 3 +- lib/cartopy/trace.pyx | 6 +- pyproject.toml | 72 ++++++++++ requirements/default.txt | 5 - requirements/ows.txt | 2 - requirements/plotting.txt | 2 - requirements/tests.txt | 3 - setup.cfg | 5 - setup.py | 194 +++------------------------ 15 files changed, 227 insertions(+), 419 deletions(-) delete mode 100644 .appveyor.yml delete mode 100644 requirements/default.txt delete mode 100644 requirements/ows.txt delete mode 100644 requirements/plotting.txt delete mode 100644 requirements/tests.txt diff --git a/.appveyor.yml b/.appveyor.yml deleted file mode 100644 index 6778b52ea..000000000 --- a/.appveyor.yml +++ /dev/null @@ -1,46 +0,0 @@ -environment: - matrix: - - PYTHON_VERSION: "3.9" - CONDA_INSTALL_LOCN: "C:\\Miniconda3-x64" - PACKAGES: "cython numpy matplotlib-base pyproj pykdtree scipy" - -install: - # Install miniconda - # ----------------- - - set PATH=%CONDA_INSTALL_LOCN%;%CONDA_INSTALL_LOCN%\scripts;%PATH%; - - # Create the testing environment - # ------------------------------ - - conda config --set always_yes yes --set changeps1 no --set show_channel_urls yes - - conda config --add channels conda-forge - - conda config --add channels conda-forge/label/testing - - set ENV_NAME=test-environment - - set PACKAGES=%PACKAGES% owslib pep8 pillow pyshp pytest pytest-mpl!=0.16.0 - - set PACKAGES=%PACKAGES% setuptools_scm shapely - - conda create -n %ENV_NAME% python=%PYTHON_VERSION% %PACKAGES% - - activate %ENV_NAME% - - set INCLUDE=%CONDA_PREFIX%\Library\include;%INCLUDE% - - set LIB=%CONDA_PREFIX%\Library\lib;%LIB% - - # Conda debug - # ----------- - - conda list -n %ENV_NAME% - - conda list -n %ENV_NAME% --explicit - - conda info -a - -build_script: - # Install cartopy - # --------------- - - pip install --no-deps . - - python -c "import cartopy; print('Version ', cartopy.__version__)" - -test_script: - - set MPLBACKEND=Agg - - set PYPROJ_GLOBAL_CONTEXT=ON - - pytest -ra --pyargs cartopy - --mpl --mpl-generate-summary=html --mpl-results-path=cartopy_test_output - -artifacts: - - path: cartopy_test_output - name: cartopy_test_output - type: zip diff --git a/.circleci/config.yml b/.circleci/config.yml index 389e640c8..e5dfbd71a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -12,56 +12,21 @@ version: 2.1 apt-run: &apt-install name: Install apt packages command: | - apt-get -qq update - apt-get install -y \ + sudo apt -qq update + sudo apt install -y \ gcc \ g++ \ make -env-run: &env-setup - # Create the basic testing environment - # Mixing conda-forge and defaults in root is a recipe for trouble, so create - # a separate environment. - name: Setup conda environment - command: | - conda config \ - --set always_yes yes \ - --set changeps1 no \ - --set show_channel_urls yes \ - --set auto_activate_base false - conda config --add channels conda-forge - conda create -n test-environment python=$PYTHON_VERSION - -deps-run: &deps-install - name: Install Python dependencies - command: | - conda install -n test-environment --quiet \ - cython \ - 'matplotlib>3.3' \ - numpy \ - owslib \ - pillow \ - pyproj \ - pykdtree \ - pyshp \ - scipy \ - setuptools_scm \ - shapely \ - $EXTRA_PACKAGES \ - --file docs/doc-requirements.txt - conda list -n test-environment - cp-run: &cp-install name: Install Cartopy command: | - source activate test-environment - pip install -ve . + python -m pip install --upgrade --user pip + python -m pip install --user -ve .[doc,extras,ows,plotting] doc-run: &doc-build name: Build documentation command: | - source activate test-environment - PYPROJ_GLOBAL_CONTEXT=ON make -C docs html @@ -72,16 +37,11 @@ doc-run: &doc-build jobs: docs-python3: docker: - - image: continuumio/miniconda3:latest + - image: cimg/python:3.11 steps: - checkout - run: *apt-install - - run: - <<: *env-setup - environment: - PYTHON_VERSION: 3.11 - - run: *deps-install - run: *cp-install - run: *doc-build diff --git a/.github/workflows/ci-testing.yml b/.github/workflows/ci-testing.yml index 815f83d3e..fd9877272 100644 --- a/.github/workflows/ci-testing.yml +++ b/.github/workflows/ci-testing.yml @@ -10,81 +10,71 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-latest] + os: [ubuntu-latest, macos-latest, windows-latest] python-version: [3.9, '3.10', '3.11'] shapely-dev: [false] include: - os: ubuntu-latest python-version: '3.11' shapely-dev: true - defaults: - run: - shell: bash -l {0} steps: - uses: actions/checkout@v3 - - uses: conda-incubator/setup-miniconda@v2 with: - activate-environment: test-environment + fetch-depth: 0 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: python-version: ${{ matrix.python-version }} - channels: conda-forge/label/testing,conda-forge + cache: 'pip' - name: Minimum packages - # Only run on Linux for now - # Conda's linux packages don't grab the testing label of matplotlib causing failures due to freetype differences if: matrix.python-version == '3.9' && matrix.os == 'ubuntu-latest' id: minimum-packages run: | - echo "PACKAGES=cython=0.29.24 matplotlib-base=3.4 numpy=1.21 owslib=0.24.1 pyproj=3.1 proj=8.0 scipy=1.6.3 shapely=1.7.1" >> $GITHUB_ENV - - - name: Latest packages - if: steps.minimum-packages.conclusion == 'skipped' && !matrix.shapely-dev - run: | - echo "PACKAGES=cython fiona matplotlib-base numpy pyproj pykdtree scipy shapely" >> $GITHUB_ENV - - - name: Latest packages with Shapely dev - if: steps.minimum-packages.conclusion == 'skipped' && matrix.shapely-dev - run: | - echo "PACKAGES=cython fiona matplotlib-base numpy pyproj pykdtree scipy geos" >> $GITHUB_ENV + pip install cython==0.29.24 matplotlib==3.4.3 numpy==1.21 owslib==0.24.1 pyproj==3.1 scipy==1.6.3 shapely==1.7.1 - name: Coverage packages id: coverage # only want the coverage to be run on the latest ubuntu if: matrix.python-version == '3.11' && matrix.os == 'ubuntu-latest' run: | - echo "PACKAGES=$PACKAGES pytest-cov coveralls" >> $GITHUB_ENV echo "CYTHON_COVERAGE=1" >> $GITHUB_ENV - echo "EXTRA_TEST_ARGS=--cov=cartopy -ra" >> $GITHUB_ENV - - - name: Install dependencies - run: | - PACKAGES="$PACKAGES owslib pep8 pillow pyshp pytest pytest-mpl!=0.16.0" - PACKAGES="$PACKAGES pytest-xdist setuptools_scm" - conda install $PACKAGES - conda info -a - conda list + # Also add doctest here to avoid windows runners which expect a different path separator + echo "EXTRA_TEST_ARGS=--cov=cartopy -ra --doctest-modules" >> $GITHUB_ENV + pip install cython - name: Install Shapely dev if: matrix.shapely-dev run: | - python -m pip install git+https://github.com/shapely/shapely.git@main + # Install Shapely from source on ubuntu + sudo apt-get update + sudo apt-get install -yy libgeos-dev + pip install git+https://github.com/shapely/shapely.git@main - name: Install Cartopy id: install run: | - MPL_CONFIG_DIR=~/.config/matplotlib - mkdir -p $MPL_CONFIG_DIR - echo "backend : agg" > $MPL_CONFIG_DIR/matplotlibrc - pip install --no-deps -e . + pip install -e .[test] python -c "import cartopy; print('Version ', cartopy.__version__)" + - name: Install extras + # Default is to install just the minimum testing requirements, + # but we want to get as much coverage as possible. + if: steps.minimum-packages.conclusion == 'skipped' + run: | + pip install .[extras,ows,plotting] + - name: Testing id: test + # we need to force bash to use line continuations + shell: bash run: | # Check that the downloader tool at least knows where to get the data from (but don't actually download it) python tools/cartopy_feature_download.py gshhs physical --dry-run CARTOPY_GIT_DIR=$PWD - PYPROJ_GLOBAL_CONTEXT=ON pytest -ra -n 4 --doctest-modules \ + pytest -ra -n 4 \ --color=yes \ --mpl --mpl-generate-summary=html \ --mpl-results-path="cartopy_test_output-${{ matrix.os }}-${{ matrix.python-version }}" \ diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5de9b2dd1..2966c1ea7 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,5 +1,9 @@ name: Build and upload to PyPI +concurrency: + group: ${{ github.workflow }}-${{ github.event.number }}-${{ github.event.ref }} + cancel-in-progress: true + # Only build on published releases on: release: @@ -7,57 +11,114 @@ on: - published jobs: - build: - name: Build sdist - runs-on: ubuntu-18.04 - defaults: - run: - shell: bash -l {0} + build_sdist: + name: Build source distribution + runs-on: ubuntu-latest + outputs: + SDIST_NAME: ${{ steps.sdist.outputs.SDIST_NAME }} steps: - uses: actions/checkout@v3 - - uses: conda-incubator/setup-miniconda@v2 with: - activate-environment: test-environment - python-version: ${{ matrix.python-version }} - channels: conda-forge/label/testing,conda-forge + # We need the full history to generate the proper version number + fetch-depth: 0 + + - uses: actions/setup-python@v4 + name: Install Python + with: + python-version: '3.11' - name: Install dependencies + run: python -m pip install build twine + + - name: Build sdist + id: sdist run: | - PACKAGES="cython fiona matplotlib-base numpy pyproj pykdtree scipy" - PACKAGES="$PACKAGES owslib pep8 pillow pyshp pytest" - PACKAGES="$PACKAGES pytest-xdist setuptools_scm shapely" - conda install $PACKAGES + python -m build --sdist + # Get the name of the build sdist file for later use + echo "SDIST_NAME=$(ls -1 dist)" >> $GITHUB_OUTPUT - - name: Create sdist - run: python setup.py build_ext sdist + - name: Check README rendering for PyPI + run: twine check dist/* - - name: Save built packages as artifact + - name: Upload sdist result uses: actions/upload-artifact@v3 with: - name: packages-${{ runner.os }}-${{ matrix.python-version }} - path: dist/ + name: sdist + path: dist/*.tar.gz if-no-files-found: error - retention-days: 5 + + generate-wheels-matrix: + name: Generate wheels matrix + needs: build_sdist + runs-on: ubuntu-latest + outputs: + include: ${{ steps.set-matrix.outputs.include }} + steps: + - uses: actions/checkout@v3 + - name: Install cibuildwheel + run: pipx install cibuildwheel==2.14.1 + - id: set-matrix + run: | + MATRIX=$( + { + cibuildwheel --print-build-identifiers --platform linux \ + | jq -nRc '{"only": inputs, "os": "ubuntu-latest"}' \ + && cibuildwheel --print-build-identifiers --platform macos \ + | jq -nRc '{"only": inputs, "os": "macos-latest"}' \ + && cibuildwheel --print-build-identifiers --platform windows \ + | jq -nRc '{"only": inputs, "os": "windows-2019"}' + } | jq -sc + ) + echo "include=$MATRIX" >> $GITHUB_OUTPUT + env: + CIBW_BUILD: "cp39-* cp310-* cp311-*" + # Skip 32 bit windows builds and musllinux due to lack of numpy wheels + CIBW_SKIP: "*-win32 *-musllinux*" + CIBW_ARCHS_MACOS: x86_64 arm64 + build_wheels: + name: Build ${{ matrix.os }} ${{ matrix.only }} + needs: [generate-wheels-matrix, build_sdist] + strategy: + matrix: + include: ${{ fromJson(needs.generate-wheels-matrix.outputs.include) }} + runs-on: ${{ matrix.os }} + defaults: + run: + shell: bash + steps: + + - name: Download sdist + uses: actions/download-artifact@v3 + with: + name: sdist + path: dist/ + + - uses: pypa/cibuildwheel@f21bb8376a051ffb6cb5604b28ccaef7b90e8ab7 # v2.14.1 + with: + only: ${{ matrix.only }} + package-dir: dist/${{ needs.build_sdist.outputs.SDIST_NAME }} + + - uses: actions/upload-artifact@v3 + with: + path: ./wheelhouse/*.whl publish: name: Publish to PyPI - needs: build + needs: [build_wheels, build_sdist] environment: name: PyPI url: https://pypi.org/project/cartopy permissions: id-token: write # IMPORTANT: this permission is mandatory for trusted publishing - runs-on: ubuntu-18.04 + runs-on: ubuntu-latest steps: - name: Download packages uses: actions/download-artifact@v3 - - - name: Consolidate packages for upload - run: | - mkdir dist - cp packages-*/* dist/ + with: + name: artifact + path: dist - name: Publish Package uses: pypa/gh-action-pypi-publish@v1.8.8 diff --git a/INSTALL b/INSTALL index 23351841f..0fed352a1 100644 --- a/INSTALL +++ b/INSTALL @@ -1,20 +1,17 @@ Installation ============ -Conda pre-built binaries ------------------------- +Cartopy (as of v0.22+) provides binary wheels for most major operating systems. +The easiest way to install Cartopy is:: -The easiest way to install Cartopy is by using -`Conda `_. If conda is already installed, -installation is as easy as:: - - conda install -c conda-forge cartopy + pip install cartopy -Other pre-built binaries ------------------------- +Other binaries +-------------- Additional pre-built binaries can be found at a variety of sources, including: +* `Conda `_ * Christoph Gohlke (https://www.lfd.uci.edu/~gohlke/pythonlibs/) maintains unofficial Windows binaries of cartopy. * `OSGeo Live `_. @@ -46,11 +43,8 @@ Required dependencies ~~~~~~~~~~~~~~~~~~~~~ In order to install Cartopy, or to access its basic functionality, it will be -necessary to first install **GEOS**, **Shapely**, and -**pyshp**. Many of these packages can be installed using pip or -other package managers such as apt-get (Linux) and brew (macOS). Many of these -dependencies are built as part of Cartopy's conda distribution, and the recipes -for these packages can be found at https://github.com/conda-forge/feedstocks. +necessary to first install the required dependencies listed below. +These packages can be installed using pip. We include a conda environment file that contains a list of all the dependencies required to build and install cartopy, which can be used to @@ -63,47 +57,6 @@ To use it:: conda activate cartopy-dev pip install -e . -You can also use your system's package manager to install the dependencies. - -Ubuntu / Debian -_______________ - -On Debian, you can install the required system libraries using the system package manager:: - - sudo apt -y install libgeos-dev - -Then you can proceed to install cartopy using a python package manager:: - - pip3 install cartopy - -MacOS -_____ - -For macOS, the required dependencies can be installed in the following way:: - - brew install geos - pip3 install --upgrade pyshp - # shapely needs to be built from source to link to geos. If it is already - # installed, uninstall it by: pip3 uninstall shapely - pip3 install shapely --no-binary shapely - -Still on macOS, make sure you have installed pkg-config and set the -`PKG_CONFIG_PATH` environment variable as follows:: - - brew install pkg-config - export PKG_CONFIG_PATH=/usr/local/bin/pkgconfig - -Then you can install cartopy using:: - - pip3 install cartopy - -Other -_____ - -If you are installing dependencies with a package manager on Linux, you may -need to install the development packages (look for a "-dev" or "-devel" suffix) in addition -to the core packages. - Further information about the required dependencies can be found here: **Python** 3.9 or later (https://www.python.org/) @@ -113,9 +66,8 @@ Further information about the required dependencies can be found here: Python package for 2D plotting. Python package required for any graphical capabilities. -**Shapely** 1.7.1 or later (https://github.com/Toblerity/Shapely) - Python package for the manipulation and analysis of planar geometric - objects. +**Shapely** 1.7.1 or later (https://github.com/shapely/shapely) + Python package for the manipulation and analysis of planar geometric objects. **pyshp** 2.1 or later (https://pypi.python.org/pypi/pyshp) Pure Python read/write support for ESRI Shapefile format. @@ -127,7 +79,9 @@ Optional Dependencies ~~~~~~~~~~~~~~~~~~~~~ To make the most of Cartopy by enabling additional functionality, you may want -to install these optional dependencies. +to install these optional dependencies. They are also included in some of the +optional groups when installing. For example, use `pip install .[ows]` to install +the optional OWS libraries. **Pillow** 6.1.0 or later (https://python-pillow.org) A popular fork of PythonImagingLibrary. @@ -157,6 +111,3 @@ These packages are required for the full Cartopy test suite to run. **pytest-mpl** 0.11 or later (https://github.com/matplotlib/pytest-mpl) Pytest plugin to facilitate image comparison for Matplotlib figures - -**pep8** 1.3.3 or later (https://pypi.python.org/pypi/pep8) - Python package for software testing. diff --git a/MANIFEST.in b/MANIFEST.in index 15f79d452..7480cb6fb 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -3,9 +3,7 @@ prune .circleci prune benchmarks prune docs prune examples -include requirements/*.txt graft tools -exclude .appveyor.yml exclude .coveragerc exclude .git-blame-ignore-revs include .gitattributes @@ -15,4 +13,6 @@ include CHANGES include COPYING* include environment.yml include INSTALL -recursive-include lib/cartopy *.cpp *.h *.py *.pyx +recursive-include lib/cartopy *.cpp *.py *.pyx +recursive-include lib/cartopy *.TXT *.dbf *.jpg *.json *.nc *.png *.shp *.shx *.txt +include lib/cartopy/data/LICENSE diff --git a/docs/source/reference/matplotlib.rst b/docs/source/reference/matplotlib.rst index b113914ab..19cb8fa93 100644 --- a/docs/source/reference/matplotlib.rst +++ b/docs/source/reference/matplotlib.rst @@ -64,8 +64,7 @@ Additional extensions ~~~~~~~~~~~~~~~~~~~~~ Extra functionality that is primarily intended for developers. They describe -some of the capabilities for transforming -between GEOS, Shapely, and Matplotlib paths. +some of the capabilities for transforming between Shapely, and Matplotlib paths. .. autosummary:: :toctree: generated/ diff --git a/lib/cartopy/trace.pyx b/lib/cartopy/trace.pyx index 3cac0cad3..d4550b47d 100644 --- a/lib/cartopy/trace.pyx +++ b/lib/cartopy/trace.pyx @@ -305,9 +305,7 @@ cdef bool straightAndDomain(double t_start, const Point &p_start, p_mid = interpolator.interpolate(t_mid) # Determine the closest point on the segment to the midpoint, in - # normalized coordinates. We could use GEOSProjectNormalized_r - # here, but since it's a single line segment, it's much easier to - # just do the math ourselves: + # normalized coordinates. # ○̩ (x1, y1) (assume that this is not necessarily vertical) # │ # │ D @@ -446,7 +444,7 @@ cdef void _project_segment(double[:] src_from, double[:] src_to, double threshold, LineAccumulator lines, bool geom_fully_inside=False) except *: cdef Point p_current, p_min, p_max, p_end - cdef double t_current, t_min, t_max + cdef double t_current, t_min=0, t_max=1 cdef State state p_current.x, p_current.y = src_from diff --git a/pyproject.toml b/pyproject.toml index 3784b8aa5..b4cfc58fa 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,6 +8,73 @@ requires = [ ] build-backend = "setuptools.build_meta" +[project] +name = "Cartopy" +authors = [ + {name = "UK Met Office"}, +] +description = "A Python library for cartographic visualizations with Matplotlib" +readme = "README.md" +requires-python = ">=3.9" +keywords = ["cartography", "map", "transform", "projection", "pyproj", "shapely", "shapefile"] +license = {file = "COPYING.LESSER"} +classifiers = [ + 'Development Status :: 4 - Beta', + 'Framework :: Matplotlib', + 'License :: OSI Approved :: GNU Lesser General Public License v3 or later (LGPLv3+)', + 'Operating System :: MacOS :: MacOS X', + 'Operating System :: Microsoft :: Windows', + 'Operating System :: POSIX', + 'Operating System :: POSIX :: AIX', + 'Operating System :: POSIX :: Linux', + 'Programming Language :: C++', + 'Programming Language :: Python', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.9', + 'Programming Language :: Python :: 3.10', + 'Programming Language :: Python :: 3.11', + 'Programming Language :: Python :: 3 :: Only', + 'Topic :: Scientific/Engineering', + 'Topic :: Scientific/Engineering :: GIS', + 'Topic :: Scientific/Engineering :: Visualization', +] +dependencies = [ + "numpy>=1.21", + "matplotlib>=3.4", + "shapely>=1.7", + "packaging>=20", + "pyshp>=2.1", + "pyproj>=3.1.0", +] +dynamic = ["version"] + +[project.optional-dependencies] +doc = ["beautifulsoup4", "pydata-sphinx-theme", "sphinx", "sphinx-gallery"] +speedups = ["pykdtree", "fiona"] +ows = ["OWSLib>=0.20.0", "pillow>=6.1.0"] +plotting = ["pillow>=6.1.0", "scipy>=1.3.1"] +test = ["pytest>=5.1.2", "pytest-mpl>=0.11", "pytest-xdist", "pytest-cov", "coveralls"] + +[project.scripts] +feature_download = "tools.cartopy_feature_download.py:__main__" + +[project.urls] +documentation='https://scitools.org.uk/cartopy/docs/latest/' +homepage='https://github.com/SciTools/cartopy' + +[tool.setuptools.packages.find] +where = ["lib"] +exclude = ["cartopy.tests*"] + +[tool.setuptools.package-data] +cartopy = ["lib/cartopy/tests/mpl/baseline_images/**", + "lib/cartopy/data/**", + "lib/cartopy/tests/lakes_shapefile/**", + "io/srtm.npz"] + +[tool.setuptools_scm] +write_to = "lib/cartopy/_version.py" + [tool.codespell] ignore-words-list = "damon,koordinates,linz,slippy,subtiles,tring" skip = "./.git,./docs/build,./docs/source/gallery,./docs/source/reference,*.cpp,*.css,*.examples,*.js,*.html,*.ipynb,*.pdf,*.rst.txt" @@ -25,3 +92,8 @@ lines_after_imports = 2 no_lines_before = "LOCALFOLDER" skip_gitignore = true verbose = false + +[tool.pytest.ini_options] +addopts = "--mpl" +testpaths = ["lib"] +python_files = ["test_*.py"] diff --git a/requirements/default.txt b/requirements/default.txt deleted file mode 100644 index 861450c3c..000000000 --- a/requirements/default.txt +++ /dev/null @@ -1,5 +0,0 @@ -numpy>=1.18 -matplotlib>=3.1 -shapely>=1.6.4 -pyshp>=2.1 -pyproj>=3.0.0 diff --git a/requirements/ows.txt b/requirements/ows.txt deleted file mode 100644 index 05caa5d0b..000000000 --- a/requirements/ows.txt +++ /dev/null @@ -1,2 +0,0 @@ -OWSLib>=0.20.0 -pillow>=6.1.0 diff --git a/requirements/plotting.txt b/requirements/plotting.txt deleted file mode 100644 index 89bfb59b9..000000000 --- a/requirements/plotting.txt +++ /dev/null @@ -1,2 +0,0 @@ -pillow>=6.1.0 -scipy>=1.3.1 diff --git a/requirements/tests.txt b/requirements/tests.txt deleted file mode 100644 index 02688a323..000000000 --- a/requirements/tests.txt +++ /dev/null @@ -1,3 +0,0 @@ -packaging>=20 -pytest>=5.1.2 -pytest-mpl>=0.11 diff --git a/setup.cfg b/setup.cfg index 2fda28171..ce9c43405 100644 --- a/setup.cfg +++ b/setup.cfg @@ -3,8 +3,3 @@ exclude = \ build, \ setup.py, \ docs/source/conf.py - -[tool:pytest] -addopts = --mpl -testpaths = lib -python_files = test_*.py diff --git a/setup.py b/setup.py index 4ddda131c..d2a9676c7 100644 --- a/setup.py +++ b/setup.py @@ -4,35 +4,11 @@ # See COPYING and COPYING.LESSER in the root of the repository for full # licensing details. -# NOTE: This file must remain Python 2 compatible for the foreseeable future, -# to ensure that we error out properly for people with outdated setuptools -# and/or pip. -import sys - - -PYTHON_MIN_VERSION = (3, 9) - -if sys.version_info < PYTHON_MIN_VERSION: - error = """ -Beginning with Cartopy 0.22, Python {} or above is required. -You are using Python {}. - -This may be due to an out of date pip. - -Make sure you have pip >= 9.0.1. -""".format('.'.join(str(n) for n in PYTHON_MIN_VERSION), - '.'.join(str(n) for n in sys.version_info[:3])) - sys.exit(error) - - -from collections import defaultdict import os from pathlib import Path -import subprocess -from sysconfig import get_config_var -import warnings -from setuptools import Extension, find_packages, setup +import numpy as np +from setuptools import Extension, setup # The existence of a PKG-INFO directory is enough to tell us whether this is a @@ -41,176 +17,40 @@ IS_SDIST = (HERE / 'PKG-INFO').exists() FORCE_CYTHON = os.environ.get('FORCE_CYTHON', False) -if not IS_SDIST or FORCE_CYTHON: +USE_CYTHON = not IS_SDIST or FORCE_CYTHON +if USE_CYTHON: import Cython if Cython.__version__ < '0.29': raise ImportError( "Cython 0.29+ is required to install cartopy from source.") + ext = '.pyx' +else: + ext = '.cpp' - from Cython.Distutils import build_ext as cy_build_ext - - -try: - import numpy as np -except ImportError: - raise ImportError('NumPy 1.21+ is required to install cartopy.') - - -def file_walk_relative(root): - """ - Return a list of files from the top of the tree, removing - the lib/cartopy prefix from the resulting paths. - - """ - return [str(p.relative_to(Path('lib') / 'cartopy')) - for p in root.glob("**/*")] - - -# Dependency checks -# ================= - -# Python dependencies -extras_require = {} -for name in (HERE / 'requirements').iterdir(): - with open(name) as fh: - section, ext = name.stem, name.suffix - extras_require[section] = [] - for line in fh: - if line.startswith('#'): - pass - elif line.startswith('-'): - pass - else: - extras_require[section].append(line.strip()) -install_requires = extras_require.pop('default') -tests_require = extras_require.get('tests', []) - -# General extension paths -if sys.platform.startswith('win'): - def get_config_var(name): - return '.' -include_dir = get_config_var('INCLUDEDIR') -library_dir = get_config_var('LIBDIR') -extra_extension_args = defaultdict(list) -if not sys.platform.startswith('win'): - extra_extension_args["runtime_library_dirs"].append( - get_config_var('LIBDIR') - ) - -# Description -# =========== -with open(HERE / 'README.md') as fh: - description = ''.join(fh.readlines()) - - -cython_coverage_enabled = os.environ.get('CYTHON_COVERAGE', None) -if cython_coverage_enabled: - extra_extension_args["define_macros"].append( - ('CYTHON_TRACE_NOGIL', '1') - ) +# Macros to enable Cython coverage +define_macros = [] +if os.environ.get('CYTHON_COVERAGE'): + define_macros.append(('CYTHON_TRACE_NOGIL', '1')) extensions = [ Extension( 'cartopy.trace', - ['lib/cartopy/trace.pyx'], - include_dirs=[include_dir, './lib/cartopy', np.get_include()], + [f'lib/cartopy/trace{ext}'], + include_dirs=[np.get_include()], language='c++', - **extra_extension_args), + define_macros=define_macros), ] - -if cython_coverage_enabled: +if USE_CYTHON: # We need to explicitly cythonize the extension in order # to control the Cython compiler_directives. from Cython.Build import cythonize - - directives = {'linetrace': True, - 'binding': True} - extensions = cythonize(extensions, compiler_directives=directives) - - -def decythonize(extensions, **_ignore): - # Remove pyx sources from extensions. - # Note: even if there are changes to the pyx files, they will be ignored. - for extension in extensions: - sources = [] - for sfile in extension.sources: - spath = Path(sfile) - ext = spath.suffix - if ext in ('.pyx',): - if extension.language == 'c++': - ext = '.cpp' - else: - ext = '.c' - sfile = str(spath.with_suffix(ext)) - sources.append(sfile) - extension.sources[:] = sources - return extensions + compiler_directives = {"profile": True, "linetrace": True} + extensions = cythonize(extensions, compiler_directives=compiler_directives) -if IS_SDIST and not FORCE_CYTHON: - extensions = decythonize(extensions) - cmdclass = {} -else: - cmdclass = {'build_ext': cy_build_ext} - -base_path = Path('lib') / 'cartopy' -package_data = ( - file_walk_relative(base_path / 'tests' / 'mpl' / 'baseline_images') - + file_walk_relative(base_path / 'data') - + file_walk_relative(base_path / 'tests' / 'lakes_shapefile') - + ['io/srtm.npz']) - # Main setup # ========== setup( - name='Cartopy', - url='https://scitools.org.uk/cartopy/docs/latest/', - download_url='https://github.com/SciTools/cartopy', - author='UK Met Office', - description='A cartographic python library with Matplotlib support for ' - 'visualisation', - long_description=description, - long_description_content_type='text/markdown', - license="LGPLv3", - keywords="cartography map transform projection proj proj.4 geos shapely " - "shapefile", - - install_requires=install_requires, - extras_require=extras_require, - tests_require=tests_require, - - use_scm_version={ - 'write_to': 'lib/cartopy/_version.py', - }, - - packages=find_packages("lib"), - package_dir={'': 'lib'}, - package_data={'cartopy': package_data}, - - scripts=['tools/cartopy_feature_download.py'], ext_modules=extensions, - cmdclass=cmdclass, - python_requires='>=' + '.'.join(str(n) for n in PYTHON_MIN_VERSION), - classifiers=[ - 'Development Status :: 4 - Beta', - 'Framework :: Matplotlib', - 'License :: OSI Approved :: GNU Lesser General Public License v3 ' - 'or later (LGPLv3+)', - 'Operating System :: MacOS :: MacOS X', - 'Operating System :: Microsoft :: Windows', - 'Operating System :: POSIX', - 'Operating System :: POSIX :: AIX', - 'Operating System :: POSIX :: Linux', - 'Programming Language :: C++', - 'Programming Language :: Python', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.9', - 'Programming Language :: Python :: 3.10', - 'Programming Language :: Python :: 3.11', - 'Programming Language :: Python :: 3 :: Only', - 'Topic :: Scientific/Engineering', - 'Topic :: Scientific/Engineering :: GIS', - 'Topic :: Scientific/Engineering :: Visualization', - ], )