diff --git a/hdbscan/_hdbscan_boruvka.pyx b/hdbscan/_hdbscan_boruvka.pyx index 38e1b34b..bceae9e5 100644 --- a/hdbscan/_hdbscan_boruvka.pyx +++ b/hdbscan/_hdbscan_boruvka.pyx @@ -1,3 +1,4 @@ +# distutils: define_macros=NPY_NO_DEPRECATED_API=NPY_1_7_API_VERSION # cython: boundscheck=False # cython: nonecheck=False # cython: wraparound=False @@ -89,7 +90,7 @@ cdef inline np.double_t balltree_min_dist_dual( np.double_t radius2, np.intp_t node1, np.intp_t node2, - np.double_t[:, ::1] centroid_dist) nogil except -1: + np.double_t[:, ::1] centroid_dist) except -1 nogil: cdef np.double_t dist_pt = centroid_dist[node1, node2] return max(0, (dist_pt - radius1 - radius2)) @@ -139,7 +140,7 @@ cdef inline np.double_t kdtree_min_rdist_dual( np.intp_t node1, np.intp_t node2, np.double_t[:, :, ::1] node_bounds, - np.intp_t num_features) nogil except -1: + np.intp_t num_features) except -1 nogil: cdef np.double_t d, d1, d2, rdist = 0.0 cdef np.double_t zero = 0.0 @@ -603,7 +604,7 @@ cdef class KDTreeBoruvkaAlgorithm (object): return self.components.shape[0] cdef int dual_tree_traversal(self, np.intp_t node1, - np.intp_t node2) nogil except -1: + np.intp_t node2) except -1 nogil: """Perform a dual tree traversal, pruning wherever possible, to find the nearest neighbor not in the same component for each component. This is akin to a standard dual tree NN search, but we also prune diff --git a/hdbscan/_hdbscan_linkage.pyx b/hdbscan/_hdbscan_linkage.pyx index 66152e38..74eb381f 100644 --- a/hdbscan/_hdbscan_linkage.pyx +++ b/hdbscan/_hdbscan_linkage.pyx @@ -1,3 +1,4 @@ +# distutils: define_macros=NPY_NO_DEPRECATED_API=NPY_1_7_API_VERSION # cython: boundscheck=False # cython: nonecheck=False # Minimum spanning tree single linkage implementation for hdbscan diff --git a/hdbscan/_hdbscan_reachability.pyx b/hdbscan/_hdbscan_reachability.pyx index 3f4e3141..aba1dbd7 100644 --- a/hdbscan/_hdbscan_reachability.pyx +++ b/hdbscan/_hdbscan_reachability.pyx @@ -1,3 +1,4 @@ +# distutils: define_macros=NPY_NO_DEPRECATED_API=NPY_1_7_API_VERSION # cython: boundscheck=False # cython: nonecheck=False # cython: initializedcheck=False diff --git a/hdbscan/_hdbscan_tree.pyx b/hdbscan/_hdbscan_tree.pyx index 7eb43c04..aacf6e0f 100644 --- a/hdbscan/_hdbscan_tree.pyx +++ b/hdbscan/_hdbscan_tree.pyx @@ -1,3 +1,4 @@ +# distutils: define_macros=NPY_NO_DEPRECATED_API=NPY_1_7_API_VERSION # cython: boundscheck=False # cython: nonecheck=False # cython: initializedcheck=False diff --git a/hdbscan/_prediction_utils.pyx b/hdbscan/_prediction_utils.pyx index c8c0a5aa..1a8ffa76 100644 --- a/hdbscan/_prediction_utils.pyx +++ b/hdbscan/_prediction_utils.pyx @@ -1,4 +1,5 @@ -#cython: boundscheck=False, nonecheck=False, initializedcheck=False +# distutils: define_macros=NPY_NO_DEPRECATED_API=NPY_1_7_API_VERSION +# cython: boundscheck=False, nonecheck=False, initializedcheck=False # Utility routines in cython for prediction in hdbscan # Authors: Leland McInnes # License: 3-clause BSD diff --git a/hdbscan/dist_metrics.pxd b/hdbscan/dist_metrics.pxd index df3c8af8..8afad363 100644 --- a/hdbscan/dist_metrics.pxd +++ b/hdbscan/dist_metrics.pxd @@ -1,7 +1,8 @@ #!python -#cython: boundscheck=False -#cython: wraparound=False -#cython: cdivision=True +# distutils: define_macros=NPY_NO_DEPRECATED_API=NPY_1_7_API_VERSION +# cython: boundscheck=False +# cython: wraparound=False +# cython: cdivision=True import cython cimport cython @@ -33,7 +34,7 @@ DTYPE = np.double # We use these for the default (euclidean) case so that they can be # inlined. This leads to faster computation for the most common case cdef inline DTYPE_t euclidean_dist(DTYPE_t* x1, DTYPE_t* x2, - ITYPE_t size) nogil except -1: + ITYPE_t size) except -1 nogil: cdef DTYPE_t tmp, d=0 cdef np.intp_t j for j in range(size): @@ -43,7 +44,7 @@ cdef inline DTYPE_t euclidean_dist(DTYPE_t* x1, DTYPE_t* x2, cdef inline DTYPE_t euclidean_rdist(DTYPE_t* x1, DTYPE_t* x2, - ITYPE_t size) nogil except -1: + ITYPE_t size) except -1 nogil: cdef DTYPE_t tmp, d=0 cdef np.intp_t j for j in range(size): @@ -52,7 +53,7 @@ cdef inline DTYPE_t euclidean_rdist(DTYPE_t* x1, DTYPE_t* x2, return d -cdef inline DTYPE_t euclidean_dist_to_rdist(DTYPE_t dist) nogil except -1: +cdef inline DTYPE_t euclidean_dist_to_rdist(DTYPE_t dist) except -1 nogil: return dist * dist @@ -79,10 +80,10 @@ cdef class DistanceMetric: cdef object kwargs cdef DTYPE_t dist(self, DTYPE_t* x1, DTYPE_t* x2, - ITYPE_t size) nogil except -1 + ITYPE_t size) except -1 nogil cdef DTYPE_t rdist(self, DTYPE_t* x1, DTYPE_t* x2, - ITYPE_t size) nogil except -1 + ITYPE_t size) except -1 nogil cdef int pdist(self, DTYPE_t[:, ::1] X, DTYPE_t[:, ::1] D) except -1 @@ -91,4 +92,4 @@ cdef class DistanceMetric: cdef DTYPE_t _rdist_to_dist(self, DTYPE_t rdist) except -1 - cdef DTYPE_t _dist_to_rdist(self, DTYPE_t dist) nogil except -1 + cdef DTYPE_t _dist_to_rdist(self, DTYPE_t dist) except -1 nogil diff --git a/hdbscan/dist_metrics.pyx b/hdbscan/dist_metrics.pyx index 7416a9ff..418f684d 100644 --- a/hdbscan/dist_metrics.pyx +++ b/hdbscan/dist_metrics.pyx @@ -1,4 +1,5 @@ # !python +# distutils: define_macros=NPY_NO_DEPRECATED_API=NPY_1_7_API_VERSION # cython: boundscheck=False # cython: wraparound=False # cython: cdivision=True @@ -301,7 +302,7 @@ cdef class DistanceMetric: raise NotImplementedError("DistanceMetric is an abstract class") cdef DTYPE_t dist(self, DTYPE_t* x1, DTYPE_t* x2, - ITYPE_t size) nogil except -1: + ITYPE_t size) except -1 nogil: """Compute the distance between vectors x1 and x2 This should be overridden in a base class. @@ -309,7 +310,7 @@ cdef class DistanceMetric: return -999 cdef DTYPE_t rdist(self, DTYPE_t* x1, DTYPE_t* x2, - ITYPE_t size) nogil except -1: + ITYPE_t size) except -1 nogil: """Compute the reduced distance between vectors x1 and x2. This can optionally be overridden in a base class. @@ -345,7 +346,7 @@ cdef class DistanceMetric: """Convert the reduced distance to the distance""" return rdist - cdef DTYPE_t _dist_to_rdist(self, DTYPE_t dist) nogil except -1: + cdef DTYPE_t _dist_to_rdist(self, DTYPE_t dist) except -1 nogil: """Convert the distance to the reduced distance""" return dist @@ -422,17 +423,17 @@ cdef class EuclideanDistance(DistanceMetric): self.p = 2 cdef inline DTYPE_t dist(self, DTYPE_t* x1, DTYPE_t* x2, - ITYPE_t size) nogil except -1: + ITYPE_t size) except -1 nogil: return euclidean_dist(x1, x2, size) cdef inline DTYPE_t rdist(self, DTYPE_t* x1, DTYPE_t* x2, - ITYPE_t size) nogil except -1: + ITYPE_t size) except -1 nogil: return euclidean_rdist(x1, x2, size) cdef inline DTYPE_t _rdist_to_dist(self, DTYPE_t rdist) except -1: return sqrt(rdist) - cdef inline DTYPE_t _dist_to_rdist(self, DTYPE_t dist) nogil except -1: + cdef inline DTYPE_t _dist_to_rdist(self, DTYPE_t dist) except -1 nogil: return dist * dist def rdist_to_dist(self, rdist): @@ -458,7 +459,7 @@ cdef class SEuclideanDistance(DistanceMetric): self.p = 2 cdef inline DTYPE_t rdist(self, DTYPE_t* x1, DTYPE_t* x2, - ITYPE_t size) nogil except -1: + ITYPE_t size) except -1 nogil: if size != self.size: with gil: raise ValueError('SEuclidean dist: size of V does not match') @@ -470,13 +471,13 @@ cdef class SEuclideanDistance(DistanceMetric): return d cdef inline DTYPE_t dist(self, DTYPE_t* x1, DTYPE_t* x2, - ITYPE_t size) nogil except -1: + ITYPE_t size) except -1 nogil: return sqrt(self.rdist(x1, x2, size)) cdef inline DTYPE_t _rdist_to_dist(self, DTYPE_t rdist) except -1: return sqrt(rdist) - cdef inline DTYPE_t _dist_to_rdist(self, DTYPE_t dist) nogil except -1: + cdef inline DTYPE_t _dist_to_rdist(self, DTYPE_t dist) except -1 nogil: return dist * dist def rdist_to_dist(self, rdist): @@ -499,7 +500,7 @@ cdef class ManhattanDistance(DistanceMetric): self.p = 1 cdef inline DTYPE_t dist(self, DTYPE_t* x1, DTYPE_t* x2, - ITYPE_t size) nogil except -1: + ITYPE_t size) except -1 nogil: cdef DTYPE_t d = 0 cdef np.intp_t j for j in range(size): @@ -520,7 +521,7 @@ cdef class ChebyshevDistance(DistanceMetric): self.p = INF cdef inline DTYPE_t dist(self, DTYPE_t* x1, DTYPE_t* x2, - ITYPE_t size) nogil except -1: + ITYPE_t size) except -1 nogil: cdef DTYPE_t d = 0 cdef np.intp_t j for j in range(size): @@ -551,7 +552,7 @@ cdef class MinkowskiDistance(DistanceMetric): self.p = p cdef inline DTYPE_t rdist(self, DTYPE_t* x1, DTYPE_t* x2, - ITYPE_t size) nogil except -1: + ITYPE_t size) except -1 nogil: cdef DTYPE_t d=0 cdef np.intp_t j for j in range(size): @@ -559,13 +560,13 @@ cdef class MinkowskiDistance(DistanceMetric): return d cdef inline DTYPE_t dist(self, DTYPE_t* x1, DTYPE_t* x2, - ITYPE_t size) nogil except -1: + ITYPE_t size) except -1 nogil: return pow(self.rdist(x1, x2, size), 1. / self.p) cdef inline DTYPE_t _rdist_to_dist(self, DTYPE_t rdist) except -1: return pow(rdist, 1. / self.p) - cdef inline DTYPE_t _dist_to_rdist(self, DTYPE_t dist) nogil except -1: + cdef inline DTYPE_t _dist_to_rdist(self, DTYPE_t dist) except -1 nogil: return pow(dist, self.p) def rdist_to_dist(self, rdist): @@ -606,7 +607,7 @@ cdef class WMinkowskiDistance(DistanceMetric): self.size = self.vec.shape[0] cdef inline DTYPE_t rdist(self, DTYPE_t* x1, DTYPE_t* x2, - ITYPE_t size) nogil except -1: + ITYPE_t size) except -1 nogil: if size != self.size: with gil: raise ValueError('WMinkowskiDistance dist: ' @@ -618,13 +619,13 @@ cdef class WMinkowskiDistance(DistanceMetric): return d cdef inline DTYPE_t dist(self, DTYPE_t* x1, DTYPE_t* x2, - ITYPE_t size) nogil except -1: + ITYPE_t size) except -1 nogil: return pow(self.rdist(x1, x2, size), 1. / self.p) cdef inline DTYPE_t _rdist_to_dist(self, DTYPE_t rdist) except -1: return pow(rdist, 1. / self.p) - cdef inline DTYPE_t _dist_to_rdist(self, DTYPE_t dist) nogil except -1: + cdef inline DTYPE_t _dist_to_rdist(self, DTYPE_t dist) except -1 nogil: return pow(dist, self.p) def rdist_to_dist(self, rdist): @@ -668,7 +669,7 @@ cdef class MahalanobisDistance(DistanceMetric): self.vec_ptr = get_vec_ptr(self.vec) cdef inline DTYPE_t rdist(self, DTYPE_t* x1, DTYPE_t* x2, - ITYPE_t size) nogil except -1: + ITYPE_t size) except -1 nogil: if size != self.size: with gil: raise ValueError('Mahalanobis dist: size of V does not match') @@ -688,13 +689,13 @@ cdef class MahalanobisDistance(DistanceMetric): return d cdef inline DTYPE_t dist(self, DTYPE_t* x1, DTYPE_t* x2, - ITYPE_t size) nogil except -1: + ITYPE_t size) except -1 nogil: return sqrt(self.rdist(x1, x2, size)) cdef inline DTYPE_t _rdist_to_dist(self, DTYPE_t rdist) except -1: return sqrt(rdist) - cdef inline DTYPE_t _dist_to_rdist(self, DTYPE_t dist) nogil except -1: + cdef inline DTYPE_t _dist_to_rdist(self, DTYPE_t dist) except -1 nogil: return dist * dist def rdist_to_dist(self, rdist): @@ -717,7 +718,7 @@ cdef class HammingDistance(DistanceMetric): D(x, y) = \frac{1}{N} \sum_i \delta_{x_i, y_i} """ cdef inline DTYPE_t dist(self, DTYPE_t* x1, DTYPE_t* x2, - ITYPE_t size) nogil except -1: + ITYPE_t size) except -1 nogil: cdef int n_unequal = 0 cdef np.intp_t j for j in range(size): @@ -739,7 +740,7 @@ cdef class CanberraDistance(DistanceMetric): D(x, y) = \sum_i \frac{|x_i - y_i|}{|x_i| + |y_i|} """ cdef inline DTYPE_t dist(self, DTYPE_t* x1, DTYPE_t* x2, - ITYPE_t size) nogil except -1: + ITYPE_t size) except -1 nogil: cdef DTYPE_t denom, d = 0 cdef np.intp_t j for j in range(size): @@ -762,7 +763,7 @@ cdef class BrayCurtisDistance(DistanceMetric): D(x, y) = \frac{\sum_i |x_i - y_i|}{\sum_i(|x_i| + |y_i|)} """ cdef inline DTYPE_t dist(self, DTYPE_t* x1, DTYPE_t* x2, - ITYPE_t size) nogil except -1: + ITYPE_t size) except -1 nogil: cdef DTYPE_t num = 0, denom = 0 cdef np.intp_t j for j in range(size): @@ -788,7 +789,7 @@ cdef class JaccardDistance(DistanceMetric): D(x, y) = \frac{N_{TF} + N_{FT}}{N_{TT} + N_{TF} + N_{FT}} """ cdef inline DTYPE_t dist(self, DTYPE_t* x1, DTYPE_t* x2, - ITYPE_t size) nogil except -1: + ITYPE_t size) except -1 nogil: cdef int tf1, tf2, n_eq = 0, nnz = 0 cdef np.intp_t j for j in range(size): @@ -815,7 +816,7 @@ cdef class MatchingDistance(DistanceMetric): D(x, y) = \frac{N_{TF} + N_{FT}}{N} """ cdef inline DTYPE_t dist(self, DTYPE_t* x1, DTYPE_t* x2, - ITYPE_t size) nogil except -1: + ITYPE_t size) except -1 nogil: cdef int tf1, tf2, n_neq = 0 cdef np.intp_t j for j in range(size): @@ -839,7 +840,7 @@ cdef class DiceDistance(DistanceMetric): D(x, y) = \frac{N_{TF} + N_{FT}}{2 * N_{TT} + N_{TF} + N_{FT}} """ cdef inline DTYPE_t dist(self, DTYPE_t* x1, DTYPE_t* x2, - ITYPE_t size) nogil except -1: + ITYPE_t size) except -1 nogil: cdef int tf1, tf2, n_neq = 0, ntt = 0 cdef np.intp_t j for j in range(size): @@ -864,7 +865,7 @@ cdef class KulsinskiDistance(DistanceMetric): D(x, y) = 1 - \frac{N_{TT}}{N + N_{TF} + N_{FT}} """ cdef inline DTYPE_t dist(self, DTYPE_t* x1, DTYPE_t* x2, - ITYPE_t size) nogil except -1: + ITYPE_t size) except -1 nogil: cdef int tf1, tf2, ntt = 0, n_neq = 0 cdef np.intp_t j for j in range(size): @@ -889,7 +890,7 @@ cdef class RogersTanimotoDistance(DistanceMetric): D(x, y) = \frac{2 (N_{TF} + N_{FT})}{N + N_{TF} + N_{FT}} """ cdef inline DTYPE_t dist(self, DTYPE_t* x1, DTYPE_t* x2, - ITYPE_t size) nogil except -1: + ITYPE_t size) except -1 nogil: cdef int tf1, tf2, n_neq = 0 cdef np.intp_t j for j in range(size): @@ -913,7 +914,7 @@ cdef class RussellRaoDistance(DistanceMetric): D(x, y) = \frac{N - N_{TT}}{N} """ cdef inline DTYPE_t dist(self, DTYPE_t* x1, DTYPE_t* x2, - ITYPE_t size) nogil except -1: + ITYPE_t size) except -1 nogil: cdef int tf1, tf2, ntt = 0 cdef np.intp_t j for j in range(size): @@ -937,7 +938,7 @@ cdef class SokalMichenerDistance(DistanceMetric): D(x, y) = \frac{2 (N_{TF} + N_{FT})}{N + N_{TF} + N_{FT}} """ cdef inline DTYPE_t dist(self, DTYPE_t* x1, DTYPE_t* x2, - ITYPE_t size) nogil except -1: + ITYPE_t size) except -1 nogil: cdef int tf1, tf2, n_neq = 0 cdef np.intp_t j for j in range(size): @@ -961,7 +962,7 @@ cdef class SokalSneathDistance(DistanceMetric): D(x, y) = \frac{N_{TF} + N_{FT}}{N_{TT} / 2 + N_{TF} + N_{FT}} """ cdef inline DTYPE_t dist(self, DTYPE_t* x1, DTYPE_t* x2, - ITYPE_t size) nogil except -1: + ITYPE_t size) except -1 nogil: cdef int tf1, tf2, ntt = 0, n_neq = 0 cdef np.intp_t j for j in range(size): @@ -989,7 +990,7 @@ cdef class HaversineDistance(DistanceMetric): + cos(x1)cos(y1)sin^2((x2 - y2) / 2)}] """ cdef inline DTYPE_t rdist(self, DTYPE_t* x1, DTYPE_t* x2, - ITYPE_t size) nogil except -1: + ITYPE_t size) except -1 nogil: if size != 2: with gil: raise ValueError("Haversine distance only valid " @@ -999,7 +1000,7 @@ cdef class HaversineDistance(DistanceMetric): return (sin_0 * sin_0 + cos(x1[0]) * cos(x2[0]) * sin_1 * sin_1) cdef inline DTYPE_t dist(self, DTYPE_t* x1, DTYPE_t* x2, - ITYPE_t size) nogil except -1: + ITYPE_t size) except -1 nogil: if size != 2: with gil: raise ValueError("Haversine distance only valid in" @@ -1012,7 +1013,7 @@ cdef class HaversineDistance(DistanceMetric): cdef inline DTYPE_t _rdist_to_dist(self, DTYPE_t rdist) except -1: return 2 * asin(sqrt(rdist)) - cdef inline DTYPE_t _dist_to_rdist(self, DTYPE_t dist) nogil except -1: + cdef inline DTYPE_t _dist_to_rdist(self, DTYPE_t dist) except -1 nogil: cdef DTYPE_t tmp = sin(0.5 * dist) return tmp * tmp @@ -1051,7 +1052,7 @@ cdef class HaversineDistance(DistanceMetric): # cdef class CosineDistance(DistanceMetric): # cdef inline DTYPE_t dist(self, DTYPE_t* x1, DTYPE_t* x2, -# ITYPE_t size) nogil except -1: +# ITYPE_t size) except -1 nogil: # cdef DTYPE_t d = 0, norm1 = 0, norm2 = 0 # cdef np.intp_t j # for j in range(size): @@ -1066,7 +1067,7 @@ cdef class HaversineDistance(DistanceMetric): cdef class ArccosDistance(DistanceMetric): cdef inline DTYPE_t dist(self, DTYPE_t* x1, DTYPE_t* x2, - ITYPE_t size) nogil except -1: + ITYPE_t size) except -1 nogil: cdef DTYPE_t d = 0, norm1 = 0, norm2 = 0 cdef np.intp_t j for j in range(size): @@ -1124,7 +1125,7 @@ cdef class PyFuncDistance(DistanceMetric): # only way to be back compatible is to inherit `dist` from the base class # without GIL and called an inline `_dist` which acquire GIL. cdef inline DTYPE_t dist(self, DTYPE_t* x1, DTYPE_t* x2, - ITYPE_t size) nogil except -1: + ITYPE_t size) except -1 nogil: return self._dist(x1, x2, size) cdef inline DTYPE_t _dist(self, DTYPE_t* x1, DTYPE_t* x2, diff --git a/hdbscan/hdbscan_.py b/hdbscan/hdbscan_.py index ad6d110e..ea1b06ce 100644 --- a/hdbscan/hdbscan_.py +++ b/hdbscan/hdbscan_.py @@ -764,7 +764,7 @@ def hdbscan( # Checks input and converts to an nd-array where possible if metric != "precomputed" or issparse(X): - X = check_array(X, accept_sparse="csr", force_all_finite=False) + X = check_array(X, accept_sparse="csr", ensure_all_finite=False) else: # Only non-sparse, precomputed distance matrices are handled here # and thereby allowed to contain numpy.inf for missing distances @@ -1229,7 +1229,7 @@ def fit(self, X, y=None): if self.metric != "precomputed": # Non-precomputed matrices may contain non-finite values. # Rows with these values - X = check_array(X, accept_sparse="csr", force_all_finite=False) + X = check_array(X, accept_sparse="csr", ensure_all_finite=False) self._raw_data = X self._all_finite = is_finite(X) diff --git a/hdbscan/robust_single_linkage_.py b/hdbscan/robust_single_linkage_.py index 090b0928..3cec94f9 100644 --- a/hdbscan/robust_single_linkage_.py +++ b/hdbscan/robust_single_linkage_.py @@ -151,7 +151,7 @@ def robust_single_linkage(X, cut, k=5, alpha=1.4142135623730951, gamma=5, metric='euclidean', algorithm='best', memory=Memory(None, verbose=0), leaf_size=40, core_dist_n_jobs=4, **kwargs): - """Perform robust single linkage clustering from a vector array + r"""Perform robust single linkage clustering from a vector array or distance matrix. Parameters diff --git a/pyproject.toml b/pyproject.toml index 9ea88166..019ef286 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [build-system] requires = [ "setuptools", - "wheel", "cython<4", - "numpy<3" + "numpy>=2, <3" ] +build-backend = "setuptools.build_meta" diff --git a/requirements.txt b/requirements.txt index 10f932e8..8964a2bb 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ numpy>=1.20,<3 scipy>= 1.0 -scikit-learn>=0.20 +scikit-learn>=1.6.0 joblib>=1.0 diff --git a/setup.py b/setup.py index d6110edc..cd901831 100644 --- a/setup.py +++ b/setup.py @@ -62,7 +62,6 @@ def requirements(): 'Development Status :: 4 - Beta', 'Intended Audience :: Science/Research', 'Intended Audience :: Developers', - 'License :: OSI Approved', 'Programming Language :: C', 'Programming Language :: Python', 'Topic :: Software Development', @@ -80,7 +79,7 @@ def requirements(): 'url': 'http://github.com/scikit-learn-contrib/hdbscan', 'maintainer': 'Leland McInnes', 'maintainer_email': 'leland.mcinnes@gmail.com', - 'license': 'BSD', + 'license-expression': 'BSD-3-Clause', 'packages': ['hdbscan', 'hdbscan.tests'], 'install_requires': requirements(), 'ext_modules': cythonize([ @@ -91,8 +90,6 @@ def requirements(): _prediction_utils, dist_metrics]), 'cmdclass': {'build_ext': CustomBuildExtCommand}, - 'test_suite': 'nose.collector', - 'tests_require': ['nose'], 'data_files': ('hdbscan/dist_metrics.pxd',) }