Skip to content

Commit e859046

Browse files
marscherkeewisIllviljandcherian
authored andcommitted
remove requirement for setuptools.pkg_resources (pydata#5845)
Co-authored-by: keewis <[email protected]> Co-authored-by: Illviljan <[email protected]> Co-authored-by: Keewis <[email protected]> Co-authored-by: Deepak Cherian <[email protected]> Co-authored-by: dcherian <[email protected]>
1 parent 1257489 commit e859046

File tree

12 files changed

+54
-45
lines changed

12 files changed

+54
-45
lines changed

ci/min_deps_check.py

+3-11
Original file line numberDiff line numberDiff line change
@@ -20,24 +20,16 @@
2020
"isort",
2121
"mypy",
2222
"pip",
23+
"setuptools",
2324
"pytest",
2425
"pytest-cov",
2526
"pytest-env",
2627
"pytest-xdist",
2728
}
2829

29-
POLICY_MONTHS = {"python": 24, "numpy": 18, "setuptools": 42}
30+
POLICY_MONTHS = {"python": 24, "numpy": 18}
3031
POLICY_MONTHS_DEFAULT = 12
31-
POLICY_OVERRIDE = {
32-
# setuptools-scm doesn't work with setuptools < 36.7 (Nov 2017).
33-
# The conda metadata is malformed for setuptools < 38.4 (Jan 2018)
34-
# (it's missing a timestamp which prevents this tool from working).
35-
# setuptools < 40.4 (Sep 2018) from conda-forge cannot be installed into a py37
36-
# environment
37-
# TODO remove this special case and the matching note in installing.rst
38-
# after March 2022.
39-
"setuptools": (40, 4),
40-
}
32+
POLICY_OVERRIDE: Dict[str, Tuple[int, int]] = {}
4133
has_errors = False
4234

4335

ci/requirements/py37-bare-minimum.yml

-1
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,4 @@ dependencies:
1212
- pytest-xdist
1313
- numpy=1.17
1414
- pandas=1.0
15-
- setuptools=40.4
1615
- typing_extensions=3.7

ci/requirements/py37-min-all-deps.yml

+2-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ dependencies:
4444
- rasterio=1.1
4545
- scipy=1.4
4646
- seaborn=0.10
47-
- setuptools=40.4
47+
# don't need to pin setuptools, now that we don't depend on it
48+
- setuptools
4849
- sparse=0.8
4950
- toolz=0.10
5051
- typing_extensions=3.7

doc/getting-started-guide/installing.rst

+2-3
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ Required dependencies
77
---------------------
88

99
- Python (3.7 or later)
10-
- setuptools (40.4 or later)
11-
- ``typing_extensions`` (3.7 or later)
10+
- `importlib_metadata <https://importlib_metadata.readthedocs.io/>`__ (1.4 or later, Python 3.7 only)
11+
- ``typing_extensions`` (3.7 or later, Python 3.7 only)
1212
- `numpy <http://www.numpy.org/>`__ (1.17 or later)
1313
- `pandas <http://pandas.pydata.org/>`__ (1.0 or later)
1414

@@ -93,7 +93,6 @@ dependencies:
9393

9494
- **Python:** 24 months
9595
(`NEP-29 <https://numpy.org/neps/nep-0029-deprecation_policy.html>`_)
96-
- **setuptools:** 42 months (but no older than 40.4)
9796
- **numpy:** 18 months
9897
(`NEP-29 <https://numpy.org/neps/nep-0029-deprecation_policy.html>`_)
9998
- **all other libraries:** 12 months

doc/whats-new.rst

+4
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,10 @@ Internal Changes
134134
By `Tom Nicholas <https://github.com/TomNicholas>`_.
135135
- Add an ASV benchmark CI and improve performance of the benchmarks (:pull:`5796`)
136136
By `Jimmy Westling <https://github.com/illviljan>`_.
137+
- Use ``importlib`` to replace functionality of ``pkg_resources`` such
138+
as version setting and loading of resources. (:pull:`5845`).
139+
By `Martin K. Scherer <https://github.com/marscher>`_.
140+
137141

138142
.. _whats-new.0.19.0:
139143

setup.cfg

+2-2
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,8 @@ python_requires = >=3.7
7878
install_requires =
7979
numpy >= 1.17
8080
pandas >= 1.0
81-
typing_extensions >= 3.7
82-
setuptools >= 40.4 # For pkg_resources
81+
importlib-metadata; python_version < '3.8'
82+
typing_extensions >= 3.7; python_version < '3.8'
8383

8484
[options.extras_require]
8585
io =

xarray/__init__.py

