uproot 5.3.7__tar.gz → 5.3.8__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 (280) hide show
  1. {uproot-5.3.7 → uproot-5.3.8}/.github/workflows/deploy.yml +9 -0
  2. {uproot-5.3.7 → uproot-5.3.8}/.pre-commit-config.yaml +1 -1
  3. {uproot-5.3.7 → uproot-5.3.8}/PKG-INFO +1 -1
  4. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/_util.py +0 -3
  5. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/models/RNTuple.py +8 -4
  6. uproot-5.3.8/src/uproot/source/coalesce.py +132 -0
  7. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/source/fsspec.py +24 -49
  8. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/streamers.py +4 -4
  9. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/version.py +2 -2
  10. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0008_start_interpretation.py +1 -2
  11. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0416_writing_compressed_data.py +7 -14
  12. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0662_rntuple_stl_containers.py +0 -3
  13. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0692_fsspec_reading.py +0 -8
  14. {uproot-5.3.7 → uproot-5.3.8}/tests/test_1191_rntuple_fixes.py +4 -0
  15. uproot-5.3.8/tests/test_1198_coalesce.py +39 -0
  16. uproot-5.3.8/tests/test_1221_AwkwardForth_bug.py +22 -0
  17. {uproot-5.3.7 → uproot-5.3.8}/.all-contributorsrc +0 -0
  18. {uproot-5.3.7 → uproot-5.3.8}/.github/ISSUE_TEMPLATE/bug-report.md +0 -0
  19. {uproot-5.3.7 → uproot-5.3.8}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  20. {uproot-5.3.7 → uproot-5.3.8}/.github/ISSUE_TEMPLATE/documentation.md +0 -0
  21. {uproot-5.3.7 → uproot-5.3.8}/.github/ISSUE_TEMPLATE/feature-request.md +0 -0
  22. {uproot-5.3.7 → uproot-5.3.8}/.github/dependabot.yml +0 -0
  23. {uproot-5.3.7 → uproot-5.3.8}/.github/workflows/build-distributions.yml +0 -0
  24. {uproot-5.3.7 → uproot-5.3.8}/.github/workflows/build-test.yml +0 -0
  25. {uproot-5.3.7 → uproot-5.3.8}/.github/workflows/semantic-pr-title.yml +0 -0
  26. {uproot-5.3.7 → uproot-5.3.8}/.github/workflows/upload-nightly-wheels.yml +0 -0
  27. {uproot-5.3.7 → uproot-5.3.8}/.gitignore +0 -0
  28. {uproot-5.3.7 → uproot-5.3.8}/.readthedocs.yml +0 -0
  29. {uproot-5.3.7 → uproot-5.3.8}/CITATION.cff +0 -0
  30. {uproot-5.3.7 → uproot-5.3.8}/LICENSE +0 -0
  31. {uproot-5.3.7 → uproot-5.3.8}/README.md +0 -0
  32. {uproot-5.3.7 → uproot-5.3.8}/dev/example-objects.py +0 -0
  33. {uproot-5.3.7 → uproot-5.3.8}/dev/make-models.py +0 -0
  34. {uproot-5.3.7 → uproot-5.3.8}/docs-img/diagrams/abstraction-layers.png +0 -0
  35. {uproot-5.3.7 → uproot-5.3.8}/docs-img/diagrams/abstraction-layers.svg +0 -0
  36. {uproot-5.3.7 → uproot-5.3.8}/docs-img/diagrams/example-dask-graph.png +0 -0
  37. {uproot-5.3.7 → uproot-5.3.8}/docs-img/diagrams/uproot-awkward-timeline.png +0 -0
  38. {uproot-5.3.7 → uproot-5.3.8}/docs-img/diagrams/uproot-awkward-timeline.svg +0 -0
  39. {uproot-5.3.7 → uproot-5.3.8}/docs-img/logo/logo-300px-white.png +0 -0
  40. {uproot-5.3.7 → uproot-5.3.8}/docs-img/logo/logo-300px.png +0 -0
  41. {uproot-5.3.7 → uproot-5.3.8}/docs-img/logo/logo-600px.png +0 -0
  42. {uproot-5.3.7 → uproot-5.3.8}/docs-img/logo/logo.svg +0 -0
  43. {uproot-5.3.7 → uproot-5.3.8}/docs-img/photos/switcheroo.jpg +0 -0
  44. {uproot-5.3.7 → uproot-5.3.8}/docs-sphinx/_templates/breadcrumbs.html +0 -0
  45. {uproot-5.3.7 → uproot-5.3.8}/docs-sphinx/basic.rst +0 -0
  46. {uproot-5.3.7 → uproot-5.3.8}/docs-sphinx/conf.py +0 -0
  47. {uproot-5.3.7 → uproot-5.3.8}/docs-sphinx/index.rst +0 -0
  48. {uproot-5.3.7 → uproot-5.3.8}/docs-sphinx/make_changelog.py +0 -0
  49. {uproot-5.3.7 → uproot-5.3.8}/docs-sphinx/prepare_docstrings.py +0 -0
  50. {uproot-5.3.7 → uproot-5.3.8}/docs-sphinx/requirements.txt +0 -0
  51. {uproot-5.3.7 → uproot-5.3.8}/docs-sphinx/uproot3-to-4.rst +0 -0
  52. {uproot-5.3.7 → uproot-5.3.8}/pyproject.toml +0 -0
  53. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/__init__.py +0 -0
  54. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/_awkwardforth.py +0 -0
  55. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/_dask.py +0 -0
  56. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/behavior.py +0 -0
  57. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/behaviors/RooCurve.py +0 -0
  58. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/behaviors/RooHist.py +0 -0
  59. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/behaviors/TAxis.py +0 -0
  60. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/behaviors/TBranch.py +0 -0
  61. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/behaviors/TBranchElement.py +0 -0
  62. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/behaviors/TDatime.py +0 -0
  63. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/behaviors/TGraph.py +0 -0
  64. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/behaviors/TGraphAsymmErrors.py +0 -0
  65. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/behaviors/TGraphErrors.py +0 -0
  66. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/behaviors/TH1.py +0 -0
  67. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/behaviors/TH2.py +0 -0
  68. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/behaviors/TH2Poly.py +0 -0
  69. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/behaviors/TH3.py +0 -0
  70. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/behaviors/TParameter.py +0 -0
  71. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/behaviors/TProfile.py +0 -0
  72. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/behaviors/TProfile2D.py +0 -0
  73. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/behaviors/TProfile3D.py +0 -0
  74. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/behaviors/TTree.py +0 -0
  75. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/behaviors/__init__.py +0 -0
  76. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/cache.py +0 -0
  77. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/compression.py +0 -0
  78. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/const.py +0 -0
  79. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/containers.py +0 -0
  80. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/deserialization.py +0 -0
  81. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/dynamic.py +0 -0
  82. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/exceptions.py +0 -0
  83. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/extras.py +0 -0
  84. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/interpretation/__init__.py +0 -0
  85. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/interpretation/grouped.py +0 -0
  86. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/interpretation/identify.py +0 -0
  87. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/interpretation/jagged.py +0 -0
  88. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/interpretation/library.py +0 -0
  89. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/interpretation/numerical.py +0 -0
  90. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/interpretation/objects.py +0 -0
  91. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/interpretation/strings.py +0 -0
  92. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/language/__init__.py +0 -0
  93. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/language/python.py +0 -0
  94. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/model.py +0 -0
  95. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/models/TArray.py +0 -0
  96. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/models/TAtt.py +0 -0
  97. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/models/TBasket.py +0 -0
  98. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/models/TBranch.py +0 -0
  99. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/models/TClonesArray.py +0 -0
  100. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/models/TDatime.py +0 -0
  101. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/models/TGraph.py +0 -0
  102. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/models/TH.py +0 -0
  103. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/models/THashList.py +0 -0
  104. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/models/TLeaf.py +0 -0
  105. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/models/TList.py +0 -0
  106. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/models/TMatrixT.py +0 -0
  107. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/models/TNamed.py +0 -0
  108. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/models/TObjArray.py +0 -0
  109. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/models/TObjString.py +0 -0
  110. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/models/TObject.py +0 -0
  111. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/models/TRef.py +0 -0
  112. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/models/TString.py +0 -0
  113. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/models/TTable.py +0 -0
  114. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/models/TTime.py +0 -0
  115. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/models/TTree.py +0 -0
  116. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/models/__init__.py +0 -0
  117. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/pyroot.py +0 -0
  118. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/reading.py +0 -0
  119. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/serialization.py +0 -0
  120. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/sink/__init__.py +0 -0
  121. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/sink/file.py +0 -0
  122. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/source/__init__.py +0 -0
  123. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/source/chunk.py +0 -0
  124. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/source/cursor.py +0 -0
  125. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/source/file.py +0 -0
  126. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/source/futures.py +0 -0
  127. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/source/http.py +0 -0
  128. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/source/object.py +0 -0
  129. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/source/s3.py +0 -0
  130. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/source/xrootd.py +0 -0
  131. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/writing/__init__.py +0 -0
  132. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/writing/_cascade.py +0 -0
  133. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/writing/_cascadentuple.py +0 -0
  134. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/writing/_cascadetree.py +0 -0
  135. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/writing/_dask_write.py +0 -0
  136. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/writing/identify.py +0 -0
  137. {uproot-5.3.7 → uproot-5.3.8}/src/uproot/writing/writable.py +0 -0
  138. {uproot-5.3.7 → uproot-5.3.8}/tests/__init__.py +0 -0
  139. {uproot-5.3.7 → uproot-5.3.8}/tests/conftest.py +0 -0
  140. {uproot-5.3.7 → uproot-5.3.8}/tests/samples/h_dynamic.pkl +0 -0
  141. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0001_source_class.py +0 -0
  142. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0006_notify_when_downloaded.py +0 -0
  143. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0007_single_chunk_interface.py +0 -0
  144. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0009_nested_directories.py +0 -0
  145. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0010_start_streamers.py +0 -0
  146. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0011_generate_classes_from_streamers.py +0 -0
  147. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0013_rntuple_anchor.py +0 -0
  148. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0014_all_ttree_versions.py +0 -0
  149. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0016_interpretations.py +0 -0
  150. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0017_multi_basket_multi_branch_fetch.py +0 -0
  151. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0018_array_fetching_interface.py +0 -0
  152. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0022_number_of_branches.py +0 -0
  153. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0023_more_interpretations_1.py +0 -0
  154. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0023_ttree_versions.py +0 -0
  155. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0028_fallback_to_read_streamer.py +0 -0
  156. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0029_more_string_types.py +0 -0
  157. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0031_test_stl_containers.py +0 -0
  158. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0033_more_interpretations_2.py +0 -0
  159. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0034_generic_objects_in_ttrees.py +0 -0
  160. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0035_datatype_generality.py +0 -0
  161. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0038_memberwise_serialization.py +0 -0
  162. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0043_iterate_function.py +0 -0
  163. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0044_concatenate_function.py +0 -0
  164. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0046_histograms_bh_hist.py +0 -0
  165. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0053_parents_should_not_be_bases.py +0 -0
  166. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0058_detach_model_objects_from_files.py +0 -0
  167. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0066_fix_http_fallback_freeze.py +0 -0
  168. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0067_common_entry_offsets.py +0 -0
  169. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0081_dont_parse_colons.py +0 -0
  170. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0087_memberwise_splitting_not_implemented_messages.py +0 -0
  171. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0088_read_with_http.py +0 -0
  172. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0099_read_from_file_object.py +0 -0
  173. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0112_fix_pandas_with_cut.py +0 -0
  174. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0118_fix_name_fetch_again.py +0 -0
  175. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0123_atlas_issues.py +0 -0
  176. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0126_turn_unknown_emptyarrays_into_known_types.py +0 -0
  177. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0167_use_the_common_histogram_interface.py +0 -0
  178. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0172_allow_allocators_in_vector_typenames.py +0 -0
  179. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0173_empty_and_multiprocessing_bugs.py +0 -0
  180. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0182_complain_about_missing_files.py +0 -0
  181. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0194_fix_lost_cuts_in_iterate.py +0 -0
  182. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0220_contiguous_byte_ranges_in_http.py +0 -0
  183. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0228_read_TProfiles.py +0 -0
  184. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0240_read_TGraphAsymmErrors.py +0 -0
  185. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0278_specializations_for_TParameter.py +0 -0
  186. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0302_pickle.py +0 -0
  187. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0303_empty_jagged_array.py +0 -0
  188. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0320_start_working_on_ROOT_writing.py +0 -0
  189. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0322_writablefile_infrastructure.py +0 -0
  190. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0329_update_existing_root_files.py +0 -0
  191. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0335_empty_ttree_division_by_zero.py +0 -0
  192. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0341_manipulate_streamer_info.py +0 -0
  193. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0344_writabledirectory_can_read.py +0 -0
  194. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0345_bulk_copy_method.py +0 -0
  195. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0349_write_TObjString.py +0 -0
  196. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0350_read_RooCurve_RooHist.py +0 -0
  197. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0351_write_TList.py +0 -0
  198. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0352_write_THashList.py +0 -0
  199. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0384_move_behavior_of_and_fix_383.py +0 -0
  200. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0398_dimensions_in_leaflist.py +0 -0
  201. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0405_write_a_histogram.py +0 -0
  202. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0406_write_a_ttree.py +0 -0
  203. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0407_read_TDatime.py +0 -0
  204. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0412_write_multidimensional_numpy_to_ttree.py +0 -0
  205. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0414_write_jagged_arrays.py +0 -0
  206. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0418_read_TTable.py +0 -0
  207. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0420_pyroot_uproot_interoperability.py +0 -0
  208. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0422_hist_integration.py +0 -0
  209. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0430_global_index_for_tuples_of_DataFrames.py +0 -0
  210. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0438_TClonesArray_is_not_AsGrouped.py +0 -0
  211. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0439_check_awkward_before_numpy.py +0 -0
  212. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0442_regular_TClonesArray.py +0 -0
  213. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0472_tstreamerinfo_for_ttree.py +0 -0
  214. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0475_remember_to_update_freesegments.py +0 -0
  215. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0484_manually_add_model_for_TMatrixTSym_double_.py +0 -0
  216. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0487_implement_asdtypeinplace.py +0 -0
  217. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0498_create_leaf_branch_in_extend.py +0 -0
  218. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0519_remove_memmap_copy.py +0 -0
  219. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0520_dynamic_classes_cant_be_abc_subclasses.py +0 -0
  220. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0569_fBits_is_4_bytes.py +0 -0
  221. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0576_unicode_in_names.py +0 -0
  222. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0578_dask_for_numpy.py +0 -0
  223. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0580_round_trip_for_no_flow_histograms.py +0 -0
  224. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0589_explicitly_interpret_RVec_type.py +0 -0
  225. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0603_dask_delayed_open.py +0 -0
  226. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0609_num_enteries_func.py +0 -0
  227. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0610_awkward_form.py +0 -0
  228. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0630_rntuple_basics.py +0 -0
  229. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0637_setup_tests_for_AwkwardForth.py +0 -0
  230. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0643_reading_vector_pair_TLorentzVector_int.py +0 -0
  231. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0651_implement_transformed_axis.py +0 -0
  232. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0652_dask_for_awkward.py +0 -0
  233. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0692_fsspec_writing.py +0 -0
  234. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0700_dask_empty_arrays.py +0 -0
  235. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0705_rntuple_writing_metadata.py +0 -0
  236. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0750_avoid_empty_TBasket_issue.py +0 -0
  237. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0755_dask_awkward_column_projection.py +0 -0
  238. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0791_protect_uproot_project_columns_from_dask_node_names.py +0 -0
  239. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0798_DAOD_PHYSLITE.py +0 -0
  240. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0808_fix_awkward_form_for_AsStridedObjects.py +0 -0
  241. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0816_separate_AwkwardForth_machines_by_TBranch.py +0 -0
  242. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0832_ak_add_doc_should_also_add_to_typetracer.py +0 -0
  243. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0840_support_tleafG.py +0 -0
  244. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0841_fix_814.py +0 -0
  245. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0844_fix_delete_hist_from_root.py +0 -0
  246. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0852_fix_strided_interp_extra_offsets.py +0 -0
  247. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0870_writing_arrays_of_type_unknown_fix_822.py +0 -0
  248. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0876_uproot_dask_blind_steps.py +0 -0
  249. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0886_fix_awkward_form_breadcrumbs.py +0 -0
  250. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0910_fix_906_members_non_numerical_branches.py +0 -0
  251. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0911_fix_interp_array_non_numerical_objs_issue_880.py +0 -0
  252. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0912_fix_pandas_and_double_nested_vectors_issue_885.py +0 -0
  253. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0916_read_from_s3.py +0 -0
  254. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0927_dont_assume_uproot_in_global_scope_in_TPython_Eval.py +0 -0
  255. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0930_expressions_in_pandas.py +0 -0
  256. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0940_feat_add_TLeafC_string_support.py +0 -0
  257. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0962_RNTuple_update.py +0 -0
  258. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0965_inverted_axes_variances_hist_888.py +0 -0
  259. {uproot-5.3.7 → uproot-5.3.8}/tests/test_0976_path_object_split.py +0 -0
  260. {uproot-5.3.7 → uproot-5.3.8}/tests/test_1000-write-TProfiles.py +0 -0
  261. {uproot-5.3.7 → uproot-5.3.8}/tests/test_1043_const_std_string.py +0 -0
  262. {uproot-5.3.7 → uproot-5.3.8}/tests/test_1058_dask_awkward_report.py +0 -0
  263. {uproot-5.3.7 → uproot-5.3.8}/tests/test_1063_dask_distributed.py +0 -0
  264. {uproot-5.3.7 → uproot-5.3.8}/tests/test_1070_pandas_dataframe_building_performance_fix.py +0 -0
  265. {uproot-5.3.7 → uproot-5.3.8}/tests/test_1085_dask_write.py +0 -0
  266. {uproot-5.3.7 → uproot-5.3.8}/tests/test_1102_any_locks_in_models_must_be_transient.py +0 -0
  267. {uproot-5.3.7 → uproot-5.3.8}/tests/test_1114_fix_attempt_to_concatenate_numpy_with_awkward.py +0 -0
  268. {uproot-5.3.7 → uproot-5.3.8}/tests/test_1120_check_decompression_executor_pass_for_dask.py +0 -0
  269. {uproot-5.3.7 → uproot-5.3.8}/tests/test_1127_fix_allow_colon_in_key_names.py +0 -0
  270. {uproot-5.3.7 → uproot-5.3.8}/tests/test_1146_split_ranges_for_large_files_over_http.py +0 -0
  271. {uproot-5.3.7 → uproot-5.3.8}/tests/test_1154_classof_using_relative_path.py +0 -0
  272. {uproot-5.3.7 → uproot-5.3.8}/tests/test_1160_std_string_in_TDirectory.py +0 -0
  273. {uproot-5.3.7 → uproot-5.3.8}/tests/test_1180_read_free_floating_vector_issue_1179.py +0 -0
  274. {uproot-5.3.7 → uproot-5.3.8}/tests/test_1181_support_for_stl_list.py +0 -0
  275. {uproot-5.3.7 → uproot-5.3.8}/tests/test_1182_add_support_for_bitset.py +0 -0
  276. {uproot-5.3.7 → uproot-5.3.8}/tests/test_1183_ttime_custom.py +0 -0
  277. {uproot-5.3.7 → uproot-5.3.8}/tests/test_1186_dtype_might_raise_ValueError.py +0 -0
  278. {uproot-5.3.7 → uproot-5.3.8}/tests/test_1189_dask_failing_on_duplicate_keys.py +0 -0
  279. {uproot-5.3.7 → uproot-5.3.8}/tests/test_1207_fix_title_of_TBranch_with_counter.py +0 -0
  280. {uproot-5.3.7 → uproot-5.3.8}/tests/test_1212_dont_let_update_mess_up_file_version.py +0 -0
