lsst-daf-butler 29.2025.2000__tar.gz → 29.2025.2300__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 (436) hide show
  1. {lsst_daf_butler-29.2025.2000/python/lsst_daf_butler.egg-info → lsst_daf_butler-29.2025.2300}/PKG-INFO +1 -1
  2. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/_butler.py +34 -4
  3. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/_butler_collections.py +4 -0
  4. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/cli/cmd/commands.py +22 -1
  5. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/cli/utils.py +1 -1
  6. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/datastore/_datastore.py +6 -2
  7. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/datastores/chainedDatastore.py +55 -88
  8. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/datastores/fileDatastore.py +161 -25
  9. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/datastores/inMemoryDatastore.py +1 -1
  10. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/direct_butler/_direct_butler.py +197 -75
  11. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/direct_query_driver/_driver.py +29 -10
  12. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/direct_query_driver/_query_builder.py +74 -17
  13. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/direct_query_driver/_sql_column_visitor.py +19 -1
  14. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/queries/overlaps.py +1 -1
  15. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/queries/tree/_column_expression.py +39 -0
  16. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/queries/tree/_predicate.py +16 -8
  17. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/bridge/monolithic.py +57 -31
  18. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/datasets/byDimensions/summaries.py +4 -4
  19. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/dimensions/static.py +20 -8
  20. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/interfaces/_database.py +1 -2
  21. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/interfaces/_dimensions.py +7 -2
  22. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/remote_butler/_http_connection.py +15 -3
  23. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/remote_butler/_remote_butler.py +16 -3
  24. lsst_daf_butler-29.2025.2300/python/lsst/daf/butler/remote_butler/server/_config.py +109 -0
  25. lsst_daf_butler-29.2025.2300/python/lsst/daf/butler/remote_butler/server/_dependencies.py +124 -0
  26. lsst_daf_butler-29.2025.2300/python/lsst/daf/butler/remote_butler/server/_gafaelfawr.py +125 -0
  27. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/remote_butler/server/_server.py +9 -4
  28. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/remote_butler/server/_telemetry.py +1 -1
  29. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/remote_butler/server/handlers/_external.py +10 -2
  30. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/script/ingest_zip.py +13 -1
  31. lsst_daf_butler-29.2025.2300/python/lsst/daf/butler/script/queryCollections.py +378 -0
  32. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/script/removeRuns.py +2 -11
  33. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/script/retrieveArtifacts.py +1 -0
  34. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/tests/butler_queries.py +91 -0
  35. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/tests/hybrid_butler.py +20 -5
  36. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/tests/server.py +28 -3
  37. lsst_daf_butler-29.2025.2300/python/lsst/daf/butler/version.py +2 -0
  38. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300/python/lsst_daf_butler.egg-info}/PKG-INFO +1 -1
  39. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst_daf_butler.egg-info/SOURCES.txt +2 -0
  40. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_butler.py +64 -13
  41. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_cliCmdQueryCollections.py +124 -1
  42. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_datasets.py +9 -0
  43. lsst_daf_butler-29.2025.2300/tests/test_gafaelfawr.py +104 -0
  44. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_query_interface.py +0 -2
  45. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_server.py +40 -4
  46. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_simpleButler.py +5 -0
  47. lsst_daf_butler-29.2025.2000/python/lsst/daf/butler/remote_butler/server/_config.py +0 -54
  48. lsst_daf_butler-29.2025.2000/python/lsst/daf/butler/remote_butler/server/_dependencies.py +0 -59
  49. lsst_daf_butler-29.2025.2000/python/lsst/daf/butler/script/queryCollections.py +0 -222
  50. lsst_daf_butler-29.2025.2000/python/lsst/daf/butler/version.py +0 -2
  51. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/COPYRIGHT +0 -0
  52. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/LICENSE +0 -0
  53. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/MANIFEST.in +0 -0
  54. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/README.md +0 -0
  55. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/bsd_license.txt +0 -0
  56. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/doc/lsst.daf.butler/CHANGES.rst +0 -0
  57. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/doc/lsst.daf.butler/concreteStorageClasses.rst +0 -0
  58. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/doc/lsst.daf.butler/configuring.rst +0 -0
  59. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/doc/lsst.daf.butler/datastores.rst +0 -0
  60. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/doc/lsst.daf.butler/dimensions.rst +0 -0
  61. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/doc/lsst.daf.butler/formatters.rst +0 -0
  62. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/doc/lsst.daf.butler/index.rst +0 -0
  63. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/doc/lsst.daf.butler/organizing.rst +0 -0
  64. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/doc/lsst.daf.butler/queries.rst +0 -0
  65. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/doc/lsst.daf.butler/use-in-tests.rst +0 -0
  66. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/doc/lsst.daf.butler/writing-subcommands.rst +0 -0
  67. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/gpl-v3.0.txt +0 -0
  68. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/pyproject.toml +0 -0
  69. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/__init__.py +0 -0
  70. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/__init__.py +0 -0
  71. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/__init__.py +0 -0
  72. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/_butler_config.py +0 -0
  73. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/_butler_instance_options.py +0 -0
  74. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/_butler_metrics.py +0 -0
  75. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/_butler_repo_index.py +0 -0
  76. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/_collection_type.py +0 -0
  77. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/_column_categorization.py +0 -0
  78. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/_column_tags.py +0 -0
  79. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/_column_type_info.py +0 -0
  80. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/_config.py +0 -0
  81. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/_config_support.py +0 -0
  82. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/_dataset_association.py +0 -0
  83. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/_dataset_existence.py +0 -0
  84. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/_dataset_provenance.py +0 -0
  85. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/_dataset_ref.py +0 -0
  86. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/_dataset_type.py +0 -0
  87. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/_deferredDatasetHandle.py +0 -0
  88. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/_exceptions.py +0 -0
  89. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/_exceptions_legacy.py +0 -0
  90. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/_file_dataset.py +0 -0
  91. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/_file_descriptor.py +0 -0
  92. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/_formatter.py +0 -0
  93. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/_labeled_butler_factory.py +0 -0
  94. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/_limited_butler.py +0 -0
  95. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/_location.py +0 -0
  96. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/_named.py +0 -0
  97. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/_quantum.py +0 -0
  98. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/_quantum_backed.py +0 -0
  99. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/_query_all_datasets.py +0 -0
  100. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/_registry_shim.py +0 -0
  101. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/_storage_class.py +0 -0
  102. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/_storage_class_delegate.py +0 -0
  103. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/_timespan.py +0 -0
  104. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/_topology.py +0 -0
  105. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/_utilities/__init__.py +0 -0
  106. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/_utilities/locked_object.py +0 -0
  107. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/_utilities/named_locks.py +0 -0
  108. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/_utilities/thread_safe_cache.py +0 -0
  109. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/arrow_utils.py +0 -0
  110. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/cli/__init__.py +0 -0
  111. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/cli/butler.py +0 -0
  112. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/cli/cliLog.py +0 -0
  113. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/cli/cmd/__init__.py +0 -0
  114. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/cli/cmd/_remove_collections.py +0 -0
  115. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/cli/cmd/_remove_runs.py +0 -0
  116. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/cli/opt/__init__.py +0 -0
  117. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/cli/opt/arguments.py +0 -0
  118. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/cli/opt/optionGroups.py +0 -0
  119. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/cli/opt/options.py +0 -0
  120. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/cli/progress.py +0 -0
  121. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/column_spec.py +0 -0
  122. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/configs/datastore.yaml +0 -0
  123. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/configs/datastores/composites.yaml +0 -0
  124. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/configs/datastores/fileDatastore.yaml +0 -0
  125. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/configs/datastores/formatters.yaml +0 -0
  126. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/configs/datastores/writeRecipes.yaml +0 -0
  127. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/configs/dimensions.yaml +0 -0
  128. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/configs/old_dimensions/daf_butler_universe0.yaml +0 -0
  129. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/configs/old_dimensions/daf_butler_universe1.yaml +0 -0
  130. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/configs/old_dimensions/daf_butler_universe2.yaml +0 -0
  131. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/configs/old_dimensions/daf_butler_universe3.yaml +0 -0
  132. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/configs/old_dimensions/daf_butler_universe4.yaml +0 -0
  133. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/configs/old_dimensions/daf_butler_universe5.yaml +0 -0
  134. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/configs/old_dimensions/daf_butler_universe6.yaml +0 -0
  135. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/configs/old_dimensions/daf_butler_universe7.yaml +0 -0
  136. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/configs/registry.yaml +0 -0
  137. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/configs/repo_transfer_formats.yaml +0 -0
  138. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/configs/storageClasses.yaml +0 -0
  139. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/datastore/__init__.py +0 -0
  140. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/datastore/cache_manager.py +0 -0
  141. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/datastore/composites.py +0 -0
  142. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/datastore/constraints.py +0 -0
  143. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/datastore/file_templates.py +0 -0
  144. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/datastore/generic_base.py +0 -0
  145. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/datastore/record_data.py +0 -0
  146. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/datastore/stored_file_info.py +0 -0
  147. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/datastores/__init__.py +0 -0
  148. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/datastores/fileDatastoreClient.py +0 -0
  149. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/datastores/file_datastore/__init__.py +0 -0
  150. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/datastores/file_datastore/get.py +0 -0
  151. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/datastores/file_datastore/retrieve_artifacts.py +0 -0
  152. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/ddl.py +0 -0
  153. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/delegates/__init__.py +0 -0
  154. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/delegates/arrowtable.py +0 -0
  155. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/dimensions/__init__.py +0 -0
  156. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/dimensions/_config.py +0 -0
  157. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/dimensions/_coordinate.py +0 -0
  158. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/dimensions/_data_coordinate_iterable.py +0 -0
  159. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/dimensions/_database.py +0 -0
  160. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/dimensions/_elements.py +0 -0
  161. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/dimensions/_governor.py +0 -0
  162. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/dimensions/_group.py +0 -0
  163. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/dimensions/_packer.py +0 -0
  164. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/dimensions/_record_set.py +0 -0
  165. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/dimensions/_record_table.py +0 -0
  166. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/dimensions/_records.py +0 -0
  167. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/dimensions/_schema.py +0 -0
  168. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/dimensions/_skypix.py +0 -0
  169. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/dimensions/_universe.py +0 -0
  170. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/dimensions/construction.py +0 -0
  171. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/dimensions/record_cache.py +0 -0
  172. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/direct_butler/__init__.py +0 -0
  173. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/direct_butler/_direct_butler_collections.py +0 -0
  174. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/direct_query_driver/__init__.py +0 -0
  175. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/direct_query_driver/_postprocessing.py +0 -0
  176. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/direct_query_driver/_query_analysis.py +0 -0
  177. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/direct_query_driver/_result_page_converter.py +0 -0
  178. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/direct_query_driver/_sql_builders.py +0 -0
  179. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/formatters/__init__.py +0 -0
  180. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/formatters/astropyTable.py +0 -0
  181. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/formatters/file.py +0 -0
  182. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/formatters/json.py +0 -0
  183. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/formatters/logs.py +0 -0
  184. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/formatters/matplotlib.py +0 -0
  185. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/formatters/packages.py +0 -0
  186. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/formatters/parquet.py +0 -0
  187. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/formatters/pickle.py +0 -0
  188. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/formatters/typeless.py +0 -0
  189. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/formatters/yaml.py +0 -0
  190. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/json.py +0 -0
  191. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/logging.py +0 -0
  192. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/mapping_factory.py +0 -0
  193. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/name_shrinker.py +0 -0
  194. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/nonempty_mapping.py +0 -0
  195. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/persistence_context.py +0 -0
  196. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/progress.py +0 -0
  197. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/py.typed +0 -0
  198. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/pydantic_utils.py +0 -0
  199. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/queries/__init__.py +0 -0
  200. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/queries/_base.py +0 -0
  201. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/queries/_data_coordinate_query_results.py +0 -0
  202. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/queries/_dataset_query_results.py +0 -0
  203. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/queries/_dimension_record_query_results.py +0 -0
  204. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/queries/_expression_strings.py +0 -0
  205. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/queries/_general_query_results.py +0 -0
  206. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/queries/_identifiers.py +0 -0
  207. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/queries/_query.py +0 -0
  208. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/queries/convert_args.py +0 -0
  209. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/queries/driver.py +0 -0
  210. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/queries/expression_factory.py +0 -0
  211. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/queries/predicate_constraints_summary.py +0 -0
  212. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/queries/result_specs.py +0 -0
  213. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/queries/tree/__init__.py +0 -0
  214. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/queries/tree/_base.py +0 -0
  215. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/queries/tree/_column_literal.py +0 -0
  216. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/queries/tree/_column_reference.py +0 -0
  217. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/queries/tree/_column_set.py +0 -0
  218. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/queries/tree/_query_tree.py +0 -0
  219. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/queries/visitors.py +0 -0
  220. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/__init__.py +0 -0
  221. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/_caching_context.py +0 -0
  222. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/_collection_record_cache.py +0 -0
  223. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/_collection_summary.py +0 -0
  224. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/_collection_summary_cache.py +0 -0
  225. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/_config.py +0 -0
  226. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/_defaults.py +0 -0
  227. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/_exceptions.py +0 -0
  228. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/_registry.py +0 -0
  229. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/_registry_factory.py +0 -0
  230. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/attributes.py +0 -0
  231. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/bridge/__init__.py +0 -0
  232. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/bridge/ephemeral.py +0 -0
  233. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/collections/__init__.py +0 -0
  234. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/collections/_base.py +0 -0
  235. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/collections/nameKey.py +0 -0
  236. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/collections/synthIntKey.py +0 -0
  237. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/connectionString.py +0 -0
  238. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/databases/__init__.py +0 -0
  239. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/databases/postgresql.py +0 -0
  240. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/databases/sqlite.py +0 -0
  241. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/datasets/__init__.py +0 -0
  242. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/datasets/byDimensions/__init__.py +0 -0
  243. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/datasets/byDimensions/_dataset_type_cache.py +0 -0
  244. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/datasets/byDimensions/_manager.py +0 -0
  245. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/datasets/byDimensions/tables.py +0 -0
  246. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/dimensions/__init__.py +0 -0
  247. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/interfaces/__init__.py +0 -0
  248. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/interfaces/_attributes.py +0 -0
  249. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/interfaces/_bridge.py +0 -0
  250. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/interfaces/_collections.py +0 -0
  251. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/interfaces/_database_explain.py +0 -0
  252. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/interfaces/_datasets.py +0 -0
  253. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/interfaces/_obscore.py +0 -0
  254. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/interfaces/_opaque.py +0 -0
  255. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/interfaces/_versioning.py +0 -0
  256. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/managers.py +0 -0
  257. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/nameShrinker.py +0 -0
  258. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/obscore/__init__.py +0 -0
  259. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/obscore/_config.py +0 -0
  260. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/obscore/_manager.py +0 -0
  261. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/obscore/_records.py +0 -0
  262. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/obscore/_schema.py +0 -0
  263. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/obscore/_spatial.py +0 -0
  264. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/obscore/default_spatial.py +0 -0
  265. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/obscore/pgsphere.py +0 -0
  266. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/opaque.py +0 -0
  267. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/queries/__init__.py +0 -0
  268. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/queries/_builder.py +0 -0
  269. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/queries/_query.py +0 -0
  270. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/queries/_query_backend.py +0 -0
  271. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/queries/_query_context.py +0 -0
  272. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/queries/_readers.py +0 -0
  273. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/queries/_results.py +0 -0
  274. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/queries/_sql_query_backend.py +0 -0
  275. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/queries/_sql_query_context.py +0 -0
  276. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/queries/_structs.py +0 -0
  277. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/queries/butler_sql_engine.py +0 -0
  278. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/queries/expressions/__init__.py +0 -0
  279. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/queries/expressions/_predicate.py +0 -0
  280. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/queries/expressions/categorize.py +0 -0
  281. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/queries/expressions/check.py +0 -0
  282. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/queries/expressions/normalForm.py +0 -0
  283. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/queries/expressions/parser/__init__.py +0 -0
  284. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/queries/expressions/parser/exprTree.py +0 -0
  285. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/queries/expressions/parser/parser.py +0 -0
  286. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/queries/expressions/parser/parserLex.py +0 -0
  287. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/queries/expressions/parser/parserYacc.py +0 -0
  288. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/queries/expressions/parser/ply/__init__.py +0 -0
  289. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/queries/expressions/parser/ply/lex.py +0 -0
  290. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/queries/expressions/parser/ply/yacc.py +0 -0
  291. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/queries/expressions/parser/treeVisitor.py +0 -0
  292. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/queries/find_first_dataset.py +0 -0
  293. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/sql_registry.py +0 -0
  294. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/tests/__init__.py +0 -0
  295. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/tests/_database.py +0 -0
  296. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/tests/_registry.py +0 -0
  297. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/versions.py +0 -0
  298. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/registry/wildcards.py +0 -0
  299. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/remote_butler/__init__.py +0 -0
  300. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/remote_butler/_authentication.py +0 -0
  301. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/remote_butler/_collection_args.py +0 -0
  302. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/remote_butler/_config.py +0 -0
  303. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/remote_butler/_defaults.py +0 -0
  304. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/remote_butler/_errors.py +0 -0
  305. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/remote_butler/_factory.py +0 -0
  306. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/remote_butler/_query_driver.py +0 -0
  307. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/remote_butler/_query_results.py +0 -0
  308. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/remote_butler/_ref_utils.py +0 -0
  309. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/remote_butler/_registry.py +0 -0
  310. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/remote_butler/_remote_butler_collections.py +0 -0
  311. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/remote_butler/registry/__init__.py +0 -0
  312. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/remote_butler/registry/_query_common.py +0 -0
  313. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/remote_butler/registry/_query_data_coordinates.py +0 -0
  314. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/remote_butler/registry/_query_datasets.py +0 -0
  315. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/remote_butler/registry/_query_dimension_records.py +0 -0
  316. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/remote_butler/server/__init__.py +0 -0
  317. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/remote_butler/server/_factory.py +0 -0
  318. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/remote_butler/server/handlers/_external_query.py +0 -0
  319. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/remote_butler/server/handlers/_internal.py +0 -0
  320. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/remote_butler/server/handlers/_query_serialization.py +0 -0
  321. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/remote_butler/server/handlers/_query_streaming.py +0 -0
  322. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/remote_butler/server/handlers/_utils.py +0 -0
  323. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/remote_butler/server_models.py +0 -0
  324. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/repo_relocation.py +0 -0
  325. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/script/__init__.py +0 -0
  326. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/script/_associate.py +0 -0
  327. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/script/_pruneDatasets.py +0 -0
  328. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/script/butlerImport.py +0 -0
  329. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/script/certifyCalibrations.py +0 -0
  330. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/script/collectionChain.py +0 -0
  331. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/script/configDump.py +0 -0
  332. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/script/configValidate.py +0 -0
  333. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/script/createRepo.py +0 -0
  334. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/script/exportCalibs.py +0 -0
  335. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/script/ingest_files.py +0 -0
  336. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/script/queryDataIds.py +0 -0
  337. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/script/queryDatasetTypes.py +0 -0
  338. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/script/queryDatasets.py +0 -0
  339. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/script/queryDimensionRecords.py +0 -0
  340. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/script/register_dataset_type.py +0 -0
  341. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/script/removeCollections.py +0 -0
  342. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/script/removeDatasetType.py +0 -0
  343. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/script/transferDatasets.py +0 -0
  344. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/tests/__init__.py +0 -0
  345. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/tests/_datasetsHelper.py +0 -0
  346. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/tests/_dummyRegistry.py +0 -0
  347. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/tests/_examplePythonTypes.py +0 -0
  348. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/tests/_testRepo.py +0 -0
  349. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/tests/cliCmdTestBase.py +0 -0
  350. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/tests/cliLogTestBase.py +0 -0
  351. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/tests/deferredFormatter.py +0 -0
  352. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/tests/dict_convertible_model.py +0 -0
  353. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/tests/hybrid_butler_collections.py +0 -0
  354. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/tests/hybrid_butler_registry.py +0 -0
  355. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/tests/postgresql.py +0 -0
  356. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/tests/server_utils.py +0 -0
  357. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/tests/testFormatters.py +0 -0
  358. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/tests/utils.py +0 -0
  359. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/time_utils.py +0 -0
  360. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/timespan_database_representation.py +0 -0
  361. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/transfers/__init__.py +0 -0
  362. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/transfers/_context.py +0 -0
  363. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/transfers/_interfaces.py +0 -0
  364. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/transfers/_yaml.py +0 -0
  365. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst/daf/butler/utils.py +0 -0
  366. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst_daf_butler.egg-info/dependency_links.txt +0 -0
  367. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst_daf_butler.egg-info/entry_points.txt +0 -0
  368. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst_daf_butler.egg-info/requires.txt +0 -0
  369. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst_daf_butler.egg-info/top_level.txt +0 -0
  370. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/python/lsst_daf_butler.egg-info/zip-safe +0 -0
  371. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/setup.cfg +0 -0
  372. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_astropyTableFormatter.py +0 -0
  373. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_authentication.py +0 -0
  374. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_butler_factory.py +0 -0
  375. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_cliCmdAssociate.py +0 -0
  376. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_cliCmdConfigDump.py +0 -0
  377. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_cliCmdConfigValidate.py +0 -0
  378. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_cliCmdCreate.py +0 -0
  379. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_cliCmdImport.py +0 -0
  380. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_cliCmdIngestFiles.py +0 -0
  381. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_cliCmdPruneDatasets.py +0 -0
  382. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_cliCmdQueryDataIds.py +0 -0
  383. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_cliCmdQueryDatasetTypes.py +0 -0
  384. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_cliCmdQueryDatasets.py +0 -0
  385. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_cliCmdQueryDimensionRecords.py +0 -0
  386. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_cliCmdRemoveCollections.py +0 -0
  387. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_cliCmdRemoveRuns.py +0 -0
  388. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_cliCmdRetrieveArtifacts.py +0 -0
  389. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_cliLog.py +0 -0
  390. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_cliPluginLoader.py +0 -0
  391. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_cliUtilSplitCommas.py +0 -0
  392. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_cliUtilSplitKv.py +0 -0
  393. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_cliUtilToUpper.py +0 -0
  394. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_cliUtils.py +0 -0
  395. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_column_spec.py +0 -0
  396. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_composites.py +0 -0
  397. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_config.py +0 -0
  398. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_connectionString.py +0 -0
  399. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_constraints.py +0 -0
  400. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_datastore.py +0 -0
  401. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_ddl.py +0 -0
  402. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_dimension_record_containers.py +0 -0
  403. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_dimensions.py +0 -0
  404. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_exprParserLex.py +0 -0
  405. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_exprParserYacc.py +0 -0
  406. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_expressions.py +0 -0
  407. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_formatter.py +0 -0
  408. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_location.py +0 -0
  409. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_logFormatter.py +0 -0
  410. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_logging.py +0 -0
  411. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_matplotlibFormatter.py +0 -0
  412. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_nonempty_mapping.py +0 -0
  413. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_normalFormExpression.py +0 -0
  414. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_obscore.py +0 -0
  415. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_packages.py +0 -0
  416. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_parquet.py +0 -0
  417. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_postgresql.py +0 -0
  418. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_progress.py +0 -0
  419. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_pydantic_utils.py +0 -0
  420. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_quantum.py +0 -0
  421. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_quantumBackedButler.py +0 -0
  422. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_query_direct_postgresql.py +0 -0
  423. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_query_direct_sqlite.py +0 -0
  424. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_query_relations.py +0 -0
  425. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_query_remote.py +0 -0
  426. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_query_utilities.py +0 -0
  427. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_remote_butler.py +0 -0
  428. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_sqlite.py +0 -0
  429. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_storageClass.py +0 -0
  430. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_templates.py +0 -0
  431. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_testRepo.py +0 -0
  432. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_thread_utils.py +0 -0
  433. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_time_utils.py +0 -0
  434. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_timespan.py +0 -0
  435. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_utils.py +0 -0
  436. {lsst_daf_butler-29.2025.2000 → lsst_daf_butler-29.2025.2300}/tests/test_versioning.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lsst-daf-butler
