pygenogrove 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (245) hide show
  1. pygenogrove-0.2.0/.github/scripts/install-htslib-linux.sh +37 -0
  2. pygenogrove-0.2.0/.github/workflows/ci.yml +51 -0
  3. pygenogrove-0.2.0/.github/workflows/release.yml +81 -0
  4. pygenogrove-0.2.0/.gitignore +156 -0
  5. pygenogrove-0.2.0/.gitmodules +3 -0
  6. pygenogrove-0.2.0/CHANGELOG.md +42 -0
  7. pygenogrove-0.2.0/CMakeLists.txt +62 -0
  8. pygenogrove-0.2.0/PKG-INFO +461 -0
  9. pygenogrove-0.2.0/README.md +431 -0
  10. pygenogrove-0.2.0/example.py +201 -0
  11. pygenogrove-0.2.0/external/genogrove/.clang-format +45 -0
  12. pygenogrove-0.2.0/external/genogrove/.cmake-format.yaml +50 -0
  13. pygenogrove-0.2.0/external/genogrove/.git +1 -0
  14. pygenogrove-0.2.0/external/genogrove/.github/workflows/ci-macos.yml +48 -0
  15. pygenogrove-0.2.0/external/genogrove/.github/workflows/ci-ubuntu.yml +59 -0
  16. pygenogrove-0.2.0/external/genogrove/.github/workflows/continuous-benchmarking.yml +87 -0
  17. pygenogrove-0.2.0/external/genogrove/.github/workflows/release-changelog.yml +28 -0
  18. pygenogrove-0.2.0/external/genogrove/.github/workflows/update-changelog.yml +75 -0
  19. pygenogrove-0.2.0/external/genogrove/.gitignore +96 -0
  20. pygenogrove-0.2.0/external/genogrove/CHANGELOG.md +641 -0
  21. pygenogrove-0.2.0/external/genogrove/CLAUDE.md +116 -0
  22. pygenogrove-0.2.0/external/genogrove/CMakeLists.txt +146 -0
  23. pygenogrove-0.2.0/external/genogrove/CONTRIBUTING.md +45 -0
  24. pygenogrove-0.2.0/external/genogrove/LICENSE +674 -0
  25. pygenogrove-0.2.0/external/genogrove/Makefile +58 -0
  26. pygenogrove-0.2.0/external/genogrove/README.md +76 -0
  27. pygenogrove-0.2.0/external/genogrove/SANITIZERS.md +45 -0
  28. pygenogrove-0.2.0/external/genogrove/benchmarks/CMakeLists.txt +48 -0
  29. pygenogrove-0.2.0/external/genogrove/benchmarks/benchmark_utils.hpp +61 -0
  30. pygenogrove-0.2.0/external/genogrove/benchmarks/cli_benchmark.cpp +164 -0
  31. pygenogrove-0.2.0/external/genogrove/benchmarks/data/10000_intervals_sorted.txt +10003 -0
  32. pygenogrove-0.2.0/external/genogrove/benchmarks/data/10000_intervals_unsorted.txt +10003 -0
  33. pygenogrove-0.2.0/external/genogrove/benchmarks/data/1000_intervals_sorted.txt +1003 -0
  34. pygenogrove-0.2.0/external/genogrove/benchmarks/data/1000_intervals_unsorted.txt +1003 -0
  35. pygenogrove-0.2.0/external/genogrove/benchmarks/data/100_intervals_sorted.txt +103 -0
  36. pygenogrove-0.2.0/external/genogrove/benchmarks/data/100_intervals_unsorted.txt +103 -0
  37. pygenogrove-0.2.0/external/genogrove/benchmarks/data/5000_intervals_sorted.txt +5003 -0
  38. pygenogrove-0.2.0/external/genogrove/benchmarks/data/5000_intervals_unsorted.txt +5003 -0
  39. pygenogrove-0.2.0/external/genogrove/benchmarks/data/500_intervals_sorted.txt +503 -0
  40. pygenogrove-0.2.0/external/genogrove/benchmarks/data/500_intervals_unsorted.txt +503 -0
  41. pygenogrove-0.2.0/external/genogrove/benchmarks/data/Makefile +50 -0
  42. pygenogrove-0.2.0/external/genogrove/benchmarks/data/cli/query/basic/query/3p-partial/10K_sorted.bed +10000 -0
  43. pygenogrove-0.2.0/external/genogrove/benchmarks/data/cli/query/basic/query/5p-partial/10K_sorted.bed +10000 -0
  44. pygenogrove-0.2.0/external/genogrove/benchmarks/data/cli/query/basic/query/contained/10K_sorted.bed +10000 -0
  45. pygenogrove-0.2.0/external/genogrove/benchmarks/data/cli/query/basic/query/enclosed/10K_sorted.bed +10000 -0
  46. pygenogrove-0.2.0/external/genogrove/benchmarks/data/cli/query/basic/query/left-adjacent-gap/10K_sorted.bed +10000 -0
  47. pygenogrove-0.2.0/external/genogrove/benchmarks/data/cli/query/basic/query/mid-gap1/10K_sorted.bed +10000 -0
  48. pygenogrove-0.2.0/external/genogrove/benchmarks/data/cli/query/basic/query/mid-gap2/10K_sorted.bed +10000 -0
  49. pygenogrove-0.2.0/external/genogrove/benchmarks/data/cli/query/basic/query/perfect/10K_sorted.bed +10000 -0
  50. pygenogrove-0.2.0/external/genogrove/benchmarks/data/cli/query/basic/query/perfect-gap/10K_sorted.bed +10000 -0
  51. pygenogrove-0.2.0/external/genogrove/benchmarks/data/cli/query/basic/query/right-adjacent-gap/10K_sorted.bed +10000 -0
  52. pygenogrove-0.2.0/external/genogrove/benchmarks/data/cli/query/basic/truth/10K_sorted.bed +100000 -0
  53. pygenogrove-0.2.0/external/genogrove/benchmarks/data/generate_intervals +0 -0
  54. pygenogrove-0.2.0/external/genogrove/benchmarks/data/generate_intervals.cpp +83 -0
  55. pygenogrove-0.2.0/external/genogrove/benchmarks/grove_creation.cpp +174 -0
  56. pygenogrove-0.2.0/external/genogrove/benchmarks/grove_serialization.cpp +107 -0
  57. pygenogrove-0.2.0/external/genogrove/benchmarks/visualize.py +604 -0
  58. pygenogrove-0.2.0/external/genogrove/cli/CMakeLists.txt +47 -0
  59. pygenogrove-0.2.0/external/genogrove/cli/include/handlers/bed.hpp +62 -0
  60. pygenogrove-0.2.0/external/genogrove/cli/include/handlers/gff.hpp +41 -0
  61. pygenogrove-0.2.0/external/genogrove/cli/include/handlers/links.hpp +53 -0
  62. pygenogrove-0.2.0/external/genogrove/cli/include/subcalls/index.hpp +36 -0
  63. pygenogrove-0.2.0/external/genogrove/cli/include/subcalls/intersect.hpp +32 -0
  64. pygenogrove-0.2.0/external/genogrove/cli/include/subcalls/subcall.hpp +22 -0
  65. pygenogrove-0.2.0/external/genogrove/cli/src/handlers/bed.cpp +58 -0
  66. pygenogrove-0.2.0/external/genogrove/cli/src/handlers/gff.cpp +48 -0
  67. pygenogrove-0.2.0/external/genogrove/cli/src/handlers/links.cpp +113 -0
  68. pygenogrove-0.2.0/external/genogrove/cli/src/index.cpp +167 -0
  69. pygenogrove-0.2.0/external/genogrove/cli/src/intersect.cpp +178 -0
  70. pygenogrove-0.2.0/external/genogrove/cli/src/main.cpp +95 -0
  71. pygenogrove-0.2.0/external/genogrove/cmake/genogrove_config.cmake.in +4 -0
  72. pygenogrove-0.2.0/external/genogrove/include/genogrove/config/version.hpp.in +3 -0
  73. pygenogrove-0.2.0/external/genogrove/include/genogrove/data_type/all.hpp +52 -0
  74. pygenogrove-0.2.0/external/genogrove/include/genogrove/data_type/flanking_query_result.hpp +98 -0
  75. pygenogrove-0.2.0/external/genogrove/include/genogrove/data_type/genomic_coordinate.hpp +268 -0
  76. pygenogrove-0.2.0/external/genogrove/include/genogrove/data_type/interval.hpp +224 -0
  77. pygenogrove-0.2.0/external/genogrove/include/genogrove/data_type/key.hpp +344 -0
  78. pygenogrove-0.2.0/external/genogrove/include/genogrove/data_type/key_type_base.hpp +25 -0
  79. pygenogrove-0.2.0/external/genogrove/include/genogrove/data_type/kmer.hpp +278 -0
  80. pygenogrove-0.2.0/external/genogrove/include/genogrove/data_type/numeric.hpp +196 -0
  81. pygenogrove-0.2.0/external/genogrove/include/genogrove/data_type/query_result.hpp +121 -0
  82. pygenogrove-0.2.0/external/genogrove/include/genogrove/data_type/registry.hpp +396 -0
  83. pygenogrove-0.2.0/external/genogrove/include/genogrove/data_type/serialization_traits.hpp +172 -0
  84. pygenogrove-0.2.0/external/genogrove/include/genogrove/io/bam_reader.hpp +462 -0
  85. pygenogrove-0.2.0/external/genogrove/include/genogrove/io/bed_reader.hpp +174 -0
  86. pygenogrove-0.2.0/external/genogrove/include/genogrove/io/bgzf_utils.hpp +38 -0
  87. pygenogrove-0.2.0/external/genogrove/include/genogrove/io/fasta_index.hpp +133 -0
  88. pygenogrove-0.2.0/external/genogrove/include/genogrove/io/fasta_reader.hpp +109 -0
  89. pygenogrove-0.2.0/external/genogrove/include/genogrove/io/file_reader.hpp +175 -0
  90. pygenogrove-0.2.0/external/genogrove/include/genogrove/io/filetype_detector.hpp +47 -0
  91. pygenogrove-0.2.0/external/genogrove/include/genogrove/io/gff_reader.hpp +162 -0
  92. pygenogrove-0.2.0/external/genogrove/include/genogrove/io/gg_format.hpp +78 -0
  93. pygenogrove-0.2.0/external/genogrove/include/genogrove/io/kstring_guard.hpp +30 -0
  94. pygenogrove-0.2.0/external/genogrove/include/genogrove/structure/all.hpp +25 -0
  95. pygenogrove-0.2.0/external/genogrove/include/genogrove/structure/grove/graph_overlay.hpp +386 -0
  96. pygenogrove-0.2.0/external/genogrove/include/genogrove/structure/grove/grove.hpp +355 -0
  97. pygenogrove-0.2.0/external/genogrove/include/genogrove/structure/grove/grove_flanking.ipp +205 -0
  98. pygenogrove-0.2.0/external/genogrove/include/genogrove/structure/grove/grove_graph.ipp +369 -0
  99. pygenogrove-0.2.0/external/genogrove/include/genogrove/structure/grove/grove_insert.ipp +572 -0
  100. pygenogrove-0.2.0/external/genogrove/include/genogrove/structure/grove/grove_query.ipp +125 -0
  101. pygenogrove-0.2.0/external/genogrove/include/genogrove/structure/grove/grove_remove.ipp +383 -0
  102. pygenogrove-0.2.0/external/genogrove/include/genogrove/structure/grove/grove_serialize.ipp +237 -0
  103. pygenogrove-0.2.0/external/genogrove/include/genogrove/structure/grove/node.hpp +526 -0
  104. pygenogrove-0.2.0/external/genogrove/include/genogrove/structure/grove/pod_io.hpp +35 -0
  105. pygenogrove-0.2.0/external/genogrove/include/genogrove/structure/grove/zlib_streambuf.hpp +202 -0
  106. pygenogrove-0.2.0/external/genogrove/include/genogrove/utility/char_utils.hpp +19 -0
  107. pygenogrove-0.2.0/external/genogrove/include/genogrove/utility/ranges.hpp +64 -0
  108. pygenogrove-0.2.0/external/genogrove/include/genogrove/utility/tokenizer.hpp +65 -0
  109. pygenogrove-0.2.0/external/genogrove/release.json +0 -0
  110. pygenogrove-0.2.0/external/genogrove/src/data_type/genomic_coordinate.cpp +35 -0
  111. pygenogrove-0.2.0/external/genogrove/src/data_type/interval.cpp +35 -0
  112. pygenogrove-0.2.0/external/genogrove/src/data_type/kmer.cpp +64 -0
  113. pygenogrove-0.2.0/external/genogrove/src/data_type/numeric.cpp +32 -0
  114. pygenogrove-0.2.0/external/genogrove/src/io/bam_reader.cpp +488 -0
  115. pygenogrove-0.2.0/external/genogrove/src/io/bed_reader.cpp +551 -0
  116. pygenogrove-0.2.0/external/genogrove/src/io/bgzf_utils.cpp +68 -0
  117. pygenogrove-0.2.0/external/genogrove/src/io/fasta_index.cpp +123 -0
  118. pygenogrove-0.2.0/external/genogrove/src/io/fasta_reader.cpp +148 -0
  119. pygenogrove-0.2.0/external/genogrove/src/io/filetype_detector.cpp +116 -0
  120. pygenogrove-0.2.0/external/genogrove/src/io/gff_reader.cpp +553 -0
  121. pygenogrove-0.2.0/external/genogrove/src/io/gg_format.cpp +108 -0
  122. pygenogrove-0.2.0/external/genogrove/tests/CMakeLists.txt +156 -0
  123. pygenogrove-0.2.0/external/genogrove/tests/README.md +206 -0
  124. pygenogrove-0.2.0/external/genogrove/tests/cli/data/links.tsv +3 -0
  125. pygenogrove-0.2.0/external/genogrove/tests/cli/data/query.bed +3 -0
  126. pygenogrove-0.2.0/external/genogrove/tests/cli/data/query.gff +4 -0
  127. pygenogrove-0.2.0/external/genogrove/tests/cli/data/target.bed +3 -0
  128. pygenogrove-0.2.0/external/genogrove/tests/cli/data/target.gff +4 -0
  129. pygenogrove-0.2.0/external/genogrove/tests/cli/data/target_links.bed +3 -0
  130. pygenogrove-0.2.0/external/genogrove/tests/cli/index-e2e-test.cpp +393 -0
  131. pygenogrove-0.2.0/external/genogrove/tests/cli/intersect-e2e-test.cpp +334 -0
  132. pygenogrove-0.2.0/external/genogrove/tests/cli/intersect-test.cpp +256 -0
  133. pygenogrove-0.2.0/external/genogrove/tests/cli/links-test.cpp +103 -0
  134. pygenogrove-0.2.0/external/genogrove/tests/config/version_test.cpp +32 -0
  135. pygenogrove-0.2.0/external/genogrove/tests/data_type/genomic_coordinate_test.cpp +429 -0
  136. pygenogrove-0.2.0/external/genogrove/tests/data_type/interval_test.cpp +451 -0
  137. pygenogrove-0.2.0/external/genogrove/tests/data_type/key_test.cpp +29 -0
  138. pygenogrove-0.2.0/external/genogrove/tests/data_type/key_type_tests/genomic_coordinate_key_test.cpp +280 -0
  139. pygenogrove-0.2.0/external/genogrove/tests/data_type/key_type_tests/interval_key_test.cpp +227 -0
  140. pygenogrove-0.2.0/external/genogrove/tests/data_type/key_type_tests/key_comparison_typed_test.hpp +129 -0
  141. pygenogrove-0.2.0/external/genogrove/tests/data_type/key_type_tests/numeric_key_test.cpp +255 -0
  142. pygenogrove-0.2.0/external/genogrove/tests/data_type/kmer_test.cpp +384 -0
  143. pygenogrove-0.2.0/external/genogrove/tests/data_type/numeric_test.cpp +303 -0
  144. pygenogrove-0.2.0/external/genogrove/tests/data_type/query_result_test.cpp +182 -0
  145. pygenogrove-0.2.0/external/genogrove/tests/data_type/registry_test.cpp +937 -0
  146. pygenogrove-0.2.0/external/genogrove/tests/data_type/serialization_traits_test.cpp +182 -0
  147. pygenogrove-0.2.0/external/genogrove/tests/io/bamfile-test.cpp +1230 -0
  148. pygenogrove-0.2.0/external/genogrove/tests/io/bedfile-test.cpp +1090 -0
  149. pygenogrove-0.2.0/external/genogrove/tests/io/data/temp_invalid.bed +1 -0
  150. pygenogrove-0.2.0/external/genogrove/tests/io/data/test.bam +0 -0
  151. pygenogrove-0.2.0/external/genogrove/tests/io/data/test.fa +7 -0
  152. pygenogrove-0.2.0/external/genogrove/tests/io/data/test.fa.gz +0 -0
  153. pygenogrove-0.2.0/external/genogrove/tests/io/data/test.fq +12 -0
  154. pygenogrove-0.2.0/external/genogrove/tests/io/data/test.fq.gz +0 -0
  155. pygenogrove-0.2.0/external/genogrove/tests/io/data/test.gtf +4 -0
  156. pygenogrove-0.2.0/external/genogrove/tests/io/data/test.gtf.gz +0 -0
  157. pygenogrove-0.2.0/external/genogrove/tests/io/data/test.sam +18 -0
  158. pygenogrove-0.2.0/external/genogrove/tests/io/data/test_bed12.bed +3 -0
  159. pygenogrove-0.2.0/external/genogrove/tests/io/data/test_bed12.bed.gz +0 -0
  160. pygenogrove-0.2.0/external/genogrove/tests/io/data/test_bed3.bed +3 -0
  161. pygenogrove-0.2.0/external/genogrove/tests/io/data/test_bed3.bed.gz +0 -0
  162. pygenogrove-0.2.0/external/genogrove/tests/io/data/test_bed6.bed +3 -0
  163. pygenogrove-0.2.0/external/genogrove/tests/io/data/test_bed6.bed.gz +0 -0
  164. pygenogrove-0.2.0/external/genogrove/tests/io/data/test_boundary_coords.gff +3 -0
  165. pygenogrove-0.2.0/external/genogrove/tests/io/data/test_compression.bed +3 -0
  166. pygenogrove-0.2.0/external/genogrove/tests/io/data/test_compression.bed.bz2 +0 -0
  167. pygenogrove-0.2.0/external/genogrove/tests/io/data/test_compression.bed.gz +0 -0
  168. pygenogrove-0.2.0/external/genogrove/tests/io/data/test_compression.bed.lz4 +0 -0
  169. pygenogrove-0.2.0/external/genogrove/tests/io/data/test_compression.bed.xz +0 -0
  170. pygenogrove-0.2.0/external/genogrove/tests/io/data/test_compression.bed.zst +0 -0
  171. pygenogrove-0.2.0/external/genogrove/tests/io/data/test_empty_seq.fa +6 -0
  172. pygenogrove-0.2.0/external/genogrove/tests/io/data/test_gff3.gff +5 -0
  173. pygenogrove-0.2.0/external/genogrove/tests/io/data/test_gff3.gff.gz +0 -0
  174. pygenogrove-0.2.0/external/genogrove/tests/io/data/test_indexed.fa +8 -0
  175. pygenogrove-0.2.0/external/genogrove/tests/io/data/test_invalid.bed +3 -0
  176. pygenogrove-0.2.0/external/genogrove/tests/io/data/test_invalid.gff +2 -0
  177. pygenogrove-0.2.0/external/genogrove/tests/io/data/test_invalid_block_bounds.bed +1 -0
  178. pygenogrove-0.2.0/external/genogrove/tests/io/data/test_invalid_blocks.bed +1 -0
  179. pygenogrove-0.2.0/external/genogrove/tests/io/data/test_invalid_phase.gff +2 -0
  180. pygenogrove-0.2.0/external/genogrove/tests/io/data/test_invalid_score.gff +2 -0
  181. pygenogrove-0.2.0/external/genogrove/tests/io/data/test_invalid_strand.gff +2 -0
  182. pygenogrove-0.2.0/external/genogrove/tests/io/data/test_missing_gene_id.gtf +1 -0
  183. pygenogrove-0.2.0/external/genogrove/tests/io/data/test_missing_transcript_id.gtf +2 -0
  184. pygenogrove-0.2.0/external/genogrove/tests/io/data/test_mixed_bed.bed +3 -0
  185. pygenogrove-0.2.0/external/genogrove/tests/io/data/test_plain_gzip.gtf.gz +0 -0
  186. pygenogrove-0.2.0/external/genogrove/tests/io/data/test_quoted_semicolon.gtf +2 -0
  187. pygenogrove-0.2.0/external/genogrove/tests/io/filetype-detector-test.cpp +229 -0
  188. pygenogrove-0.2.0/external/genogrove/tests/io/gfffile-test.cpp +1145 -0
  189. pygenogrove-0.2.0/external/genogrove/tests/io/gg_format_test.cpp +167 -0
  190. pygenogrove-0.2.0/external/genogrove/tests/io/indexedfasta-test.cpp +206 -0
  191. pygenogrove-0.2.0/external/genogrove/tests/io/sequencefile-test.cpp +311 -0
  192. pygenogrove-0.2.0/external/genogrove/tests/structure/dataless_grove_test.cpp +68 -0
  193. pygenogrove-0.2.0/external/genogrove/tests/structure/genomic_coordinate_grove_test.cpp +363 -0
  194. pygenogrove-0.2.0/external/genogrove/tests/structure/graph_overlay_test.cpp +1121 -0
  195. pygenogrove-0.2.0/external/genogrove/tests/structure/grove_flanking_test.cpp +180 -0
  196. pygenogrove-0.2.0/external/genogrove/tests/structure/grove_remove_test.cpp +901 -0
  197. pygenogrove-0.2.0/external/genogrove/tests/structure/heterogeneous_grove_test.cpp +177 -0
  198. pygenogrove-0.2.0/external/genogrove/tests/structure/interval_grove_test.cpp +144 -0
  199. pygenogrove-0.2.0/external/genogrove/tests/structure/key_type_grove_test.hpp +1226 -0
  200. pygenogrove-0.2.0/external/genogrove/tests/structure/kmer_grove_test.cpp +258 -0
  201. pygenogrove-0.2.0/external/genogrove/tests/structure/numeric_grove_test.cpp +68 -0
  202. pygenogrove-0.2.0/external/genogrove/tests/structure/precondition_test.cpp +266 -0
  203. pygenogrove-0.2.0/external/genogrove/tests/structure/serialization_test.cpp +140 -0
  204. pygenogrove-0.2.0/external/genogrove/tests/structure/tree_validator.hpp +138 -0
  205. pygenogrove-0.2.0/external/genogrove/tests/utility/ranges-test.cpp +35 -0
  206. pygenogrove-0.2.0/external/genogrove/tests/utility/tokenizer-test.cpp +188 -0
  207. pygenogrove-0.2.0/pyproject.toml +92 -0
  208. pygenogrove-0.2.0/src/bindings.cpp +73 -0
  209. pygenogrove-0.2.0/src/data_type/flanking_query_result.hpp +42 -0
  210. pygenogrove-0.2.0/src/data_type/genomic_coordinate.hpp +95 -0
  211. pygenogrove-0.2.0/src/data_type/interval.hpp +60 -0
  212. pygenogrove-0.2.0/src/data_type/key.hpp +50 -0
  213. pygenogrove-0.2.0/src/data_type/query_result.hpp +32 -0
  214. pygenogrove-0.2.0/src/io/bed_reader.hpp +164 -0
  215. pygenogrove-0.2.0/src/io/entry_interval.hpp +59 -0
  216. pygenogrove-0.2.0/src/io/gff_reader.hpp +150 -0
  217. pygenogrove-0.2.0/src/structure/grove.hpp +401 -0
  218. pygenogrove-0.2.0/tests/__init__.py +1 -0
  219. pygenogrove-0.2.0/tests/conftest.py +20 -0
  220. pygenogrove-0.2.0/tests/data_type/__init__.py +1 -0
  221. pygenogrove-0.2.0/tests/data_type/test_bed_key.py +76 -0
  222. pygenogrove-0.2.0/tests/data_type/test_genomic_coordinate.py +175 -0
  223. pygenogrove-0.2.0/tests/data_type/test_gff_key.py +77 -0
  224. pygenogrove-0.2.0/tests/data_type/test_interval.py +139 -0
  225. pygenogrove-0.2.0/tests/data_type/test_key.py +57 -0
  226. pygenogrove-0.2.0/tests/data_type/test_query_result.py +84 -0
  227. pygenogrove-0.2.0/tests/io/__init__.py +1 -0
  228. pygenogrove-0.2.0/tests/io/test_bed_entry.py +117 -0
  229. pygenogrove-0.2.0/tests/io/test_bed_reader.py +249 -0
  230. pygenogrove-0.2.0/tests/io/test_gff_entry.py +150 -0
  231. pygenogrove-0.2.0/tests/io/test_gff_reader.py +206 -0
  232. pygenogrove-0.2.0/tests/structure/__init__.py +1 -0
  233. pygenogrove-0.2.0/tests/structure/test_bed_grove.py +104 -0
  234. pygenogrove-0.2.0/tests/structure/test_bed_grove_serialization.py +104 -0
  235. pygenogrove-0.2.0/tests/structure/test_bulk_insert.py +196 -0
  236. pygenogrove-0.2.0/tests/structure/test_dataless_grove.py +153 -0
  237. pygenogrove-0.2.0/tests/structure/test_entry_insert.py +156 -0
  238. pygenogrove-0.2.0/tests/structure/test_flanking.py +165 -0
  239. pygenogrove-0.2.0/tests/structure/test_genomic_coordinate_grove.py +138 -0
  240. pygenogrove-0.2.0/tests/structure/test_gff_grove.py +108 -0
  241. pygenogrove-0.2.0/tests/structure/test_gff_grove_serialization.py +204 -0
  242. pygenogrove-0.2.0/tests/structure/test_graph_overlay.py +302 -0
  243. pygenogrove-0.2.0/tests/structure/test_serialization.py +150 -0
  244. pygenogrove-0.2.0/tests/test_imports.py +58 -0
  245. pygenogrove-0.2.0/tests/test_version.py +31 -0
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env bash
2
+ #
3
+ # Build htslib from source inside the cibuildwheel manylinux container.
4
+ #
5
+ # genogrove (pulled in via add_subdirectory) does `pkg_check_modules(HTSLIB
6
+ # REQUIRED htslib)`, so htslib must be present at configure/build time even
7
+ # though pygenogrove only binds the interval/grove surface. The manylinux_2_28
8
+ # image (AlmaLinux 8) has no htslib package, so we build it from source into
9
+ # /usr/local; auditwheel then bundles libhts into the repaired wheel.
10
+ #
11
+ # Runs once per container via cibuildwheel's `before-all`.
12
+ set -euo pipefail
13
+
14
+ HTSLIB_VERSION="${HTSLIB_VERSION:-1.21}"
15
+ # SHA256 of the official htslib-${HTSLIB_VERSION}.tar.bz2 release asset. Pinned so
16
+ # the download is verified before extraction (supply-chain guard in the publish
17
+ # path). Keep in sync with HTSLIB_VERSION — re-verify against the samtools release
18
+ # when bumping. An override of HTSLIB_VERSION without HTSLIB_SHA256 fails closed.
19
+ HTSLIB_SHA256="${HTSLIB_SHA256:-84b510e735f4963641f26fd88c8abdee81ff4cb62168310ae716636aac0f1823}"
20
+
21
+ # Build deps for htslib (+ the compression/network backends it links).
22
+ dnf install -y \
23
+ autoconf automake make gcc perl \
24
+ zlib-devel bzip2-devel xz-devel libcurl-devel openssl-devel
25
+
26
+ curl -fsSL -o /tmp/htslib.tar.bz2 \
27
+ "https://github.com/samtools/htslib/releases/download/${HTSLIB_VERSION}/htslib-${HTSLIB_VERSION}.tar.bz2"
28
+ # Verify the tarball against the pinned checksum; abort (no extraction) on mismatch.
29
+ echo "${HTSLIB_SHA256} /tmp/htslib.tar.bz2" | sha256sum -c -
30
+ mkdir -p /tmp/htslib
31
+ tar -xjf /tmp/htslib.tar.bz2 -C /tmp/htslib --strip-components=1
32
+
33
+ cd /tmp/htslib
34
+ ./configure
35
+ make -j"$(nproc)"
36
+ make install # -> /usr/local/lib/libhts.so, /usr/local/lib/pkgconfig/htslib.pc
37
+ ldconfig
@@ -0,0 +1,51 @@
1
+ name: CI
2
+ on:
3
+ push:
4
+ branches: [main]
5
+ pull_request:
6
+
7
+ jobs:
8
+ test:
9
+ name: ${{ matrix.os }} / py${{ matrix.python-version }}
10
+ runs-on: ${{ matrix.os }}
11
+ strategy:
12
+ fail-fast: false
13
+ matrix:
14
+ os: [ubuntu-24.04, macos-14]
15
+ python-version: ["3.9", "3.10", "3.11", "3.12"]
16
+
17
+ steps:
18
+ - name: Checkout (with genogrove submodule)
19
+ uses: actions/checkout@v6
20
+ with:
21
+ submodules: recursive
22
+
23
+ # The genogrove C++ library (pulled in via add_subdirectory) links htslib,
24
+ # so it must be present at configure/build time even though pygenogrove
25
+ # currently only binds the interval/grove surface.
26
+ - name: Install htslib (Linux)
27
+ if: runner.os == 'Linux'
28
+ run: |
29
+ sudo apt-get update
30
+ sudo apt-get install -y libhts-dev
31
+
32
+ - name: Install htslib (macOS)
33
+ if: runner.os == 'macOS'
34
+ run: brew install htslib
35
+
36
+ - name: Set up Python ${{ matrix.python-version }}
37
+ uses: actions/setup-python@v6
38
+ with:
39
+ python-version: ${{ matrix.python-version }}
40
+
41
+ - name: Upgrade pip
42
+ run: python -m pip install --upgrade pip
43
+
44
+ # scikit-build-core drives CMake (fetching pybind11 via FetchContent) and
45
+ # auto-provisions cmake/ninja if the runner lacks them. The editable
46
+ # install builds the C++20 extension and makes `import pygenogrove` work.
47
+ - name: Build and install (with dev extras)
48
+ run: python -m pip install -e ".[dev]" --verbose
49
+
50
+ - name: Run tests
51
+ run: python -m pytest tests/ -v
@@ -0,0 +1,81 @@
1
+ name: Release
2
+
3
+ # Build wheels + sdist on every version tag, then publish to PyPI via Trusted
4
+ # Publishing (OIDC — no API tokens). workflow_dispatch allows a manual run to
5
+ # (re)publish whatever version is in pyproject.toml on the chosen ref.
6
+ on:
7
+ push:
8
+ tags: ["v*"]
9
+ workflow_dispatch:
10
+
11
+ jobs:
12
+ build_wheels:
13
+ name: Wheels (${{ matrix.os }})
14
+ runs-on: ${{ matrix.os }}
15
+ strategy:
16
+ fail-fast: false
17
+ matrix:
18
+ # ubuntu = manylinux x86_64; macos-14 = arm64 (Apple Silicon).
19
+ # No macOS x86_64 wheels: GitHub's Intel macos-13 runners are being
20
+ # retired and don't reliably allocate (jobs hang queued), and x86_64
21
+ # can't be cross-compiled here (Homebrew htslib is native-arch only).
22
+ # Intel Macs install from the sdist.
23
+ os: [ubuntu-24.04, macos-14]
24
+ steps:
25
+ - name: Checkout (with genogrove submodule)
26
+ uses: actions/checkout@v6
27
+ with:
28
+ submodules: recursive
29
+
30
+ - name: Build wheels
31
+ uses: pypa/cibuildwheel@v3.4.1
32
+ # All build config (target Pythons, htslib provisioning, smoke test)
33
+ # lives in [tool.cibuildwheel] in pyproject.toml.
34
+
35
+ - name: Upload wheels
36
+ uses: actions/upload-artifact@v7
37
+ with:
38
+ name: wheels-${{ matrix.os }}
39
+ path: ./wheelhouse/*.whl
40
+
41
+ build_sdist:
42
+ name: Source distribution
43
+ runs-on: ubuntu-24.04
44
+ steps:
45
+ - name: Checkout (with genogrove submodule)
46
+ uses: actions/checkout@v6
47
+ with:
48
+ submodules: recursive
49
+
50
+ - name: Set up Python
51
+ uses: actions/setup-python@v6
52
+ with:
53
+ python-version: "3.12"
54
+
55
+ - name: Build sdist
56
+ run: pipx run build --sdist
57
+
58
+ - name: Upload sdist
59
+ uses: actions/upload-artifact@v7
60
+ with:
61
+ name: sdist
62
+ path: dist/*.tar.gz
63
+
64
+ publish:
65
+ name: Publish to PyPI
66
+ needs: [build_wheels, build_sdist]
67
+ runs-on: ubuntu-24.04
68
+ # Only publish on an actual tag push, never on a bare workflow_dispatch test run.
69
+ if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
70
+ environment: pypi
71
+ permissions:
72
+ id-token: write # mandatory for Trusted Publishing (OIDC)
73
+ steps:
74
+ - name: Download all artifacts
75
+ uses: actions/download-artifact@v8
76
+ with:
77
+ path: dist
78
+ merge-multiple: true
79
+
80
+ - name: Publish to PyPI
81
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,156 @@
1
+ # Created by https://www.toptal.com/developers/gitignore/api/cmake,macos,c++
2
+ # Edit at https://www.toptal.com/developers/gitignore?templates=cmake,macos,c++
3
+
4
+ ### C++ ###
5
+ # Prerequisites
6
+ *.d
7
+
8
+ # Compiled Object files
9
+ *.slo
10
+ *.lo
11
+ *.o
12
+ *.obj
13
+
14
+ # Precompiled Headers
15
+ *.gch
16
+ *.pch
17
+
18
+ # Compiled Dynamic libraries
19
+ *.so
20
+ *.dylib
21
+ *.dll
22
+
23
+ # Fortran module files
24
+ *.mod
25
+ *.smod
26
+
27
+ # Compiled Static libraries
28
+ *.lai
29
+ *.la
30
+ *.a
31
+ *.lib
32
+
33
+ # Executables
34
+ *.exe
35
+ *.out
36
+ *.app
37
+
38
+ ### CMake ###
39
+ CMakeLists.txt.user
40
+ CMakeCache.txt
41
+ CMakeFiles
42
+ CMakeScripts
43
+ Testing
44
+ #Makefile
45
+ cmake_install.cmake
46
+ install_manifest.txt
47
+ compile_commands.json
48
+ CTestTestfile.cmake
49
+ _deps
50
+
51
+ ### CMake Patch ###
52
+ CMakeUserPresets.json
53
+
54
+ # External projects
55
+ *-prefix/
56
+
57
+ ### macOS ###
58
+ # General
59
+ .DS_Store
60
+ .AppleDouble
61
+ .LSOverride
62
+
63
+ # Icon must end with two \r
64
+ Icon
65
+
66
+
67
+ # Thumbnails
68
+ ._*
69
+
70
+ # Files that might appear in the root of a volume
71
+ .DocumentRevisions-V100
72
+ .fseventsd
73
+ .Spotlight-V100
74
+ .TemporaryItems
75
+ .Trashes
76
+ .VolumeIcon.icns
77
+ .com.apple.timemachine.donotpresent
78
+
79
+ # Directories potentially created on remote AFP share
80
+ .AppleDB
81
+ .AppleDesktop
82
+ Network Trash Folder
83
+ Temporary Items
84
+ .apdisk
85
+
86
+ ### macOS Patch ###
87
+ # iCloud generated files
88
+ *.icloud
89
+
90
+ build
91
+ .cache
92
+ CLAUDE.md
93
+
94
+ ### Python ###
95
+ # Byte-compiled / optimized / DLL files
96
+ __pycache__/
97
+ *.py[cod]
98
+ *$py.class
99
+
100
+ # Distribution / packaging
101
+ .Python
102
+ dist/
103
+ *.egg-info/
104
+ .eggs/
105
+ *.egg
106
+ wheels/
107
+ *.whl
108
+
109
+ # PyInstaller
110
+ *.manifest
111
+ *.spec
112
+
113
+ # Unit test / coverage reports
114
+ htmlcov/
115
+ .tox/
116
+ .nox/
117
+ .coverage
118
+ .coverage.*
119
+ .cache
120
+ .pytest_cache/
121
+ nosetests.xml
122
+ coverage.xml
123
+ *.cover
124
+ *.log
125
+
126
+ # Virtual environments
127
+ venv/
128
+ env/
129
+ ENV/
130
+ .venv
131
+
132
+ # IDEs
133
+ .vscode/
134
+ .idea/
135
+
136
+ # Jupyter Notebook
137
+ .ipynb_checkpoints
138
+
139
+ # pyenv
140
+ .python-version
141
+
142
+ # Type checkers
143
+ .mypy_cache/
144
+ .dmypy.json
145
+ dmypy.json
146
+
147
+ # Pyre type checker
148
+ .pyre/
149
+
150
+ # pyright
151
+ .pyright/
152
+
153
+ # Internal Claude Code config — not for the repo
154
+ .claude/
155
+
156
+ # End of https://www.toptal.com/developers/gitignore/api/cmake,macos,c++
@@ -0,0 +1,3 @@
1
+ [submodule "external/genogrove"]
2
+ path = external/genogrove
3
+ url = https://github.com/genogrove/genogrove.git
@@ -0,0 +1,42 @@
1
+ # Changelog
2
+
3
+ All notable changes to pygenogrove will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [0.2.0] - 2026-06-10
11
+
12
+ ### Added
13
+
14
+ - **Stranded `GenomicCoordinate` key type and `GenomicCoordinateGrove`** — `grove<genomic_coordinate>` exposed as `GenomicCoordinateGrove` / `GenomicCoordinateKey` / `GenomicCoordinateQueryResult` / `GenomicCoordinateFlankingResult`, plus the `GenomicCoordinate` value type (ctor `(strand, start, end)`; `strand`/`start`/`end`; `set_range`/`set_strand`; `overlaps`; comparisons). Overlap is **strand-aware** — equal strands match, `'*'` is a wildcard matching any strand, `'.'` is a concrete unstranded value — and sorting is coordinate-first (start → end → strand, `* < . < + < -`). Dataless grove only; reuses the generic `bind_grove<KeyT, DataT>` template, so insert / strand-aware intersect / flanking / graph overlay / serialization all come for free ([#1](https://github.com/genogrove/pygenogrove/issues/1), [#15](https://github.com/genogrove/pygenogrove/pull/15)).
15
+
16
+ ### Changed
17
+
18
+ - **PyPI release pipeline** — tagged releases now build manylinux x86_64 + macOS arm64 (Apple Silicon) wheels for CPython 3.9–3.12 and an sdist via cibuildwheel, then publish to PyPI through OIDC Trusted Publishing (no API tokens). htslib is provisioned and bundled into each wheel (built from source on manylinux, Homebrew on macOS), so `pip install pygenogrove` works without a system htslib. **macOS wheels are arm64-only and require macOS 14.0+** (the arm64 Homebrew bottles set the 14.0 floor; genogrove's `std::format` needs libc++ ≥ 13.3 regardless). **Intel Macs install from the sdist** — GitHub's hosted Intel runners are being retired, so x86_64 macOS wheels are not built ([#1](https://github.com/genogrove/pygenogrove/issues/1), [#14](https://github.com/genogrove/pygenogrove/pull/14), [#16](https://github.com/genogrove/pygenogrove/pull/16), [#17](https://github.com/genogrove/pygenogrove/pull/17), [#18](https://github.com/genogrove/pygenogrove/pull/18)).
19
+
20
+ ## [0.1.0] - 2026-06-09
21
+
22
+ ### Added
23
+
24
+ - **Version introspection** — `pygenogrove.__version__` (single-sourced from `pyproject.toml` at build time, no longer hardcoded in `bindings.cpp`) and `pygenogrove.__genogrove_version__` (the genogrove C++ library version the wheel was built against, read from genogrove's generated `config/version.hpp`). The two version lines follow independent SemVer cadences ([#1](https://github.com/genogrove/pygenogrove/issues/1), [#13](https://github.com/genogrove/pygenogrove/pull/13)).
25
+ - **Graph overlay on `grove<interval>`** — directed-edge operations (`add_edge`, `remove_edge`, `has_edge`, `get_neighbors`, `out_degree`, `edge_count`, `vertex_count_with_edges`) and `add_external_key` for graph-only keys outside the B+ tree index ([#1](https://github.com/genogrove/pygenogrove/issues/1), [#2](https://github.com/genogrove/pygenogrove/pull/2)).
26
+ - **Grove serialization** — `serialize(path)` and static `deserialize(path) -> Grove` over the zlib-compressed `.gg` binary format, with open/write failures surfaced as Python exceptions ([#1](https://github.com/genogrove/pygenogrove/issues/1), [#2](https://github.com/genogrove/pygenogrove/pull/2)).
27
+ - **CI, packaging, and tests** — GitHub Actions matrix build (Linux/macOS × Python 3.9–3.12), scikit-build-core `pyproject.toml`, and pytest suites for the graph overlay and serialization ([#1](https://github.com/genogrove/pygenogrove/issues/1), [#2](https://github.com/genogrove/pygenogrove/pull/2)).
28
+ - **Expanded test coverage** — ported the missing cases from the genogrove C++ suites for the bound surface (interval edge cases, node splits, graph edge directions / traversal / pointer stability, serialization round-trips); test count 25 → 55. The suite now mirrors the genogrove layout: `tests/data_type/` (`test_interval`, `test_key`, `test_query_result`) and `tests/structure/` (`test_dataless_grove`, `test_graph_overlay`, `test_serialization`), with snake_case test names matching the corresponding C++ cases ([#1](https://github.com/genogrove/pygenogrove/issues/1), [#3](https://github.com/genogrove/pygenogrove/pull/3)).
29
+ - **Data-carrying `BedGrove`** — `grove<interval, bed_entry>` exposed as `BedGrove` / `BedKey` / `BedQueryResult`, so prebuilt `.gg` files carrying BED records can be loaded, queried, and traversed from Python. `insert(index, interval, data)` and `add_external_key(interval, data)` take a `BedEntry` payload; `BedKey.data` is a live mutable reference (the payload is not part of B+ tree ordering) while `BedKey.value` is still returned by copy; `serialize`/`deserialize` round-trip the BED data. Also exposes the `BedEntry` value type (+ `BlockInfo` / `ThickInfo` / `RgbColor`). The binding sources were reorganized to mirror the genogrove tree (`src/data_type/`, `src/io/`, `src/structure/`), with the dataless and data-carrying groves sharing one `bind_grove<DataT>` template (the existing `Grove` surface is unchanged) ([#1](https://github.com/genogrove/pygenogrove/issues/1), [#4](https://github.com/genogrove/pygenogrove/pull/4)).
30
+ - **Data-carrying `GffGrove`** — `grove<interval, gff_entry>` exposed as `GffGrove` / `GffKey` / `GffQueryResult` (same surface as `BedGrove`), with the `GffEntry` value type, the `GffFormat` enum, the column-9 `attributes` as a `dict[str, str]`, and the GTF helper accessors (`get_gene_id`, `get_transcript_id`, `get_exon_number`, `get_gene_name`, `get_gene_biotype`, `is_gtf`/`is_gff3`). Reuses the `bind_interval_grove<DataT>` template; tests port the applicable genogrove `gfffile-test.cpp` cases. The data-carrying key value/data/lifetime tests were split into `tests/data_type/test_{bed,gff}_key.py` to match genogrove's `key_type_tests/` layout ([#1](https://github.com/genogrove/pygenogrove/issues/1), [#8](https://github.com/genogrove/pygenogrove/pull/8)).
31
+
32
+ - **BED/GFF file readers** — `BedReader` and `GffReader`, single-pass Python iterators over BED and GFF3/GTF files yielding `BedEntry` / `GffEntry`. Options are keyword args (`skip_invalid_lines`; `validate_gtf` for GFF); a missing file raises on construction, a malformed line raises `RuntimeError` (unless skipped), and plain/gzip/BGZF (`.gz`) inputs are auto-detected. Both expose `get_error_message()` / `get_current_line()`. Note: the first data record is validated at construction, so a malformed first record raises regardless of `skip_invalid_lines` ([#1](https://github.com/genogrove/pygenogrove/issues/1), [#9](https://github.com/genogrove/pygenogrove/pull/9)).
33
+ - **Sorted / bulk insertion** — `insert_sorted(index, interval, data)` (rightmost-append fast path) and `insert_bulk(index, items, presorted=False)` (insert many `(Interval, data)` records at once; 10–20× faster for large datasets, empty index built bottom-up in O(n)) on the data-carrying groves. Plus **entry-deriving overloads** `insert(index, entry)` and `insert_bulk(index, entries)` that compute the `Interval` key from a BED/GFF record's native coordinates (BED 0-based half-open, GFF 1-based), so callers never hand-convert — the conversion lives in one place (`src/io/entry_interval.hpp`). These require associated data, so they're absent on the dataless `Grove` ([#1](https://github.com/genogrove/pygenogrove/issues/1), [#10](https://github.com/genogrove/pygenogrove/pull/10)).
34
+ - **Nearest-neighbour queries** — `Grove.flanking(query, index) -> FlankingResult` returns the closest non-overlapping keys on either side of a query (`.predecessor` / `.successor`, each a `Key` or `None`); keys overlapping the query are excluded and, for nested intervals, the predecessor is the one with the largest end (smallest gap). Exposed on all groves (`FlankingResult` / `BedFlankingResult` / `GffFlankingResult`); the result and its keys keep the grove alive ([#1](https://github.com/genogrove/pygenogrove/issues/1), [#11](https://github.com/genogrove/pygenogrove/pull/11)).
35
+
36
+ ### Fixed
37
+
38
+ - **`intersect()` result lifetime** — the `QueryResult` returned by `Grove.intersect()` (and the keys it yields) now keep the grove alive via `keep_alive<0,1>`. Previously a key or `.data`/`.value` reference materialized from an intersect result could outlive the grove, a latent use-after-free affecting every grove instantiation ([#8](https://github.com/genogrove/pygenogrove/pull/8)).
39
+
40
+ ### Refactored
41
+
42
+ - **Generalized the grove binding templates over the key type** — `bind_grove<KeyT, DataT>` (and `bind_key` / `bind_query_result` / `bind_flanking_query_result`) replace the interval-hardcoded versions, so additional key types can be added by instantiation rather than near-duplicate headers; the now-generic `interval_key.hpp` / `interval_grove.hpp` were renamed to `key.hpp` / `grove.hpp`. No change to the Python API ([#1](https://github.com/genogrove/pygenogrove/issues/1), [#12](https://github.com/genogrove/pygenogrove/pull/12)).
@@ -0,0 +1,62 @@
1
+ cmake_minimum_required(VERSION 3.15)
2
+ project(pygenogrove)
3
+
4
+ set(CMAKE_CXX_STANDARD 20)
5
+ set(CMAKE_CXX_STANDARD_REQUIRED ON)
6
+
7
+ # Single source of truth for the package version: pyproject.toml. scikit-build-core
8
+ # passes it in as SKBUILD_PROJECT_VERSION, which we forward to the module as a
9
+ # compile definition (see target_compile_definitions below) so the version lives
10
+ # in exactly one place. A plain `cmake` dev build (no scikit-build-core) gets a
11
+ # clearly-non-release marker instead of a stale hardcoded number.
12
+ if(DEFINED SKBUILD_PROJECT_VERSION)
13
+ set(PYGENOGROVE_VERSION "${SKBUILD_PROJECT_VERSION}")
14
+ else()
15
+ set(PYGENOGROVE_VERSION "0.0.0+local")
16
+ endif()
17
+
18
+ # Fetch pybind11
19
+ include(FetchContent)
20
+ FetchContent_Declare(
21
+ pybind11
22
+ GIT_REPOSITORY https://github.com/pybind/pybind11.git
23
+ GIT_TAG v2.13.6
24
+ )
25
+ FetchContent_MakeAvailable(pybind11)
26
+
27
+ # Add genogrove library — build it as a library only. Its test/CLI/benchmark
28
+ # targets need generated headers (e.g. config/version.hpp) and extra deps we
29
+ # don't use here, and would otherwise break the wheel build.
30
+ set(BUILD_TESTING OFF CACHE BOOL "" FORCE)
31
+ set(BUILD_CLI OFF CACHE BOOL "" FORCE)
32
+ set(BUILD_BENCHMARKS OFF CACHE BOOL "" FORCE)
33
+ # genogrove's static lib must be position-independent so it can be linked
34
+ # into the pybind11 shared module (.so); otherwise ld rejects the relocation.
35
+ set(CMAKE_POSITION_INDEPENDENT_CODE ON)
36
+ add_subdirectory(external/genogrove)
37
+
38
+ # Create Python module
39
+ pybind11_add_module(pygenogrove src/bindings.cpp)
40
+ target_link_libraries(pygenogrove PRIVATE genogrove)
41
+ target_include_directories(pygenogrove PRIVATE
42
+ ${CMAKE_SOURCE_DIR}/external/genogrove/include
43
+ # genogrove's version macros live in a header it generates at configure time
44
+ # into its own binary dir; expose it so bindings.cpp can report which
45
+ # genogrove it was built against (pygenogrove.__genogrove_version__).
46
+ ${genogrove_BINARY_DIR}/include
47
+ )
48
+
49
+ # PYGENOGROVE_VERSION -> pygenogrove.__version__ (single-sourced from pyproject.toml).
50
+ target_compile_definitions(pygenogrove PRIVATE
51
+ PYGENOGROVE_VERSION="${PYGENOGROVE_VERSION}"
52
+ )
53
+
54
+ # Set output directory
55
+ set_target_properties(pygenogrove PROPERTIES
56
+ LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}
57
+ )
58
+
59
+ # Install the extension into the wheel root so `import pygenogrove` resolves.
60
+ # scikit-build-core populates the wheel from the CMake install tree; without
61
+ # this rule the module is built but never packaged, leaving it unimportable.
62
+ install(TARGETS pygenogrove LIBRARY DESTINATION .)