lsst-daf-butler 29.2025.3500__tar.gz → 29.2025.3600__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 (452) hide show
  1. {lsst_daf_butler-29.2025.3500/python/lsst_daf_butler.egg-info → lsst_daf_butler-29.2025.3600}/PKG-INFO +1 -1
  2. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/_butler.py +10 -0
  3. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/_quantum_backed.py +13 -61
  4. lsst_daf_butler-29.2025.3600/python/lsst/daf/butler/_rubin/__init__.py +31 -0
  5. lsst_daf_butler-29.2025.3600/python/lsst/daf/butler/_rubin/file_datasets.py +88 -0
  6. lsst_daf_butler-29.2025.3600/python/lsst/daf/butler/_standalone_datastore.py +129 -0
  7. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/datastores/fileDatastore.py +2 -7
  8. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/direct_butler/_direct_butler.py +43 -3
  9. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/logging.py +34 -3
  10. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/interfaces/_database.py +6 -0
  11. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/remote_butler/_remote_butler.py +1 -0
  12. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/tests/hybrid_butler.py +5 -1
  13. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/tests/utils.py +2 -2
  14. lsst_daf_butler-29.2025.3600/python/lsst/daf/butler/version.py +2 -0
  15. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600/python/lsst_daf_butler.egg-info}/PKG-INFO +1 -1
  16. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst_daf_butler.egg-info/SOURCES.txt +3 -0
  17. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_butler.py +45 -1
  18. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_logging.py +24 -0
  19. lsst_daf_butler-29.2025.3500/python/lsst/daf/butler/version.py +0 -2
  20. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/COPYRIGHT +0 -0
  21. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/LICENSE +0 -0
  22. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/MANIFEST.in +0 -0
  23. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/README.md +0 -0
  24. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/bsd_license.txt +0 -0
  25. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/doc/lsst.daf.butler/CHANGES.rst +0 -0
  26. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/doc/lsst.daf.butler/concreteStorageClasses.rst +0 -0
  27. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/doc/lsst.daf.butler/configuring.rst +0 -0
  28. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/doc/lsst.daf.butler/datastores.rst +0 -0
  29. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/doc/lsst.daf.butler/dimensions.rst +0 -0
  30. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/doc/lsst.daf.butler/formatters.rst +0 -0
  31. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/doc/lsst.daf.butler/index.rst +0 -0
  32. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/doc/lsst.daf.butler/organizing.rst +0 -0
  33. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/doc/lsst.daf.butler/queries.rst +0 -0
  34. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/doc/lsst.daf.butler/use-in-tests.rst +0 -0
  35. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/doc/lsst.daf.butler/writing-subcommands.rst +0 -0
  36. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/gpl-v3.0.txt +0 -0
  37. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/pyproject.toml +0 -0
  38. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/__init__.py +0 -0
  39. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/__init__.py +0 -0
  40. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/__init__.py +0 -0
  41. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/_butler_collections.py +0 -0
  42. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/_butler_config.py +0 -0
  43. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/_butler_instance_options.py +0 -0
  44. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/_butler_metrics.py +0 -0
  45. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/_butler_repo_index.py +0 -0
  46. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/_collection_type.py +0 -0
  47. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/_column_categorization.py +0 -0
  48. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/_column_tags.py +0 -0
  49. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/_column_type_info.py +0 -0
  50. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/_config.py +0 -0
  51. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/_config_support.py +0 -0
  52. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/_dataset_association.py +0 -0
  53. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/_dataset_existence.py +0 -0
  54. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/_dataset_provenance.py +0 -0
  55. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/_dataset_ref.py +0 -0
  56. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/_dataset_type.py +0 -0
  57. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/_deferredDatasetHandle.py +0 -0
  58. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/_exceptions.py +0 -0
  59. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/_exceptions_legacy.py +0 -0
  60. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/_file_dataset.py +0 -0
  61. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/_file_descriptor.py +0 -0
  62. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/_formatter.py +0 -0
  63. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/_labeled_butler_factory.py +0 -0
  64. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/_limited_butler.py +0 -0
  65. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/_location.py +0 -0
  66. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/_named.py +0 -0
  67. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/_quantum.py +0 -0
  68. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/_query_all_datasets.py +0 -0
  69. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/_registry_shim.py +0 -0
  70. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/_storage_class.py +0 -0
  71. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/_storage_class_delegate.py +0 -0
  72. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/_timespan.py +0 -0
  73. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/_topology.py +0 -0
  74. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/_utilities/__init__.py +0 -0
  75. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/_utilities/locked_object.py +0 -0
  76. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/_utilities/named_locks.py +0 -0
  77. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/_utilities/thread_safe_cache.py +0 -0
  78. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/arrow_utils.py +0 -0
  79. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/cli/__init__.py +0 -0
  80. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/cli/butler.py +0 -0
  81. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/cli/cliLog.py +0 -0
  82. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/cli/cmd/__init__.py +0 -0
  83. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/cli/cmd/_remove_collections.py +0 -0
  84. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/cli/cmd/_remove_runs.py +0 -0
  85. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/cli/cmd/commands.py +0 -0
  86. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/cli/opt/__init__.py +0 -0
  87. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/cli/opt/arguments.py +0 -0
  88. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/cli/opt/optionGroups.py +0 -0
  89. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/cli/opt/options.py +0 -0
  90. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/cli/progress.py +0 -0
  91. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/cli/utils.py +0 -0
  92. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/column_spec.py +0 -0
  93. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/configs/datastore.yaml +0 -0
  94. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/configs/datastores/composites.yaml +0 -0
  95. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/configs/datastores/fileDatastore.yaml +0 -0
  96. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/configs/datastores/formatters.yaml +0 -0
  97. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/configs/datastores/writeRecipes.yaml +0 -0
  98. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/configs/dimensions.yaml +0 -0
  99. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/configs/old_dimensions/daf_butler_universe0.yaml +0 -0
  100. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/configs/old_dimensions/daf_butler_universe1.yaml +0 -0
  101. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/configs/old_dimensions/daf_butler_universe2.yaml +0 -0
  102. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/configs/old_dimensions/daf_butler_universe3.yaml +0 -0
  103. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/configs/old_dimensions/daf_butler_universe4.yaml +0 -0
  104. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/configs/old_dimensions/daf_butler_universe5.yaml +0 -0
  105. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/configs/old_dimensions/daf_butler_universe6.yaml +0 -0
  106. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/configs/old_dimensions/daf_butler_universe7.yaml +0 -0
  107. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/configs/registry.yaml +0 -0
  108. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/configs/repo_transfer_formats.yaml +0 -0
  109. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/configs/storageClasses.yaml +0 -0
  110. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/datastore/__init__.py +0 -0
  111. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/datastore/_datastore.py +0 -0
  112. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/datastore/_transfer.py +0 -0
  113. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/datastore/cache_manager.py +0 -0
  114. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/datastore/composites.py +0 -0
  115. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/datastore/constraints.py +0 -0
  116. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/datastore/file_templates.py +0 -0
  117. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/datastore/generic_base.py +0 -0
  118. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/datastore/record_data.py +0 -0
  119. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/datastore/stored_file_info.py +0 -0
  120. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/datastores/__init__.py +0 -0
  121. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/datastores/chainedDatastore.py +0 -0
  122. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/datastores/file_datastore/__init__.py +0 -0
  123. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/datastores/file_datastore/get.py +0 -0
  124. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/datastores/file_datastore/retrieve_artifacts.py +0 -0
  125. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/datastores/file_datastore/transfer.py +0 -0
  126. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/datastores/inMemoryDatastore.py +0 -0
  127. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/ddl.py +0 -0
  128. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/delegates/__init__.py +0 -0
  129. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/delegates/arrowtable.py +0 -0
  130. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/dimensions/__init__.py +0 -0
  131. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/dimensions/_config.py +0 -0
  132. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/dimensions/_coordinate.py +0 -0
  133. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/dimensions/_data_coordinate_iterable.py +0 -0
  134. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/dimensions/_database.py +0 -0
  135. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/dimensions/_elements.py +0 -0
  136. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/dimensions/_governor.py +0 -0
  137. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/dimensions/_group.py +0 -0
  138. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/dimensions/_packer.py +0 -0
  139. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/dimensions/_record_set.py +0 -0
  140. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/dimensions/_record_table.py +0 -0
  141. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/dimensions/_records.py +0 -0
  142. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/dimensions/_schema.py +0 -0
  143. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/dimensions/_skypix.py +0 -0
  144. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/dimensions/_universe.py +0 -0
  145. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/dimensions/construction.py +0 -0
  146. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/dimensions/record_cache.py +0 -0
  147. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/direct_butler/__init__.py +0 -0
  148. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/direct_butler/_direct_butler_collections.py +0 -0
  149. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/direct_query_driver/__init__.py +0 -0
  150. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/direct_query_driver/_driver.py +0 -0
  151. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/direct_query_driver/_postprocessing.py +0 -0
  152. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/direct_query_driver/_query_analysis.py +0 -0
  153. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/direct_query_driver/_query_builder.py +0 -0
  154. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/direct_query_driver/_result_page_converter.py +0 -0
  155. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/direct_query_driver/_sql_builders.py +0 -0
  156. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/direct_query_driver/_sql_column_visitor.py +0 -0
  157. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/formatters/__init__.py +0 -0
  158. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/formatters/astropyTable.py +0 -0
  159. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/formatters/file.py +0 -0
  160. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/formatters/json.py +0 -0
  161. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/formatters/logs.py +0 -0
  162. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/formatters/matplotlib.py +0 -0
  163. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/formatters/packages.py +0 -0
  164. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/formatters/parquet.py +0 -0
  165. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/formatters/pickle.py +0 -0
  166. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/formatters/typeless.py +0 -0
  167. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/formatters/yaml.py +0 -0
  168. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/json.py +0 -0
  169. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/mapping_factory.py +0 -0
  170. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/name_shrinker.py +0 -0
  171. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/nonempty_mapping.py +0 -0
  172. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/persistence_context.py +0 -0
  173. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/progress.py +0 -0
  174. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/py.typed +0 -0
  175. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/pydantic_utils.py +0 -0
  176. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/queries/__init__.py +0 -0
  177. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/queries/_base.py +0 -0
  178. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/queries/_data_coordinate_query_results.py +0 -0
  179. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/queries/_dataset_query_results.py +0 -0
  180. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/queries/_dimension_record_query_results.py +0 -0
  181. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/queries/_expression_strings.py +0 -0
  182. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/queries/_general_query_results.py +0 -0
  183. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/queries/_identifiers.py +0 -0
  184. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/queries/_query.py +0 -0
  185. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/queries/convert_args.py +0 -0
  186. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/queries/driver.py +0 -0
  187. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/queries/expression_factory.py +0 -0
  188. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/queries/overlaps.py +0 -0
  189. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/queries/predicate_constraints_summary.py +0 -0
  190. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/queries/result_specs.py +0 -0
  191. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/queries/tree/__init__.py +0 -0
  192. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/queries/tree/_base.py +0 -0
  193. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/queries/tree/_column_expression.py +0 -0
  194. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/queries/tree/_column_literal.py +0 -0
  195. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/queries/tree/_column_reference.py +0 -0
  196. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/queries/tree/_column_set.py +0 -0
  197. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/queries/tree/_predicate.py +0 -0
  198. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/queries/tree/_query_tree.py +0 -0
  199. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/queries/visitors.py +0 -0
  200. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/__init__.py +0 -0
  201. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/_caching_context.py +0 -0
  202. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/_collection_record_cache.py +0 -0
  203. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/_collection_summary.py +0 -0
  204. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/_collection_summary_cache.py +0 -0
  205. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/_config.py +0 -0
  206. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/_defaults.py +0 -0
  207. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/_exceptions.py +0 -0
  208. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/_registry.py +0 -0
  209. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/_registry_factory.py +0 -0
  210. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/attributes.py +0 -0
  211. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/bridge/__init__.py +0 -0
  212. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/bridge/ephemeral.py +0 -0
  213. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/bridge/monolithic.py +0 -0
  214. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/collections/__init__.py +0 -0
  215. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/collections/_base.py +0 -0
  216. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/collections/nameKey.py +0 -0
  217. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/collections/synthIntKey.py +0 -0
  218. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/connectionString.py +0 -0
  219. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/databases/__init__.py +0 -0
  220. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/databases/postgresql.py +0 -0
  221. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/databases/sqlite.py +0 -0
  222. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/datasets/__init__.py +0 -0
  223. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/datasets/byDimensions/__init__.py +0 -0
  224. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/datasets/byDimensions/_dataset_type_cache.py +0 -0
  225. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/datasets/byDimensions/_manager.py +0 -0
  226. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/datasets/byDimensions/summaries.py +0 -0
  227. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/datasets/byDimensions/tables.py +0 -0
  228. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/dimensions/__init__.py +0 -0
  229. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/dimensions/static.py +0 -0
  230. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/interfaces/__init__.py +0 -0
  231. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/interfaces/_attributes.py +0 -0
  232. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/interfaces/_bridge.py +0 -0
  233. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/interfaces/_collections.py +0 -0
  234. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/interfaces/_database_explain.py +0 -0
  235. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/interfaces/_datasets.py +0 -0
  236. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/interfaces/_dimensions.py +0 -0
  237. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/interfaces/_obscore.py +0 -0
  238. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/interfaces/_opaque.py +0 -0
  239. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/interfaces/_versioning.py +0 -0
  240. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/managers.py +0 -0
  241. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/nameShrinker.py +0 -0
  242. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/obscore/__init__.py +0 -0
  243. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/obscore/_config.py +0 -0
  244. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/obscore/_manager.py +0 -0
  245. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/obscore/_records.py +0 -0
  246. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/obscore/_schema.py +0 -0
  247. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/obscore/_spatial.py +0 -0
  248. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/obscore/default_spatial.py +0 -0
  249. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/obscore/pgsphere.py +0 -0
  250. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/opaque.py +0 -0
  251. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/queries/__init__.py +0 -0
  252. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/queries/_builder.py +0 -0
  253. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/queries/_query.py +0 -0
  254. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/queries/_query_backend.py +0 -0
  255. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/queries/_query_context.py +0 -0
  256. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/queries/_readers.py +0 -0
  257. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/queries/_results.py +0 -0
  258. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/queries/_sql_query_backend.py +0 -0
  259. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/queries/_sql_query_context.py +0 -0
  260. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/queries/_structs.py +0 -0
  261. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/queries/butler_sql_engine.py +0 -0
  262. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/queries/expressions/__init__.py +0 -0
  263. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/queries/expressions/_predicate.py +0 -0
  264. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/queries/expressions/categorize.py +0 -0
  265. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/queries/expressions/check.py +0 -0
  266. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/queries/expressions/normalForm.py +0 -0
  267. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/queries/expressions/parser/__init__.py +0 -0
  268. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/queries/expressions/parser/exprTree.py +0 -0
  269. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/queries/expressions/parser/parser.py +0 -0
  270. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/queries/expressions/parser/parserLex.py +0 -0
  271. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/queries/expressions/parser/parserYacc.py +0 -0
  272. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/queries/expressions/parser/ply/__init__.py +0 -0
  273. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/queries/expressions/parser/ply/lex.py +0 -0
  274. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/queries/expressions/parser/ply/yacc.py +0 -0
  275. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/queries/expressions/parser/treeVisitor.py +0 -0
  276. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/queries/find_first_dataset.py +0 -0
  277. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/sql_registry.py +0 -0
  278. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/tests/__init__.py +0 -0
  279. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/tests/_database.py +0 -0
  280. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/tests/_registry.py +0 -0
  281. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/versions.py +0 -0
  282. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/registry/wildcards.py +0 -0
  283. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/remote_butler/__init__.py +0 -0
  284. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/remote_butler/_collection_args.py +0 -0
  285. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/remote_butler/_config.py +0 -0
  286. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/remote_butler/_defaults.py +0 -0
  287. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/remote_butler/_errors.py +0 -0
  288. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/remote_butler/_factory.py +0 -0
  289. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/remote_butler/_get.py +0 -0
  290. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/remote_butler/_http_connection.py +0 -0
  291. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/remote_butler/_query_driver.py +0 -0
  292. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/remote_butler/_query_results.py +0 -0
  293. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/remote_butler/_ref_utils.py +0 -0
  294. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/remote_butler/_registry.py +0 -0
  295. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/remote_butler/_remote_butler_collections.py +0 -0
  296. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/remote_butler/_remote_file_transfer_source.py +0 -0
  297. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/remote_butler/authentication/__init__.py +0 -0
  298. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/remote_butler/authentication/cadc.py +0 -0
  299. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/remote_butler/authentication/interface.py +0 -0
  300. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/remote_butler/authentication/rubin.py +0 -0
  301. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/remote_butler/registry/__init__.py +0 -0
  302. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/remote_butler/registry/_query_common.py +0 -0
  303. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/remote_butler/registry/_query_data_coordinates.py +0 -0
  304. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/remote_butler/registry/_query_datasets.py +0 -0
  305. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/remote_butler/registry/_query_dimension_records.py +0 -0
  306. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/remote_butler/server/__init__.py +0 -0
  307. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/remote_butler/server/_config.py +0 -0
  308. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/remote_butler/server/_dependencies.py +0 -0
  309. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/remote_butler/server/_factory.py +0 -0
  310. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/remote_butler/server/_gafaelfawr.py +0 -0
  311. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/remote_butler/server/_server.py +0 -0
  312. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/remote_butler/server/_telemetry.py +0 -0
  313. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/remote_butler/server/handlers/_external.py +0 -0
  314. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/remote_butler/server/handlers/_external_query.py +0 -0
  315. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/remote_butler/server/handlers/_file_info.py +0 -0
  316. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/remote_butler/server/handlers/_internal.py +0 -0
  317. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/remote_butler/server/handlers/_query_limits.py +0 -0
  318. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/remote_butler/server/handlers/_query_serialization.py +0 -0
  319. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/remote_butler/server/handlers/_query_streaming.py +0 -0
  320. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/remote_butler/server/handlers/_utils.py +0 -0
  321. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/remote_butler/server_models.py +0 -0
  322. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/repo_relocation.py +0 -0
  323. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/script/__init__.py +0 -0
  324. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/script/_associate.py +0 -0
  325. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/script/_pruneDatasets.py +0 -0
  326. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/script/butlerImport.py +0 -0
  327. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/script/certifyCalibrations.py +0 -0
  328. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/script/collectionChain.py +0 -0
  329. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/script/configDump.py +0 -0
  330. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/script/configValidate.py +0 -0
  331. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/script/createRepo.py +0 -0
  332. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/script/exportCalibs.py +0 -0
  333. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/script/ingest_files.py +0 -0
  334. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/script/ingest_zip.py +0 -0
  335. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/script/queryCollections.py +0 -0
  336. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/script/queryDataIds.py +0 -0
  337. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/script/queryDatasetTypes.py +0 -0
  338. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/script/queryDatasets.py +0 -0
  339. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/script/queryDimensionRecords.py +0 -0
  340. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/script/register_dataset_type.py +0 -0
  341. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/script/removeCollections.py +0 -0
  342. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/script/removeDatasetType.py +0 -0
  343. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/script/removeRuns.py +0 -0
  344. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/script/retrieveArtifacts.py +0 -0
  345. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/script/transferDatasets.py +0 -0
  346. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/tests/__init__.py +0 -0
  347. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/tests/_datasetsHelper.py +0 -0
  348. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/tests/_dummyRegistry.py +0 -0
  349. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/tests/_examplePythonTypes.py +0 -0
  350. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/tests/_testRepo.py +0 -0
  351. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/tests/butler_queries.py +0 -0
  352. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/tests/cliCmdTestBase.py +0 -0
  353. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/tests/cliLogTestBase.py +0 -0
  354. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/tests/deferredFormatter.py +0 -0
  355. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/tests/dict_convertible_model.py +0 -0
  356. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/tests/hybrid_butler_collections.py +0 -0
  357. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/tests/hybrid_butler_registry.py +0 -0
  358. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/tests/postgresql.py +0 -0
  359. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/tests/registry_data/__init__.py +0 -0
  360. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/tests/registry_data/base.yaml +0 -0
  361. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/tests/registry_data/ci_hsc-subset-skymap.yaml +0 -0
  362. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/tests/registry_data/ci_hsc-subset.yaml +0 -0
  363. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/tests/registry_data/datasets.yaml +0 -0
  364. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/tests/registry_data/hsc-rc2-subset-v0.yaml +0 -0
  365. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/tests/registry_data/spatial.py +0 -0
  366. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/tests/registry_data/spatial.yaml +0 -0
  367. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/tests/server.py +0 -0
  368. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/tests/server_utils.py +0 -0
  369. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/tests/testFormatters.py +0 -0
  370. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/time_utils.py +0 -0
  371. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/timespan_database_representation.py +0 -0
  372. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/transfers/__init__.py +0 -0
  373. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/transfers/_context.py +0 -0
  374. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/transfers/_interfaces.py +0 -0
  375. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/transfers/_yaml.py +0 -0
  376. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst/daf/butler/utils.py +0 -0
  377. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst_daf_butler.egg-info/dependency_links.txt +0 -0
  378. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst_daf_butler.egg-info/entry_points.txt +0 -0
  379. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst_daf_butler.egg-info/requires.txt +0 -0
  380. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst_daf_butler.egg-info/top_level.txt +0 -0
  381. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/python/lsst_daf_butler.egg-info/zip-safe +0 -0
  382. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/setup.cfg +0 -0
  383. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_astropyTableFormatter.py +0 -0
  384. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_authentication.py +0 -0
  385. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_butler_factory.py +0 -0
  386. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_cliCmdAssociate.py +0 -0
  387. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_cliCmdConfigDump.py +0 -0
  388. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_cliCmdConfigValidate.py +0 -0
  389. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_cliCmdCreate.py +0 -0
  390. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_cliCmdImport.py +0 -0
  391. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_cliCmdIngestFiles.py +0 -0
  392. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_cliCmdPruneDatasets.py +0 -0
  393. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_cliCmdQueryCollections.py +0 -0
  394. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_cliCmdQueryDataIds.py +0 -0
  395. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_cliCmdQueryDatasetTypes.py +0 -0
  396. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_cliCmdQueryDatasets.py +0 -0
  397. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_cliCmdQueryDimensionRecords.py +0 -0
  398. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_cliCmdRemoveCollections.py +0 -0
  399. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_cliCmdRemoveRuns.py +0 -0
  400. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_cliCmdRetrieveArtifacts.py +0 -0
  401. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_cliLog.py +0 -0
  402. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_cliPluginLoader.py +0 -0
  403. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_cliUtilSplitCommas.py +0 -0
  404. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_cliUtilSplitKv.py +0 -0
  405. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_cliUtilToUpper.py +0 -0
  406. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_cliUtils.py +0 -0
  407. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_column_spec.py +0 -0
  408. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_composites.py +0 -0
  409. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_config.py +0 -0
  410. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_connectionString.py +0 -0
  411. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_constraints.py +0 -0
  412. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_datasets.py +0 -0
  413. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_datastore.py +0 -0
  414. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_ddl.py +0 -0
  415. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_dimension_record_containers.py +0 -0
  416. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_dimensions.py +0 -0
  417. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_exprParserLex.py +0 -0
  418. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_exprParserYacc.py +0 -0
  419. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_expressions.py +0 -0
  420. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_formatter.py +0 -0
  421. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_gafaelfawr.py +0 -0
  422. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_location.py +0 -0
  423. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_logFormatter.py +0 -0
  424. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_matplotlibFormatter.py +0 -0
  425. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_nonempty_mapping.py +0 -0
  426. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_normalFormExpression.py +0 -0
  427. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_obscore.py +0 -0
  428. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_packages.py +0 -0
  429. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_parquet.py +0 -0
  430. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_postgresql.py +0 -0
  431. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_progress.py +0 -0
  432. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_pydantic_utils.py +0 -0
  433. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_quantum.py +0 -0
  434. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_quantumBackedButler.py +0 -0
  435. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_query_direct_postgresql.py +0 -0
  436. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_query_direct_sqlite.py +0 -0
  437. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_query_interface.py +0 -0
  438. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_query_relations.py +0 -0
  439. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_query_remote.py +0 -0
  440. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_query_utilities.py +0 -0
  441. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_remote_butler.py +0 -0
  442. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_server.py +0 -0
  443. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_simpleButler.py +0 -0
  444. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_sqlite.py +0 -0
  445. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_storageClass.py +0 -0
  446. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_templates.py +0 -0
  447. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_testRepo.py +0 -0
  448. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_thread_utils.py +0 -0
  449. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_time_utils.py +0 -0
  450. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_timespan.py +0 -0
  451. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/tests/test_utils.py +0 -0
  452. {lsst_daf_butler-29.2025.3500 → lsst_daf_butler-29.2025.3600}/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.3500