3
- Version: 29.2025.2000
3
+ Version: 29.2025.2300
4
4
  Summary: An abstraction layer for reading and writing astronomical data to datastores.
5
5
  Author-email: Rubin Observatory Data Management <dm-admin@lists.lsst.org>
6
6
  License: BSD 3-Clause License
@@ -90,6 +90,10 @@ class SpecificButlerDataset:
90
90
  dataset: DatasetRef | None
91
91
 
92
92
 
93
+ class _DeprecatedDefault:
94
+ """Default value for a deprecated parameter."""
95
+
96
+
93
97
  class Butler(LimitedButler): # numpydoc ignore=PR02
94
98
  """Interface for data butler and factory for Butler instances.
95
99
 
@@ -1288,7 +1292,13 @@ class Butler(LimitedButler): # numpydoc ignore=PR02
1288
1292
  raise NotImplementedError()
1289
1293
 
1290
1294
  @abstractmethod
1291
- def removeRuns(self, names: Iterable[str], unstore: bool = True) -> None:
1295
+ def removeRuns(
1296
+ self,
1297
+ names: Iterable[str],
1298
+ unstore: bool | type[_DeprecatedDefault] = _DeprecatedDefault,
1299
+ *,
1300
+ unlink_from_chains: bool = False,
1301
+ ) -> None:
1292
1302
  """Remove one or more `~CollectionType.RUN` collections and the