@@ -21,6 +21,10 @@ jobs:
21
21
  needs: [build_dist]
22
22
  runs-on: ubuntu-latest
23
23
  if: github.event_name == 'release' && github.event.action == 'published'
24
+ permissions:
25
+ id-token: write
26
+ attestations: write
27
+ contents: read
24
28
 
25
29
  steps:
26
30
  - uses: actions/download-artifact@v4
@@ -31,6 +35,11 @@ jobs:
31
35
  - name: List distributions to be deployed
32
36
  run: ls -lha dist/
33
37
 
38
+ - name: Generate artifact attestation for sdist and wheel
39
+ uses: actions/attest-build-provenance@173725a1209d09b31f9d30a3890cf2757ebbff0d # v1.1.2
40
+ with:
41
+ subject-path: dist/uproot-*
42
+
34
43
  - uses: pypa/gh-action-pypi-publish@release/v1
35
44
  with:
36
45
  password: ${{ secrets.pypi_password }}
@@ -23,7 +23,7 @@ repos:
23
23
  - id: black
24
24
 
25
25
  - repo: https://github.com/astral-sh/ruff-pre-commit
26
- rev: v0.4.3
26
+ rev: v0.4.7
27
27
  hooks:
28
28
  - id: ruff
29
29
  args: [--fix, --show-fixes]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: uproot