3
+ Version: 29.2025.3600
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
@@ -1333,6 +1333,7 @@ class Butler(LimitedButler): # numpydoc ignore=PR02
1333
1333
  *datasets: FileDataset,
1334
1334
  transfer: str | None = "auto",
1335
1335
  record_validation_info: bool = True,
1336
+ skip_existing: bool = False,
1336
1337
  ) -> None:
1337
1338
  """Store and register one or more datasets that already exist on disk.
1338
1339
 
@@ -1360,6 +1361,12 @@ class Butler(LimitedButler): # numpydoc ignore=PR02
1360
1361
  or file sizes. This can be useful if such information is tracked
1361
1362
  in an external system or if the file is to be compressed in place.
1362
1363
  It is up to the datastore whether this parameter is relevant.
1364
+ skip_existing : `bool`, optional
1365
+ If `True`, a dataset will not be ingested if a dataset with the
1366
+ same dataset ID already exists in the datastore.
1367
+ If `False` (the default), a `ConflictingDefinitionError` will be
1368
+ raised if any datasets with the same dataset ID already exist
1369
+ in the datastore.
1363
1370
 
1364
1371
  Raises
1365
1372
  ------
@@ -1375,6 +1382,9 @@ class Butler(LimitedButler): # numpydoc ignore=PR02
1375
1382
  FileExistsError
1376
1383
  Raised if transfer is not `None` but the (internal) location the
1377
1384
  file would be moved to is already occupied.
1385
+ ConflictingDefinitionError
1386
+ Raised if a dataset already exists in the repository and
1387
+ ``skip_existing`` is `False`.
1378
1388
 
1379
1389
  Notes
1380
1390
  -----
@@ -27,8 +27,6 @@
27
27
 
28
28
  from __future__ import annotations
29
29
 
30
- from . import ddl
31
-
32
30
  __all__ = ("QuantumBackedButler", "QuantumProvenanceData")
33
31
 
34
32
  import itertools
@@ -51,15 +49,13 @@ from ._dataset_type import DatasetType
51
49
  from ._deferredDatasetHandle import DeferredDatasetHandle
52
50
  from ._limited_butler import LimitedButler
53
51
  from ._quantum import Quantum
52
+ from ._standalone_datastore import instantiate_standalone_datastore
54
53
  from ._storage_class import StorageClass, StorageClassFactory
55
54
  from .datastore import Datastore
56
55
  from .datastore.record_data import DatastoreRecordData, SerializedDatastoreRecordData
57
56
  from .datastores.file_datastore.retrieve_artifacts import retrieve_and_zip
58
57
  from .dimensions import DimensionUniverse
59
- from .registry.bridge.monolithic import MonolithicDatastoreRegistryBridgeManager
60
- from .registry.databases.sqlite import SqliteDatabase
61
58
  from .registry.interfaces import DatastoreRegistryBridgeManager, OpaqueTableStorageManager
62
- from .registry.opaque import ByNameOpaqueTableStorageManager
63
59
 
64
60
  if TYPE_CHECKING:
65
61
  from ._butler import Butler
@@ -67,40 +63,6 @@ if TYPE_CHECKING:
67
63
  _LOG = logging.getLogger(__name__)
68
64
 
69
65
 
70
- class _DatasetRecordStorageManagerDatastoreConstructionMimic:
71
- """A partial implementation of `DatasetRecordStorageManager` that exists
72
- only to allow a `DatastoreRegistryBridgeManager` (and hence a `Datastore`)
73
- to be constructed without a full `Registry`.
74
-
75
- Notes
76
- -----
77
- The interface implemented by this class should probably be its own ABC,
78
- and that ABC should probably be used in the definition of
79
- `DatastoreRegistryBridgeManager`, but while prototyping I'm trying to keep
80
- changes minimal.
81
- """
82
-
83
- @classmethod
84
- def getIdColumnType(cls) -> type:
85
- # Docstring inherited.
86
- return ddl.GUID
87
-
88
- @classmethod
89
- def addDatasetForeignKey(
90
- cls,
91
- tableSpec: ddl.TableSpec,
92
- *,
93
- name: str = "dataset",
94
- constraint: bool = True,
95
- onDelete: str | None = None,
96
- **kwargs: Any,
97
- ) -> ddl.FieldSpec:
98
- # Docstring inherited.
99
- idFieldSpec = ddl.FieldSpec(f"{name}_id", dtype=ddl.GUID, **kwargs)
100
- tableSpec.fields.add(idFieldSpec)
101
- return idFieldSpec
102
-
103
-
104
66
  class QuantumBackedButler(LimitedButler):
105
67
  """An implementation of `LimitedButler` intended to back execution of a