1293
1303
  datasets within them.
1294
1304
 
@@ -1301,7 +1311,13 @@ class Butler(LimitedButler): # numpydoc ignore=PR02
1301
1311
  they are present, and attempt to rollback the registry deletions if
1302
1312
  datastore deletions fail (which may not always be possible). If
1303
1313
  `False`, datastore records for these datasets are still removed,
1304
- but any artifacts (e.g. files) will not be.
1314
+ but any artifacts (e.g. files) will not be. This parameter is now
1315
+ deprecated and no longer has any effect. Files are always deleted
1316
+ from datastores unless they were ingested using full URIs.
1317
+ unlink_from_chains : `bool`, optional
1318
+ If `True` remove the RUN collection from any chains prior to
1319
+ removing the RUN. If `False` the removal will fail if any chains
1320
+ still refer to the RUN.
1305
1321
 
1306
1322
  Raises
1307
1323
  ------
@@ -1374,7 +1390,14 @@ class Butler(LimitedButler): # numpydoc ignore=PR02
1374
1390
  raise NotImplementedError()
1375
1391
 
1376
1392
  @abstractmethod
1377
- def ingest_zip(self, zip_file: ResourcePathExpression, transfer: str = "auto") -> None:
1393
+ def ingest_zip(
1394
+ self,
1395
+ zip_file: ResourcePathExpression,
1396
+ transfer: str = "auto",
1397
+ *,
1398
+ transfer_dimensions: bool = False,
1399
+ dry_run: bool = False,
1400
+ ) -> None:
1378
1401
  """Ingest a Zip file into this butler.
1379
1402
 
1380
1403
  The Zip file must have been created by `retrieve_artifacts_zip`.
@@ -1385,10 +1408,17 @@ class Butler(LimitedButler): # numpydoc ignore=PR02
1385
1408
  Path to the Zip file.
1386
1409
  transfer : `str`, optional
1387
1410
  Method to use to transfer the Zip into the datastore.
1411
+ transfer_dimensions : `bool`, optional
1412
+ If `True`, dimension record data associated with the new datasets
1413
+ will be transferred from the Zip file, if present.
1414
+ dry_run : `bool`, optional
1415
+ If `True` the ingest will be processed without any modifications
1416
+ made to the target butler and as if the target butler did not
1417
+ have any of the datasets.
1388
1418
 
1389
1419
  Notes
1390
1420
  -----
1391
- Run collections are created as needed.
1421
+ Run collections and dataset types are created as needed.
1392
1422
  """
