diff --git a/build_tools/azure/install.sh b/build_tools/azure/install.sh index 26b184d6f7d1d..1c76a7a4aa5d3 100755 --- a/build_tools/azure/install.sh +++ b/build_tools/azure/install.sh @@ -83,11 +83,11 @@ python_environment_install_and_activate() { echo "Installing development dependency wheels" dev_anaconda_url=https://pypi.anaconda.org/scipy-wheels-nightly/simple pip install --pre --upgrade --timeout=60 --extra-index $dev_anaconda_url numpy pandas scipy - echo "Installing Cython from PyPI enabling pre-releases" - pip install --pre cython - echo "Installing joblib master" + echo "Installing Cython from latest sources" + pip install https://github.com/cython/cython/archive/master.zip + echo "Installing joblib from latest sources" pip install https://github.com/joblib/joblib/archive/master.zip - echo "Installing pillow master" + echo "Installing pillow from latest sources" pip install https://github.com/python-pillow/Pillow/archive/main.zip fi } diff --git a/sklearn/_build_utils/__init__.py b/sklearn/_build_utils/__init__.py index 6828192aaf4a5..755171ee770c4 100644 --- a/sklearn/_build_utils/__init__.py +++ b/sklearn/_build_utils/__init__.py @@ -40,6 +40,7 @@ def cythonize_extensions(extension): """Check that a recent Cython is available and cythonize extensions""" _check_cython_version() from Cython.Build import cythonize + import Cython # Fast fail before cythonization if compiler fails compiling basic test # code even without OpenMP @@ -70,20 +71,37 @@ def cythonize_extensions(extension): os.environ.get("SKLEARN_ENABLE_DEBUG_CYTHON_DIRECTIVES", "0") != "0" ) + compiler_directives = { + "language_level": 3, + "boundscheck": cython_enable_debug_directives, + "wraparound": False, + "initializedcheck": False, + "nonecheck": False, + "cdivision": True, + } + + # TODO: once Cython 3 is released and we require Cython>=3 we should get + # rid of the `legacy_implicit_noexcept` directive. + # This should mostly consist in: + # + # - ensuring nogil is at the end of function signature, + # e.g. replace "nogil except -1" by "except -1 nogil". + # + # - "noexcept"-qualifying Cython and externalized C interfaces + # which aren't raising nor propagating exceptions. + # See: https://cython.readthedocs.io/en/latest/src/userguide/language_basics.html#error-return-values # noqa + # + # See: https://github.com/cython/cython/issues/5088 for more details + if parse(Cython.__version__) > parse("3.0.0a11"): + compiler_directives["legacy_implicit_noexcept"] = True + return cythonize( extension, nthreads=n_jobs, compile_time_env={ "SKLEARN_OPENMP_PARALLELISM_ENABLED": sklearn._OPENMP_SUPPORTED }, - compiler_directives={ - "language_level": 3, - "boundscheck": cython_enable_debug_directives, - "wraparound": False, - "initializedcheck": False, - "nonecheck": False, - "cdivision": True, - }, + compiler_directives=compiler_directives, ) diff --git a/sklearn/neighbors/_binary_tree.pxi b/sklearn/neighbors/_binary_tree.pxi index 415fa0292fcda..00b5b3c2758d3 100644 --- a/sklearn/neighbors/_binary_tree.pxi +++ b/sklearn/neighbors/_binary_tree.pxi @@ -846,7 +846,7 @@ cdef class BinaryTree: # with numbers of points between leaf_size and 2 * leaf_size self.n_levels = int( np.log2(fmax(1, (n_samples - 1) / self.leaf_size)) + 1) - self.n_nodes = (2 ** self.n_levels) - 1 + self.n_nodes = (2 ** self.n_levels) - 1 # allocate arrays for storage self.idx_array = np.arange(n_samples, dtype=ITYPE) diff --git a/sklearn/neighbors/_quad_tree.pyx b/sklearn/neighbors/_quad_tree.pyx index 3d2c306a38177..a7607cb56e0eb 100644 --- a/sklearn/neighbors/_quad_tree.pyx +++ b/sklearn/neighbors/_quad_tree.pyx @@ -52,7 +52,7 @@ cdef class _QuadTree: # Parameters of the tree self.n_dimensions = n_dimensions self.verbose = verbose - self.n_cells_per_cell = 2 ** self.n_dimensions + self.n_cells_per_cell = (2 ** self.n_dimensions) # Inner structures self.max_depth = 0 diff --git a/sklearn/tree/_tree.pyx b/sklearn/tree/_tree.pyx index 68cb2475d3868..e5d983b1344bf 100644 --- a/sklearn/tree/_tree.pyx +++ b/sklearn/tree/_tree.pyx @@ -155,7 +155,7 @@ cdef class DepthFirstTreeBuilder(TreeBuilder): cdef int init_capacity if tree.max_depth <= 10: - init_capacity = (2 ** (tree.max_depth + 1)) - 1 + init_capacity = (2 ** (tree.max_depth + 1)) - 1 else: init_capacity = 2047