Skip to content

Commit a282d48

Browse files
committed
prepping basemap for pyproject.toml
1 parent 7d8c6b3 commit a282d48

File tree

2 files changed

+65
-253
lines changed

2 files changed

+65
-253
lines changed

packages/basemap/build.py

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
def get_requirements(filename):
2+
"""Read requirements from file."""
3+
with open(filename) as f:
4+
return [line.strip() for line in f if line.strip() and not line.startswith('#')]
5+
6+
def get_package_data():
7+
return {
8+
"mpl_toolkits.basemap": ["data/*"]
9+
}

packages/basemap/setup.py

+56-253
Original file line numberDiff line numberDiff line change
@@ -1,272 +1,75 @@
11
#! /usr/bin/env python
22
# -*- coding: utf-8 -*-
33
# flake8: noqa: E122
4-
"""basemap -- Plot data on map projections with matplotlib."""
5-
6-
import io
7-
import os
8-
import re
9-
import sys
10-
import glob
11-
import warnings
12-
from setuptools import setup
13-
from setuptools import find_packages
14-
from setuptools.command.sdist import sdist
15-
from setuptools.extension import Extension
16-
17-
try:
18-
import Cython
19-
cython_major_version = int(Cython.__version__.split(".", 1)[0])
20-
except ImportError:
21-
cython_major_version = 0
22-
23-
24-
def get_content(name, splitlines=False):
25-
"""Return the file contents with project root as root folder."""
26-
27-
here = os.path.abspath(os.path.dirname(__file__))
28-
path = os.path.join(here, name)
29-
with io.open(path, "r", encoding="utf-8") as fd:
30-
content = fd.read()
31-
if splitlines:
32-
content = [row for row in content.splitlines() if row]
33-
return content
34-
35-
36-
def get_version(pkgname):
37-
"""Return package version without importing the file."""
38-
39-
here = os.path.abspath(os.path.dirname(__file__))
40-
path = os.path.join(*[here, "src"] + pkgname.split(".") + ["__init__.py"])
41-
with io.open(path, "r", encoding="utf-8") as fd:
42-
pattern = r"""\n__version__[ ]*=[ ]*["']([^"]+)["']"""
43-
return re.search(pattern, fd.read()).group(1)
4+
import os, sys, glob, warnings
5+
import numpy as np
6+
from setuptools import setup, Extension
447

458

469
def get_geos_install_prefix():
4710
"""Return GEOS installation prefix or None if not found."""
48-
4911
env_candidate = os.environ.get("GEOS_DIR", None)
5012
if env_candidate is not None:
51-
candidates = [env_candidate]
52-
else:
53-
candidates = [os.path.expanduser("~/local"), os.path.expanduser("~"),
54-
"/usr/local", "/usr", "/opt/local", "/opt", "/sw"]
13+
return env_candidate
14+
15+
candidates = [
16+
os.path.expanduser("~/local"),
17+
os.path.expanduser("~"),
18+
"/usr/local",
19+
"/usr",
20+
"/opt/local",
21+
"/opt",
22+
"/sw",
23+
]
5524

56-
# Prepare filename pattern to find the GEOS library.
5725
extensions = {"win32": "dll", "cygwin": "dll", "darwin": "dylib"}
5826
libext = extensions.get(sys.platform, "so*")
59-
libname = "*geos_c*.{0}".format(libext)
27+
libname = f"*geos_c*.{libext}"
6028
libdirs = ["bin", "lib", "lib/x86_64-linux-gnu", "lib64"]
6129

6230
for prefix in candidates:
63-
libfiles = []
6431
for libdir in libdirs:
65-
libfiles.extend(glob.glob(os.path.join(prefix, libdir, libname)))
66-
hfile = os.path.join(prefix, "include", "geos_c.h")
67-
if os.path.isfile(hfile) and libfiles:
68-
return prefix
69-
70-
# At this point, the GEOS library was not found, so we throw a warning if
71-
# the user is trying to build the library.
72-
build_cmds = ("bdist_wheel", "build", "install")
73-
if any(cmd in sys.argv[1:] for cmd in build_cmds):
74-
warnings.warn(" ".join([
75-
"Cannot find GEOS library and/or headers in standard locations",
76-
"('{0}'). Please install the corresponding packages using your",
77-
"software management system or set the environment variable",
78-
"GEOS_DIR to point to the location where GEOS is installed",
79-
"(for example, if 'geos_c.h' is in '/usr/local/include'",
80-
"and 'libgeos_c' is in '/usr/local/lib', then you need to",
81-
"set GEOS_DIR to '/usr/local'",
82-
]).format("', '".join(candidates)), RuntimeWarning)
32+
if glob.glob(os.path.join(prefix, libdir, libname)):
33+
hfile = os.path.join(prefix, "include", "geos_c.h")
34+
if os.path.isfile(hfile):
35+
return prefix
8336
return None
8437