1393
1423
  raise NotImplementedError()
1394
1424
 
@@ -108,6 +108,10 @@ class ButlerCollections(ABC, Sequence):
108
108
  """Collection defaults associated with this butler."""
109
109
  raise NotImplementedError("Defaults must be implemented by a subclass")
110
110
 
111
+ def __str__(self) -> str:
112
+ """Return string representation."""
113
+ return f"{self.__class__.__name__}(defaults={self.defaults})"
114
+
111
115
  @abstractmethod
112
116
  def extend_chain(self, parent_collection_name: str, child_collection_names: str | Iterable[str]) -> None:
113
117
  """Add children to the end of a CHAINED collection.
@@ -424,6 +424,21 @@ def prune_datasets(**kwargs: Any) -> None:
424
424
  case_sensitive=False,
425
425
  ),
426
426
  )
427
+ @click.option(
428
+ "-t",
429
+ "--show-dataset-types",
430
+ is_flag=True,
431
+ help="Also show the dataset types registered within each collection.",
432
+ )
433
+ @click.option(
434
+ "--exclude-dataset-types",
435
+ type=click.STRING,
436
+ multiple=True,
437
+ default=["*_config,*_log,*_metadata,packages"],
438
+ callback=split_commas,
439
+ show_default=True,
440
+ help="Dataset types (comma-separated) to exclude. Only valid with --show-dataset-types.",
441
+ )
427
442
  @options_file_option()
428
443
  def query_collections(*args: Any, **kwargs: Any) -> None:
429
444
  """Get the collections whose names match an expression."""
@@ -454,7 +469,7 @@ def query_dataset_types(*args: Any, **kwargs: Any) -> None:
454
469
  """Get the dataset types in a repository."""
455
470
  table = script.queryDatasetTypes(*args, **kwargs)
456
471
  if table:
457
- table.pprint_all()
472
+ table.pprint_all(align="<")
458
473
  else:
459
474
  print("No results. Try --help for more information.")
460
475
 
@@ -829,6 +844,12 @@ def export_calibs(*args: Any, **kwargs: Any) -> None:
829
844
  @repo_argument(required=True)
830
845
  @click.argument("zip", required=True)
831
846
  @transfer_option()
847
+ @transfer_dimensions_option(
848
+ default=False, help="Attempt to register missing dimension records during ingest."
849
+ )
850
+ @click.option(
851
+ "--dry-run/--no-dry-run", default=False, help="Enable dry run mode and do not ingest any datasets."
852
+ )
832
853
  def ingest_zip(**kwargs: Any) -> None:
833
854
  """Ingest a Zip file created by retrieve-artifacts.