+7-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import pkg_resources
2-
31
from . import testing, tutorial, ufuncs
42
from .backends.api import (
53
load_dataarray,
@@ -30,7 +28,13 @@
3028
from .util.print_versions import show_versions
3129

3230
try:
33-
__version__ = pkg_resources.get_distribution("xarray").version
31+
from importlib.metadata import version as _version
32+
except ImportError:
33+
# if the fallback library is missing, we are doomed.
34+
from importlib_metadata import version as _version # type: ignore[no-redef]
35+
36+
try:
37+
__version__ = _version("xarray")
3438
except Exception:
3539
# Local copy or not installed with setuptools.
3640
# Disable minimum version checks on downstream libraries.

xarray/backends/plugins.py

+27-19
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,27 @@
33
import itertools
44
import warnings
55

6-
import pkg_resources
7-
86
from .common import BACKEND_ENTRYPOINTS, BackendEntrypoint
97

10-
STANDARD_BACKENDS_ORDER = ["netcdf4", "h5netcdf", "scipy"]
8+
try:
9+
from importlib.metadata import Distribution
10+
except ImportError:
11+
# if the fallback library is missing, we are doomed.
12+
from importlib_metadata import Distribution # type: ignore[no-redef]
1113

1214

13-
def remove_duplicates(pkg_entrypoints):
15+
STANDARD_BACKENDS_ORDER = ["netcdf4", "h5netcdf", "scipy"]
1416

17+
18+
def remove_duplicates(entrypoints):
1519
# sort and group entrypoints by name
16-
pkg_entrypoints = sorted(pkg_entrypoints, key=lambda ep: ep.name)
17-
pkg_entrypoints_grouped = itertools.groupby(pkg_entrypoints, key=lambda ep: ep.name)
20+
entrypoints = sorted(entrypoints, key=lambda ep: ep.name)
21+
entrypoints_grouped = itertools.groupby(entrypoints, key=lambda ep: ep.name)
1822
# check if there are multiple entrypoints for the same name
19-
unique_pkg_entrypoints = []
20-
for name, matches in pkg_entrypoints_grouped:
23+
unique_entrypoints = []
24+
for name, matches in entrypoints_grouped:
2125
matches = list(matches)
22-
unique_pkg_entrypoints.append(matches[0])
26+
unique_entrypoints.append(matches[0])
2327
matches_len = len(matches)
2428
if matches_len > 1:
2529
selected_module_name = matches[0].module_name
@@ -29,7 +33,7 @@ def remove_duplicates(pkg_entrypoints):
2933
f"\n {all_module_names}.\n It will be used: {selected_module_name}.",
3034
RuntimeWarning,
3135
)
32-
return unique_pkg_entrypoints
36+
return unique_entrypoints
3337

3438

3539
def detect_parameters(open_dataset):
@@ -50,12 +54,12 @@ def detect_parameters(open_dataset):
5054
return tuple(parameters_list)
5155

5256

53-
def backends_dict_from_pkg(pkg_entrypoints):
57+
def backends_dict_from_pkg(entrypoints):
5458
backend_entrypoints = {}
55-
for pkg_ep in pkg_entrypoints:
56-
name = pkg_ep.name
59+
for entrypoint in entrypoints:
60+
name = entrypoint.name
5761
try:
58-
backend = pkg_ep.load()
62+
backend = entrypoint.load()
5963
backend_entrypoints[name] = backend
6064
except Exception as ex:
6165
warnings.warn(f"Engine {name!r} loading failed:\n{ex}", RuntimeWarning)
@@ -80,13 +84,13 @@ def sort_backends(backend_entrypoints):
8084
return ordered_backends_entrypoints
8185

8286

83-
def build_engines(pkg_entrypoints):
87+
def build_engines(entrypoints):
8488
backend_entrypoints = {}
8589
for backend_name, backend in BACKEND_ENTRYPOINTS.items():
8690
if backend.available:
8791
backend_entrypoints[backend_name] = backend
88-
pkg_entrypoints = remove_duplicates(pkg_entrypoints)
89-
external_backend_entrypoints = backends_dict_from_pkg(pkg_entrypoints)
92+
entrypoints = remove_duplicates(entrypoints)
93+
external_backend_entrypoints = backends_dict_from_pkg(entrypoints)
9094
backend_entrypoints.update(external_backend_entrypoints)
9195
backend_entrypoints = sort_backends(backend_entrypoints)
9296
set_missing_parameters(backend_entrypoints)
@@ -95,8 +99,12 @@ def build_engines(pkg_entrypoints):
9599

96100
@functools.lru_cache(maxsize=1)
97101
def list_engines():
98-
pkg_entrypoints = pkg_resources.iter_entry_points("xarray.backends")
99-
return build_engines(pkg_entrypoints)
102+
entrypoints = (
103+
entry_point
104+
for entry_point in Distribution.from_name("xarray").entry_points
105+
if entry_point.module == "xarray.backends"
106+
)
107+
return build_engines(entrypoints)
100108

101109

102110
def guess_engine(store_spec):

xarray/core/formatting_html.py

+7-5
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,23 @@
22
from collections import OrderedDict
33
from functools import lru_cache, partial
44
from html import escape
5-
6-
import pkg_resources
5+
from importlib.resources import read_binary
76

87
from .formatting import inline_variable_array_repr, short_data_repr
98
from .options import _get_boolean_with_default
109

11-
STATIC_FILES = ("static/html/icons-svg-inline.html", "static/css/style.css")
10+
STATIC_FILES = (
11+
("xarray.static.html", "icons-svg-inline.html"),
12+
("xarray.static.css", "style.css"),
13+
)
1214

1315

1416
@lru_cache(None)
1517
def _load_static_files():
1618
"""Lazily load the resource files into memory the first time they are needed"""
1719
return [
18-
pkg_resources.resource_string("xarray", fname).decode("utf8")
19-
for fname in STATIC_FILES
20+
read_binary(package, resource).decode("utf-8")
21+
for package, resource in STATIC_FILES
2022
]
2123

2224

xarray/static/__init__.py

Whitespace-only changes.

xarray/static/css/__init__.py

Whitespace-only changes.

xarray/static/html/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)