106
68
  single `Quantum`.
@@ -190,9 +152,9 @@ class QuantumBackedButler(LimitedButler):
190
152
  config: Config | ResourcePathExpression,
191
153
  quantum: Quantum,
192
154
  dimensions: DimensionUniverse,
193
- filename: str = ":memory:",
194
- OpaqueManagerClass: type[OpaqueTableStorageManager] = ByNameOpaqueTableStorageManager,
195
- BridgeManagerClass: type[DatastoreRegistryBridgeManager] = MonolithicDatastoreRegistryBridgeManager,
155
+ filename: str | None = None,
156
+ OpaqueManagerClass: type[OpaqueTableStorageManager] | None = None,
157
+ BridgeManagerClass: type[DatastoreRegistryBridgeManager] | None = None,
196
158
  search_paths: list[str] | None = None,
197
159
  dataset_types: Mapping[str, DatasetType] | None = None,
198
160
  metrics: ButlerMetrics | None = None,
@@ -253,9 +215,9 @@ class QuantumBackedButler(LimitedButler):
253
215
  predicted_outputs: Iterable[DatasetId],
254
216
  dimensions: DimensionUniverse,
255
217
  datastore_records: Mapping[str, DatastoreRecordData],
256
- filename: str = ":memory:",
257
- OpaqueManagerClass: type[OpaqueTableStorageManager] = ByNameOpaqueTableStorageManager,
258
- BridgeManagerClass: type[DatastoreRegistryBridgeManager] = MonolithicDatastoreRegistryBridgeManager,
218
+ filename: str | None = None,
219
+ OpaqueManagerClass: type[OpaqueTableStorageManager] | None = None,
220
+ BridgeManagerClass: type[DatastoreRegistryBridgeManager] | None = None,
259
221
  search_paths: list[str] | None = None,