834
855
 
@@ -1057,7 +1057,7 @@ class MWCommand(click.Command):
1057
1057
  return ret
1058
1058
 
1059
1059
  @epilog.setter
1060
- def epilog(self, val: str) -> None:
1060
+ def epilog(self, val: str | None) -> None:
1061
1061
  self._epilog = val
1062
1062
 
1063
1063
 
@@ -1082,7 +1082,7 @@ class Datastore(metaclass=ABCMeta):
1082
1082
  raise NotImplementedError()
1083
1083
 
1084
1084
  @abstractmethod
1085
- def ingest_zip(self, zip_path: ResourcePath, transfer: str | None) -> None:
1085
+ def ingest_zip(self, zip_path: ResourcePath, transfer: str | None, *, dry_run: bool = False) -> None:
1086
1086
  """Ingest an indexed Zip file and contents.
1087
1087
 
1088
1088
  The Zip file must have an index file as created by `retrieveArtifacts`.
@@ -1093,6 +1093,10 @@ class Datastore(metaclass=ABCMeta):
1093
1093
  Path to the Zip file.
1094
1094
  transfer : `str`
1095
1095
  Method to use for transferring the Zip file into the datastore.
1096
+ dry_run : `bool`, optional
1097
+ If `True` the ingest will be processed without any modifications
1098
+ made to the target datastore and as if the target datastore did not
1099
+ have any of the datasets.
1096
1100
  """
1097
1101
  raise NotImplementedError()
1098
1102
 
@@ -1504,7 +1508,7 @@ class NullDatastore(Datastore):
1504
1508
  def getURI(self, datasetRef: DatasetRef, predict: bool = False) -> ResourcePath:
1505
1509
  raise FileNotFoundError("This is a no-op datastore that can not access a real datastore")
1506
1510
 
1507
- def ingest_zip(self, zip_path: ResourcePath, transfer: str | None) -> None:
1511
+ def ingest_zip(self, zip_path: ResourcePath, transfer: str | None, *, dry_run: bool = False) -> None:
1508
1512
  raise NotImplementedError("Can only ingest a Zip into a real datastore.")
1509
1513
 