3
- Version: 5.3.7
3
+ Version: 5.3.8
4
4
  Summary: ROOT I/O in pure Python and NumPy.
5
5
  Project-URL: Download, https://github.com/scikit-hep/uproot5/releases
6
6
  Project-URL: Homepage, https://github.com/scikit-hep/uproot5
@@ -13,7 +13,6 @@ import itertools
13
13
  import numbers
14
14
  import os
15
15
  import re
16
- import sys
17
16
  import warnings
18
17
  from collections.abc import Iterable
19
18
  from pathlib import Path
@@ -28,8 +27,6 @@ import uproot.source.chunk
28
27
  import uproot.source.fsspec
29
28
  import uproot.source.object
30
29
 
31
- macos = sys.platform == "darwin"
32
-
33
30
 
34
31
  def tobytes(array):
35
32
  """
@@ -480,9 +480,13 @@ in file {self.file.file_path}"""
480
480
  pagelist = linklist[ncol]
481
481
  dtype_byte = self.column_records[ncol].type
482
482
  dtype_str = uproot.const.rntuple_col_num_to_dtype_dict[dtype_byte]
483
- dtype = numpy.dtype("bool") if dtype_str == "bit" else numpy.dtype(dtype_str)
484
-
485
483
  total_len = numpy.sum([desc.num_elements for desc in pagelist], dtype=int)
