From 963c950b48dc12fd5e29f65cb9b976990fbd0db1 Mon Sep 17 00:00:00 2001 From: ajfriend Date: Sat, 1 Jun 2024 14:17:33 -0700 Subject: [PATCH 01/37] trying a scikit-build-core setup --- pyproject.toml | 55 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index ce6867f8..9fd40f6a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,59 @@ [build-system] requires = [ - 'scikit-build', + 'scikit-build-core', 'cython', 'cmake', ] +build-backend = 'scikit_build_core.build' + + +[project] +name = 'h3' +description = 'Hierarchical hexagonal geospatial indexing system' +readme = 'readme.md' +license = 'Apache 2.0 License' +authors = [ + { name = 'Uber Technologies', email = 'ajfriend@gmail.com' }, +] +maintainers = [ + { name = 'AJ Friend', email = "ajfriend@gmail.com" }, +] +requires-python = '>=3.8' + +dependencies = [] + +classifiers = [ + 'Development Status :: 5 - Production/Stable', + 'Intended Audience :: Developers', + 'Intended Audience :: Science/Research', + 'License :: OSI Approved :: Apache Software License', + 'Programming Language :: C', + 'Programming Language :: Cython', + 'Programming Language :: Python :: 3.8', + 'Programming Language :: Python :: 3.9', + 'Programming Language :: Python :: 3.10', + 'Programming Language :: Python :: 3.11', + 'Programming Language :: Python :: 3.12', + 'Operating System :: MacOS :: MacOS X', + 'Operating System :: POSIX :: Linux', + 'Operating System :: Microsoft :: Windows', + 'Topic :: Scientific/Engineering :: GIS', +] + +[project.urls] +Homepage = "https://github.com/organization/package" +Documentation = "https://package.readthedocs.io/" +"Bug Tracker" = "https://github.com/organization/package/issues" +Discussions = "https://github.com/organization/package/discussions" +Changelog = "https://package.readthedocs.io/en/latest/changelog.html" + + +[project.optional-dependencies] +numpy = ['numpy'] +test = ['pytest', 'pytest-cov', 'flake8', 'pylint'] +all = ['numpy', 'pytest', 'pytest-cov', 'flake8', 'pylint'] +docs = [ + 'jupyter-book', + 'flake8', + 'sphinx>=7.3.3', # https://github.com/sphinx-doc/sphinx/issues/12290 +] From fd6c2f8ef92e18a9c1edba4169bc6a58f3616e0d Mon Sep 17 00:00:00 2001 From: ajfriend Date: Sat, 1 Jun 2024 14:45:14 -0700 Subject: [PATCH 02/37] trying things --- CMakeLists.txt | 9 +++++++-- MANIFEST.in | 24 ------------------------ pyproject.toml | 3 ++- requirements.in | 15 --------------- setup.py | 44 -------------------------------------------- 5 files changed, 9 insertions(+), 86 deletions(-) delete mode 100644 MANIFEST.in delete mode 100644 requirements.in delete mode 100644 setup.py diff --git a/CMakeLists.txt b/CMakeLists.txt index 85ea71cc..541666ac 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,11 +1,16 @@ -cmake_minimum_required(VERSION 3.7.2) +cmake_minimum_required(VERSION 3.15...3.26) -project(h3) +project(${SKBUILD_PROJECT_NAME} LANGUAGES C) set(CMAKE_POSITION_INDEPENDENT_CODE ON) # Always make a release build set(CMAKE_BUILD_TYPE Release) +find_package( + Python + COMPONENTS Interpreter Development.Module + REQUIRED) + # Avoid building tooling we won't need for release # See all options with `cmake -LA` in an `h3/build` directory, # or at https://h3geo.org/docs/next/core-library/compilation-options/ diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index 6ccde1f6..00000000 --- a/MANIFEST.in +++ /dev/null @@ -1,24 +0,0 @@ -# MANIFEST.in commands specified here: -# https://packaging.python.org/en/latest/guides/using-manifest-in/#manifest-in-commands - -include CHANGELOG.md -include CMakeLists.txt -include LICENSE -include makefile -include pyproject.toml -include readme.md -include requirements.in -include setup.py - -graft src/h3/ - -prune src/h3lib/ - -include src/h3lib/LICENSE -include src/h3lib/README.md -include src/h3lib/VERSION -include src/h3lib/CMakeLists.txt - -graft src/h3lib/cmake -graft src/h3lib/src/h3lib -exclude MANIFEST.in diff --git a/pyproject.toml b/pyproject.toml index 9fd40f6a..bac095f8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,9 +9,10 @@ build-backend = 'scikit_build_core.build' [project] name = 'h3' +version = '4.0.0b6' description = 'Hierarchical hexagonal geospatial indexing system' readme = 'readme.md' -license = 'Apache 2.0 License' +license = {file = 'LICENSE'} authors = [ { name = 'Uber Technologies', email = 'ajfriend@gmail.com' }, ] diff --git a/requirements.in b/requirements.in deleted file mode 100644 index dc355b97..00000000 --- a/requirements.in +++ /dev/null @@ -1,15 +0,0 @@ -# Required for pip-compile until -# https://github.com/jazzband/pip-tools/issues/1047 is resolved. -# -# In the meantime, this information is duplicated from -# pyproject.toml - -scikit-build -cython -cmake - -# for docs - -jupyter-book -flake8 -sphinx>=7.3.3 # https://github.com/sphinx-doc/sphinx/issues/12290 diff --git a/setup.py b/setup.py deleted file mode 100644 index 23353b18..00000000 --- a/setup.py +++ /dev/null @@ -1,44 +0,0 @@ -import os -from setuptools import find_packages -from skbuild import setup - -here = os.path.abspath(os.path.dirname(__file__)) - -about = {} -with open(os.path.join(here, 'src', 'h3', '_version.py')) as f: - exec(f.read(), about) - - -def long_desc(): - here = os.path.abspath(os.path.dirname(__file__)) - fname = os.path.join(here, 'readme.md') - with open(fname) as f: - long_description = f.read() - - return long_description - - -setup( - name = 'h3', - version = about['__version__'], - description = about['__description__'], - long_description = long_desc(), - long_description_content_type = 'text/markdown', - license = about['__license__'], - author = about['__author__'], - author_email = about['__author_email__'], - url = about['__url__'], - classifiers = about['__classifiers__'], - include_package_data=True, - packages = find_packages( - 'src', - exclude = ["*.tests", "*.tests.*", "tests.*", "tests"], - ), - package_dir = {'': 'src'}, - cmake_languages = ('C'), - extras_require={ - 'numpy': ['numpy'], - 'test': ['pytest', 'pytest-cov', 'flake8', 'pylint'], - 'all': ['numpy', 'pytest', 'pytest-cov', 'flake8', 'pylint'], - }, -) From 48bd3be28a4f7dcb5f646b4b5bc44fc561ce0d62 Mon Sep 17 00:00:00 2001 From: Isaac Brodsky Date: Fri, 21 Jun 2024 17:02:30 -0500 Subject: [PATCH 03/37] vendor FindCython --- src/h3/_cy/CMakeLists.txt | 10 +- src/h3/_cy/FindCython.cmake | 88 ++++++++++ src/h3/_cy/UseCython.cmake | 330 ++++++++++++++++++++++++++++++++++++ 3 files changed, 424 insertions(+), 4 deletions(-) create mode 100644 src/h3/_cy/FindCython.cmake create mode 100644 src/h3/_cy/UseCython.cmake diff --git a/src/h3/_cy/CMakeLists.txt b/src/h3/_cy/CMakeLists.txt index 5d392d2c..b58748a0 100644 --- a/src/h3/_cy/CMakeLists.txt +++ b/src/h3/_cy/CMakeLists.txt @@ -1,5 +1,7 @@ +list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}) + find_package(Cython MODULE REQUIRED) -find_package(PythonExtensions MODULE REQUIRED) +# find_package(PythonExtensions MODULE REQUIRED) include_directories(${CMAKE_CURRENT_SOURCE_DIR}) @@ -7,9 +9,9 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}) set(CYTHON_ANNOTATE TRUE) macro(add_cython_file filename) - add_cython_target(${filename} C PY3) - add_library(${filename} MODULE ${filename} ${LIB_SOURCE_FILES} ${CONFIGURED_API_HEADER}) - python_extension_module(${filename}) + add_cython_target(${filename} C PY3 OUTPUT_VAR filename_out) + add_library(${filename} MODULE ${filename_out}) + # python_extension_module(${filename}) set_property(TARGET ${filename} PROPERTY C_STANDARD 99) target_link_libraries(${filename} h3) install(TARGETS ${filename} LIBRARY DESTINATION src/h3/_cy) diff --git a/src/h3/_cy/FindCython.cmake b/src/h3/_cy/FindCython.cmake new file mode 100644 index 00000000..c8de1311 --- /dev/null +++ b/src/h3/_cy/FindCython.cmake @@ -0,0 +1,88 @@ +#.rst: +# +# Find ``cython`` executable. +# +# This module will set the following variables in your project: +# +# ``CYTHON_EXECUTABLE`` +# path to the ``cython`` program +# +# ``CYTHON_VERSION`` +# version of ``cython`` +# +# ``CYTHON_FOUND`` +# true if the program was found +# +# For more information on the Cython project, see https://cython.org/. +# +# *Cython is a language that makes writing C extensions for the Python language +# as easy as Python itself.* +# +#============================================================================= +# Copyright 2011 Kitware, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#============================================================================= + +# Use the Cython executable that lives next to the Python executable +# if it is a local installation. +if(Python_EXECUTABLE) + get_filename_component(_python_path ${Python_EXECUTABLE} PATH) +elseif(Python3_EXECUTABLE) + get_filename_component(_python_path ${Python3_EXECUTABLE} PATH) +elseif(DEFINED PYTHON_EXECUTABLE) + get_filename_component(_python_path ${PYTHON_EXECUTABLE} PATH) +endif() + +if(DEFINED _python_path) + find_program(CYTHON_EXECUTABLE + NAMES cython cython.bat cython3 + HINTS ${_python_path} + DOC "path to the cython executable") +else() + find_program(CYTHON_EXECUTABLE + NAMES cython cython.bat cython3 + DOC "path to the cython executable") +endif() + +if(CYTHON_EXECUTABLE) + set(CYTHON_version_command ${CYTHON_EXECUTABLE} --version) + + execute_process(COMMAND ${CYTHON_version_command} + OUTPUT_VARIABLE CYTHON_version_output + ERROR_VARIABLE CYTHON_version_error + RESULT_VARIABLE CYTHON_version_result + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_STRIP_TRAILING_WHITESPACE) + + if(NOT ${CYTHON_version_result} EQUAL 0) + set(_error_msg "Command \"${CYTHON_version_command}\" failed with") + set(_error_msg "${_error_msg} output:\n${CYTHON_version_error}") + message(SEND_ERROR "${_error_msg}") + else() + if("${CYTHON_version_output}" MATCHES "^[Cc]ython version ([^,]+)") + set(CYTHON_VERSION "${CMAKE_MATCH_1}") + else() + if("${CYTHON_version_error}" MATCHES "^[Cc]ython version ([^,]+)") + set(CYTHON_VERSION "${CMAKE_MATCH_1}") + endif() + endif() + endif() +endif() + +include(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(Cython REQUIRED_VARS CYTHON_EXECUTABLE) + +mark_as_advanced(CYTHON_EXECUTABLE) + +include(UseCython) diff --git a/src/h3/_cy/UseCython.cmake b/src/h3/_cy/UseCython.cmake new file mode 100644 index 00000000..21b838e6 --- /dev/null +++ b/src/h3/_cy/UseCython.cmake @@ -0,0 +1,330 @@ +#.rst: +# +# The following functions are defined: +# +# .. cmake:command:: Cython_compile_pyx +# +# Create custom rules to generate the source code for a Python extension module +# using cython. +# +# Cython_compile_pyx( [ ...] +# [TARGET_LANGUAGE C | CXX] +# [LANGUAGE_LEVEL 2 | 3 | 3str] +# [OUTPUT_VAR ]) +# +# Options: +# +# ``TARGET_LANGUAGE [C | CXX]`` +# Force the generation of either a C or C++ file. By default, a C file is +# generated, unless the C language is not enabled for the project; in this +# case, a C++ file is generated by default. +# +# ``LANGUAGE_LEVEL [2 | 3 | 3str]`` +# Force compilation using either Python-2, Python-3 or Python-3str syntax and +# code semantics. +# By default, Python-3str syntax and semantics are used if the major version +# of Python found is 3 and Cython >=3 is used. Otherwise, Python-2 syntax and +# semantics are used. +# Using the Python-3str syntax and semantics means there cython does not assume +# unicode is used by by default for string literals under Python 2 +# +# ``OUTPUT_VAR `` +# Set the variable ```` in the parent scope to the path to the +# generated source file. By default, ```` is used as the output +# variable name. +# +# Defined variables: +# +# ```` +# The path of the generated source file. +# +# Usage example: +# +# .. code-block:: cmake +# +# find_package(Cython) +# +# Cython_compile_pyx(_hello.pyx +# OUTPUT_VAR _hello_source_files +# ) +# +# Python_add_library(_hello +# MODULE ${_hello_source_files} +# WITH_SOABI +# ) +# +# +# .. cmake:command:: add_cython_target +# +# Create a custom rule to generate the source code for a Python extension module +# using cython. +# +# add_cython_target( [] +# [C | CXX] +# [PY2 | PY3] +# [OUTPUT_VAR ]) +# +# ```` is the name of the new target, and ```` +# is the path to a cython source file. Note that, despite the name, no new +# targets are created by this function. Instead, see ``OUTPUT_VAR`` for +# retrieving the path to the generated source for subsequent targets. +# +# If only ```` is provided, and it ends in the ".pyx" extension, then it +# is assumed to be the ````. The name of the input without the +# extension is used as the target name. If only ```` is provided, and it +# does not end in the ".pyx" extension, then the ```` is assumed to +# be ``.pyx``. +# +# The Cython include search path is amended with any entries found in the +# ``INCLUDE_DIRECTORIES`` property of the directory containing the +# ```` file. Use ``include_directories`` to add to the Cython +# include search path. +# +# Options: +# +# ``C | CXX`` +# Force the generation of either a C or C++ file. By default, a C file is +# generated, unless the C language is not enabled for the project; in this +# case, a C++ file is generated by default. +# +# ``PY2 | PY3`` +# Force compilation using either Python-2 or Python-3 syntax and code +# semantics. By default, Python-2 syntax and semantics are used if the major +# version of Python found is 2. Otherwise, Python-3 syntax and semantics are +# used. +# +# ``OUTPUT_VAR `` +# Set the variable ```` in the parent scope to the path to the +# generated source file. By default, ```` is used as the output +# variable name. +# +# Defined variables: +# +# ```` +# The path of the generated source file. +# +# Cache variables that affect the behavior include: +# +# ``CYTHON_ANNOTATE`` +# Whether to create an annotated .html file when compiling. +# +# ``CYTHON_FLAGS`` +# Additional flags to pass to the Cython compiler. +# +# Usage example: +# +# .. code-block:: cmake +# +# find_package(Cython) +# +# # Note: In this case, either one of these arguments may be omitted; their +# # value would have been inferred from that of the other. +# add_cython_target(cy_code cy_code.pyx) +# +# add_library(cy_code MODULE ${cy_code}) +# target_link_libraries(cy_code ...) +# +#============================================================================= +# Copyright 2011 Kitware, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#============================================================================= + + +function(add_cython_target _name) + set(_options C CXX PY2 PY3) + set(_one_value OUTPUT_VAR) + set(_multi_value ) + + cmake_parse_arguments(_args + "${_options}" + "${_one_value}" + "${_multi_value}" + ${ARGN} + ) + + # Configuration options. + set(CYTHON_ANNOTATE OFF + CACHE BOOL "Create an annotated .html file when compiling *.pyx.") + + set(CYTHON_FLAGS "" CACHE STRING + "Extra flags to the cython compiler.") + mark_as_advanced(CYTHON_ANNOTATE CYTHON_FLAGS) + + if(_args_C) + set(_target_language "C") + endif() + if(_args_CXX) + set(_target_language "CXX") + endif() + + if(_args_PY2) + set(_language_level "2") + endif() + if(_args_PY3) + set(_language_level "3") + endif() + + list(GET _args_UNPARSED_ARGUMENTS 0 _arg0) + + # if provided, use _arg0 as the input file path + if(_arg0) + set(_source_file ${_arg0}) + + # otherwise, must determine source file from name, or vice versa + else() + get_filename_component(_name_ext "${_name}" EXT) + + # if extension provided, _name is the source file + if(_name_ext) + set(_source_file ${_name}) + get_filename_component(_name "${_source_file}" NAME_WE) + + # otherwise, assume the source file is ${_name}.pyx + else() + set(_source_file ${_name}.pyx) + endif() + endif() + + # Set additional flags. + set(_cython_args) + if(CYTHON_ANNOTATE) + list(APPEND _cython_args "--annotate") + endif() + if(CMAKE_BUILD_TYPE STREQUAL "Debug" OR + CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo") + list(APPEND _cython_args + "--gdb" + "--line-directives" + ) + endif() + string(STRIP "${CYTHON_FLAGS}" _stripped_cython_flags) + if(_stripped_cython_flags) + string(REGEX REPLACE " " ";" CYTHON_FLAGS_LIST "${_stripped_cython_flags}") + list(APPEND _cython_args ${CYTHON_FLAGS_LIST}) + endif() + + Cython_compile_pyx( + TARGET_LANGUAGE ${_target_language} + LANGUAGE_LEVEL ${_language_level} + CYTHON_ARGS ${_cython_args} + OUTPUT_VAR ${_args_OUTPUT_VAR} + ${_source_file} + ) + + if(_args_OUTPUT_VAR) + set(${_args_OUTPUT_VAR} ${${_args_OUTPUT_VAR}} PARENT_SCOPE) + endif() +endfunction() + +function(Cython_compile_pyx) + set(_options ) + set(_one_value LANGUAGE_LEVEL TARGET_LANGUAGE OUTPUT_VAR) + set(_multi_value CYTHON_ARGS) + + cmake_parse_arguments(_args + "${_options}" + "${_one_value}" + "${_multi_value}" + ${ARGN} + ) + + # Get source file location + set(_source_files ${_args_UNPARSED_ARGUMENTS}) + + # Set target language + get_property(_languages GLOBAL PROPERTY ENABLED_LANGUAGES) + set(_target_language ${_args_TARGET_LANGUAGE}) + if(NOT _target_language) + if("C" IN_LIST _languages) + set(_target_language "C") + elseif("CXX" IN_LIST _languages) + set(_target_language "CXX") + endif() + else() + if(NOT _target_language MATCHES "^(C|CXX)$") + message(FATAL_ERROR "TARGET_LANGUAGE must be one of C or CXX") + endif() + endif() + + set(_target_language_C_arg "") + set(_target_language_C_extension "c") + set(_target_language_CXX_arg "--cplus") + set(_target_language_CXX_extension "cxx") + + set(_target_language_arg ${_target_language_${_target_language}_arg}) + set(_target_language_extension ${_target_language_${_target_language}_extension}) + + # Set language level + set(_language_level ${_args_LANGUAGE_LEVEL}) + if(NOT _args_LANGUAGE_LEVEL) + set(_language_level "3str") + else() + if(NOT _language_level MATCHES "^(2|3|3str)$") + message(FATAL_ERROR "LANGUAGE_LEVEL must be one of 2, 3, or 3str") + endif() + endif() + + set(_language_level_2_arg "-2") + set(_language_level_3_arg "-3") + set(_language_level_3str_arg "--3str") + + set(_language_level_arg "${_language_level_${_language_level}_arg}") + + # Generated depfile is expected to have the ".dep" extension and be located along + # side the generated source file. + set(_depfile ${generated_file}.dep) + set(_depfile_arg "-M") + + set(generated_files) + + foreach(_source_file IN LISTS _source_files) + cmake_path(GET _source_file STEM _name) + set(generated_file "${CMAKE_CURRENT_BINARY_DIR}/${_name}.${_target_language_extension}") + set_source_files_properties(${generated_file} PROPERTIES GENERATED TRUE) + + file(RELATIVE_PATH generated_file_relative + ${CMAKE_BINARY_DIR} ${generated_file}) + + set(comment "Generating ${_target_language} source ${generated_file_relative}") + + get_source_file_property(pyx_location ${_source_file} LOCATION) + + # Add the command to run the compiler. + add_custom_command( + OUTPUT ${generated_file} + COMMAND ${CYTHON_EXECUTABLE} + ARGS + ${_target_language_arg} + ${_language_level_arg} + ${_args_CYTHON_ARGS} + ${_depfile_arg} + ${pyx_location} + --output-file ${generated_file} + DEPENDS + ${_source_file} + DEPFILE + ${_cython_depfile} + VERBATIM + COMMENT ${comment} + ) + list(APPEND generated_files ${generated_file}) + endforeach() + + if(_args_OUTPUT_VAR) + set(_output_var ${_args_OUTPUT_VAR}) + set(${_output_var} ${generated_files} PARENT_SCOPE) + endif() + +endfunction() + From a9e972961ccd9fcca68f8ecbeb99edfb3e69126e Mon Sep 17 00:00:00 2001 From: Isaac Brodsky Date: Fri, 21 Jun 2024 17:19:04 -0500 Subject: [PATCH 04/37] fix build --- makefile | 1 - src/h3/_cy/CMakeLists.txt | 24 ++++++++++++++++-------- src/h3/_version.py | 2 +- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/makefile b/makefile index 629caa7f..2c94df18 100644 --- a/makefile +++ b/makefile @@ -15,7 +15,6 @@ init: purge $(PYTHON) -m venv env ./env/bin/pip install --upgrade pip wheel setuptools ./env/bin/pip install .[all] - ./env/bin/pip install -r requirements.in clear: -./env/bin/pip uninstall -y h3 diff --git a/src/h3/_cy/CMakeLists.txt b/src/h3/_cy/CMakeLists.txt index b58748a0..86231637 100644 --- a/src/h3/_cy/CMakeLists.txt +++ b/src/h3/_cy/CMakeLists.txt @@ -1,20 +1,28 @@ list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}) -find_package(Cython MODULE REQUIRED) +# find_package(Cython MODULE REQUIRED) # find_package(PythonExtensions MODULE REQUIRED) include_directories(${CMAKE_CURRENT_SOURCE_DIR}) # Build Cython annotations -set(CYTHON_ANNOTATE TRUE) +# set(CYTHON_ANNOTATE TRUE) macro(add_cython_file filename) - add_cython_target(${filename} C PY3 OUTPUT_VAR filename_out) - add_library(${filename} MODULE ${filename_out}) - # python_extension_module(${filename}) + add_custom_command( + OUTPUT "${filename}.c" + COMMENT + "Making ${CMAKE_CURRENT_BINARY_DIR}/${filename}.c from ${CMAKE_CURRENT_SOURCE_DIR}/${filename}.pyx" + COMMAND Python::Interpreter -m cython + "${CMAKE_CURRENT_SOURCE_DIR}/${filename}.pyx" --output-file "${filename}.c" -I ${CMAKE_CURRENT_SOURCE_DIR} + DEPENDS "${filename}.pyx" + VERBATIM) + + python_add_library(${filename} MODULE "${filename}.c" WITH_SOABI) + set_property(TARGET ${filename} PROPERTY C_STANDARD 99) - target_link_libraries(${filename} h3) - install(TARGETS ${filename} LIBRARY DESTINATION src/h3/_cy) + target_link_libraries(${filename} PRIVATE h3) + install(TARGETS ${filename} LIBRARY DESTINATION ${SKBUILD_PROJECT_NAME}/_cy) endmacro() # GLOB pattern is recommended against @@ -44,5 +52,5 @@ install( memory.pxd memory.pyx DESTINATION - src/h3/_cy + ${SKBUILD_PROJECT_NAME}/_cy ) diff --git a/src/h3/_version.py b/src/h3/_version.py index d1d952c9..41bf4d04 100644 --- a/src/h3/_version.py +++ b/src/h3/_version.py @@ -1,4 +1,4 @@ -__version__ = '4.0.0b5' +__version__ = '4.0.0b6' __description__ = 'Hierarchical hexagonal geospatial indexing system' __url__ = 'https://github.com/uber/h3-py' __license__ = 'Apache 2.0 License' From c5394a1e2539a2184324d67b691c9d5188db117b Mon Sep 17 00:00:00 2001 From: Isaac Brodsky Date: Fri, 21 Jun 2024 17:19:55 -0500 Subject: [PATCH 05/37] remove unused --- src/h3/_cy/CMakeLists.txt | 6 - src/h3/_cy/FindCython.cmake | 88 ---------- src/h3/_cy/UseCython.cmake | 330 ------------------------------------ 3 files changed, 424 deletions(-) delete mode 100644 src/h3/_cy/FindCython.cmake delete mode 100644 src/h3/_cy/UseCython.cmake diff --git a/src/h3/_cy/CMakeLists.txt b/src/h3/_cy/CMakeLists.txt index 86231637..68d63619 100644 --- a/src/h3/_cy/CMakeLists.txt +++ b/src/h3/_cy/CMakeLists.txt @@ -1,13 +1,7 @@ list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}) -# find_package(Cython MODULE REQUIRED) -# find_package(PythonExtensions MODULE REQUIRED) - include_directories(${CMAKE_CURRENT_SOURCE_DIR}) -# Build Cython annotations -# set(CYTHON_ANNOTATE TRUE) - macro(add_cython_file filename) add_custom_command( OUTPUT "${filename}.c" diff --git a/src/h3/_cy/FindCython.cmake b/src/h3/_cy/FindCython.cmake deleted file mode 100644 index c8de1311..00000000 --- a/src/h3/_cy/FindCython.cmake +++ /dev/null @@ -1,88 +0,0 @@ -#.rst: -# -# Find ``cython`` executable. -# -# This module will set the following variables in your project: -# -# ``CYTHON_EXECUTABLE`` -# path to the ``cython`` program -# -# ``CYTHON_VERSION`` -# version of ``cython`` -# -# ``CYTHON_FOUND`` -# true if the program was found -# -# For more information on the Cython project, see https://cython.org/. -# -# *Cython is a language that makes writing C extensions for the Python language -# as easy as Python itself.* -# -#============================================================================= -# Copyright 2011 Kitware, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -#============================================================================= - -# Use the Cython executable that lives next to the Python executable -# if it is a local installation. -if(Python_EXECUTABLE) - get_filename_component(_python_path ${Python_EXECUTABLE} PATH) -elseif(Python3_EXECUTABLE) - get_filename_component(_python_path ${Python3_EXECUTABLE} PATH) -elseif(DEFINED PYTHON_EXECUTABLE) - get_filename_component(_python_path ${PYTHON_EXECUTABLE} PATH) -endif() - -if(DEFINED _python_path) - find_program(CYTHON_EXECUTABLE - NAMES cython cython.bat cython3 - HINTS ${_python_path} - DOC "path to the cython executable") -else() - find_program(CYTHON_EXECUTABLE - NAMES cython cython.bat cython3 - DOC "path to the cython executable") -endif() - -if(CYTHON_EXECUTABLE) - set(CYTHON_version_command ${CYTHON_EXECUTABLE} --version) - - execute_process(COMMAND ${CYTHON_version_command} - OUTPUT_VARIABLE CYTHON_version_output - ERROR_VARIABLE CYTHON_version_error - RESULT_VARIABLE CYTHON_version_result - OUTPUT_STRIP_TRAILING_WHITESPACE - ERROR_STRIP_TRAILING_WHITESPACE) - - if(NOT ${CYTHON_version_result} EQUAL 0) - set(_error_msg "Command \"${CYTHON_version_command}\" failed with") - set(_error_msg "${_error_msg} output:\n${CYTHON_version_error}") - message(SEND_ERROR "${_error_msg}") - else() - if("${CYTHON_version_output}" MATCHES "^[Cc]ython version ([^,]+)") - set(CYTHON_VERSION "${CMAKE_MATCH_1}") - else() - if("${CYTHON_version_error}" MATCHES "^[Cc]ython version ([^,]+)") - set(CYTHON_VERSION "${CMAKE_MATCH_1}") - endif() - endif() - endif() -endif() - -include(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(Cython REQUIRED_VARS CYTHON_EXECUTABLE) - -mark_as_advanced(CYTHON_EXECUTABLE) - -include(UseCython) diff --git a/src/h3/_cy/UseCython.cmake b/src/h3/_cy/UseCython.cmake deleted file mode 100644 index 21b838e6..00000000 --- a/src/h3/_cy/UseCython.cmake +++ /dev/null @@ -1,330 +0,0 @@ -#.rst: -# -# The following functions are defined: -# -# .. cmake:command:: Cython_compile_pyx -# -# Create custom rules to generate the source code for a Python extension module -# using cython. -# -# Cython_compile_pyx( [ ...] -# [TARGET_LANGUAGE C | CXX] -# [LANGUAGE_LEVEL 2 | 3 | 3str] -# [OUTPUT_VAR ]) -# -# Options: -# -# ``TARGET_LANGUAGE [C | CXX]`` -# Force the generation of either a C or C++ file. By default, a C file is -# generated, unless the C language is not enabled for the project; in this -# case, a C++ file is generated by default. -# -# ``LANGUAGE_LEVEL [2 | 3 | 3str]`` -# Force compilation using either Python-2, Python-3 or Python-3str syntax and -# code semantics. -# By default, Python-3str syntax and semantics are used if the major version -# of Python found is 3 and Cython >=3 is used. Otherwise, Python-2 syntax and -# semantics are used. -# Using the Python-3str syntax and semantics means there cython does not assume -# unicode is used by by default for string literals under Python 2 -# -# ``OUTPUT_VAR `` -# Set the variable ```` in the parent scope to the path to the -# generated source file. By default, ```` is used as the output -# variable name. -# -# Defined variables: -# -# ```` -# The path of the generated source file. -# -# Usage example: -# -# .. code-block:: cmake -# -# find_package(Cython) -# -# Cython_compile_pyx(_hello.pyx -# OUTPUT_VAR _hello_source_files -# ) -# -# Python_add_library(_hello -# MODULE ${_hello_source_files} -# WITH_SOABI -# ) -# -# -# .. cmake:command:: add_cython_target -# -# Create a custom rule to generate the source code for a Python extension module -# using cython. -# -# add_cython_target( [] -# [C | CXX] -# [PY2 | PY3] -# [OUTPUT_VAR ]) -# -# ```` is the name of the new target, and ```` -# is the path to a cython source file. Note that, despite the name, no new -# targets are created by this function. Instead, see ``OUTPUT_VAR`` for -# retrieving the path to the generated source for subsequent targets. -# -# If only ```` is provided, and it ends in the ".pyx" extension, then it -# is assumed to be the ````. The name of the input without the -# extension is used as the target name. If only ```` is provided, and it -# does not end in the ".pyx" extension, then the ```` is assumed to -# be ``.pyx``. -# -# The Cython include search path is amended with any entries found in the -# ``INCLUDE_DIRECTORIES`` property of the directory containing the -# ```` file. Use ``include_directories`` to add to the Cython -# include search path. -# -# Options: -# -# ``C | CXX`` -# Force the generation of either a C or C++ file. By default, a C file is -# generated, unless the C language is not enabled for the project; in this -# case, a C++ file is generated by default. -# -# ``PY2 | PY3`` -# Force compilation using either Python-2 or Python-3 syntax and code -# semantics. By default, Python-2 syntax and semantics are used if the major -# version of Python found is 2. Otherwise, Python-3 syntax and semantics are -# used. -# -# ``OUTPUT_VAR `` -# Set the variable ```` in the parent scope to the path to the -# generated source file. By default, ```` is used as the output -# variable name. -# -# Defined variables: -# -# ```` -# The path of the generated source file. -# -# Cache variables that affect the behavior include: -# -# ``CYTHON_ANNOTATE`` -# Whether to create an annotated .html file when compiling. -# -# ``CYTHON_FLAGS`` -# Additional flags to pass to the Cython compiler. -# -# Usage example: -# -# .. code-block:: cmake -# -# find_package(Cython) -# -# # Note: In this case, either one of these arguments may be omitted; their -# # value would have been inferred from that of the other. -# add_cython_target(cy_code cy_code.pyx) -# -# add_library(cy_code MODULE ${cy_code}) -# target_link_libraries(cy_code ...) -# -#============================================================================= -# Copyright 2011 Kitware, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -#============================================================================= - - -function(add_cython_target _name) - set(_options C CXX PY2 PY3) - set(_one_value OUTPUT_VAR) - set(_multi_value ) - - cmake_parse_arguments(_args - "${_options}" - "${_one_value}" - "${_multi_value}" - ${ARGN} - ) - - # Configuration options. - set(CYTHON_ANNOTATE OFF - CACHE BOOL "Create an annotated .html file when compiling *.pyx.") - - set(CYTHON_FLAGS "" CACHE STRING - "Extra flags to the cython compiler.") - mark_as_advanced(CYTHON_ANNOTATE CYTHON_FLAGS) - - if(_args_C) - set(_target_language "C") - endif() - if(_args_CXX) - set(_target_language "CXX") - endif() - - if(_args_PY2) - set(_language_level "2") - endif() - if(_args_PY3) - set(_language_level "3") - endif() - - list(GET _args_UNPARSED_ARGUMENTS 0 _arg0) - - # if provided, use _arg0 as the input file path - if(_arg0) - set(_source_file ${_arg0}) - - # otherwise, must determine source file from name, or vice versa - else() - get_filename_component(_name_ext "${_name}" EXT) - - # if extension provided, _name is the source file - if(_name_ext) - set(_source_file ${_name}) - get_filename_component(_name "${_source_file}" NAME_WE) - - # otherwise, assume the source file is ${_name}.pyx - else() - set(_source_file ${_name}.pyx) - endif() - endif() - - # Set additional flags. - set(_cython_args) - if(CYTHON_ANNOTATE) - list(APPEND _cython_args "--annotate") - endif() - if(CMAKE_BUILD_TYPE STREQUAL "Debug" OR - CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo") - list(APPEND _cython_args - "--gdb" - "--line-directives" - ) - endif() - string(STRIP "${CYTHON_FLAGS}" _stripped_cython_flags) - if(_stripped_cython_flags) - string(REGEX REPLACE " " ";" CYTHON_FLAGS_LIST "${_stripped_cython_flags}") - list(APPEND _cython_args ${CYTHON_FLAGS_LIST}) - endif() - - Cython_compile_pyx( - TARGET_LANGUAGE ${_target_language} - LANGUAGE_LEVEL ${_language_level} - CYTHON_ARGS ${_cython_args} - OUTPUT_VAR ${_args_OUTPUT_VAR} - ${_source_file} - ) - - if(_args_OUTPUT_VAR) - set(${_args_OUTPUT_VAR} ${${_args_OUTPUT_VAR}} PARENT_SCOPE) - endif() -endfunction() - -function(Cython_compile_pyx) - set(_options ) - set(_one_value LANGUAGE_LEVEL TARGET_LANGUAGE OUTPUT_VAR) - set(_multi_value CYTHON_ARGS) - - cmake_parse_arguments(_args - "${_options}" - "${_one_value}" - "${_multi_value}" - ${ARGN} - ) - - # Get source file location - set(_source_files ${_args_UNPARSED_ARGUMENTS}) - - # Set target language - get_property(_languages GLOBAL PROPERTY ENABLED_LANGUAGES) - set(_target_language ${_args_TARGET_LANGUAGE}) - if(NOT _target_language) - if("C" IN_LIST _languages) - set(_target_language "C") - elseif("CXX" IN_LIST _languages) - set(_target_language "CXX") - endif() - else() - if(NOT _target_language MATCHES "^(C|CXX)$") - message(FATAL_ERROR "TARGET_LANGUAGE must be one of C or CXX") - endif() - endif() - - set(_target_language_C_arg "") - set(_target_language_C_extension "c") - set(_target_language_CXX_arg "--cplus") - set(_target_language_CXX_extension "cxx") - - set(_target_language_arg ${_target_language_${_target_language}_arg}) - set(_target_language_extension ${_target_language_${_target_language}_extension}) - - # Set language level - set(_language_level ${_args_LANGUAGE_LEVEL}) - if(NOT _args_LANGUAGE_LEVEL) - set(_language_level "3str") - else() - if(NOT _language_level MATCHES "^(2|3|3str)$") - message(FATAL_ERROR "LANGUAGE_LEVEL must be one of 2, 3, or 3str") - endif() - endif() - - set(_language_level_2_arg "-2") - set(_language_level_3_arg "-3") - set(_language_level_3str_arg "--3str") - - set(_language_level_arg "${_language_level_${_language_level}_arg}") - - # Generated depfile is expected to have the ".dep" extension and be located along - # side the generated source file. - set(_depfile ${generated_file}.dep) - set(_depfile_arg "-M") - - set(generated_files) - - foreach(_source_file IN LISTS _source_files) - cmake_path(GET _source_file STEM _name) - set(generated_file "${CMAKE_CURRENT_BINARY_DIR}/${_name}.${_target_language_extension}") - set_source_files_properties(${generated_file} PROPERTIES GENERATED TRUE) - - file(RELATIVE_PATH generated_file_relative - ${CMAKE_BINARY_DIR} ${generated_file}) - - set(comment "Generating ${_target_language} source ${generated_file_relative}") - - get_source_file_property(pyx_location ${_source_file} LOCATION) - - # Add the command to run the compiler. - add_custom_command( - OUTPUT ${generated_file} - COMMAND ${CYTHON_EXECUTABLE} - ARGS - ${_target_language_arg} - ${_language_level_arg} - ${_args_CYTHON_ARGS} - ${_depfile_arg} - ${pyx_location} - --output-file ${generated_file} - DEPENDS - ${_source_file} - DEPFILE - ${_cython_depfile} - VERBATIM - COMMENT ${comment} - ) - list(APPEND generated_files ${generated_file}) - endforeach() - - if(_args_OUTPUT_VAR) - set(_output_var ${_args_OUTPUT_VAR}) - set(${_output_var} ${generated_files} PARENT_SCOPE) - endif() - -endfunction() - From a14ee96b18cc3fa59eb6a52e32155c5afc833096 Mon Sep 17 00:00:00 2001 From: ajfriend Date: Fri, 21 Jun 2024 16:40:36 -0700 Subject: [PATCH 06/37] cython tests working --- .github/workflows/tests.yml | 4 ++-- CMakeLists.txt | 2 +- makefile | 5 +++-- pyproject.toml | 4 ++-- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index ee175036..22a98d78 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -43,6 +43,6 @@ jobs: - name: Tests run: | - pip install Cython - cythonize -i tests/test_cython/cython_example.pyx + pip install cython + cythonize tests/test_cython/cython_example.pyx pytest tests --cov=h3 --full-trace diff --git a/CMakeLists.txt b/CMakeLists.txt index 541666ac..40ce38e1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,4 +42,4 @@ install( FILES "${CMAKE_CURRENT_BINARY_DIR}/src/h3lib/src/h3lib/include/h3api.h" DESTINATION - src/h3/_cy) + ${SKBUILD_PROJECT_NAME}/_cy) diff --git a/makefile b/makefile index 2c94df18..1e3271c7 100644 --- a/makefile +++ b/makefile @@ -39,11 +39,12 @@ annotations: rebuild cp _skbuild/*/cmake-build/src/h3/_cy/*.html ./annotations test: - ./env/bin/cythonize -i tests/test_cython/cython_example.pyx + ./env/bin/pip install cython + ./env/bin/cythonize tests/test_cython/cython_example.pyx ./env/bin/pytest tests --cov=h3 --cov-report term-missing --durations=10 lint: - ./env/bin/flake8 src/h3 setup.py tests + ./env/bin/flake8 src/h3 tests ./env/bin/pylint --disable=all --enable=import-error tests/ lab: diff --git a/pyproject.toml b/pyproject.toml index bac095f8..8392d099 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -50,9 +50,9 @@ Changelog = "https://package.readthedocs.io/en/latest/changelog.html" [project.optional-dependencies] -numpy = ['numpy'] +numpy = ['numpy<2'] test = ['pytest', 'pytest-cov', 'flake8', 'pylint'] -all = ['numpy', 'pytest', 'pytest-cov', 'flake8', 'pylint'] +all = ['numpy<2', 'pytest', 'pytest-cov', 'flake8', 'pylint'] docs = [ 'jupyter-book', 'flake8', From 957cbed341a755bc7908765908baa3daec43f73c Mon Sep 17 00:00:00 2001 From: ajfriend Date: Fri, 21 Jun 2024 16:45:44 -0700 Subject: [PATCH 07/37] fix lint action --- .github/workflows/coverage-lint.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/coverage-lint.yml b/.github/workflows/coverage-lint.yml index 24ec82e1..e1860566 100644 --- a/.github/workflows/coverage-lint.yml +++ b/.github/workflows/coverage-lint.yml @@ -26,7 +26,7 @@ jobs: pip install .[all] - name: Lint - run: flake8 src/h3 setup.py tests + run: flake8 src/h3 tests - name: Pylint # As a test for visibility of API bindings, we want to ensure that pylint has no From 71d636b66379a67b646a16465807410b90e703cb Mon Sep 17 00:00:00 2001 From: ajfriend Date: Fri, 21 Jun 2024 16:47:43 -0700 Subject: [PATCH 08/37] coverage fix --- .github/workflows/coverage-lint.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/coverage-lint.yml b/.github/workflows/coverage-lint.yml index e1860566..aa13519e 100644 --- a/.github/workflows/coverage-lint.yml +++ b/.github/workflows/coverage-lint.yml @@ -35,8 +35,8 @@ jobs: - name: Coverage run: | - pip install Cython - cythonize -i tests/test_cython/cython_example.pyx + pip install cython + cythonize tests/test_cython/cython_example.pyx pytest --cov=h3 --full-trace --cov-report=xml - name: Upload coverage to Codecov From f8fd3d0744177a003b76816ae1bf11164b75ce34 Mon Sep 17 00:00:00 2001 From: ajfriend Date: Fri, 21 Jun 2024 18:35:23 -0700 Subject: [PATCH 09/37] drop annotation stuff for now, because i can't get it working --- .github/workflows/coverage-lint.yml | 11 ----------- makefile | 6 +----- 2 files changed, 1 insertion(+), 16 deletions(-) diff --git a/.github/workflows/coverage-lint.yml b/.github/workflows/coverage-lint.yml index aa13519e..3d95817b 100644 --- a/.github/workflows/coverage-lint.yml +++ b/.github/workflows/coverage-lint.yml @@ -45,14 +45,3 @@ jobs: file: ./coverage.xml fail_ci_if_error: true token: ${{ secrets.CODECOV_TOKEN }} - - - name: Copy Cython annotations to project dir - run: | - mkdir annotations - cp _skbuild/*/cmake-build/src/h3/_cy/*.html ./annotations - - - name: Upload artifacts to GitHub - uses: actions/upload-artifact@v4.3.1 - with: - name: annotations - path: ./annotations diff --git a/makefile b/makefile index 1e3271c7..8e12c576 100644 --- a/makefile +++ b/makefile @@ -19,7 +19,6 @@ init: purge clear: -./env/bin/pip uninstall -y h3 -@rm -rf MANIFEST - -@rm -rf annotations -@rm -rf .pytest_cache _skbuild dist .coverage build docs/_build -@find . -type d -name '__pycache__' | xargs rm -r -@find . -type d -name '*.egg-info' | xargs rm -r @@ -27,6 +26,7 @@ clear: -@find . -type f -name '*.so' | xargs rm -r -@find . -type d -name '*.ipynb_checkpoints' | xargs rm -r -@find ./tests -type f -name '*.c' | xargs rm -r + -@find ./tests -type f -name '*.html' | xargs rm -r rebuild: clear ./env/bin/pip install .[all] @@ -34,10 +34,6 @@ rebuild: clear purge: clear -@rm -rf env -annotations: rebuild - mkdir -p annotations - cp _skbuild/*/cmake-build/src/h3/_cy/*.html ./annotations - test: ./env/bin/pip install cython ./env/bin/cythonize tests/test_cython/cython_example.pyx From 9cd175fb39358e957ef2900f70ee3a7bf92c472a Mon Sep 17 00:00:00 2001 From: ajfriend Date: Fri, 21 Jun 2024 18:37:56 -0700 Subject: [PATCH 10/37] book building --- .github/workflows/build_docs.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/build_docs.yml b/.github/workflows/build_docs.yml index 0ad48bab..b30bd410 100644 --- a/.github/workflows/build_docs.yml +++ b/.github/workflows/build_docs.yml @@ -22,7 +22,6 @@ jobs: - name: Install dependencies run: | pip install --upgrade pip setuptools wheel - pip install -r requirements.in pip install -r requirements-dev.txt pip install .[all] From 073db04cf7c2ec45501b1e7df9f91c308b119110 Mon Sep 17 00:00:00 2001 From: ajfriend Date: Fri, 21 Jun 2024 18:45:17 -0700 Subject: [PATCH 11/37] all target --- pyproject.toml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 8392d099..4b7043cb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -52,9 +52,18 @@ Changelog = "https://package.readthedocs.io/en/latest/changelog.html" [project.optional-dependencies] numpy = ['numpy<2'] test = ['pytest', 'pytest-cov', 'flake8', 'pylint'] -all = ['numpy<2', 'pytest', 'pytest-cov', 'flake8', 'pylint'] docs = [ 'jupyter-book', 'flake8', 'sphinx>=7.3.3', # https://github.com/sphinx-doc/sphinx/issues/12290 ] +all = [ + 'numpy<2', + 'pytest', + 'pytest-cov', + 'flake8', + 'pylint', + 'jupyter-book', + 'sphinx>=7.3.3', # https://github.com/sphinx-doc/sphinx/issues/12290 +] + From 8645c63838e494d9886aa7cda04315eedc68df0b Mon Sep 17 00:00:00 2001 From: ajfriend Date: Fri, 21 Jun 2024 18:49:38 -0700 Subject: [PATCH 12/37] try again --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 4b7043cb..ee77b918 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -64,6 +64,6 @@ all = [ 'flake8', 'pylint', 'jupyter-book', - 'sphinx>=7.3.3', # https://github.com/sphinx-doc/sphinx/issues/12290 + 'sphinx>=7.3.3', ] From dc65bbc6f9cf18839ca4be4688d8bf844ff105f7 Mon Sep 17 00:00:00 2001 From: ajfriend Date: Fri, 21 Jun 2024 18:54:12 -0700 Subject: [PATCH 13/37] don't install all --- .github/workflows/coverage-lint.yml | 2 +- .github/workflows/tests.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/coverage-lint.yml b/.github/workflows/coverage-lint.yml index 3d95817b..ca4f8321 100644 --- a/.github/workflows/coverage-lint.yml +++ b/.github/workflows/coverage-lint.yml @@ -23,7 +23,7 @@ jobs: - name: Install from source run: | pip install --upgrade pip setuptools wheel - pip install .[all] + pip install .[test] - name: Lint run: flake8 src/h3 tests diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 22a98d78..e56d4d25 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -39,7 +39,7 @@ jobs: - name: Install from source run: | pip install --upgrade pip setuptools wheel - pip install .[all] + pip install .[test] - name: Tests run: | From 4d5c66b7f5bdb587a1d55bf83bf93ee5b38ee3ed Mon Sep 17 00:00:00 2001 From: ajfriend Date: Fri, 21 Jun 2024 19:52:53 -0700 Subject: [PATCH 14/37] numpy! --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index ee77b918..750ae982 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -51,7 +51,7 @@ Changelog = "https://package.readthedocs.io/en/latest/changelog.html" [project.optional-dependencies] numpy = ['numpy<2'] -test = ['pytest', 'pytest-cov', 'flake8', 'pylint'] +test = ['pytest', 'pytest-cov', 'flake8', 'pylint', 'numpy<2'] docs = [ 'jupyter-book', 'flake8', From a0d58b7c64db1b72473c296287decb9c779f9469 Mon Sep 17 00:00:00 2001 From: ajfriend Date: Fri, 21 Jun 2024 20:00:45 -0700 Subject: [PATCH 15/37] pip install h3.tar.gz[test] --- .github/workflows/wheels.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/wheels.yml b/.github/workflows/wheels.yml index 8df9ed80..9685abe6 100644 --- a/.github/workflows/wheels.yml +++ b/.github/workflows/wheels.yml @@ -43,7 +43,7 @@ jobs: pip install --upgrade pip setuptools wheel pip install pytest cp dist/h3-*.tar.gz h3.tar.gz - pip install h3.tar.gz[all] + pip install h3.tar.gz[test] - name: Test sdist run: pytest --cov=h3 --full-trace From 325aa09987a53ef5414ea513084db62aab414fd8 Mon Sep 17 00:00:00 2001 From: ajfriend Date: Fri, 21 Jun 2024 20:03:50 -0700 Subject: [PATCH 16/37] drop wheel builds for 3.6 and 3.7 --- .github/workflows/wheels.yml | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/.github/workflows/wheels.yml b/.github/workflows/wheels.yml index 9685abe6..f08e7c26 100644 --- a/.github/workflows/wheels.yml +++ b/.github/workflows/wheels.yml @@ -76,12 +76,6 @@ jobs: build: 'cp*-manylinux_x86_64' name: Linux Intel glibc 64-bit - - os: ubuntu-22.04 - build: 'cp36-musllinux_x86_64' - name: Linux Intel musl 64-bit 3.6 - - os: ubuntu-22.04 - build: 'cp37-musllinux_x86_64' - name: Linux Intel musl 64-bit 3.7 - os: ubuntu-22.04 build: 'cp38-musllinux_x86_64' name: Linux Intel musl 64-bit 3.8 @@ -98,12 +92,6 @@ jobs: build: 'cp312-musllinux_x86_64' name: Linux Intel musl 64-bit 3.12 - - os: ubuntu-22.04 - build: 'cp36-manylinux_aarch64' - name: Linux Aarch64 3.6 - - os: ubuntu-22.04 - build: 'cp37-manylinux_aarch64' - name: Linux Aarch64 3.7 - os: ubuntu-22.04 build: 'cp38-manylinux_aarch64' name: Linux Aarch64 3.8 From ef436ce816a110c67849fa95eb290e05d6be46f8 Mon Sep 17 00:00:00 2001 From: ajfriend Date: Sat, 22 Jun 2024 09:30:29 -0700 Subject: [PATCH 17/37] move coverage config to pyproject.toml --- .coveragerc | 5 ----- pyproject.toml | 18 ++++++++++++------ 2 files changed, 12 insertions(+), 11 deletions(-) delete mode 100644 .coveragerc diff --git a/.coveragerc b/.coveragerc deleted file mode 100644 index 662935de..00000000 --- a/.coveragerc +++ /dev/null @@ -1,5 +0,0 @@ -[run] -omit = - */h3/api/basic_int/__init__.py - */h3/api/memview_int/__init__.py - */h3/api/numpy_int/__init__.py diff --git a/pyproject.toml b/pyproject.toml index 750ae982..94d998bb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,7 +17,7 @@ authors = [ { name = 'Uber Technologies', email = 'ajfriend@gmail.com' }, ] maintainers = [ - { name = 'AJ Friend', email = "ajfriend@gmail.com" }, + { name = 'AJ Friend', email = 'ajfriend@gmail.com' }, ] requires-python = '>=3.8' @@ -42,11 +42,11 @@ classifiers = [ ] [project.urls] -Homepage = "https://github.com/organization/package" -Documentation = "https://package.readthedocs.io/" -"Bug Tracker" = "https://github.com/organization/package/issues" -Discussions = "https://github.com/organization/package/discussions" -Changelog = "https://package.readthedocs.io/en/latest/changelog.html" +Homepage = 'https://github.com/organization/package' +Documentation = 'https://package.readthedocs.io/' +'Bug Tracker' = 'https://github.com/organization/package/issues' +Discussions = 'https://github.com/organization/package/discussions' +Changelog = 'https://package.readthedocs.io/en/latest/changelog.html' [project.optional-dependencies] @@ -67,3 +67,9 @@ all = [ 'sphinx>=7.3.3', ] +[tool.coverage.run] +omit = [ + '*/h3/api/basic_int/__init__.py', + '*/h3/api/memview_int/__init__.py', + '*/h3/api/numpy_int/__init__.py' +] From 5ffa5569ff05fa259dad923e02100211ffd198e2 Mon Sep 17 00:00:00 2001 From: ajfriend Date: Sat, 22 Jun 2024 10:17:51 -0700 Subject: [PATCH 18/37] remove requirements-dev.txt --- .github/workflows/build_docs.yml | 1 - makefile | 10 +++++----- pyproject.toml | 15 +++++++++------ requirements-dev.txt | 8 -------- 4 files changed, 14 insertions(+), 20 deletions(-) delete mode 100644 requirements-dev.txt diff --git a/.github/workflows/build_docs.yml b/.github/workflows/build_docs.yml index b30bd410..328dc449 100644 --- a/.github/workflows/build_docs.yml +++ b/.github/workflows/build_docs.yml @@ -22,7 +22,6 @@ jobs: - name: Install dependencies run: | pip install --upgrade pip setuptools wheel - pip install -r requirements-dev.txt pip install .[all] - name: Build the book diff --git a/makefile b/makefile index 8e12c576..f0103e9d 100644 --- a/makefile +++ b/makefile @@ -4,7 +4,7 @@ PYTHON=$(shell command -v python || command -v python3) build-docs: - ./env/bin/pip install -r requirements-dev.txt + ./env/bin/pip install .[all] ./env/bin/jupyter-book build docs/ --warningiserror --keep-going --all open: @@ -14,12 +14,12 @@ init: purge git submodule update --init $(PYTHON) -m venv env ./env/bin/pip install --upgrade pip wheel setuptools - ./env/bin/pip install .[all] + ./env/bin/pip install .[test] clear: -./env/bin/pip uninstall -y h3 -@rm -rf MANIFEST - -@rm -rf .pytest_cache _skbuild dist .coverage build docs/_build + -@rm -rf .pytest_cache _skbuild dist .coverage build docs/_build .ruff_cache -@find . -type d -name '__pycache__' | xargs rm -r -@find . -type d -name '*.egg-info' | xargs rm -r -@find . -type f -name '*.pyc' | xargs rm -r @@ -29,7 +29,7 @@ clear: -@find ./tests -type f -name '*.html' | xargs rm -r rebuild: clear - ./env/bin/pip install .[all] + ./env/bin/pip install .[test] purge: clear -@rm -rf env @@ -44,5 +44,5 @@ lint: ./env/bin/pylint --disable=all --enable=import-error tests/ lab: - ./env/bin/pip install -r requirements-dev.txt + ./env/bin/pip install .[all] ./env/bin/jupyter lab diff --git a/pyproject.toml b/pyproject.toml index 94d998bb..2598137b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -52,19 +52,22 @@ Changelog = 'https://package.readthedocs.io/en/latest/changelog.html' [project.optional-dependencies] numpy = ['numpy<2'] test = ['pytest', 'pytest-cov', 'flake8', 'pylint', 'numpy<2'] -docs = [ +all = [ 'jupyter-book', 'flake8', 'sphinx>=7.3.3', # https://github.com/sphinx-doc/sphinx/issues/12290 -] -all = [ + 'jupyterlab', + 'jupyterlab-geojson', + 'geopandas', + 'geodatasets', + 'matplotlib', + 'contextily', + 'cartopy', + 'geoviews', 'numpy<2', 'pytest', 'pytest-cov', - 'flake8', 'pylint', - 'jupyter-book', - 'sphinx>=7.3.3', ] [tool.coverage.run] diff --git a/requirements-dev.txt b/requirements-dev.txt deleted file mode 100644 index c6ffe776..00000000 --- a/requirements-dev.txt +++ /dev/null @@ -1,8 +0,0 @@ -jupyterlab -jupyterlab-geojson -geopandas -geodatasets -matplotlib -contextily -cartopy -geoviews From a810bbee131d7a152acb9d134350384979198c8e Mon Sep 17 00:00:00 2001 From: ajfriend Date: Sat, 22 Jun 2024 10:21:13 -0700 Subject: [PATCH 19/37] remove cmake from the build system requirements --- pyproject.toml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 2598137b..324a02cb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,12 +1,7 @@ [build-system] -requires = [ - 'scikit-build-core', - 'cython', - 'cmake', -] +requires = ['scikit-build-core', 'cython'] build-backend = 'scikit_build_core.build' - [project] name = 'h3' version = '4.0.0b6' From f738c6d92ee88811bbd306bada462cffe43c7da1 Mon Sep 17 00:00:00 2001 From: ajfriend Date: Sat, 22 Jun 2024 10:28:14 -0700 Subject: [PATCH 20/37] single sourcing the version number in _version.py --- pyproject.toml | 2 +- src/h3/_version.py | 23 ----------------------- 2 files changed, 1 insertion(+), 24 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 324a02cb..55e3b6be 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = 'scikit_build_core.build' [project] name = 'h3' -version = '4.0.0b6' +dynamic = ['version'] description = 'Hierarchical hexagonal geospatial indexing system' readme = 'readme.md' license = {file = 'LICENSE'} diff --git a/src/h3/_version.py b/src/h3/_version.py index 41bf4d04..f4766195 100644 --- a/src/h3/_version.py +++ b/src/h3/_version.py @@ -1,24 +1 @@ __version__ = '4.0.0b6' -__description__ = 'Hierarchical hexagonal geospatial indexing system' -__url__ = 'https://github.com/uber/h3-py' -__license__ = 'Apache 2.0 License' -__author__ = 'Uber Technologies' -__author_email__ = 'AJ Friend ' -__classifiers__ = [ - 'Development Status :: 5 - Production/Stable', - 'Intended Audience :: Developers', - 'Intended Audience :: Science/Research', - 'License :: OSI Approved :: Apache Software License', - 'Programming Language :: C', - 'Programming Language :: Cython', - 'Programming Language :: Python :: 3.7', - 'Programming Language :: Python :: 3.8', - 'Programming Language :: Python :: 3.9', - 'Programming Language :: Python :: 3.10', - 'Programming Language :: Python :: 3.11', - 'Programming Language :: Python :: 3.12', - 'Operating System :: MacOS :: MacOS X', - 'Operating System :: POSIX :: Linux', - 'Operating System :: Microsoft :: Windows', - 'Topic :: Scientific/Engineering :: GIS', -] From 0ce30f7044baf7f91c1b8c9baf0b66f1d81da7d7 Mon Sep 17 00:00:00 2001 From: ajfriend Date: Sat, 22 Jun 2024 10:33:04 -0700 Subject: [PATCH 21/37] i think scikitbuild-core doesn't work with dynamic = ['version']. try something else --- pyproject.toml | 2 +- src/h3/_version.py | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 55e3b6be..324a02cb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = 'scikit_build_core.build' [project] name = 'h3' -dynamic = ['version'] +version = '4.0.0b6' description = 'Hierarchical hexagonal geospatial indexing system' readme = 'readme.md' license = {file = 'LICENSE'} diff --git a/src/h3/_version.py b/src/h3/_version.py index f4766195..712565a5 100644 --- a/src/h3/_version.py +++ b/src/h3/_version.py @@ -1 +1,3 @@ -__version__ = '4.0.0b6' +from importlib import metadata + +__version__ = metadata.version(__package__ or __name__) From 47ece53983fbf3e1d6f06d544196c2e3d585e65a Mon Sep 17 00:00:00 2001 From: ajfriend Date: Sat, 22 Jun 2024 11:21:04 -0700 Subject: [PATCH 22/37] uber's --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 324a02cb..c8fbf07f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,7 +5,7 @@ build-backend = 'scikit_build_core.build' [project] name = 'h3' version = '4.0.0b6' -description = 'Hierarchical hexagonal geospatial indexing system' +description = "Uber's hierarchical hexagonal geospatial indexing system" readme = 'readme.md' license = {file = 'LICENSE'} authors = [ From 42e614fe6893aa6672c62009d17d9834e13551f5 Mon Sep 17 00:00:00 2001 From: ajfriend Date: Sat, 22 Jun 2024 11:25:11 -0700 Subject: [PATCH 23/37] alphabetical files in cmakelists.txt --- src/h3/_cy/CMakeLists.txt | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/h3/_cy/CMakeLists.txt b/src/h3/_cy/CMakeLists.txt index 68d63619..2b591bac 100644 --- a/src/h3/_cy/CMakeLists.txt +++ b/src/h3/_cy/CMakeLists.txt @@ -21,14 +21,13 @@ endmacro() # GLOB pattern is recommended against # https://cmake.org/cmake/help/v3.14/command/file.html?highlight=file#filesystem -add_cython_file(util) -add_cython_file(latlng) add_cython_file(cells) add_cython_file(edges) -add_cython_file(to_multipoly) add_cython_file(error_system) +add_cython_file(latlng) add_cython_file(memory) - +add_cython_file(to_multipoly) +add_cython_file(util) # Include pyx and pxd files in distribution for use by Cython API install( @@ -37,14 +36,14 @@ install( cells.pyx edges.pxd edges.pyx + error_system.pyx + h3lib.pxd latlng.pxd latlng.pyx - h3lib.pxd - util.pxd - util.pyx - error_system.pyx memory.pxd memory.pyx + util.pxd + util.pyx DESTINATION ${SKBUILD_PROJECT_NAME}/_cy ) From b1efd87fe51969a528a8289fe2075568f097ffab Mon Sep 17 00:00:00 2001 From: ajfriend Date: Sat, 22 Jun 2024 12:10:23 -0700 Subject: [PATCH 24/37] tidy up files in the sdist --- pyproject.toml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index c8fbf07f..ff8eed00 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -71,3 +71,20 @@ omit = [ '*/h3/api/memview_int/__init__.py', '*/h3/api/numpy_int/__init__.py' ] + + +[tool.scikit-build] +sdist.exclude = [ + 'src/h3lib', + 'docs', + 'dev_notes.md', + 'makefile', +] +sdist.include = [ + 'src/h3lib/LICENSE', + 'src/h3lib/README.md', + 'src/h3lib/VERSION', + 'src/h3lib/CMakeLists.txt', + 'src/h3lib/cmake/*', + 'src/h3lib/src/h3lib/*' +] From 4392e2e6be5b6b83d199ac9fa81a66f867052ae3 Mon Sep 17 00:00:00 2001 From: ajfriend Date: Sat, 22 Jun 2024 12:40:34 -0700 Subject: [PATCH 25/37] move pytest config to pyproject.toml --- .github/workflows/coverage-lint.yml | 2 +- .github/workflows/tests.yml | 2 +- .github/workflows/wheels.yml | 2 +- makefile | 2 +- pyproject.toml | 3 +++ 5 files changed, 7 insertions(+), 4 deletions(-) diff --git a/.github/workflows/coverage-lint.yml b/.github/workflows/coverage-lint.yml index ca4f8321..08021693 100644 --- a/.github/workflows/coverage-lint.yml +++ b/.github/workflows/coverage-lint.yml @@ -37,7 +37,7 @@ jobs: run: | pip install cython cythonize tests/test_cython/cython_example.pyx - pytest --cov=h3 --full-trace --cov-report=xml + pytest --cov-report=xml - name: Upload coverage to Codecov uses: codecov/codecov-action@v4.3.0 diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index e56d4d25..8075b013 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -45,4 +45,4 @@ jobs: run: | pip install cython cythonize tests/test_cython/cython_example.pyx - pytest tests --cov=h3 --full-trace + pytest diff --git a/.github/workflows/wheels.yml b/.github/workflows/wheels.yml index f08e7c26..c1c7f337 100644 --- a/.github/workflows/wheels.yml +++ b/.github/workflows/wheels.yml @@ -46,7 +46,7 @@ jobs: pip install h3.tar.gz[test] - name: Test sdist - run: pytest --cov=h3 --full-trace + run: pytest - name: Upload artifacts to GitHub uses: actions/upload-artifact@v4.3.1 diff --git a/makefile b/makefile index f0103e9d..a838caa0 100644 --- a/makefile +++ b/makefile @@ -37,7 +37,7 @@ purge: clear test: ./env/bin/pip install cython ./env/bin/cythonize tests/test_cython/cython_example.pyx - ./env/bin/pytest tests --cov=h3 --cov-report term-missing --durations=10 + ./env/bin/pytest lint: ./env/bin/flake8 src/h3 tests diff --git a/pyproject.toml b/pyproject.toml index ff8eed00..9c0d95ce 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -65,6 +65,9 @@ all = [ 'pylint', ] +[tool.pytest.ini_options] +addopts = "--cov=h3 --cov=tests --cov-report=term-missing --durations=10" + [tool.coverage.run] omit = [ '*/h3/api/basic_int/__init__.py', From c08b8c53631427360c40c50668056f9c3ccfd9c6 Mon Sep 17 00:00:00 2001 From: ajfriend Date: Sat, 22 Jun 2024 12:46:28 -0700 Subject: [PATCH 26/37] CIBW_TEST_COMMAND: pytest --- .github/workflows/wheels.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/wheels.yml b/.github/workflows/wheels.yml index c1c7f337..d7256a6e 100644 --- a/.github/workflows/wheels.yml +++ b/.github/workflows/wheels.yml @@ -132,7 +132,7 @@ jobs: - uses: pypa/cibuildwheel@v2.17.0 env: CIBW_TEST_REQUIRES: pytest numpy - CIBW_TEST_COMMAND: pytest {project}/tests + CIBW_TEST_COMMAND: pytest CIBW_ARCHS_LINUX: auto aarch64 CIBW_BUILD: ${{ matrix.build }} From db649a110b0ddb0f6a013dcc0d6862b1c63eb289 Mon Sep 17 00:00:00 2001 From: ajfriend Date: Sat, 22 Jun 2024 12:51:08 -0700 Subject: [PATCH 27/37] CIBW_TEST_COMMAND: pytest {project}/tests --- .github/workflows/wheels.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/wheels.yml b/.github/workflows/wheels.yml index d7256a6e..c1c7f337 100644 --- a/.github/workflows/wheels.yml +++ b/.github/workflows/wheels.yml @@ -132,7 +132,7 @@ jobs: - uses: pypa/cibuildwheel@v2.17.0 env: CIBW_TEST_REQUIRES: pytest numpy - CIBW_TEST_COMMAND: pytest + CIBW_TEST_COMMAND: pytest {project}/tests CIBW_ARCHS_LINUX: auto aarch64 CIBW_BUILD: ${{ matrix.build }} From 9d5c6209d06108c63c6bedc84a96e753a716f187 Mon Sep 17 00:00:00 2001 From: ajfriend Date: Sat, 22 Jun 2024 12:54:06 -0700 Subject: [PATCH 28/37] CIBW_TEST_REQUIRES: pytest pytest-cov numpy --- .github/workflows/wheels.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/wheels.yml b/.github/workflows/wheels.yml index c1c7f337..c06d1259 100644 --- a/.github/workflows/wheels.yml +++ b/.github/workflows/wheels.yml @@ -131,7 +131,7 @@ jobs: - uses: pypa/cibuildwheel@v2.17.0 env: - CIBW_TEST_REQUIRES: pytest numpy + CIBW_TEST_REQUIRES: pytest pytest-cov numpy CIBW_TEST_COMMAND: pytest {project}/tests CIBW_ARCHS_LINUX: auto aarch64 CIBW_BUILD: ${{ matrix.build }} From 36f14dc385ae182004d7f39400312d1113d86041 Mon Sep 17 00:00:00 2001 From: ajfriend Date: Sat, 22 Jun 2024 13:24:57 -0700 Subject: [PATCH 29/37] get better coverage on the testing code --- .github/workflows/wheels.yml | 1 - tests/polyfill/test_polyfill.py | 6 ++---- tests/polyfill/test_polygon_class.py | 8 +++++--- tests/test_h3.py | 4 ++++ 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/.github/workflows/wheels.yml b/.github/workflows/wheels.yml index c06d1259..c40ec937 100644 --- a/.github/workflows/wheels.yml +++ b/.github/workflows/wheels.yml @@ -41,7 +41,6 @@ jobs: - name: Install from sdist run: | pip install --upgrade pip setuptools wheel - pip install pytest cp dist/h3-*.tar.gz h3.tar.gz pip install h3.tar.gz[test] diff --git a/tests/polyfill/test_polyfill.py b/tests/polyfill/test_polyfill.py index b78e8751..1431b876 100644 --- a/tests/polyfill/test_polyfill.py +++ b/tests/polyfill/test_polyfill.py @@ -135,12 +135,10 @@ def test_invalid_polygon(): some `cdef` functions. """ with pytest.raises(TypeError): - poly = h3.LatLngPoly([1, 2, 3]) - h3.h3shape_to_cells(poly, 4) + h3.LatLngPoly([1, 2, 3]) with pytest.raises(ValueError): - poly = h3.LatLngPoly([[1, 2, 3]]) - h3.h3shape_to_cells(poly, 4) + h3.LatLngPoly([[1, 2, 3]]) def test_bad_geo_input(): diff --git a/tests/polyfill/test_polygon_class.py b/tests/polyfill/test_polygon_class.py index c38505dc..3996d302 100644 --- a/tests/polyfill/test_polygon_class.py +++ b/tests/polyfill/test_polygon_class.py @@ -39,8 +39,10 @@ def test_LatLngPoly_len(): def test_bad_subclass(): class H3Shoop(h3.H3Shape): - def __geo_interface__(): - pass + def __geo_interface__(self): + return 'foo' + shoop = H3Shoop() + shoop.__geo_interface__() with pytest.raises(ValueError): - h3.h3shape_to_cells(H3Shoop(), res=9) + h3.h3shape_to_cells(shoop, res=9) diff --git a/tests/test_h3.py b/tests/test_h3.py index 186145fa..1b09fe86 100644 --- a/tests/test_h3.py +++ b/tests/test_h3.py @@ -6,6 +6,10 @@ from . import util as u +def test_approx_helper(): + assert not u.approx2('abc', 'abdc') + + def test_is_valid_cell(): assert h3.is_valid_cell('85283473fffffff') assert h3.is_valid_cell('850dab63fffffff') From f9d4f24b74ee39cb8ef5b8f9abaf4ff12bd3af0d Mon Sep 17 00:00:00 2001 From: Pieter Provoost Date: Sun, 25 Aug 2024 19:35:08 +0200 Subject: [PATCH 30/37] fix api reference link (#385) --- readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index d4142be9..fafc529f 100644 --- a/readme.md +++ b/readme.md @@ -63,12 +63,12 @@ conda install h3-py ## APIs [api_comparison]: https://uber.github.io/h3-py/api_comparison -[api_reference]: https://uber.github.io/h3-py/api_reference +[api_quick]: https://uber.github.io/h3-py/api_quick We provide [multiple APIs][api_comparison] in `h3-py`. - All APIs have the same set of functions; - see the [API reference][api_reference]. + see the [API reference][api_quick]. - The APIs differ only in their input/output formats; see the [API comparison page][api_comparison]. From 9a7442b31f483bd35b383ceb0b0ce172f0f2451b Mon Sep 17 00:00:00 2001 From: Shiran Yuan Date: Tue, 27 Aug 2024 08:05:20 -0700 Subject: [PATCH 31/37] Added Bindings for Vertex-Related Functions (#388) * Update CHANGELOG.md * Update h3lib.pxd * Update latlng.pxd * Update latlng.pyx * Update util.pxd * Update util.pyx * Update _version.py * Update __init__.py * Update __init__.py * Update test_h3.py * Update __init__.py * Update test_h3.py * Update CHANGELOG.md * Update __init__.py * Update test_h3.py * Update _version.py * Update test_h3.py * Update __init__.py * Update CMakeLists.txt * Update latlng.pxd * Update latlng.pyx * Create vertex.pxd * Create vertex.pyx * Update __init__.py * Update test_h3.py * Update __init__.py * Update api_quick.md --- CHANGELOG.md | 4 +- docs/api_quick.md | 12 ++++++ src/h3/_cy/CMakeLists.txt | 2 + src/h3/_cy/__init__.py | 7 ++++ src/h3/_cy/h3lib.pxd | 5 +++ src/h3/_cy/latlng.pyx | 2 +- src/h3/_cy/util.pxd | 1 + src/h3/_cy/util.pyx | 7 +++- src/h3/_cy/vertex.pxd | 6 +++ src/h3/_cy/vertex.pyx | 54 +++++++++++++++++++++++++ src/h3/api/basic_int/__init__.py | 67 ++++++++++++++++++++++++++++++++ tests/test_h3.py | 55 ++++++++++++++++++++++++++ 12 files changed, 218 insertions(+), 4 deletions(-) create mode 100644 src/h3/_cy/vertex.pxd create mode 100644 src/h3/_cy/vertex.pyx diff --git a/CHANGELOG.md b/CHANGELOG.md index 37cf91cf..268c7446 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,9 +14,9 @@ Because H3-Py is versioned in lockstep with the H3 core library, please avoid adding features or APIs which do not map onto the [H3 core API](https://uber.github.io/h3/#/documentation/api-reference/). -## Unreleased +## Unreleased - 2024-08-23 -- None +- Added bindings for `cellToVertex`, `cellToVertexes`, `vertexToLatLng`, and `isValidVertex` (#323) ## [4.0.0b5] - 2024-05-19 diff --git a/docs/api_quick.md b/docs/api_quick.md index d73f1144..0753ddb0 100644 --- a/docs/api_quick.md +++ b/docs/api_quick.md @@ -24,6 +24,7 @@ and should be generally aligned with the is_pentagon is_res_class_III is_valid_directed_edge + is_valid_vertex ``` ## Index representation @@ -108,6 +109,17 @@ Functions relating H3 objects to geographic (lat/lng) coordinates. get_directed_edge_origin ``` +## Vertexes + +```{eval-rst} +.. currentmodule:: h3 + +.. autosummary:: + cell_to_vertex + cell_to_vertexes + vertex_to_latlng +``` + ## Polygon interface The ``LatLngPoly`` and ``LatLngMultiPoly`` objects and their related functions allow users to represent (multi)polygons of lat/lng points and convert back and forth between H3 cells. diff --git a/src/h3/_cy/CMakeLists.txt b/src/h3/_cy/CMakeLists.txt index 2b591bac..f3161c63 100644 --- a/src/h3/_cy/CMakeLists.txt +++ b/src/h3/_cy/CMakeLists.txt @@ -44,6 +44,8 @@ install( memory.pyx util.pxd util.pyx + vertex.pxd + vertex.pyx DESTINATION ${SKBUILD_PROJECT_NAME}/_cy ) diff --git a/src/h3/_cy/__init__.py b/src/h3/_cy/__init__.py index c208711e..c739bc04 100644 --- a/src/h3/_cy/__init__.py +++ b/src/h3/_cy/__init__.py @@ -60,6 +60,13 @@ great_circle_distance, ) +from .vertex import ( + cell_to_vertex, + cell_to_vertexes, + vertex_to_latlng, + is_valid_vertex, +) + from .to_multipoly import ( cells_to_multi_polygon ) diff --git a/src/h3/_cy/h3lib.pxd b/src/h3/_cy/h3lib.pxd index 00fff601..eae1b853 100644 --- a/src/h3/_cy/h3lib.pxd +++ b/src/h3/_cy/h3lib.pxd @@ -69,6 +69,7 @@ cdef extern from 'h3api.h': int isPentagon(H3int h) nogil int isResClassIII(H3int h) nogil int isValidDirectedEdge(H3int edge) nogil + int isValidVertex(H3int v) nogil double degsToRads(double degrees) nogil double radsToDegs(double radians) nogil @@ -80,6 +81,10 @@ cdef extern from 'h3api.h': H3Error cellToLatLng(H3int h, LatLng *) nogil H3Error gridDistance(H3int h1, H3int h2, int64_t *distance) nogil + H3Error cellToVertex(H3int cell, int vertexNum, H3int *out) nogil + H3Error cellToVertexes(H3int cell, H3int *vertexes) nogil + H3Error vertexToLatLng(H3int vertex, LatLng *coord) nogil + H3Error maxGridDiskSize(int k, int64_t *out) nogil # num/out/N? H3Error gridDisk(H3int h, int k, H3int *out) nogil diff --git a/src/h3/_cy/latlng.pyx b/src/h3/_cy/latlng.pyx index 520b950b..c3e0cdb8 100644 --- a/src/h3/_cy/latlng.pyx +++ b/src/h3/_cy/latlng.pyx @@ -8,7 +8,7 @@ from .util cimport ( check_edge, check_res, deg2coord, - coord2deg, + coord2deg ) from .error_system cimport check_for_error diff --git a/src/h3/_cy/util.pxd b/src/h3/_cy/util.pxd index 15e97ad0..4d7d962c 100644 --- a/src/h3/_cy/util.pxd +++ b/src/h3/_cy/util.pxd @@ -9,4 +9,5 @@ cpdef H3str int_to_str(H3int x) cdef check_cell(H3int h) cdef check_edge(H3int e) cdef check_res(int res) +cdef check_vertex(H3int v) cdef check_distance(int k) diff --git a/src/h3/_cy/util.pyx b/src/h3/_cy/util.pyx index 8bc061db..7b8a9f20 100644 --- a/src/h3/_cy/util.pyx +++ b/src/h3/_cy/util.pyx @@ -1,4 +1,4 @@ -from .h3lib cimport H3int, H3str, isValidCell, isValidDirectedEdge +from .h3lib cimport H3int, H3str, isValidCell, isValidDirectedEdge, isValidVertex cimport h3lib @@ -7,6 +7,7 @@ from .error_system import ( H3DomainError, H3DirEdgeInvalidError, H3CellInvalidError, + H3VertexInvalidError ) cdef h3lib.LatLng deg2coord(double lat, double lng) nogil: @@ -73,6 +74,10 @@ cdef check_edge(H3int e): if isValidDirectedEdge(e) == 0: raise H3DirEdgeInvalidError('Integer is not a valid H3 edge: {}'.format(hex(e))) +cdef check_vertex(H3int v): + if isValidVertex(v) == 0: + raise H3VertexInvalidError('Integer is not a valid H3 vertex: {}'.format(hex(v))) + cdef check_res(int res): if (res < 0) or (res > 15): raise H3ResDomainError(res) diff --git a/src/h3/_cy/vertex.pxd b/src/h3/_cy/vertex.pxd new file mode 100644 index 00000000..98d890ce --- /dev/null +++ b/src/h3/_cy/vertex.pxd @@ -0,0 +1,6 @@ +from .h3lib cimport bool, H3int + +cpdef H3int cell_to_vertex(H3int h, int vertex_num) except 1 +cpdef H3int[:] cell_to_vertexes(H3int h) +cpdef (double, double) vertex_to_latlng(H3int v) except * +cpdef bool is_valid_vertex(H3int v) diff --git a/src/h3/_cy/vertex.pyx b/src/h3/_cy/vertex.pyx new file mode 100644 index 00000000..26a674af --- /dev/null +++ b/src/h3/_cy/vertex.pyx @@ -0,0 +1,54 @@ +cimport h3lib +from h3lib cimport bool, H3int + +from .util cimport ( + check_cell, + check_vertex, + coord2deg +) + +from .error_system cimport check_for_error + +from .memory cimport H3MemoryManager + + +cpdef H3int cell_to_vertex(H3int h, int vertex_num) except 1: + cdef: + H3int out + + check_cell(h) + + check_for_error( + h3lib.cellToVertex(h, vertex_num, &out) + ) + + return out + +cpdef H3int[:] cell_to_vertexes(H3int h): + cdef: + H3int out + + check_cell(h) + + hmm = H3MemoryManager(6) + check_for_error( + h3lib.cellToVertexes(h, hmm.ptr) + ) + mv = hmm.to_mv() + + return mv + +cpdef (double, double) vertex_to_latlng(H3int v) except *: + cdef: + h3lib.LatLng c + + check_vertex(v) + + check_for_error( + h3lib.vertexToLatLng(v, &c) + ) + + return coord2deg(c) + +cpdef bool is_valid_vertex(H3int v): + return h3lib.isValidVertex(v) == 1 diff --git a/src/h3/api/basic_int/__init__.py b/src/h3/api/basic_int/__init__.py index d1122d83..81861897 100644 --- a/src/h3/api/basic_int/__init__.py +++ b/src/h3/api/basic_int/__init__.py @@ -996,3 +996,70 @@ def great_circle_distance(latlng1, latlng2, unit='km'): lat2, lng2, unit = unit ) + + +def cell_to_vertex(h, vertex_num): + """ + Return a (specified) vertex of an H3 cell. + + Parameters + ---------- + h : H3Cell + vertex_num : int + Vertex number (0-5) + + Returns + ------- + The vertex + """ + h = _in_scalar(h) + h = _cy.cell_to_vertex(h, vertex_num) + return _out_scalar(h) + + +def cell_to_vertexes(h): + """ + Return a list of vertexes of an H3 cell. + The list will be of length 5 for pentagons and 6 for hexagons. + + Parameters + ---------- + h : H3Cell + + Returns + ------- + A list of vertexes + """ + h = _in_scalar(h) + mv = _cy.cell_to_vertexes(h) + return _out_collection(mv) + + +def vertex_to_latlng(v): + """ + Return latitude and longitude of a vertex. + + Returns + ------- + lat : float + Latitude + lng : float + Longitude + """ + v = _in_scalar(v) + return _cy.vertex_to_latlng(v) + + +def is_valid_vertex(v): + """ + Validates an H3 vertex. + + Returns + ------- + bool + """ + try: + v = _in_scalar(v) + return _cy.is_valid_vertex(v) + except (ValueError, TypeError): + return False diff --git a/tests/test_h3.py b/tests/test_h3.py index 1b09fe86..051480a6 100644 --- a/tests/test_h3.py +++ b/tests/test_h3.py @@ -391,3 +391,58 @@ def test_grid_path_cells(): with pytest.raises(h3.H3ResMismatchError): h3.grid_path_cells(h1, '8001fffffffffff') + + +def test_cell_to_vertex(): + # pentagon + assert h3.cell_to_vertex('814c3ffffffffff', 0) == '2014c3ffffffffff' + assert h3.cell_to_vertex('814c3ffffffffff', 1) == '2114c3ffffffffff' + assert h3.cell_to_vertex('814c3ffffffffff', 2) == '2214c3ffffffffff' + assert h3.cell_to_vertex('814c3ffffffffff', 3) == '2314c3ffffffffff' + assert h3.cell_to_vertex('814c3ffffffffff', 4) == '2414c3ffffffffff' + try: + h3.cell_to_vertex('814c3ffffffffff', 5) + except h3._cy.error_system.H3DomainError: + pass + else: + assert False + + # hexagon + assert h3.cell_to_vertex('814d7ffffffffff', 0) == '2014d7ffffffffff' + assert h3.cell_to_vertex('814d7ffffffffff', 1) == '2213abffffffffff' + assert h3.cell_to_vertex('814d7ffffffffff', 2) == '2113abffffffffff' + assert h3.cell_to_vertex('814d7ffffffffff', 3) == '2414c3ffffffffff' + assert h3.cell_to_vertex('814d7ffffffffff', 4) == '2314c3ffffffffff' + assert h3.cell_to_vertex('814d7ffffffffff', 5) == '2414cfffffffffff' + + +def test_cell_to_vertexes(): + # pentagon + assert h3.cell_to_vertexes('814c3ffffffffff') == [ + '2014c3ffffffffff', + '2114c3ffffffffff', + '2214c3ffffffffff', + '2314c3ffffffffff', + '2414c3ffffffffff', + ] + + # hexagon + assert h3.cell_to_vertexes('814d7ffffffffff') == [ + '2014d7ffffffffff', + '2213abffffffffff', + '2113abffffffffff', + '2414c3ffffffffff', + '2314c3ffffffffff', + '2414cfffffffffff', + ] + + +def test_vertex_to_latlng(): + latlng = h3.vertex_to_latlng('2114c3ffffffffff') + assert latlng == approx((24.945215618732814, -70.33904370008679)) + + +def test_is_valid_vertex(): + assert h3.is_valid_vertex('2114c3ffffffffff') + assert not h3.is_valid_vertex(2455495337847029759) + assert not h3.is_valid_vertex('foobar') From 459235af82a0dcd4d44555d375e9c061f6ad3e6a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Sep 2024 16:12:49 -0700 Subject: [PATCH 32/37] Bump actions/download-artifact from 4.1.4 to 4.1.7 in /.github/workflows (#392) Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 4.1.4 to 4.1.7. - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](https://github.com/actions/download-artifact/compare/v4.1.4...v4.1.7) --- updated-dependencies: - dependency-name: actions/download-artifact dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/wheels.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/wheels.yml b/.github/workflows/wheels.yml index c40ec937..659a1939 100644 --- a/.github/workflows/wheels.yml +++ b/.github/workflows/wheels.yml @@ -164,7 +164,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/download-artifact@v4.1.4 + - uses: actions/download-artifact@v4.1.7 with: name: wheels_and_sdist path: dist From 58731baa6794984c629fa1970f3964370420867e Mon Sep 17 00:00:00 2001 From: AJ Friend Date: Tue, 3 Sep 2024 17:13:21 -0700 Subject: [PATCH 33/37] prep for v4.0.0b6 release (#394) --- CHANGELOG.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 268c7446..81e800c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,11 @@ Because H3-Py is versioned in lockstep with the H3 core library, please avoid adding features or APIs which do not map onto the [H3 core API](https://uber.github.io/h3/#/documentation/api-reference/). -## Unreleased - 2024-08-23 +## Unreleased + +None. + +## [4.0.0b6] - 2024-09-03 - Added bindings for `cellToVertex`, `cellToVertexes`, `vertexToLatLng`, and `isValidVertex` (#323) From 40cdd867325691f8de7d69901ea6dcc35e028294 Mon Sep 17 00:00:00 2001 From: ajfriend Date: Sat, 22 Jun 2024 11:25:11 -0700 Subject: [PATCH 34/37] alphabetical files in cmakelists.txt --- src/h3/_cy/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/h3/_cy/CMakeLists.txt b/src/h3/_cy/CMakeLists.txt index f3161c63..2cb2b6f3 100644 --- a/src/h3/_cy/CMakeLists.txt +++ b/src/h3/_cy/CMakeLists.txt @@ -26,6 +26,8 @@ add_cython_file(edges) add_cython_file(error_system) add_cython_file(latlng) add_cython_file(memory) +add_cython_file(vertex) + add_cython_file(to_multipoly) add_cython_file(util) From 72820a44c433618a8d02c834953099cf1db06e65 Mon Sep 17 00:00:00 2001 From: ajfriend Date: Wed, 4 Sep 2024 08:07:35 -0700 Subject: [PATCH 35/37] single --- tests/test_cython/test_cython.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_cython/test_cython.py b/tests/test_cython/test_cython.py index 89aa0646..1833de3f 100644 --- a/tests/test_cython/test_cython.py +++ b/tests/test_cython/test_cython.py @@ -12,7 +12,7 @@ def test_cython_api(): if latlng_to_cell_vect is None: - print("Not running Cython test because cython example was not compiled") + print('Not running Cython test because cython example was not compiled') return N = 100000 @@ -22,7 +22,7 @@ def test_cython_api(): lats = np.array(lats, dtype=np.float64) lngs = np.array(lngs, dtype=np.float64) - out = np.zeros(len(lats), dtype="uint64") + out = np.zeros(len(lats), dtype='uint64') latlng_to_cell_vect(lats, lngs, res, out) assert out[0] == 617284541015654399 From 7d18958f30754136bda199bdef5c4b02ed297313 Mon Sep 17 00:00:00 2001 From: AJ Friend Date: Wed, 4 Sep 2024 08:39:49 -0700 Subject: [PATCH 36/37] test with numpy>=2 --- pyproject.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 9c0d95ce..eceb53b0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -45,8 +45,8 @@ Changelog = 'https://package.readthedocs.io/en/latest/changelog.html' [project.optional-dependencies] -numpy = ['numpy<2'] -test = ['pytest', 'pytest-cov', 'flake8', 'pylint', 'numpy<2'] +numpy = ['numpy>=2'] +test = ['pytest', 'pytest-cov', 'flake8', 'pylint', 'numpy>=2'] all = [ 'jupyter-book', 'flake8', @@ -59,7 +59,7 @@ all = [ 'contextily', 'cartopy', 'geoviews', - 'numpy<2', + 'numpy>=2', 'pytest', 'pytest-cov', 'pylint', From 121314a6212b7687d8c1df4192358faf2fb87a49 Mon Sep 17 00:00:00 2001 From: AJ Friend Date: Wed, 4 Sep 2024 08:45:27 -0700 Subject: [PATCH 37/37] drop lower bound on numpy version --- pyproject.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index eceb53b0..c6a6ddbe 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -45,8 +45,8 @@ Changelog = 'https://package.readthedocs.io/en/latest/changelog.html' [project.optional-dependencies] -numpy = ['numpy>=2'] -test = ['pytest', 'pytest-cov', 'flake8', 'pylint', 'numpy>=2'] +numpy = ['numpy'] +test = ['pytest', 'pytest-cov', 'flake8', 'pylint', 'numpy'] all = [ 'jupyter-book', 'flake8', @@ -59,7 +59,7 @@ all = [ 'contextily', 'cartopy', 'geoviews', - 'numpy>=2', + 'numpy', 'pytest', 'pytest-cov', 'pylint',