1510
1514
  def retrieveArtifacts(
@@ -32,7 +32,6 @@ from __future__ import annotations
32
32
  __all__ = ("ChainedDatastore",)
33
33
 
34
34
  import itertools
35
- import logging
36
35
  import time
37
36
  import warnings
38
37
  from collections.abc import Callable, Collection, Iterable, Mapping, Sequence
@@ -51,13 +50,14 @@ from lsst.daf.butler.datastore.record_data import DatastoreRecordData
51
50
  from lsst.daf.butler.datastores.file_datastore.retrieve_artifacts import ArtifactIndexInfo, ZipIndex
52
51
  from lsst.resources import ResourcePath
53
52
  from lsst.utils import doImportType
53
+ from lsst.utils.logging import getLogger
54
54
 
55
55
  if TYPE_CHECKING:
56
56
  from lsst.daf.butler import Config, DatasetProvenance, DatasetType, LookupKey, StorageClass
57
57
  from lsst.daf.butler.registry.interfaces import DatasetIdRef, DatastoreRegistryBridgeManager
58
58
  from lsst.resources import ResourcePathExpression
59
59
 
60
- log = logging.getLogger(__name__)
60
+ log = getLogger(__name__)
61
61
 
62
62
 
63
63
  class _IngestPrepData(Datastore.IngestPrepData):
@@ -912,7 +912,7 @@ class ChainedDatastore(Datastore):
912
912
 
913
913
  return merged_artifact_map
914
914
 
915
- def ingest_zip(self, zip_path: ResourcePath, transfer: str | None) -> None:
915
+ def ingest_zip(self, zip_path: ResourcePath, transfer: str | None, *, dry_run: bool = False) -> None:
916
916
  """Ingest an indexed Zip file and contents.
917
917
 
918
918
  The Zip file must have an index file as created by `retrieveArtifacts`.
@@ -923,6 +923,10 @@ class ChainedDatastore(Datastore):
923
923
  Path to the Zip file.
924
924
  transfer : `str`
925
925
  Method to use for transferring the Zip file into the datastore.
926
+ dry_run : `bool`, optional
927
+ If `True` the ingest will be processed without any modifications
928
+ made to the target datastore and as if the target datastore did not
929
+ have any of the datasets.
926
930
 
927
931
  Notes
928
932
  -----
@@ -966,7 +970,7 @@ class ChainedDatastore(Datastore):
966
970
  log.debug("Datastore %s skipping zip ingest due to constraints", datastore.name)
967
971
  continue
968
972
  try:
969
- datastore.ingest_zip(zip_path, transfer=transfer)
973
+ datastore.ingest_zip(zip_path, transfer=transfer, dry_run=dry_run)
970
974
  except NotImplementedError:
971
975
  continue
972
976
  except Exception as e:
@@ -1239,102 +1243,65 @@ class ChainedDatastore(Datastore):
1239
1243
  dry_run: bool = False,
1240
1244
  ) -> tuple[set[DatasetRef], set[DatasetRef]]:
1241
1245
  # Docstring inherited
1242
- # mypy does not understand "type(self) is not type(source)"
1243
- if isinstance(source_datastore, ChainedDatastore):
1244
- # Both the source and destination are chained datastores.
1245
- source_datastores = tuple(source_datastore.datastores)
1246
- else:
1247
- # The source datastore is different, forward everything to the
1248
- # child datastores.
1249
- source_datastores = (source_datastore,)
1250
-
1251
1246
  if not refs:
1252
- # Nothing to transfer.
1253
1247
  return set(), set()
1254
1248
 
1255
- # Need to know the set of all possible refs that could be transferred.
1256
- remaining_refs = set(refs)
1257
-
1258
- missing_from_source: set[DatasetRef] | None = None
1259
- all_accepted = set()
1249
+ # Assume that each child datastore knows how to look inside a chained
1250
+ # datastore for compatible datastores (and so there is no need to
1251
+ # unpack the source datastores here).
1252
+ # Need to decide if a ref accepted by one datastore should be sent to
1253
+ # later datastores (as is done in put()). More efficient to filter out
1254
+ # accepted datasets.
1255
+ if artifact_existence is None:
1256
+ artifact_existence = {}
1257
+ available_refs = set(refs)
1258
+ accepted: set[DatasetRef] = set()
1259
+ rejected: set[DatasetRef] = set()
1260
1260
  nsuccess = 0
1261
- for source_child in source_datastores:
1262
- # If we are reading from a chained datastore, it's possible that
1263
- # only a subset of the datastores know about the dataset. We can't
1264
- # ask the receiving datastore to copy it when it doesn't exist
1265
- # so we have to filter again based on what the source datastore
1266
- # understands.
1267
- known_to_source = source_child.knows_these(list(refs))
1268
-
1269
- # Need to know that there is a possibility that some of these
1270
- # datasets exist but are unknown to the source datastore if
1271
- # trust is enabled.
1272
- if getattr(source_child, "trustGetRequest", False):
1273
- unknown = [ref for ref, known in known_to_source.items() if not known]
1274
- existence = source_child.mexists(unknown, artifact_existence)
1275
- for ref, exists in existence.items():
1276
- known_to_source[ref] = exists
1277
-
1278
- missing = {ref for ref, known in known_to_source.items() if not known}
1279
- if missing:
1280
- if missing_from_source is None:
1281
- missing_from_source = missing
1282
- else:
1283
- missing_from_source &= missing
1284
-
1285
- # Try to transfer from each source datastore to each child
1286
- # datastore. Have to make sure we don't transfer something
1287
- # we've already transferred to this destination on later passes.
1288
-
1289
- # Filter the initial list based on the datasets we have
1290
- # not yet transferred.
1291
- these_refs = []
1292
- for ref in refs:
1293
- if ref in remaining_refs and known_to_source[ref]:
1294
- these_refs.append(ref)
1295
-
1296
- if not these_refs:
1297
- # Already transferred all datasets known to this datastore.
1298
- continue
1299
1261
 
1300
- for datastore, constraints in zip(self.datastores, self.datastoreConstraints, strict=True):
1301
- if constraints is not None:
1302
- filtered_refs = []
1303
- for ref in these_refs:
1304
- if constraints.isAcceptable(ref):
1305
- filtered_refs.append(ref)
1306
- else:
1307
- log.debug("Rejecting ref by constraints: %s", ref)
1308
- else:
1309
- filtered_refs = list(these_refs)
1310
- try:
1311
- accepted, _ = datastore.transfer_from(
1312
- source_child,
1313
- filtered_refs,
1314
- transfer,
1315
- artifact_existence,
1316
- dry_run=dry_run,
1317
- )
1318
- except (TypeError, NotImplementedError):
1319
- # The datastores were incompatible.
1320
- continue
1321
- else:
1322
- nsuccess += 1
1262
+ log.debug("Initiating transfer to chained datastore %s from %s", self.name, source_datastore.name)
1263
+ for datastore in self.datastores:
1264
+ # Rejections from this datastore might be acceptances in the next.
1265
+ # We add them all up but then recalculate at the end.
1266
+ if not available_refs:
1267
+ break
1268
+ log.verbose("Transferring %d datasets to %s from chain", len(available_refs), datastore.name)
1323
1269
 
1324
- # Remove the accepted datasets from those remaining.
1325
- remaining_refs = remaining_refs - accepted
1270
+ try:
1271
+ current_accepted, current_rejected = datastore.transfer_from(
1272
+ source_datastore,
1273
+ available_refs,
1274
+ transfer=transfer,
1275
+ artifact_existence=artifact_existence,
1276
+ dry_run=dry_run,
1277
+ )
1278
+ except (TypeError, NotImplementedError):
1279
+ # The datastores were incompatible.
1280
+ continue
1281
+ else:
1282
+ nsuccess += 1
1326
1283
 
1327
- # Keep track of everything we have accepted.
1328
- all_accepted.update(accepted)
1284
+ # Do not send accepted refs to later datastores.
1285
+ available_refs -= current_accepted
1329
1286
 
1330
- if missing_from_source:
1331
- for ref in missing_from_source:
1332
- log.warning("Asked to transfer dataset %s but no file artifacts exist for it", ref)
1287
+ accepted.update(current_accepted)
1288
+ rejected.update(current_rejected)
1333
1289
 
1334
1290
  if nsuccess == 0:
1335
1291
  raise TypeError(f"None of the child datastores could accept transfers from {source_datastore!r}")
1336
1292
 
1337
- return all_accepted, remaining_refs
1293
+ # It's not rejected if some other datastore accepted it.
1294
+ rejected -= accepted
1295
+ log.verbose(
1296
+ "Finished transfer_from %s to %s with %d accepted, %d rejected from %d requested.",
1297
+ source_datastore.name,
1298
+ self.name,
1299
+ len(accepted),
1300
+ len(rejected),
1301
+ len(refs),
1302
+ )
1303
+
1304
+ return accepted, rejected
1338
1305
 
1339
1306
  def get_opaque_table_definitions(self) -> Mapping[str, DatastoreOpaqueTable]:
1340
1307
  # Docstring inherited from the base class.
@@ -34,6 +34,7 @@ __all__ = ("FileDatastore",)
34
34
  import contextlib
35
35
  import hashlib
36
36
  import logging
37
+ import math
37
38
  from collections import defaultdict
38
39
  from collections.abc import Callable, Collection, Iterable, Mapping, Sequence
39
40
  from typing import TYPE_CHECKING, Any, ClassVar, cast
@@ -1559,7 +1560,8 @@ class FileDatastore(GenericBaseDatastore[StoredFileInfo]):
1559
1560
  # Single chunk but multiple files. Summarize.
1560
1561
  log.log(
1561
1562
  log_threshold,
1562
- "Number of datasets found in datastore: %d out of %d datasets checked.",
1563
+ "Number of datasets found in datastore %s: %d out of %d datasets checked.",
1564
+ self.name,
1563
1565
  n_found,
1564
1566
  n_checked,
1565
1567
  )
@@ -2158,7 +2160,7 @@ class FileDatastore(GenericBaseDatastore[StoredFileInfo]):
2158
2160
 
2159
2161
  return artifact_map
2160
2162
 
2161
- def ingest_zip(self, zip_path: ResourcePath, transfer: str | None) -> None:
2163
+ def ingest_zip(self, zip_path: ResourcePath, transfer: str | None, *, dry_run: bool = False) -> None:
2162
2164
  """Ingest an indexed Zip file and contents.
2163
2165
 
2164
2166
  The Zip file must have an index file as created by `retrieveArtifacts`.
@@ -2169,6 +2171,10 @@ class FileDatastore(GenericBaseDatastore[StoredFileInfo]):
2169
2171
  Path to the Zip file.
2170
2172
  transfer : `str`
2171
2173
  Method to use for transferring the Zip file into the datastore.
2174
+ dry_run : `bool`, optional
2175
+ If `True` the ingest will be processed without any modifications
2176
+ made to the target datastore and as if the target datastore did not
2177
+ have any of the datasets.
2172
2178
 
2173
2179
  Notes
2174
2180
  -----
@@ -2219,9 +2225,12 @@ class FileDatastore(GenericBaseDatastore[StoredFileInfo]):
2219
2225
  tgtLocation.uri.dirname().mkdir()
2220
2226
 
2221
2227
  # Transfer the Zip file into the datastore.
2222
- tgtLocation.uri.transfer_from(
2223
- zip_path, transfer=transfer, transaction=self._transaction, overwrite=True
2224
- )
2228
+ if not dry_run:
2229
+ tgtLocation.uri.transfer_from(
2230
+ zip_path, transfer=transfer, transaction=self._transaction, overwrite=True
2231
+ )
2232
+ else:
2233
+ log.info("Would be copying Zip from %s to %s", zip_path, tgtLocation)
2225
2234
 
2226
2235
  if tgtLocation is None:
2227
2236
  path_in_store = str(zip_path)
@@ -2239,7 +2248,10 @@ class FileDatastore(GenericBaseDatastore[StoredFileInfo]):
2239
2248
  for id_ in index_info.ids:
2240
2249
  artifacts.append((id_to_ref[id_], info))
2241
2250
 
2242
- self._register_datasets(artifacts, insert_mode=DatabaseInsertMode.INSERT)
2251
+ if not dry_run:
2252
+ self._register_datasets(artifacts, insert_mode=DatabaseInsertMode.INSERT)
2253
+ else:
2254
+ log.info("Would be registering %d artifacts from Zip into datastore", len(artifacts))
2243
2255
 
2244
2256
  def get(
2245
2257
  self,
@@ -2543,10 +2555,24 @@ class FileDatastore(GenericBaseDatastore[StoredFileInfo]):
2543
2555
  removed = set()
2544
2556
  if refs:
2545
2557
  selected_ids = {ref.id for ref in refs}
2546
- n_chunks = 0
2547
- for chunk in chunk_iterable(selected_ids, chunk_size=50_000):
2548
- n_chunks += 1
2549
- log.verbose("Emptying trash for chunk %d of size %d", n_chunks, len(chunk))
2558
+ chunk_size = 50_000
2559
+ n_chunks = math.ceil(len(selected_ids) / chunk_size)
2560
+ chunk_num = 0
2561
+ for chunk in chunk_iterable(selected_ids, chunk_size=chunk_size):
2562
+ chunk_num += 1
2563
+ if n_chunks == 1:
2564
+ log.verbose(
2565
+ "Emptying datastore trash for %d dataset%s",
2566
+ len(chunk),
2567
+ "s" if len(chunk) != 1 else "",
2568
+ )
2569
+ else:
2570
+ log.verbose(
2571
+ "Emptying datastore trash for chunk %d out of %d of size %d",
2572
+ chunk_num,
2573
+ n_chunks,
2574
+ len(chunk),
2575
+ )
2550
2576
  removed.update(
2551
2577
  self._empty_trash_subset(ignore_errors=ignore_errors, selected_ids=chunk, dry_run=dry_run)
2552
2578
  )
@@ -2683,9 +2709,10 @@ class FileDatastore(GenericBaseDatastore[StoredFileInfo]):
2683
2709
 
2684
2710
  if artifacts_to_keep:
2685
2711
  log.verbose(
2686
- "%d artifact%s were not deleted because they are associated with other datasets",
2712
+ "%d artifact%s %s not deleted because of association with other datasets",
2687
2713
  len(artifacts_to_keep),
2688
2714
  "s" if len(artifacts_to_keep) != 1 else "",
2715
+ "were" if len(artifacts_to_keep) != 1 else "was",
2689
2716
  )
2690
2717
 
2691
2718
  if not artifacts_to_delete:
@@ -2763,20 +2790,7 @@ class FileDatastore(GenericBaseDatastore[StoredFileInfo]):
2763
2790
  artifact_existence: dict[ResourcePath, bool] | None = None,
2764
2791
  dry_run: bool = False,
2765
2792
  ) -> tuple[set[DatasetRef], set[DatasetRef]]:
2766
- log.verbose("transfer_from %s to %s", source_datastore.name, self.name)
2767
- # Docstring inherited
2768
- if type(self) is not type(source_datastore):
2769
- raise TypeError(
2770
- f"Datastore mismatch between this datastore ({type(self)}) and the "
2771
- f"source datastore ({type(source_datastore)})."
2772
- )
2773
-
2774
- # Be explicit for mypy
2775
- if not isinstance(source_datastore, FileDatastore):
2776
- raise TypeError(
2777
- "Can only transfer to a FileDatastore from another FileDatastore, not"
2778
- f" {type(source_datastore)}"
2779
- )
2793
+ log.verbose("Transferring %d datasets from %s to %s", len(refs), source_datastore.name, self.name)
2780
2794
 
2781
2795
  # Stop early if "direct" transfer mode is requested. That would
2782
2796
  # require that the URI inside the source datastore should be stored
@@ -2788,6 +2802,128 @@ class FileDatastore(GenericBaseDatastore[StoredFileInfo]):
2788
2802
  " those files are controlled by the other datastore."
2789
2803
  )