484
+ if dtype_str == "switch":
485
+ dtype = numpy.dtype([("index", "int64"), ("tag", "int32")])
486
+ elif dtype_str == "bit":
487
+ dtype = numpy.dtype("bool")
488
+ else:
489
+ dtype = numpy.dtype(dtype_str)
486
490
  res = numpy.empty(total_len, dtype)
487
491
  split = 14 <= dtype_byte <= 21 or 26 <= dtype_byte <= 28
488
492
  zigzag = 26 <= dtype_byte <= 28
@@ -568,8 +572,8 @@ in file {self.file.file_path}"""
568
572
 
569
573
  # Supporting function and classes
570
574
  def _split_switch_bits(content):
571
- kindex = numpy.bitwise_and(content, numpy.int64(0x00000000000FFFFF))
572
- tags = (content >> 44).astype("int8") - 1
575
+ tags = content["tag"].astype(numpy.dtype("int8")) - 1
576
+ kindex = content["index"]
573
577
  return kindex, tags
574
578
 
575
579
 
@@ -0,0 +1,132 @@
1
+ """Read coalescing algorithms
2
+
3
+ Inspired in part by https://github.com/cms-sw/cmssw/blob/master/IOPool/TFileAdaptor/src/ReadRepacker.h
4
+ """
5
+
6
+ from __future__ import annotations
7
+
8
+ import queue
9
+ from concurrent.futures import Future
10
+ from dataclasses import dataclass
11
+ from typing import Callable
12
+
13
+ import uproot.source.chunk
14
+
15
+
16
+ @dataclass
17
+ class CoalesceConfig:
18
+ max_range_gap: int = 32 * 1024
19
+ max_request_ranges: int = 1024
20
+ max_request_bytes: int = 10 * 1024 * 1024
21
+ min_first_request_bytes: int = 32 * 1024
22
+
23
+
24
+ DEFAULT_CONFIG = CoalesceConfig()
25
+
26
+
27
+ class SliceFuture:
28
+ def __init__(self, parent: Future, s: slice | int):
29
+ self._parent = parent
30
+ self._s = s
31
+
32
+ def add_done_callback(self, callback, *, context=None):
33
+ self._parent.add_done_callback(callback)
34
+
35
+ def result(self, timeout=None):
36
+ return self._parent.result(timeout=timeout)[self._s]
37
+
38
+
39
+ @dataclass
40
+ class RangeRequest:
41
+ start: int
42
+ stop: int
43
+ future: Future | None
44
+
45
+
46
+ @dataclass
47
+ class Cluster:
48
+ ranges: list[RangeRequest]
49
+
50
+ @property
51
+ def start(self):
52
+ # since these are built from sorted ranges, this is the min start
53
+ return self.ranges[0].start
54
+
55
+ @property
56
+ def stop(self):
57
+ return max(range.stop for range in self.ranges)
58
+
59
+ def __len__(self):
60
+ return self.stop - self.start
61
+
62
+ def set_future(self, future: Future):
63
+ for range in self.ranges:
64
+ local_start = range.start - self.start
65
+ local_stop = range.stop - self.start
66
+ range.future = SliceFuture(future, slice(local_start, local_stop))
67
+
68
+
69
+ @dataclass
70
+ class CoalescedRequest:
71
+ clusters: list[Cluster]
72
+
73
+ def ranges(self):
74
+ return [(cluster.start, cluster.stop) for cluster in self.clusters]
75
+
76
+ def set_future(self, future: Future):
77
+ for i, cluster in enumerate(self.clusters):
78
+ cluster.set_future(SliceFuture(future, i))
79
+
80
+
81
+ def _merge_adjacent(ranges: list[RangeRequest], config: CoalesceConfig):
82
+ sorted_ranges = sorted(ranges, key=lambda r: r.start)
83
+ cluster = Cluster([])
84
+ for current_range in sorted_ranges:
85
+ if cluster.ranges and current_range.start - cluster.stop > config.max_range_gap:
86
+ yield cluster
87
+ cluster = Cluster([])
88
+ cluster.ranges.append(current_range)
89
+ if cluster.ranges:
90
+ yield cluster
91
+
92
+
93
+ def _coalesce(ranges: list[RangeRequest], config: CoalesceConfig):
94
+ clusters: list[Cluster] = []
95
+ request_bytes: int = 0
96
+ first_request = True
97
+ for cluster in _merge_adjacent(ranges, config):
98
+ if clusters and (
99
+ len(clusters) + 1 >= config.max_request_ranges
100
+ or request_bytes + len(cluster) >= config.max_request_bytes
101
+ or (first_request and request_bytes >= config.min_first_request_bytes)
102
+ ):
103
+ yield CoalescedRequest(clusters)
104
+ clusters = []
105
+ request_bytes = 0
106
+ first_request = False
107
+ clusters.append(cluster)
108
+ request_bytes += len(cluster)
109
+ if clusters:
110
+ yield CoalescedRequest(clusters)
111
+
112
+
113
+ def coalesce_requests(
114
+ ranges: list[tuple[int, int]],
115
+ submit_fn: Callable[[list[tuple[int, int]]], Future],
116
+ source: uproot.source.chunk.Source,
117
+ notifications: queue.Queue,
118
+ config: CoalesceConfig | None = None,
119
+ ):
120
+ if config is None:
121
+ config = DEFAULT_CONFIG
122
+ all_requests = [RangeRequest(start, stop, None) for start, stop in ranges]
123
+ for merged_request in _coalesce(all_requests, config):
124
+ future = submit_fn(merged_request.ranges())
125
+ merged_request.set_future(future)
126
+
127
+ def chunkify(req: RangeRequest):
128
+ chunk = uproot.source.chunk.Chunk(source, req.start, req.stop, req.future)
129
+ req.future.add_done_callback(uproot.source.chunk.notifier(chunk, notifications))
130
+ return chunk
131
+
132
+ return list(map(chunkify, all_requests))
@@ -12,26 +12,14 @@ import fsspec.asyn
12
12
  import uproot
13
13
  import uproot.source.chunk
14
14
  import uproot.source.futures
15
-
16
-
17
- class PartFuture:
18
- """For splitting the result of fs._cat_ranges into its components"""
19
-
20
- def __init__(self, parent_future: concurrent.futures.Future, part_index: int):
21
- self._parent = parent_future
22
- self._part_index = part_index
23
-
24
- def add_done_callback(self, callback, *, context=None):
25
- self._parent.add_done_callback(callback)
26
-
27
- def result(self, timeout=None):
28
- return self._parent.result(timeout=timeout)[self._part_index]
15
+ from uproot.source.coalesce import CoalesceConfig, coalesce_requests
29
16
 
30
17
 
31
18
  class FSSpecSource(uproot.source.chunk.Source):
32
19
  """