260
222
  dataset_types: Mapping[str, DatasetType] | None = None,
261
223
  metrics: ButlerMetrics | None = None,
@@ -316,10 +278,10 @@ class QuantumBackedButler(LimitedButler):
316
278
  predicted_inputs: Iterable[DatasetId],
317
279
  predicted_outputs: Iterable[DatasetId],
318
280
  dimensions: DimensionUniverse,
319
- filename: str = ":memory:",
281
+ filename: str | None = None,
320
282
  datastore_records: Mapping[str, DatastoreRecordData] | None = None,
321
- OpaqueManagerClass: type[OpaqueTableStorageManager] = ByNameOpaqueTableStorageManager,
322
- BridgeManagerClass: type[DatastoreRegistryBridgeManager] = MonolithicDatastoreRegistryBridgeManager,
283
+ OpaqueManagerClass: type[OpaqueTableStorageManager] | None = None,
284
+ BridgeManagerClass: type[DatastoreRegistryBridgeManager] | None = None,
323
285
  search_paths: list[str] | None = None,
324
286
  dataset_types: Mapping[str, DatasetType] | None = None,
325
287
  metrics: ButlerMetrics | None = None,
@@ -359,19 +321,9 @@ class QuantumBackedButler(LimitedButler):
359
321
  Metrics object for gathering butler statistics.