2790
2804
 
2805
+ if not refs:
2806
+ return set(), set()
2807
+
2808
+ # Potentially can be transferring from a chain.
2809
+ datastores = getattr(source_datastore, "datastores", [source_datastore])
2810
+
2811
+ incompatible: list[Datastore] = []
2812
+ acceptable: list[FileDatastore] = []
2813
+ for current_source in datastores:
2814
+ if not isinstance(current_source, FileDatastore):
2815
+ incompatible.append(current_source)
2816
+ else:
2817
+ acceptable.append(current_source)
2818
+
2819
+ if len(incompatible) == len(datastores):
2820
+ if len(datastores) == 1:
2821
+ raise TypeError(
2822
+ "Can only transfer to a FileDatastore from another FileDatastore, not"
2823
+ f" {get_full_type_name(source_datastore)}"
2824
+ )
2825
+ else:
2826
+ types = [get_full_type_name(d) for d in datastores]
2827
+ raise TypeError(
2828
+ f"ChainedDatastore encountered that had no FileDatastores. Had {','.join(types)}"
2829
+ )
2830
+
2831
+ if len(acceptable) == 1:
2832
+ # No need to filter in advance since there is only one usable
2833
+ # source datastore.
2834
+ return self._transfer_from(
2835
+ acceptable[0], refs, transfer=transfer, artifact_existence=artifact_existence, dry_run=dry_run
2836
+ )
2837
+
2838
+ # To avoid complaints from the transfer that the source does not have
2839
+ # a ref, partition refs by source datastores, and any unknown to both
2840
+ # are sent to any that support trustGetRequest.
2841
+ unassigned_refs: set[DatasetRef] = set(refs)
2842
+ known_refs: list[set[DatasetRef]] = []
2843
+ for datastore in acceptable:
2844
+ known_to_datastore = {ref for ref, known in datastore.knows_these(refs).items() if known}
2845
+ known_refs.append(known_to_datastore)
2846
+ unassigned_refs -= known_to_datastore
2847
+
2848
+ if unassigned_refs:
2849
+ for datastore, refs_known_to_datastore in zip(acceptable, known_refs, strict=True):
2850
+ if datastore.trustGetRequest:
2851
+ # Have to check each datastore in turn. If we do not do
2852
+ # this warnings will be issued further down for datasets
2853
+ # that are in one and not the other. The existence cache
2854
+ # will prevent repeat checks.
2855
+ exist_in_store = datastore.mexists(unassigned_refs, artifact_existence=artifact_existence)
2856
+ present = {ref for ref, exists in exist_in_store.items() if exists}
2857
+ refs_known_to_datastore.update(present)
2858
+ # Only transferring once so do not need to check later
2859
+ # datastores.
2860
+ unassigned_refs -= present
2861
+ log.debug(
2862
+ "Adding %d missing refs to list for transfer from %s", len(present), datastore.name
2863
+ )
2864
+
2865
+ if unassigned_refs:
2866
+ log.warning(
2867
+ "Encountered %d dataset%s where no file artifacts exist from the "
2868
+ "source datastore and will be skipped.",
2869
+ len(unassigned_refs),
2870
+ "s" if len(unassigned_refs) != 1 else "",
2871
+ )
2872
+
2873
+ # Once we have accepted refs from one datastore, do not need to try to
2874
+ # transfer them again.
2875
+ accepted: set[DatasetRef] = set()
2876
+ rejected: set[DatasetRef] = set()
2877
+ if artifact_existence is None:
2878
+ artifact_existence = {}
2879
+
2880
+ for current_source, refs_to_transfer in zip(acceptable, known_refs, strict=True):
2881
+ # Do not transfer if already transferred.
2882
+ refs_to_transfer -= accepted
2883
+ # No need to retry something that has already been rejected.
2884
+ refs_to_transfer -= rejected
2885
+
2886
+ if not refs_to_transfer:
2887
+ continue
2888
+
2889
+ log.verbose(
2890
+ "Requesting transfer of %d dataset%s from datastore %s to %s",
2891
+ len(refs_to_transfer),
2892
+ "s" if len(refs_to_transfer) != 1 else "",
2893
+ current_source.name,
2894
+ self.name,
2895
+ )
2896
+ current_accepted, current_rejected = self._transfer_from(
2897
+ current_source,
2898
+ refs_to_transfer,
2899
+ transfer=transfer,
2900
+ artifact_existence=artifact_existence,
2901
+ dry_run=dry_run,
2902
+ )
2903
+
2904
+ accepted.update(current_accepted)
2905
+ rejected.update(current_rejected)
2906
+
2907
+ log.verbose(
2908
+ "Finished transfer_from %s to %s with %d accepted, %d rejected, %d requested",
2909
+ source_datastore.name,
2910
+ self.name,
2911
+ len(accepted),
2912
+ len(rejected),
2913
+ len(refs),
2914
+ )
2915
+
2916
+ return accepted, rejected
2917
+
2918
+ @transactional
2919
+ def _transfer_from(
2920
+ self,
2921
+ source_datastore: FileDatastore,
2922
+ refs: Collection[DatasetRef],
2923
+ transfer: str = "auto",
2924
+ artifact_existence: dict[ResourcePath, bool] | None = None,
2925
+ dry_run: bool = False,
2926
+ ) -> tuple[set[DatasetRef], set[DatasetRef]]:
2791
2927
  # Empty existence lookup if none given.
2792
2928
  if artifact_existence is None:
2793
2929
  artifact_existence = {}
@@ -523,7 +523,7 @@ class InMemoryDatastore(GenericBaseDatastore[StoredMemoryItemInfo]):
523
523
  raise AssertionError(f"Unexpectedly got no URI for in-memory datastore for {ref}")
524
524
  return primary
525
525
 
526
- def ingest_zip(self, zip_path: ResourcePath, transfer: str | None) -> None:
526
+ def ingest_zip(self, zip_path: ResourcePath, transfer: str | None, *, dry_run: bool = False) -> None:
527
527
  raise NotImplementedError("Can only ingest a Zip into a file datastore.")
528
528
 
529
529
  def retrieveArtifacts(