33
20
  Args:
34
21
  file_path (str): A URL for the file to open.
22
+ coalesce_config (struct, optional): Configuration options for read coalescing
35
23
  **kwargs (dict): any extra arguments to be forwarded to the particular
36
24
  FileSystem instance constructor. This might include S3 access keys,
37
25
  or HTTP headers, etc.
@@ -40,8 +28,11 @@ class FSSpecSource(uproot.source.chunk.Source):
40
28
  to get many chunks in one request.
41
29
  """
42
30
 
43
- def __init__(self, file_path: str, **options):
31
+ def __init__(
32
+ self, file_path: str, coalesce_config: CoalesceConfig | None = None, **options
33
+ ):
44
34
  super().__init__()
35
+ self._coalesce_config = coalesce_config
45
36
  self._fs, self._file_path = fsspec.core.url_to_fs(
46
37
  file_path, **self.extract_fsspec_options(options)
47
38
  )
@@ -50,7 +41,6 @@ class FSSpecSource(uproot.source.chunk.Source):
50
41
  self._async_impl = self._fs.async_impl
51
42
 
52
43
  self._file = None
53
- self._fh = None
54
44
 
55
45
  self._open()
56
46
 
@@ -75,25 +65,20 @@ class FSSpecSource(uproot.source.chunk.Source):
75
65
  return f"<{type(self).__name__} {path} at 0x{id(self):012x}>"
76
66
 
77
67
  def __getstate__(self):
78
- self._fh = None
79
68
  state = dict(self.__dict__)
80
69
  state.pop("_executor")
81
70
  state.pop("_file")
82
- state.pop("_fh")
83
71
  return state
84
72
 
85
73
  def __setstate__(self, state):
86
74
  self.__dict__ = state
87
75
  self._file = None
88
- self._fh = None
89
76
  self._open()
90
77
 
91
78
  def __enter__(self):
92
- self._fh = self._file.__enter__()
93
79
  return self
94
80
 
95
81
  def __exit__(self, exception_type, exception_value, traceback):
96
- self._fh = None
97
82
  self._file.__exit__(exception_type, exception_value, traceback)
98
83
  self._executor.shutdown()
99
84
 
@@ -110,20 +95,16 @@ class FSSpecSource(uproot.source.chunk.Source):
110
95
  self._num_requests += 1
111
96
  self._num_requested_chunks += 1
112
97
  self._num_requested_bytes += stop - start
113
- if self._fh:
114
- self._fh.seek(start)
115
- data = self._fh.read(stop - start)
116
- else:
117
- data = self._fs.cat_file(self._file_path, start, stop)
98
+ data = self._fs.cat_file(self._file_path, start=start, end=stop)
118
99
  future = uproot.source.futures.TrivialFuture(data)
119
100
  return uproot.source.chunk.Chunk(self, start, stop, future)
120
101
 
121
102
  def chunks(
122
- self, ranges: list[(int, int)], notifications: queue.Queue
103
+ self, ranges: list[tuple[int, int]], notifications: queue.Queue
123
104
  ) -> list[uproot.source.chunk.Chunk]:
124
105
  """