360
322
  """
361
323
  butler_config = ButlerConfig(config, searchPaths=search_paths)
362
- butler_root = butler_config.get("root", butler_config.configDir)
363
- db = SqliteDatabase.fromUri(f"sqlite:///{filename}", origin=0)
364
- with db.declareStaticTables(create=True) as context:
365
- opaque_manager = OpaqueManagerClass.initialize(db, context)
366
- bridge_manager = BridgeManagerClass.initialize(
367
- db,
368
- context,
369
- opaque=opaque_manager,
370
- # MyPy can tell it's a fake, but we know it shouldn't care.
371
- datasets=_DatasetRecordStorageManagerDatastoreConstructionMimic, # type: ignore
372
- universe=dimensions,
373
- )
374
- datastore = Datastore.fromConfig(butler_config, bridge_manager, butler_root)
324
+ datastore, _ = instantiate_standalone_datastore(
325
+ butler_config, dimensions, filename, OpaqueManagerClass, BridgeManagerClass
326
+ )
375
327
 
376
328
  # TODO: We need to inform `Datastore` here that it needs to support
377
329
  # predictive reads; This only really works for file datastore but
@@ -0,0 +1,31 @@
1
+ # This file is part of daf_butler.
2
+ #
3
+ # Developed for the LSST Data Management System.
4
+ # This product includes software developed by the LSST Project
5
+ # (http://www.lsst.org).
6
+ # See the COPYRIGHT file at the top-level directory of this distribution
7
+ # for details of code ownership.
8
+ #
9
+ # This software is dual licensed under the GNU General Public License and also
10
+ # under a 3-clause BSD license. Recipients may choose which of these licenses
11
+ # to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
12
+ # respectively. If you choose the GPL option then the following text applies
13
+ # (but note that there is still no warranty even if you opt for BSD instead):
14
+ #
15
+ # This program is free software: you can redistribute it and/or modify
16
+ # it under the terms of the GNU General Public License as published by
17
+ # the Free Software Foundation, either version 3 of the License, or
18
+ # (at your option) any later version.
19
+ #
20
+ # This program is distributed in the hope that it will be useful,
21
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
22
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23
+ # GNU General Public License for more details.
24
+ #
25
+ # You should have received a copy of the GNU General Public License
26
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
27
+
28
+ """Modules in the ``_rubin`` package contain functions that are used internally
29
+ by other LSST packages. The interfaces and behavior of these functions are
30
+ subject to change at any time.
31
+ """
@@ -0,0 +1,88 @@
1
+ # This file is part of daf_butler.
2
+ #
3
+ # Developed for the LSST Data Management System.
4
+ # This product includes software developed by the LSST Project
5
+ # (http://www.lsst.org).
6
+ # See the COPYRIGHT file at the top-level directory of this distribution
7
+ # for details of code ownership.
8
+ #
9
+ # This software is dual licensed under the GNU General Public License and also
10
+ # under a 3-clause BSD license. Recipients may choose which of these licenses
11
+ # to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
12
+ # respectively. If you choose the GPL option then the following text applies
13
+ # (but note that there is still no warranty even if you opt for BSD instead):
14
+ #
15
+ # This program is free software: you can redistribute it and/or modify
16
+ # it under the terms of the GNU General Public License as published by
17
+ # the Free Software Foundation, either version 3 of the License, or
18
+ # (at your option) any later version.
19
+ #
20
+ # This program is distributed in the hope that it will be useful,
21
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
22
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23
+ # GNU General Public License for more details.
24
+ #
25
+ # You should have received a copy of the GNU General Public License
26
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
27
+
28
+ from __future__ import annotations
29
+
30
+ __all__ = ("transfer_datasets_to_datastore",)
31
+
32
+ from collections.abc import Iterable
33
+
34
+ from .._butler import Butler
35
+ from .._butler_config import ButlerConfig
36
+ from .._dataset_ref import DatasetRef
37
+ from .._file_dataset import FileDataset
38
+ from .._standalone_datastore import instantiate_standalone_datastore
39
+ from ..direct_butler import DirectButler
40
+
41
+
42
+ def transfer_datasets_to_datastore(
43
+ source_butler: Butler, output_config: ButlerConfig, refs: Iterable[DatasetRef]
44
+ ) -> list[FileDataset]:
45
+ """Copy datasets into a `Datastore` without writing entries into the
46
+ associated registry database.
47
+
48
+ Parameters
49
+ ----------
50
+ source_butler : `Butler`
51
+ Butler instance from which to copy datasets.
52
+ output_config : `ButlerConfig`
53
+ Butler configuration specifying the configuration for the target
54
+ datastore.
55
+ refs : `~collections.abc.Iterable` [ `DatasetRef` ]
56
+ List of datasets to copy into the target datastore.
57
+
58
+ Returns
59
+ -------
60
+ file_datasets : `list` [ `FileDataset` ]
61
+ `FileDataset` instances representing the artifacts copied to
62
+ the target datastore.
63
+ """
64
+ refs = list(refs)
65
+ if len(refs) == 0:
66
+ return []
67
+
68
+ if not isinstance(source_butler, DirectButler):
69
+ raise ValueError("Butler must be an instance of DirectButler")
70
+
71
+ # Refs must contain dimension records to allow for filename template
72
+ # expansion in the datastore.
73
+ refs = source_butler._registry.expand_refs(list(refs))
74
+ # Read out the absolute URLs of the datasets we are about to transfer.
75
+ datasets = list(source_butler._datastore.export(refs, directory=None, transfer="direct"))
76
+
77
+ # Set up a temporary, initially empty, in-memory DB for the target
78
+ # Datastore.
79
+ dimension_universe = datasets[0].refs[0].dimensions.universe
80
+ datastore, db = instantiate_standalone_datastore(output_config, dimension_universe)
81
+ try:
82
+ # Write the files to their destination in the target datastore.
83
+ datastore.ingest(*datasets, transfer="copy", record_validation_info=False)
84
+ # Read out the relative URLs of the files, for their location
85
+ # in the target datastore.
86
+ return list(datastore.export(refs, directory=None, transfer=None))
87
+ finally:
88
+ db.dispose()
@@ -0,0 +1,129 @@
1
+ # This file is part of daf_butler.
2
+ #
3
+ # Developed for the LSST Data Management System.
4
+ # This product includes software developed by the LSST Project
5
+ # (http://www.lsst.org).
6
+ # See the COPYRIGHT file at the top-level directory of this distribution
7
+ # for details of code ownership.
8
+ #
9
+ # This software is dual licensed under the GNU General Public License and also
10
+ # under a 3-clause BSD license. Recipients may choose which of these licenses
11
+ # to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
12
+ # respectively. If you choose the GPL option then the following text applies
13
+ # (but note that there is still no warranty even if you opt for BSD instead):
14
+ #
15
+ # This program is free software: you can redistribute it and/or modify
16
+ # it under the terms of the GNU General Public License as published by
17
+ # the Free Software Foundation, either version 3 of the License, or
18
+ # (at your option) any later version.
19
+ #
20
+ # This program is distributed in the hope that it will be useful,
21
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
22
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23
+ # GNU General Public License for more details.
24
+ #
25
+ # You should have received a copy of the GNU General Public License
26
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
27
+
28
+ from __future__ import annotations
29
+
30
+ __all__ = ("instantiate_standalone_datastore",)
31
+
32
+ from typing import Any
33
+
34
+ from . import ddl
35
+ from ._butler_config import ButlerConfig
36
+ from .datastore import Datastore
37
+ from .dimensions import DimensionUniverse
38
+ from .registry.bridge.monolithic import MonolithicDatastoreRegistryBridgeManager
39
+ from .registry.databases.sqlite import SqliteDatabase
40
+ from .registry.interfaces import Database, DatastoreRegistryBridgeManager, OpaqueTableStorageManager
41
+ from .registry.opaque import ByNameOpaqueTableStorageManager
42
+
43
+
44
+ def instantiate_standalone_datastore(
45
+ butler_config: ButlerConfig,
46
+ dimensions: DimensionUniverse,
47
+ filename: str | None = None,
48
+ OpaqueManagerClass: type[OpaqueTableStorageManager] | None = None,
49
+ BridgeManagerClass: type[DatastoreRegistryBridgeManager] | None = None,
50
+ ) -> tuple[Datastore, Database]:
51
+ """Initialize a `Datastore` instance without an associated `Registry`.
52
+
53
+ Parameters
54
+ ----------
55
+ butler_config : `ButlerConfig`
56
+ Butler configuration that defines the configuration for the `Datastore`
57
+ to be initialized.
58
+ dimensions : `DimensionUniverse`
59
+ Dimension universe used by the Butler repository backing the
60
+ `Datastore`.
61
+ filename : `str`, optional
62
+ Name for the SQLite database that will back the `Datastore`; defaults
63
+ to an in-memory database.
64
+ OpaqueManagerClass : `type`, optional
65
+ A subclass of `OpaqueTableStorageManager` to use for datastore
66
+ opaque records. Default is a SQL-backed implementation.
67
+ BridgeManagerClass : `type`, optional
68
+ A subclass of `DatastoreRegistryBridgeManager` to use for datastore
69
+ location records. Default is a SQL-backed implementation.
70
+
71
+ Returns
72
+ -------
73
+ datastore_and_database : `tuple` [ `Datastore` , `Database` ]
74
+ The temporary datastore, and the database instance backing it.
75
+
76
+ Notes
77
+ -----
78
+ This allows files to be written and read without access to the Butler
79
+ database. It is primarily used by `QuantumBackedButler`.
80
+ """
81
+ if filename is None:
82
+ filename = ":memory:"
83
+ if OpaqueManagerClass is None:
84
+ OpaqueManagerClass = ByNameOpaqueTableStorageManager
85
+ if BridgeManagerClass is None:
86
+ BridgeManagerClass = MonolithicDatastoreRegistryBridgeManager
87
+
88
+ butler_root = butler_config.get("root", butler_config.configDir)
89
+ db = SqliteDatabase.fromUri(f"sqlite:///{filename}", origin=0)
90
+ with db.declareStaticTables(create=True) as context:
91
+ opaque_manager = OpaqueManagerClass.initialize(db, context)
92
+ bridge_manager = BridgeManagerClass.initialize(
93
+ db,
94
+ context,
95
+ opaque=opaque_manager,
96
+ # MyPy can tell it's a fake, but we know it shouldn't care.
97
+ datasets=_DatasetRecordStorageManagerDatastoreConstructionMimic, # type: ignore
98
+ universe=dimensions,
99
+ )
100
+
101
+ datastore = Datastore.fromConfig(butler_config, bridge_manager, butler_root)
102
+ return (datastore, db)
103
+
104
+
105
+ class _DatasetRecordStorageManagerDatastoreConstructionMimic:
106
+ """A partial implementation of `DatasetRecordStorageManager` that exists
107
+ only to allow a `DatastoreRegistryBridgeManager` (and hence a `Datastore`)
108
+ to be constructed without a full `Registry`.
109
+ """
110
+
111
+ @classmethod
112
+ def getIdColumnType(cls) -> type:
113
+ # Docstring inherited.
114
+ return ddl.GUID
115
+
116
+ @classmethod
117
+ def addDatasetForeignKey(
118
+ cls,
119
+ tableSpec: ddl.TableSpec,
120
+ *,
121
+ name: str = "dataset",
122
+ constraint: bool = True,
123
+ onDelete: str | None = None,
124
+ **kwargs: Any,
125
+ ) -> ddl.FieldSpec:
126
+ # Docstring inherited.
127
+ idFieldSpec = ddl.FieldSpec(f"{name}_id", dtype=ddl.GUID, **kwargs)
128
+ tableSpec.fields.add(idFieldSpec)
129
+ return idFieldSpec
@@ -1385,6 +1385,7 @@ class FileDatastore(GenericBaseDatastore[StoredFileInfo]):
1385
1385
 
1386
1386
  def knows_these(self, refs: Iterable[DatasetRef]) -> dict[DatasetRef, bool]:
1387
1387
  # Docstring inherited from the base class.
1388
+ refs = list(refs)
1388
1389
 
1389
1390
  # The records themselves. Could be missing some entries.
1390
1391
  records = self._get_stored_records_associated_with_refs(refs, ignore_datastore_records=True)
@@ -3050,17 +3051,11 @@ class FileDatastore(GenericBaseDatastore[StoredFileInfo]):
3050
3051
  if transfer == "auto" and directory is None:
3051
3052
  transfer = None
3052
3053
 
3053
- if transfer is not None and directory is None:
3054
+ if transfer is not None and transfer != "direct" and directory is None:
3054
3055
  raise TypeError(f"Cannot export using transfer mode {transfer} with no export directory given")
3055
3056
 
3056
3057
  if transfer == "move":
3057
3058
  raise TypeError("Can not export by moving files out of datastore.")
3058
- elif transfer == "direct":
3059
- # For an export, treat this as equivalent to None. We do not
3060
- # want an import to risk using absolute URIs to datasets owned
3061
- # by another datastore.
3062
- log.info("Treating 'direct' transfer mode as in-place export.")
3063
- transfer = None
3064
3059
 
3065
3060
  # Force the directory to be a URI object
3066
3061
  directoryUri: ResourcePath | None = None
@@ -1797,6 +1797,7 @@ class DirectButler(Butler): # numpydoc ignore=PR02
1797
1797
  *datasets: FileDataset,
1798
1798
  transfer: str | None = "auto",
1799
1799
  record_validation_info: bool = True,
1800
+ skip_existing: bool = False,
1800
1801
  ) -> None:
1801
1802
  # Docstring inherited.
1802
1803
  if not datasets:
@@ -1806,6 +1807,21 @@ class DirectButler(Butler): # numpydoc ignore=PR02
1806
1807
  _LOG.verbose("Ingesting %d file dataset%s.", len(datasets), "" if len(datasets) == 1 else "s")
1807
1808
  progress = Progress("lsst.daf.butler.Butler.ingest", level=VERBOSE)
1808
1809
 
1810
+ new_datasets, existing_datasets = self._partition_datasets_by_known(datasets)
1811
+ if existing_datasets:
1812
+ if skip_existing:
1813
+ _LOG.info(
1814
+ "Skipping %d datasets which already exist in the repository.", len(existing_datasets)
1815
+ )
1816
+ else:
1817
+ raise ConflictingDefinitionError(
1818
+ f"Datastore already contains {len(existing_datasets)} of the given datasets."
1819
+ f" Example: {existing_datasets[0]}"
1820
+ )
1821
+
1822
+ # We use `datasets` rather `new_datasets` for the Registry
1823
+ # portion of this, to let it confirm that everything matches the
1824
+ # existing datasets.
1809
1825
  import_info = self._prepare_ingest_file_datasets(datasets, progress)
1810
1826
 
1811
1827
  with self.transaction():
@@ -1813,17 +1829,41 @@ class DirectButler(Butler): # numpydoc ignore=PR02
1813
1829
 
1814
1830
  # Bulk-insert everything into Datastore.
1815
1831
  # We do not know if any of the registry entries already existed
1816
- # (_importDatasets only complains if they exist but differ) so
1817
- # we have to catch IntegrityError explicitly.
1832
+ # (_importDatasets only complains if they exist but differ).
1833
+ # The _partition_datasets_by_known logic above should catch most
1834
+ # instances where we attempt to re-ingest files that were already
1835
+ # ingested, but a concurrent writer could cause a unique constraint
1836
+ # violation here.
1818
1837
  try:
1819
1838
  self._datastore.ingest(
1820
- *datasets, transfer=transfer, record_validation_info=record_validation_info
1839
+ *new_datasets, transfer=transfer, record_validation_info=record_validation_info
1821
1840
  )
1822
1841
  except IntegrityError as e:
1823
1842
  raise ConflictingDefinitionError(
1824
1843
  f"Datastore already contains one or more datasets: {e}"
1825
1844
  ) from e
1826
1845
 
1846
+ def _partition_datasets_by_known(
1847
+ self, datasets: Iterable[FileDataset]
1848
+ ) -> tuple[list[FileDataset], list[FileDataset]]:
1849
+ """Divides the given `FileDataset` objects into two groups: those for
1850
+ which the Datastore already has an entry, and those for which it does
1851
+ not.
1852
+ """
1853
+ new_datasets = []
1854
+ existing_datasets = []
1855
+
1856
+ refs = itertools.chain.from_iterable(dataset.refs for dataset in datasets)
1857
+ known_refs = self._datastore.knows_these(refs)
1858
+
1859
+ for dataset in datasets:
1860
+ if any(known_refs[ref] for ref in dataset.refs):
1861
+ existing_datasets.append(dataset)
1862
+ else:
1863
+ new_datasets.append(dataset)
1864
+
1865
+ return new_datasets, existing_datasets
1866
+
1827
1867
  @contextlib.contextmanager
1828
1868
  def export(
1829
1869
  self,
@@ -35,6 +35,7 @@ import traceback
35
35
  from collections.abc import Callable, Generator, Iterable, Iterator
36
36
  from contextlib import contextmanager
37
37
  from logging import Formatter, LogRecord, StreamHandler
38
+ from types import TracebackType
38
39
  from typing import IO, Any, ClassVar, overload
39
40
 
40
41
  from pydantic import BaseModel, ConfigDict, PrivateAttr, RootModel
@@ -127,6 +128,9 @@ class ButlerMDC:
127
128
  def set_mdc(cls, mdc: dict[str, str]) -> Generator[None, None, None]:
128
129
  """Set the MDC key for this context.