8538

86-
class basemap_sdist(sdist): # pylint: disable=invalid-name
87-
"""Custom `sdist` so that it will not pack DLLs on Windows if present."""
88-
89-
def run(self):
90-
"""Custom `run` command."""
91-
92-
# Replace DLL data files and add GEOS build script.
93-
orig_data_files = self.distribution.data_files
94-
self.distribution.data_files = [
95-
(".", glob.glob(os.path.join("utils", "*.py")))]
96-
97-
# Run the original `run` method and leave `data_files` as it was found.
98-
try:
99-
sdist.run(self)
100-
finally:
101-
self.distribution.data_files = orig_data_files
102-
103-
104-
# Initialise include and library dirs.
105-
data_files = []
106-
include_dirs = []
107-
library_dirs = []
108-
runtime_library_dirs = []
109-
110-
# Define NumPy include dirs.
111-
numpy_include_path = os.environ.get("NUMPY_INCLUDE_PATH", None)
112-
if numpy_include_path is not None:
113-
include_dirs.append(numpy_include_path)
114-
else:
115-
try:
116-
import numpy
117-
include_dirs.append(numpy.get_include())
118-
except ImportError as err:
119-
cmds = ("bdist_wheel", "build", "install")
120-
if any(cmd in sys.argv[1:] for cmd in cmds):
121-
warnings.warn("unable to locate NumPy headers", RuntimeWarning)
122-
123-
# Define GEOS include, library and runtime dirs.
124-
geos_install_prefix = get_geos_install_prefix()
125-
if geos_install_prefix is not None:
126-
include_dirs.append(os.path.join(geos_install_prefix, "include"))
127-
library_dirs.append(os.path.join(geos_install_prefix, "lib"))
128-
library_dirs.append(os.path.join(geos_install_prefix, "lib64"))
129-
runtime_library_dirs = library_dirs
130-
if os.name == "nt" or sys.platform == "cygwin":
131-
# On Windows:
132-
# - DLLs get installed under `bin`.
133-
# - We need to inject later the DLL in the wheel using `data_files`.
134-
# - We do not use `runtime_library_dirs` as workaround for a
135-
# `distutils` bug (http://bugs.python.org/issue2437).
136-
library_dirs.append(os.path.join(geos_install_prefix, "bin"))
137-
runtime_library_dirs = []
138-
dlls = glob.glob(os.path.join(geos_install_prefix, "*", "*geos_c*.dll"))
139-
if dlls:
140-
data_files.append(("../..", sorted(dlls)))
141-
142-
# Define `_geoslib` extension module. It cannot be installed in the
143-
# `mpl_toolkits.basemap` namespace or `Basemap` objects will not be pickleable.
144-
ext_modules = [
145-
Extension(**{
146-
"name":
147-
"_geoslib",
148-
"sources": [
149-
"src/_geoslib.pyx",
150-
],
151-
"libraries": [
152-
"geos_c",
153-
],
154-
"include_dirs":
155-
include_dirs,
156-
"library_dirs":
157-
library_dirs,
158-
"runtime_library_dirs":
159-
runtime_library_dirs,
160-
}),
161-
]
162-
for ext in ext_modules:
163-
ext.cython_directives = [
164-
("language_level", str(sys.version_info[0])),
165-
("legacy_implicit_noexcept", True),
166-
][:1 + int(cython_major_version >= 3)]
167-
168-
# Define all the different requirements.
169-
setup_requires = get_content("requirements-setup.txt", splitlines=True)
170-
install_requires = get_content("requirements.txt", splitlines=True)
171-
if sys.version_info[:2] == (3, 2):
172-
# Hack for Python 3.2 because pip < 8 cannot handle version markers.
173-
marker1 = '; python_version == "3.2"'
174-
marker2 = '; python_version >= "2.7"'
175-
setup_requires = [
176-
item.replace(marker1, "").replace(marker2, "") for item in setup_requires
177-
if item.endswith(marker1) or item.endswith(marker2)
178-
or "python_version" not in item]
179-
install_requires = [
180-
item.replace(marker1, "").replace(marker2, "") for item in install_requires
181-
if item.endswith(marker1) or item.endswith(marker2)
182-
or "python_version" not in item]
183-
else:
184-
marker1 = '; python_version == "3.2"'
185-
setup_requires = [item for item in setup_requires if not item.endswith(marker1)]
186-
install_requires = [item for item in install_requires if not item.endswith(marker1)]
187-
188-
setup(**{
189-
"name":
190-
"basemap",
191-
"version":
192-
get_version("mpl_toolkits.basemap"),
193-
"license":
194-
"MIT",
195-
"description":
196-
"Plot data on map projections with matplotlib",
197-
"long_description":
198-
get_content("README.md"),
199-
"long_description_content_type":
200-
"text/markdown",
201-
"url":
202-
"https://matplotlib.org/basemap",
203-
"author":
204-
"Jeff Whitaker",
205-
"author_email":
206-
207-
"maintainer":
208-
"Víctor Molina García",
209-
"maintainer_email":
210-
211-
"classifiers": [
212-
"Development Status :: 5 - Production/Stable",
213-
"Intended Audience :: Education",
214-
"Intended Audience :: Science/Research",
215-
"License :: OSI Approved :: MIT License",
216-
"Operating System :: OS Independent",
217-
"Programming Language :: Python :: 2",
218-
"Programming Language :: Python :: 3",
219-
"Topic :: Scientific/Engineering :: Visualization",
220-
"Topic :: Software Development :: Libraries :: Python Modules",
221-
],
222-
"keywords": [
223-
"GIS",
224-
"maps",
225-
"plots",
226-
],
227-
"namespace_packages": [
228-
"mpl_toolkits",
229-
],
230-
"package_dir":
231-
{"": "src"},
232-
"packages":
233-
find_packages(where="src"),
234-
"ext_modules":
235-
ext_modules,
236-
"data_files":
237-
data_files,
238-
"python_requires":
239-
", ".join([
240-
">=2.6",
241-
"!=3.0.*",
242-
"!=3.1.*",
243-
"<3.13",
244-
]),
245-
"setup_requires":
246-
setup_requires,
247-
"install_requires":
248-
install_requires,
249-
"extras_require": {
250-
"doc":
251-
get_content("requirements-doc.txt", splitlines=True),
252-
"lint":
253-
get_content("requirements-lint.txt", splitlines=True),
254-
"test":
255-
get_content("requirements-test.txt", splitlines=True),
256-
"owslib":
257-
get_content("requirements-owslib.txt", splitlines=True),
258-
"pillow":
259-
get_content("requirements-pillow.txt", splitlines=True),
260-
},
261-
"cmdclass": {
262-
"sdist": basemap_sdist,
263-
},
264-
"project_urls": {
265-
"Bug Tracker":
266-
"https://github.com/matplotlib/basemap/issues",
267-
"Documentation":
268-
"https://matplotlib.org/basemap/",
269-
"Source":
270-
"https://github.com/matplotlib/basemap",
271-
},
272-
})
39+
def get_extension_kwargs():
40+
include_dirs = [np.get_include()]
41+
library_dirs = []
42+
runtime_library_dirs = []
43+
data_files = []
44+
45+
# Get GEOS paths
46+
geos_prefix = get_geos_install_prefix()
47+
if geos_prefix:
48+
include_dirs.append(os.path.join(geos_prefix, "include"))
49+
lib_dir = os.path.join(geos_prefix, "lib")
50+
lib64_dir = os.path.join(geos_prefix, "lib64")
51+
library_dirs.extend([lib_dir, lib64_dir])
52+
runtime_library_dirs = library_dirs.copy()
53+
54+
if os.name == "nt" or sys.platform == "cygwin":
55+
bin_dir = os.path.join(geos_prefix, "bin")
56+
library_dirs.append(bin_dir)
57+
runtime_library_dirs = []
58+
dlls = glob.glob(os.path.join(geos_prefix, "*", "*geos_c*.dll"))
59+
if dlls:
60+
data_files.append(("../..", sorted(dlls)))
61+
62+
return {
63+
"name": "_geoslib",
64+
"sources": ["src/_geoslib.pyx"],
65+
"libraries": ["geos_c"],
66+
"include_dirs": include_dirs,
67+
"library_dirs": library_dirs,
68+
"runtime_library_dirs": runtime_library_dirs,
69+
}
70+
71+
72+
setup(
73+
ext_modules=[Extension(**get_extension_kwargs())],
74+
data_files=get_extension_kwargs().get("data_files", []),
75+
)

0 commit comments

Comments
 (0)