125
106
  Args:
126
- ranges (list of (int, int) 2-tuples): Intervals to fetch
107
+ ranges (list of tuple[int, int] 2-tuples): Intervals to fetch
127
108
  as (start, stop) pairs in a single request, if possible.
128
109
  notifications (``queue.Queue``): Indicator of completed
129
110
  chunks. After each gets filled, it is ``put`` on the
@@ -171,29 +152,23 @@ class FSSpecSource(uproot.source.chunk.Source):
171
152
  # TODO: when python 3.8 is dropped, use `asyncio.to_thread` instead (also remove the try/except block above)
172
153
  return await to_thread(blocking_func, *args, **kwargs)
173
154
 
174
- paths = [self._file_path] * len(ranges)
175
- starts = [start for start, _ in ranges]
176
- ends = [stop for _, stop in ranges]
177
- # _cat_ranges is async while cat_ranges is not.
178
- coroutine = (
179
- self._fs._cat_ranges(paths=paths, starts=starts, ends=ends)
180
- if self._async_impl
181
- else async_wrapper_thread(
182
- self._fs.cat_ranges, paths=paths, starts=starts, ends=ends
155
+ def submit(request_ranges: list[tuple[int, int]]):
156
+ paths = [self._file_path] * len(request_ranges)
157
+ starts = [start for start, _ in request_ranges]
158
+ ends = [stop for _, stop in request_ranges]
159
+ # _cat_ranges is async while cat_ranges is not.
160
+ coroutine = (
161
+ self._fs._cat_ranges(paths=paths, starts=starts, ends=ends)
162
+ if self._async_impl
163
+ else async_wrapper_thread(
164
+ self._fs.cat_ranges, paths=paths, starts=starts, ends=ends
165
+ )
183
166
  )
184
- )
185
-
186
- future = self._executor.submit(coroutine)
167
+ return self._executor.submit(coroutine)
187
168
 
188
- chunks = []
189
- for index, (start, stop) in enumerate(ranges):
190
- chunk_future = PartFuture(future, index)
191
- chunk = uproot.source.chunk.Chunk(self, start, stop, chunk_future)
192
- chunk_future.add_done_callback(
193
- uproot.source.chunk.notifier(chunk, notifications)
194
- )
195
- chunks.append(chunk)
196
- return chunks
169
+ return coalesce_requests(
170
+ ranges, submit, self, notifications, config=self._coalesce_config
171
+ )
197
172
 
198
173
  @property
199
174
  def async_impl(self) -> bool:
@@ -999,14 +999,14 @@ class Model_TStreamerBasicType(Model_TStreamerElement):
999
999
  else:
1000
1000
  # AwkwardForth testing E: test_0637's 01,02,05,08,09,11,12,13,15,16,29,35,39,45,46,47,49,50,56
1001
1001
  read_members.append(" if forth_obj is not None:")
1002
- for i in range(len(formats[0])):
1002
+ for i in range(len(formats[-1])):
1003
1003
  read_members.extend(
1004
1004
  [
1005
1005
  " key = key_number ; key_number += 1",
1006
1006
  ' form_key = f"node{key}-data"',
1007
- f' nested_forth_stash = af.Node(f"node{{key}}", field_name={fields[0][i]!r}, form_details={{ "class": "NumpyArray", "primitive": "{af.struct_to_dtype_name[formats[0][i]]}", "inner_shape": [], "parameters": {{}}, "form_key": f"node{{key}}"}})',
1008
- f' nested_forth_stash.header_code.append(f"output {{form_key}} {af.struct_to_dtype_name[formats[0][i]]}\\n")',
1009
- f' nested_forth_stash.pre_code.append(f"stream !{formats[0][i]}-> {{form_key}}\\n")',
1007
+ f' nested_forth_stash = af.Node(f"node{{key}}", field_name={fields[-1][i]!r}, form_details={{ "class": "NumpyArray", "primitive": "{af.struct_to_dtype_name[formats[-1][i]]}", "inner_shape": [], "parameters": {{}}, "form_key": f"node{{key}}"}})',
1008
+ f' nested_forth_stash.header_code.append(f"output {{form_key}} {af.struct_to_dtype_name[formats[-1][i]]}\\n")',
1009
+ f' nested_forth_stash.pre_code.append(f"stream !{formats[-1][i]}-> {{form_key}}\\n")',
1010
1010
  " forth_obj.add_node(nested_forth_stash)",
1011
1011
  ]
1012
1012
  )
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '5.3.7'
16
- __version_tuple__ = version_tuple = (5, 3, 7)
15
+ __version__ = version = '5.3.8'
16
+ __version_tuple__ = version_tuple = (5, 3, 8)
@@ -49,8 +49,7 @@ def test_file_header(use_isal):
49
49
 
50
50
  @pytest.mark.parametrize("use_deflate", [False, True])
51
51
  def test_file_header(use_deflate):
52
- # FIXME: https://github.com/dcwatson/deflate/issues/42
53
- if use_deflate and not uproot._util.macos:
52
+ if use_deflate:
54
53
  pytest.importorskip("deflate")
55
54
  uproot.ZLIB.use_deflate = use_deflate
56
55
  filename = skhep_testdata.data_path("uproot-Zmumu.root")
@@ -34,8 +34,7 @@ def test_ZLIB(use_isal):
34
34
 
35
35
  @pytest.mark.parametrize("use_deflate", [False, True])
36
36
  def test_deflate(use_deflate):
37
- # FIXME: https://github.com/dcwatson/deflate/issues/42
38
- if use_deflate and not uproot._util.macos:
37
+ if use_deflate:
39
38
  pytest.importorskip("deflate")
40
39
  uproot.ZLIB.library = "deflate"
41
40
  else:
@@ -134,8 +133,7 @@ def test_histogram_ZLIB(tmp_path, use_isal):
134
133
 
135
134
  @pytest.mark.parametrize("use_deflate", [False, True])
136
135
  def test_histogram_deflate(tmp_path, use_deflate):
137
- # FIXME: https://github.com/dcwatson/deflate/issues/42
138
- if use_deflate and not uproot._util.macos:
136
+ if use_deflate:
139
137
  pytest.importorskip("deflate")
140
138
  uproot.ZLIB.library = "deflate"
141
139
  else:
@@ -593,8 +591,7 @@ def test_multicompression_5(tmp_path, use_isal):
593
591
 
594
592
  @pytest.mark.parametrize("use_deflate", [False, True])
595
593
  def test_multicompression_1_deflate(tmp_path, use_deflate):
596
- # FIXME: https://github.com/dcwatson/deflate/issues/42
597
- if use_deflate and not uproot._util.macos:
594
+ if use_deflate:
598
595
  pytest.importorskip("deflate")
599
596
  uproot.ZLIB.library = "deflate"
600
597
  else:
@@ -628,8 +625,7 @@ def test_multicompression_1_deflate(tmp_path, use_deflate):
628
625
 
629
626
  @pytest.mark.parametrize("use_deflate", [False, True])
630
627
  def test_multicompression_2_deflate(tmp_path, use_deflate):
631
- # FIXME: https://github.com/dcwatson/deflate/issues/42
632
- if use_deflate and not uproot._util.macos:
628
+ if use_deflate:
633
629
  pytest.importorskip("deflate")
634
630
  uproot.ZLIB.library = "deflate"
635
631
  else:
@@ -662,8 +658,7 @@ def test_multicompression_2_deflate(tmp_path, use_deflate):
662
658
 
663
659
  @pytest.mark.parametrize("use_deflate", [False, True])
664
660
  def test_multicompression_3_deflate(tmp_path, use_deflate):
665
- # FIXME: https://github.com/dcwatson/deflate/issues/42
666
- if use_deflate and not uproot._util.macos:
661
+ if use_deflate:
667
662
  pytest.importorskip("deflate")
668
663
  uproot.ZLIB.library = "deflate"
669
664
  else:
@@ -697,8 +692,7 @@ def test_multicompression_3_deflate(tmp_path, use_deflate):
697
692
 
698
693
  @pytest.mark.parametrize("use_deflate", [False, True])
699
694
  def test_multicompression_4_deflate(tmp_path, use_deflate):
700
- # FIXME: https://github.com/dcwatson/deflate/issues/42
701
- if use_deflate and not uproot._util.macos:
695
+ if use_deflate:
702
696
  pytest.importorskip("deflate")
703
697
  uproot.ZLIB.library = "deflate"
704
698
  else:
@@ -730,8 +724,7 @@ def test_multicompression_4_deflate(tmp_path, use_deflate):
730
724
 
731
725
  @pytest.mark.parametrize("use_deflate", [False, True])
732
726
  def test_multicompression_5_deflate(tmp_path, use_deflate):
733
- # FIXME: https://github.com/dcwatson/deflate/issues/42
734
- if use_deflate and not uproot._util.macos:
727
+ if use_deflate:
735
728
  pytest.importorskip("deflate")
736
729
  uproot.ZLIB.library = "deflate"
737
730
  else:
@@ -13,9 +13,6 @@ import uproot
13
13
  ak = pytest.importorskip("awkward")
14
14
 
15
15
 
16
- @pytest.mark.skip(
17
- reason="FIXME: skipping test_ntuple_stl_containers.root until #928 is fixed"
18
- )
19
16
  def test_rntuple_stl_containers():
20
17
  filename = skhep_testdata.data_path("test_ntuple_stl_containers.root")
21
18
  with uproot.open(filename) as f:
@@ -97,10 +97,6 @@ def test_open_fsspec_local():
97
97
  )