129
130
 
131
+ This context manager also adds a mapping named ``mdc`` to any
132
+ exceptions that escape it.
133
+
130
134
  Parameters
131
135
  ----------
132
136
  mdc : `dict` of `str`, `str`
@@ -143,6 +147,12 @@ class ButlerMDC:
143
147
 
144
148
  try:
145
149
  yield
150
+ except BaseException as e:
151
+ # In logging, inner context overrules outer context. Need the same
152
+ # for exceptions.
153
+ inner_context: MDCDict = e.mdc if hasattr(e, "mdc") else MDCDict()
154
+ e.mdc = cls._MDC.copy() | inner_context # type: ignore[attr-defined]
155
+ raise
146
156
  finally:
147
157
  for k, v in previous.items():
148
158
  if not v:
@@ -155,10 +165,31 @@ class ButlerMDC:
155
165
  """Add a log record factory that adds a MDC record to `LogRecord`."""
156
166
  old_factory = logging.getLogRecordFactory()
157
167
 
158
- def record_factory(*args: Any, **kwargs: Any) -> LogRecord:
159
- record = old_factory(*args, **kwargs)
168
+ # Need explicit args in case exc_info is called as an arg (and because
169
+ # the factory API has a parameter literally called `args`).
170
+ def record_factory(
171
+ name: str,
172
+ level: int,
173
+ fn: str,
174
+ lno: int,
175
+ msg: str,
176
+ args: tuple,
177
+ exc_info: tuple | None,
178
+ func: str | None = None,
179
+ sinfo: TracebackType | None = None,
180
+ **kwargs: Any,
181
+ ) -> LogRecord:
182
+ record = old_factory(name, level, fn, lno, msg, args, exc_info, func, sinfo, **kwargs)
160
183
  # Make sure we send a copy of the global dict in the record.
161
- record.MDC = MDCDict(cls._MDC)
184
+ mdc = MDCDict(cls._MDC)
185
+ if exc_info is not None:
186
+ _, ex, _ = exc_info
187
+ # TODO: this doesn't handle chained exceptions, fix on DM-47546
188
+ if hasattr(ex, "mdc"):
189
+ # Context at the point where the exception was raised
190
+ # takes precedence.
191
+ mdc.update(ex.mdc)
192
+ record.MDC = mdc
162
193
  return record
163
194
 
164
195
  cls._old_factory = old_factory
@@ -287,6 +287,12 @@ class Database(ABC):
287
287
  self._metadata = metadata
288
288
  self._allow_temporary_tables = allow_temporary_tables
289
289
 
290
+ def dispose(self) -> None:
291
+ """Close all open database connections held by this `Database`
292
+ instance.
293
+ """
294
+ self._engine.dispose()
295
+
290
296
  def __repr__(self) -> str:
291
297
  # Rather than try to reproduce all the parameters used to create
292
298
  # the object, instead report the more useful information of the
@@ -576,6 +576,7 @@ class RemoteButler(Butler): # numpydoc ignore=PR02
576
576
  *datasets: FileDataset,
577
577
  transfer: str | None = "auto",
578
578
  record_validation_info: bool = True,
579
+ skip_existing: bool = False,
579
580
  ) -> None:
580
581
  # Docstring inherited.
581
582
  raise NotImplementedError()
@@ -292,9 +292,13 @@ class HybridButler(Butler):
292
292
  *datasets: FileDataset,
293
293
  transfer: str | None = "auto",
294
294
  record_validation_info: bool = True,
295
+ skip_existing: bool = False,
295
296
  ) -> None:
296
297
  return self._direct_butler.ingest(
297
- *datasets, transfer=transfer, record_validation_info=record_validation_info
298
+ *datasets,
299
+ transfer=transfer,
300
+ record_validation_info=record_validation_info,
301
+ skip_existing=skip_existing,
298
302
  )
299
303
 
300
304
  def export(
@@ -381,8 +381,8 @@ class MetricTestRepo:
381
381
  ),
382
382
  )
383
383
 
384
- self.addDataset({"instrument": "DummyCamComp", "visit": 423})
385
- self.addDataset({"instrument": "DummyCamComp", "visit": 424})
384
+ self.ref1 = self.addDataset({"instrument": "DummyCamComp", "visit": 423})
385
+ self.ref2 = self.addDataset({"instrument": "DummyCamComp", "visit": 424})
386
386
 
387
387
  def addDataset(
388
388
  self, dataId: dict[str, Any], run: str | None = None, datasetType: DatasetType | None = None
@@ -0,0 +1,2 @@
1
+ __all__ = ["__version__"]
2
+ __version__ = "29.2025.3600"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lsst-daf-butler
3
- Version: 29.2025.3500
3
+ Version: 29.2025.3600
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
@@ -51,6 +51,7 @@ python/lsst/daf/butler/_quantum.py
51
51
  python/lsst/daf/butler/_quantum_backed.py
52
52
  python/lsst/daf/butler/_query_all_datasets.py
53
53
  python/lsst/daf/butler/_registry_shim.py
54
+ python/lsst/daf/butler/_standalone_datastore.py
54
55
  python/lsst/daf/butler/_storage_class.py
55
56
  python/lsst/daf/butler/_storage_class_delegate.py
56
57
  python/lsst/daf/butler/_timespan.py
@@ -72,6 +73,8 @@ python/lsst/daf/butler/time_utils.py
72
73
  python/lsst/daf/butler/timespan_database_representation.py
73
74
  python/lsst/daf/butler/utils.py
74
75
  python/lsst/daf/butler/version.py
76
+ python/lsst/daf/butler/_rubin/__init__.py
77
+ python/lsst/daf/butler/_rubin/file_datasets.py
75
78
  python/lsst/daf/butler/_utilities/__init__.py
76
79
  python/lsst/daf/butler/_utilities/locked_object.py
77
80
  python/lsst/daf/butler/_utilities/named_locks.py