98
98
  def test_open_fsspec_s3(handler):
99
99
  pytest.importorskip("s3fs")
100
- if sys.version_info < (3, 11):
101
- pytest.skip(
102
- "https://github.com/scikit-hep/uproot5/pull/1012",
103
- )
104
100
 
105
101
  with uproot.open(
106
102
  "s3://pivarski-princeton/pythia_ppZee_run17emb.picoDst.root:PicoDst",
@@ -461,10 +457,6 @@ def test_fsspec_globbing_xrootd_no_files(handler):
461
457
  )
462
458
  def test_fsspec_globbing_s3(handler):
463
459
  pytest.importorskip("s3fs")
464
- if sys.version_info < (3, 11):
465
- pytest.skip(
466
- "https://github.com/scikit-hep/uproot5/pull/1012",
467
- )
468
460
 
469
461
  iterator = uproot.iterate(
470
462
  {"s3://pivarski-princeton/pythia_ppZee_run17emb.*.root": "PicoDst"},
@@ -1,5 +1,6 @@
1
1
  # BSD 3-Clause License; see https://github.com/scikit-hep/uproot5/blob/main/LICENSE
2
2
 
3
+ import pytest
3
4
  import skhep_testdata
4
5
 
5
6
  import uproot
@@ -57,6 +58,9 @@ def test_empty_page_list():
57
58
  assert data[0] == 0
58
59
 
59
60
 
61
+ @pytest.mark.skip(
62
+ reason="The file takes too long to download (about 5 seconds). Need to find a smaller test file."
63
+ )
60
64
  def test_multiple_page_lists():
61
65
  url = "http://root.cern/files/tutorials/ntpl004_dimuon_v1rc2.root"
62
66
  with uproot.open(f"simplecache::{url}") as f:
@@ -0,0 +1,39 @@
1
+ import pytest
2
+ from uproot.source.coalesce import CoalesceConfig, RangeRequest, _coalesce, Future
3
+
4
+
5
+ @pytest.mark.parametrize(
6
+ "config",
7
+ [
8
+ CoalesceConfig(),
9
+ CoalesceConfig(max_range_gap=2, max_request_ranges=1),
10
+ ],
11
+ ids=["default", "tiny"],
12
+ )
13
+ @pytest.mark.parametrize(
14
+ "ranges",
15
+ [
16
+ [(1, 3), (4, 6), (10, 20)],
17
+ [(1, 3), (10, 20), (4, 6), (9, 10)],
18
+ [(1, 3), (10, 20), (6, 15)],
19
+ [(1, 3), (10, 20), (6, 25)],
20
+ ],
21
+ ids=["sorted", "jumbled", "overlapped", "nested"],
22
+ )
23
+ def test_coalesce(ranges, config):
24
+ data = b"abcdefghijklmnopqurstuvwxyz"
25
+
26
+ all_requests = [RangeRequest(start, stop, None) for start, stop in ranges]
27
+ nreq = 0
28
+ for merged_request in _coalesce(all_requests, config):
29
+ future = Future()
30
+ future.set_result([data[start:stop] for start, stop in merged_request.ranges()])
31
+ merged_request.set_future(future)
32
+ nreq += 1
33
+
34
+ if config.max_range_gap == 2:
35
+ assert nreq > 1
36
+
37
+ for req in all_requests:
38
+ assert req.future
39
+ assert req.future.result() == data[req.start : req.stop]
@@ -0,0 +1,22 @@
1
+ # BSD 3-Clause License; see https://github.com/scikit-hep/uproot5/blob/main/LICENSE
2
+
3
+ import pytest
4
+ import uproot
5
+ import skhep_testdata
6
+
7
+
8
+ def test():
9
+ with uproot.open(skhep_testdata.data_path("uproot-issue-1221.root")) as file:
10
+ record = file["TrkAna"]["trkana"]["demtsh"].array()[-1, -1, -1]
11
+ assert record.tolist() == {
12
+ "wdot": -0.6311486959457397,
13
+ "dhit": True,
14
+ "poca": {
15
+ "fCoordinates": {
16
+ "fX": -526.5504760742188,
17
+ "fY": -195.0541534423828,
18
+ "fZ": 1338.90771484375,
19
+ }
20
+ },
21
+ "dactive": True,
22
+ }
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes