lsst-daf-butler 30.0.0rc2__tar.gz → 30.0.0rc3__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 (439) hide show
  1. {lsst_daf_butler-30.0.0rc2/python/lsst_daf_butler.egg-info → lsst_daf_butler-30.0.0rc3}/PKG-INFO +1 -1
  2. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/doc/lsst.daf.butler/CHANGES.rst +115 -0
  3. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/_butler.py +8 -5
  4. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/_butler_metrics.py +49 -2
  5. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/_formatter.py +2 -7
  6. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/_labeled_butler_factory.py +28 -8
  7. lsst_daf_butler-30.0.0rc3/python/lsst/daf/butler/_rubin/temporary_for_ingest.py +207 -0
  8. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/configs/datastores/formatters.yaml +1 -0
  9. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/configs/storageClasses.yaml +15 -0
  10. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/datastore/record_data.py +1 -1
  11. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/datastores/fileDatastore.py +15 -12
  12. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/dimensions/_coordinate.py +5 -0
  13. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/direct_butler/_direct_butler.py +45 -28
  14. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/logging.py +9 -3
  15. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/bridge/monolithic.py +17 -13
  16. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/datasets/byDimensions/_manager.py +49 -45
  17. lsst_daf_butler-30.0.0rc3/python/lsst/daf/butler/registry/expand_data_ids.py +93 -0
  18. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/interfaces/_database.py +6 -1
  19. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/sql_registry.py +2 -24
  20. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/remote_butler/_remote_butler.py +5 -1
  21. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/tests/hybrid_butler.py +4 -1
  22. lsst_daf_butler-30.0.0rc3/python/lsst/daf/butler/tests/registry_data/lsstcam-subset.yaml +191 -0
  23. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/tests/testFormatters.py +2 -2
  24. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/transfers/_context.py +7 -6
  25. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/version.py +1 -1
  26. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3/python/lsst_daf_butler.egg-info}/PKG-INFO +1 -1
  27. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst_daf_butler.egg-info/SOURCES.txt +3 -0
  28. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_butler.py +114 -1
  29. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_butler_factory.py +11 -7
  30. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_datastore.py +40 -0
  31. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/COPYRIGHT +0 -0
  32. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/LICENSE +0 -0
  33. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/MANIFEST.in +0 -0
  34. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/README.md +0 -0
  35. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/bsd_license.txt +0 -0
  36. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/doc/lsst.daf.butler/concreteStorageClasses.rst +0 -0
  37. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/doc/lsst.daf.butler/configuring.rst +0 -0
  38. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/doc/lsst.daf.butler/datastores.rst +0 -0
  39. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/doc/lsst.daf.butler/dimensions.rst +0 -0
  40. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/doc/lsst.daf.butler/formatters.rst +0 -0
  41. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/doc/lsst.daf.butler/index.rst +0 -0
  42. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/doc/lsst.daf.butler/organizing.rst +0 -0
  43. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/doc/lsst.daf.butler/queries.rst +0 -0
  44. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/doc/lsst.daf.butler/use-in-tests.rst +0 -0
  45. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/doc/lsst.daf.butler/writing-subcommands.rst +0 -0
  46. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/gpl-v3.0.txt +0 -0
  47. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/pyproject.toml +0 -0
  48. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/__init__.py +0 -0
  49. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/__init__.py +0 -0
  50. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/__init__.py +0 -0
  51. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/_butler_collections.py +0 -0
  52. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/_butler_config.py +0 -0
  53. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/_butler_instance_options.py +0 -0
  54. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/_butler_repo_index.py +0 -0
  55. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/_collection_type.py +0 -0
  56. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/_config.py +0 -0
  57. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/_config_support.py +0 -0
  58. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/_dataset_association.py +0 -0
  59. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/_dataset_existence.py +0 -0
  60. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/_dataset_provenance.py +0 -0
  61. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/_dataset_ref.py +0 -0
  62. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/_dataset_type.py +0 -0
  63. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/_deferredDatasetHandle.py +0 -0
  64. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/_exceptions.py +0 -0
  65. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/_exceptions_legacy.py +0 -0
  66. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/_file_dataset.py +0 -0
  67. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/_file_descriptor.py +0 -0
  68. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/_limited_butler.py +0 -0
  69. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/_location.py +0 -0
  70. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/_named.py +0 -0
  71. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/_quantum.py +0 -0
  72. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/_quantum_backed.py +0 -0
  73. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/_query_all_datasets.py +0 -0
  74. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/_registry_shim.py +0 -0
  75. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/_rubin/__init__.py +0 -0
  76. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/_rubin/file_datasets.py +0 -0
  77. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/_standalone_datastore.py +0 -0
  78. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/_storage_class.py +0 -0
  79. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/_storage_class_delegate.py +0 -0
  80. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/_timespan.py +0 -0
  81. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/_topology.py +0 -0
  82. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/_utilities/__init__.py +0 -0
  83. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/_utilities/locked_object.py +0 -0
  84. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/_utilities/named_locks.py +0 -0
  85. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/_utilities/thread_safe_cache.py +0 -0
  86. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/_uuid.py +0 -0
  87. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/arrow_utils.py +0 -0
  88. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/cli/__init__.py +0 -0
  89. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/cli/butler.py +0 -0
  90. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/cli/cliLog.py +0 -0
  91. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/cli/cmd/__init__.py +0 -0
  92. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/cli/cmd/_remove_collections.py +0 -0
  93. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/cli/cmd/_remove_runs.py +0 -0
  94. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/cli/cmd/commands.py +0 -0
  95. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/cli/opt/__init__.py +0 -0
  96. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/cli/opt/arguments.py +0 -0
  97. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/cli/opt/optionGroups.py +0 -0
  98. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/cli/opt/options.py +0 -0
  99. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/cli/progress.py +0 -0
  100. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/cli/utils.py +0 -0
  101. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/column_spec.py +0 -0
  102. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/configs/datastore.yaml +0 -0
  103. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/configs/datastores/composites.yaml +0 -0
  104. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/configs/datastores/fileDatastore.yaml +0 -0
  105. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/configs/datastores/writeRecipes.yaml +0 -0
  106. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/configs/dimensions.yaml +0 -0
  107. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/configs/old_dimensions/daf_butler_universe0.yaml +0 -0
  108. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/configs/old_dimensions/daf_butler_universe1.yaml +0 -0
  109. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/configs/old_dimensions/daf_butler_universe2.yaml +0 -0
  110. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/configs/old_dimensions/daf_butler_universe3.yaml +0 -0
  111. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/configs/old_dimensions/daf_butler_universe4.yaml +0 -0
  112. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/configs/old_dimensions/daf_butler_universe5.yaml +0 -0
  113. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/configs/old_dimensions/daf_butler_universe6.yaml +0 -0
  114. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/configs/old_dimensions/daf_butler_universe7.yaml +0 -0
  115. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/configs/registry.yaml +0 -0
  116. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/configs/repo_transfer_formats.yaml +0 -0
  117. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/datastore/__init__.py +0 -0
  118. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/datastore/_datastore.py +0 -0
  119. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/datastore/_transfer.py +0 -0
  120. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/datastore/cache_manager.py +0 -0
  121. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/datastore/composites.py +0 -0
  122. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/datastore/constraints.py +0 -0
  123. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/datastore/file_templates.py +0 -0
  124. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/datastore/generic_base.py +0 -0
  125. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/datastore/stored_file_info.py +0 -0
  126. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/datastores/__init__.py +0 -0
  127. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/datastores/chainedDatastore.py +0 -0
  128. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/datastores/file_datastore/__init__.py +0 -0
  129. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/datastores/file_datastore/get.py +0 -0
  130. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/datastores/file_datastore/retrieve_artifacts.py +0 -0
  131. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/datastores/file_datastore/transfer.py +0 -0
  132. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/datastores/inMemoryDatastore.py +0 -0
  133. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/ddl.py +0 -0
  134. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/delegates/__init__.py +0 -0
  135. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/delegates/arrowtable.py +0 -0
  136. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/dimensions/__init__.py +0 -0
  137. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/dimensions/_config.py +0 -0
  138. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/dimensions/_data_coordinate_iterable.py +0 -0
  139. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/dimensions/_database.py +0 -0
  140. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/dimensions/_elements.py +0 -0
  141. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/dimensions/_governor.py +0 -0
  142. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/dimensions/_group.py +0 -0
  143. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/dimensions/_packer.py +0 -0
  144. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/dimensions/_record_set.py +0 -0
  145. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/dimensions/_record_table.py +0 -0
  146. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/dimensions/_records.py +0 -0
  147. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/dimensions/_schema.py +0 -0
  148. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/dimensions/_skypix.py +0 -0
  149. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/dimensions/_universe.py +0 -0
  150. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/dimensions/construction.py +0 -0
  151. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/dimensions/record_cache.py +0 -0
  152. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/direct_butler/__init__.py +0 -0
  153. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/direct_butler/_direct_butler_collections.py +0 -0
  154. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/direct_query_driver/__init__.py +0 -0
  155. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/direct_query_driver/_driver.py +0 -0
  156. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/direct_query_driver/_postprocessing.py +0 -0
  157. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/direct_query_driver/_query_analysis.py +0 -0
  158. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/direct_query_driver/_query_builder.py +0 -0
  159. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/direct_query_driver/_result_page_converter.py +0 -0
  160. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/direct_query_driver/_sql_builders.py +0 -0
  161. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/direct_query_driver/_sql_column_visitor.py +0 -0
  162. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/formatters/__init__.py +0 -0
  163. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/formatters/astropyTable.py +0 -0
  164. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/formatters/file.py +0 -0
  165. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/formatters/json.py +0 -0
  166. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/formatters/logs.py +0 -0
  167. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/formatters/matplotlib.py +0 -0
  168. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/formatters/packages.py +0 -0
  169. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/formatters/parquet.py +0 -0
  170. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/formatters/pickle.py +0 -0
  171. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/formatters/typeless.py +0 -0
  172. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/formatters/yaml.py +0 -0
  173. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/json.py +0 -0
  174. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/mapping_factory.py +0 -0
  175. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/name_shrinker.py +0 -0
  176. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/nonempty_mapping.py +0 -0
  177. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/persistence_context.py +0 -0
  178. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/progress.py +0 -0
  179. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/py.typed +0 -0
  180. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/pydantic_utils.py +0 -0
  181. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/queries/__init__.py +0 -0
  182. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/queries/_base.py +0 -0
  183. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/queries/_data_coordinate_query_results.py +0 -0
  184. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/queries/_dataset_query_results.py +0 -0
  185. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/queries/_dimension_record_query_results.py +0 -0
  186. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/queries/_expression_strings.py +0 -0
  187. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/queries/_general_query_results.py +0 -0
  188. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/queries/_identifiers.py +0 -0
  189. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/queries/_query.py +0 -0
  190. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/queries/convert_args.py +0 -0
  191. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/queries/driver.py +0 -0
  192. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/queries/expression_factory.py +0 -0
  193. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/queries/expressions/__init__.py +0 -0
  194. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/queries/expressions/categorize.py +0 -0
  195. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/queries/expressions/parser/__init__.py +0 -0
  196. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/queries/expressions/parser/exprTree.py +0 -0
  197. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/queries/expressions/parser/parser.py +0 -0
  198. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/queries/expressions/parser/parserLex.py +0 -0
  199. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/queries/expressions/parser/parserYacc.py +0 -0
  200. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/queries/expressions/parser/ply/__init__.py +0 -0
  201. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/queries/expressions/parser/ply/lex.py +0 -0
  202. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/queries/expressions/parser/ply/yacc.py +0 -0
  203. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/queries/expressions/parser/treeVisitor.py +0 -0
  204. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/queries/overlaps.py +0 -0
  205. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/queries/predicate_constraints_summary.py +0 -0
  206. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/queries/result_specs.py +0 -0
  207. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/queries/tree/__init__.py +0 -0
  208. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/queries/tree/_base.py +0 -0
  209. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/queries/tree/_column_expression.py +0 -0
  210. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/queries/tree/_column_literal.py +0 -0
  211. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/queries/tree/_column_reference.py +0 -0
  212. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/queries/tree/_column_set.py +0 -0
  213. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/queries/tree/_predicate.py +0 -0
  214. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/queries/tree/_query_tree.py +0 -0
  215. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/queries/visitors.py +0 -0
  216. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/__init__.py +0 -0
  217. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/_caching_context.py +0 -0
  218. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/_collection_record_cache.py +0 -0
  219. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/_collection_summary.py +0 -0
  220. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/_collection_summary_cache.py +0 -0
  221. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/_config.py +0 -0
  222. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/_defaults.py +0 -0
  223. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/_exceptions.py +0 -0
  224. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/_registry.py +0 -0
  225. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/_registry_base.py +0 -0
  226. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/_registry_factory.py +0 -0
  227. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/attributes.py +0 -0
  228. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/bridge/__init__.py +0 -0
  229. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/bridge/ephemeral.py +0 -0
  230. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/collections/__init__.py +0 -0
  231. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/collections/_base.py +0 -0
  232. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/collections/nameKey.py +0 -0
  233. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/collections/synthIntKey.py +0 -0
  234. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/connectionString.py +0 -0
  235. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/databases/__init__.py +0 -0
  236. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/databases/postgresql.py +0 -0
  237. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/databases/sqlite.py +0 -0
  238. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/datasets/__init__.py +0 -0
  239. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/datasets/byDimensions/__init__.py +0 -0
  240. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/datasets/byDimensions/_dataset_type_cache.py +0 -0
  241. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/datasets/byDimensions/summaries.py +0 -0
  242. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/datasets/byDimensions/tables.py +0 -0
  243. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/dimensions/__init__.py +0 -0
  244. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/dimensions/static.py +0 -0
  245. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/interfaces/__init__.py +0 -0
  246. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/interfaces/_attributes.py +0 -0
  247. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/interfaces/_bridge.py +0 -0
  248. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/interfaces/_collections.py +0 -0
  249. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/interfaces/_database_explain.py +0 -0
  250. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/interfaces/_datasets.py +0 -0
  251. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/interfaces/_dimensions.py +0 -0
  252. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/interfaces/_obscore.py +0 -0
  253. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/interfaces/_opaque.py +0 -0
  254. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/interfaces/_versioning.py +0 -0
  255. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/managers.py +0 -0
  256. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/nameShrinker.py +0 -0
  257. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/obscore/__init__.py +0 -0
  258. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/obscore/_config.py +0 -0
  259. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/obscore/_manager.py +0 -0
  260. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/obscore/_records.py +0 -0
  261. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/obscore/_schema.py +0 -0
  262. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/obscore/_spatial.py +0 -0
  263. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/obscore/default_spatial.py +0 -0
  264. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/obscore/pgsphere.py +0 -0
  265. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/opaque.py +0 -0
  266. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/queries/__init__.py +0 -0
  267. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/queries/_query_common.py +0 -0
  268. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/queries/_query_data_coordinates.py +0 -0
  269. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/queries/_query_datasets.py +0 -0
  270. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/queries/_query_dimension_records.py +0 -0
  271. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/queries/_results.py +0 -0
  272. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/tests/__init__.py +0 -0
  273. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/tests/_database.py +0 -0
  274. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/tests/_registry.py +0 -0
  275. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/versions.py +0 -0
  276. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/registry/wildcards.py +0 -0
  277. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/remote_butler/__init__.py +0 -0
  278. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/remote_butler/_collection_args.py +0 -0
  279. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/remote_butler/_config.py +0 -0
  280. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/remote_butler/_defaults.py +0 -0
  281. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/remote_butler/_errors.py +0 -0
  282. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/remote_butler/_factory.py +0 -0
  283. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/remote_butler/_get.py +0 -0
  284. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/remote_butler/_http_connection.py +0 -0
  285. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/remote_butler/_query_driver.py +0 -0
  286. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/remote_butler/_query_results.py +0 -0
  287. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/remote_butler/_ref_utils.py +0 -0
  288. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/remote_butler/_registry.py +0 -0
  289. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/remote_butler/_remote_butler_collections.py +0 -0
  290. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/remote_butler/_remote_file_transfer_source.py +0 -0
  291. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/remote_butler/authentication/__init__.py +0 -0
  292. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/remote_butler/authentication/cadc.py +0 -0
  293. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/remote_butler/authentication/interface.py +0 -0
  294. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/remote_butler/authentication/rubin.py +0 -0
  295. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/remote_butler/registry/__init__.py +0 -0
  296. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/remote_butler/server/__init__.py +0 -0
  297. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/remote_butler/server/_config.py +0 -0
  298. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/remote_butler/server/_dependencies.py +0 -0
  299. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/remote_butler/server/_factory.py +0 -0
  300. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/remote_butler/server/_gafaelfawr.py +0 -0
  301. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/remote_butler/server/_server.py +0 -0
  302. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/remote_butler/server/_telemetry.py +0 -0
  303. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/remote_butler/server/handlers/_external.py +0 -0
  304. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/remote_butler/server/handlers/_external_query.py +0 -0
  305. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/remote_butler/server/handlers/_file_info.py +0 -0
  306. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/remote_butler/server/handlers/_internal.py +0 -0
  307. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/remote_butler/server/handlers/_query_limits.py +0 -0
  308. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/remote_butler/server/handlers/_query_serialization.py +0 -0
  309. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/remote_butler/server/handlers/_query_streaming.py +0 -0
  310. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/remote_butler/server/handlers/_utils.py +0 -0
  311. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/remote_butler/server_models.py +0 -0
  312. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/repo_relocation.py +0 -0
  313. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/script/__init__.py +0 -0
  314. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/script/_associate.py +0 -0
  315. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/script/_pruneDatasets.py +0 -0
  316. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/script/butlerImport.py +0 -0
  317. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/script/certifyCalibrations.py +0 -0
  318. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/script/collectionChain.py +0 -0
  319. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/script/configDump.py +0 -0
  320. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/script/configValidate.py +0 -0
  321. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/script/createRepo.py +0 -0
  322. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/script/exportCalibs.py +0 -0
  323. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/script/ingest_files.py +0 -0
  324. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/script/ingest_zip.py +0 -0
  325. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/script/queryCollections.py +0 -0
  326. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/script/queryDataIds.py +0 -0
  327. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/script/queryDatasetTypes.py +0 -0
  328. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/script/queryDatasets.py +0 -0
  329. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/script/queryDimensionRecords.py +0 -0
  330. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/script/register_dataset_type.py +0 -0
  331. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/script/removeCollections.py +0 -0
  332. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/script/removeDatasetType.py +0 -0
  333. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/script/removeRuns.py +0 -0
  334. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/script/retrieveArtifacts.py +0 -0
  335. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/script/transferDatasets.py +0 -0
  336. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/tests/__init__.py +0 -0
  337. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/tests/_datasetsHelper.py +0 -0
  338. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/tests/_dummyRegistry.py +0 -0
  339. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/tests/_examplePythonTypes.py +0 -0
  340. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/tests/_testRepo.py +0 -0
  341. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/tests/butler_queries.py +0 -0
  342. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/tests/cliCmdTestBase.py +0 -0
  343. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/tests/cliLogTestBase.py +0 -0
  344. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/tests/deferredFormatter.py +0 -0
  345. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/tests/dict_convertible_model.py +0 -0
  346. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/tests/hybrid_butler_collections.py +0 -0
  347. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/tests/hybrid_butler_registry.py +0 -0
  348. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/tests/postgresql.py +0 -0
  349. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/tests/registry_data/__init__.py +0 -0
  350. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/tests/registry_data/base.yaml +0 -0
  351. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/tests/registry_data/ci_hsc-subset-skymap.yaml +0 -0
  352. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/tests/registry_data/ci_hsc-subset.yaml +0 -0
  353. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/tests/registry_data/datasets.yaml +0 -0
  354. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/tests/registry_data/hsc-rc2-subset-v0.yaml +0 -0
  355. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/tests/registry_data/spatial.py +0 -0
  356. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/tests/registry_data/spatial.yaml +0 -0
  357. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/tests/server.py +0 -0
  358. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/tests/server_available.py +0 -0
  359. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/tests/server_utils.py +0 -0
  360. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/tests/utils.py +0 -0
  361. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/time_utils.py +0 -0
  362. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/timespan_database_representation.py +0 -0
  363. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/transfers/__init__.py +0 -0
  364. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/transfers/_interfaces.py +0 -0
  365. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/transfers/_yaml.py +0 -0
  366. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst/daf/butler/utils.py +0 -0
  367. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst_daf_butler.egg-info/dependency_links.txt +0 -0
  368. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst_daf_butler.egg-info/entry_points.txt +0 -0
  369. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst_daf_butler.egg-info/requires.txt +0 -0
  370. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst_daf_butler.egg-info/top_level.txt +0 -0
  371. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/python/lsst_daf_butler.egg-info/zip-safe +0 -0
  372. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/setup.cfg +0 -0
  373. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_astropyTableFormatter.py +0 -0
  374. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_authentication.py +0 -0
  375. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_cliCmdAssociate.py +0 -0
  376. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_cliCmdConfigDump.py +0 -0
  377. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_cliCmdConfigValidate.py +0 -0
  378. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_cliCmdCreate.py +0 -0
  379. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_cliCmdImport.py +0 -0
  380. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_cliCmdIngestFiles.py +0 -0
  381. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_cliCmdPruneDatasets.py +0 -0
  382. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_cliCmdQueryCollections.py +0 -0
  383. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_cliCmdQueryDataIds.py +0 -0
  384. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_cliCmdQueryDatasetTypes.py +0 -0
  385. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_cliCmdQueryDatasets.py +0 -0
  386. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_cliCmdQueryDimensionRecords.py +0 -0
  387. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_cliCmdRemoveCollections.py +0 -0
  388. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_cliCmdRemoveRuns.py +0 -0
  389. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_cliCmdRetrieveArtifacts.py +0 -0
  390. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_cliLog.py +0 -0
  391. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_cliPluginLoader.py +0 -0
  392. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_cliUtilSplitCommas.py +0 -0
  393. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_cliUtilSplitKv.py +0 -0
  394. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_cliUtilToUpper.py +0 -0
  395. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_cliUtils.py +0 -0
  396. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_column_spec.py +0 -0
  397. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_composites.py +0 -0
  398. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_config.py +0 -0
  399. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_connectionString.py +0 -0
  400. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_constraints.py +0 -0
  401. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_datasets.py +0 -0
  402. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_ddl.py +0 -0
  403. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_dimension_record_containers.py +0 -0
  404. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_dimensions.py +0 -0
  405. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_exprParserLex.py +0 -0
  406. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_exprParserYacc.py +0 -0
  407. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_formatter.py +0 -0
  408. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_gafaelfawr.py +0 -0
  409. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_location.py +0 -0
  410. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_logFormatter.py +0 -0
  411. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_logging.py +0 -0
  412. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_matplotlibFormatter.py +0 -0
  413. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_nonempty_mapping.py +0 -0
  414. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_obscore.py +0 -0
  415. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_packages.py +0 -0
  416. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_parquet.py +0 -0
  417. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_postgresql.py +0 -0
  418. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_progress.py +0 -0
  419. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_pydantic_utils.py +0 -0
  420. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_quantum.py +0 -0
  421. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_quantumBackedButler.py +0 -0
  422. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_query_direct_postgresql.py +0 -0
  423. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_query_direct_sqlite.py +0 -0
  424. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_query_interface.py +0 -0
  425. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_query_remote.py +0 -0
  426. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_query_utilities.py +0 -0
  427. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_remote_butler.py +0 -0
  428. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_server.py +0 -0
  429. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_simpleButler.py +0 -0
  430. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_sqlite.py +0 -0
  431. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_storageClass.py +0 -0
  432. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_templates.py +0 -0
  433. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_testRepo.py +0 -0
  434. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_thread_utils.py +0 -0
  435. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_time_utils.py +0 -0
  436. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_timespan.py +0 -0
  437. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_utils.py +0 -0
  438. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_uuid.py +0 -0
  439. {lsst_daf_butler-30.0.0rc2 → lsst_daf_butler-30.0.0rc3}/tests/test_versioning.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lsst-daf-butler
3
- Version: 30.0.0rc2
3
+ Version: 30.0.0rc3
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-Expression: BSD-3-Clause OR GPL-3.0-or-later
@@ -1,3 +1,118 @@
1
+ Butler v30.0.0 (2026-01-15)
2
+ ===========================
3
+
4
+ New Features
5
+ ------------
6
+
7
+ - Modified ``ButlerMDC`` to preserve metadata for exceptions that are raised in a context but handled outside it.
8
+ This lets exceptions be logged by high-level handlers the same way they would have been if the problem were logged immediately. (`DM-42272 <https://rubinobs.atlassian.net/browse/DM-42272>`_)
9
+ - Added a new method ``Butler.query_all_datasets()``, which can be used to query for datasets of multiple types more efficiently than looping over ``query_datasets()``. (`DM-47563 <https://rubinobs.atlassian.net/browse/DM-47563>`_)
10
+ - Added a new registry configuration option ``temporary_tables: False`` to disable the use of temporary tables by the database backend. (`DM-51125 <https://rubinobs.atlassian.net/browse/DM-51125>`_)
11
+ - Added support to the query language to allow sky regions to be specified directly in an ADQL-like way. This includes ``CIRCLE``, ``BOX``, ``POLYGON``, and ``REGION``. (`DM-51454 <https://rubinobs.atlassian.net/browse/DM-51454>`_)
12
+ - ``Butler.transfer_dimension_records_from`` now accepts ``DataCoordinate`` instances in addition to ``DatasetRef`` instances to specify the dimension records to be transferred. (`DM-51681 <https://rubinobs.atlassian.net/browse/DM-51681>`_)
13
+ - ``Butler.ingest()`` now has an optional ``skip_existing`` parameter that makes it ignore datasets that already exist in the repository instead of raising an error. This makes it easier for applications to retry ingests. (`DM-52179 <https://rubinobs.atlassian.net/browse/DM-52179>`_)
14
+ - Added glob-style matching to column names in parquet tables, when specified via the ``columns`` parameter. (`DM-52515 <https://rubinobs.atlassian.net/browse/DM-52515>`_)
15
+ - Added a new ``--remove-from-parents`` flag for the ``remove-collections`` CLI to allow removal of collections that are still referenced from chained collections. (`DM-52782 <https://rubinobs.atlassian.net/browse/DM-52782>`_)
16
+ - We now build the Butler server Docker container for both arm64 and amd64. (`DM-52819 <https://rubinobs.atlassian.net/browse/DM-52819>`_)
17
+ - Made ``ButlerLogRecords`` extensible.
18
+
19
+ This changes the ``ButlerLogRecords`` file format (the old format can still be
20
+ read) to allow arbitrary JSON data to be serialized with the log records.
21
+
22
+ The ``ButlerLogRecords`` class has been modified to inherit from
23
+ ``collections.abc.MutableSequence`` instead of `pydantic.RootModel`, which means
24
+ Pydantic methods can no longer be called on it directly (in particular, use
25
+ ``to_json_data`` to serialize instead of ``model_dump_json``). (`DM-53019 <https://rubinobs.atlassian.net/browse/DM-53019>`_)
26
+ - The ``id`` parameter to ``Butler.get_dataset`` now accepts hexadecimal strings, in addition to UUID instances.
27
+ A new method ``Butler.get_many_datasets()`` allows the efficient lookup of multiple ``DatasetRef`` by dataset UUID. (`DM-53176 <https://rubinobs.atlassian.net/browse/DM-53176>`_)
28
+ - Added ``Butler.close()``, a context manager implementation for ``Butler``, and ``QuantumBackedButler.close()``. These can be used to ensure that database connections are closed deterministically, rather than waiting for mark-and-sweep garbage collection. (`DM-53233 <https://rubinobs.atlassian.net/browse/DM-53233>`_)
29
+ - ``LabeledButlerFactory`` now has a ``writeable`` constructor option to allow writeable Butlers to be instantiated.
30
+ ``LabeledButlerFactory`` can now be used as a context manager to control the lifetime of its database connections. (`DM-53739 <https://rubinobs.atlassian.net/browse/DM-53739>`_)
31
+
32
+ Bug Fixes
33
+ ---------
34
+
35
+ - Fixed a few server-side exceptions that should have been sent to ``RemoteButler`` clients as meaningful exceptions, but instead were triggering an HTTP 500 Internal Server Error. (`DM-51314 <https://rubinobs.atlassian.net/browse/DM-51314>`_)
36
+ - Deferred loading storage class definitions when deserializing datastore records.
37
+
38
+ This prevents storage class lookup errors when loading quantum graphs, when the storage class definitions are defined somewhere other than the defaults in ``daf_butler`` (such as a repository root). (`DM-51381 <https://rubinobs.atlassian.net/browse/DM-51381>`_)
39
+ - When exporting ``visit`` dimension records, ``Butler.export()`` now includes ``populated_by: visit`` records like ``visit_definition``/``visit_system_membership``, and the associated ``exposure`` records. (`DM-51681 <https://rubinobs.atlassian.net/browse/DM-51681>`_)
40
+ - Fixed a bug introduced in July 2024 in collection query methods that specify ``flatten_chains=True`` with name patterns.
41
+
42
+ The bug resulted in not returning all children names for a chain collection that matches the pattern, only child names that also match the pattern were returned. (`DM-51819 <https://rubinobs.atlassian.net/browse/DM-51819>`_)
43
+ - ``Butler.ingest()`` now checks for conflicting datastore records before ingesting files, reducing the likelihood of an issue where existing files are overwritten/deleted by an ingest that fails due to conflicting datasets. (`DM-52179 <https://rubinobs.atlassian.net/browse/DM-52179>`_)
44
+ - Query generation will no longer throw ``sqlalchemy.exc.ArgumentError`` when attempting to use a dataset calibration timespan constraint for a dataset search without any calibration collections. (`DM-52398 <https://rubinobs.atlassian.net/browse/DM-52398>`_)
45
+ - Changed the conceptual timespan associated with ``RUN`` and ``TAGGED`` collections from `None` / ``NULL`` to an unbounded timespan.
46
+
47
+ This fixes the behavior of temporal joins in quantum graph builds, where prior to this change a ``RUN`` or ``TAGGED`` collection earlier in the search path would be silently ignored in favor of a later ``CALIBRATION`` collection.
48
+ It also changes the value of timespan columns for these collection types via the ``Query.general`` interface.
49
+ The behavior of ``queryDatasetAssociations`` has *not* been changed for backwards-compatibility; it continues to return ``timespan=None`` for non-``CALIBRATION``` collections. (`DM-52895 <https://rubinobs.atlassian.net/browse/DM-52895>`_)
50
+ - The unit tests will no longer fail due to file descriptor exhaustion.
51
+ All `ResourceWarning` messages in the unit test suite have been fixed.
52
+ Butler instances are now garbage-collected immediately when they are no longer referenced, although their database connections still might not be released until mark-and-sweep garbage collection runs. (`DM-53233 <https://rubinobs.atlassian.net/browse/DM-53233>`_)
53
+ - Fixed compatibility of the unit test suite with pytest v9. (`DM-53266 <https://rubinobs.atlassian.net/browse/DM-53266>`_)
54
+ - Storage classes are no longer loaded implicitly when using ``Butler.registry.queryDatasets()``.
55
+ A warning about the ``datasetType`` parameter being deprecated is no longer issued when calling ``Butler.registry.queryDatasetAssociations``. (`DM-53342 <https://rubinobs.atlassian.net/browse/DM-53342>`_)
56
+ - ``FileDatastore.export_records()`` will no longer fail with ``sqlalchemy.exc.InternalError`` when given a large number of dataset IDs.
57
+ ``Butler.get_many_datasets()`` will no longer fail with ``sqlalchemy.exc.InternalError`` when given a large number of dataset IDs. (`DM-53610 <https://rubinobs.atlassian.net/browse/DM-53610>`_)
58
+
59
+
60
+ Performance Enhancement
61
+ -----------------------
62
+
63
+ - Fewer database queries are now used when inserting/exporting datasets, in cases where the datasets do not have "expanded data ID" values known in advance. (`DM-51593 <https://rubinobs.atlassian.net/browse/DM-51593>`_)
64
+ - ``Butler.transfer_from(transfer_dimensions = True)``, ``Butler.transfer_dimension_records_from()``, and ``butler transfer-datasets`` are now significantly faster. (`DM-51681 <https://rubinobs.atlassian.net/browse/DM-51681>`_)
65
+ - New dataset UUIDs are now generated using UUIDv7 instead of UUIDv4, to improve Postgres insert performance. (`DM-52719 <https://rubinobs.atlassian.net/browse/DM-52719>`_)
66
+ - Removed unnecessary directory existence checks when writing files to the datastore.
67
+ We no longer create zero-byte files to represent "directories" when writing files to an S3 datastore. (`DM-53580 <https://rubinobs.atlassian.net/browse/DM-53580>`_)
68
+
69
+
70
+ Other Changes and Additions
71
+ ---------------------------
72
+
73
+ - Updated the storage class definitions for scarlet lite models to be Zip archives that can be accessed as single blends. (`DM-49537 <https://rubinobs.atlassian.net/browse/DM-49537>`_)
74
+ - Made some registry test data available to downstream packages via `importlib.resources`. (`DM-51363 <https://rubinobs.atlassian.net/browse/DM-51363>`_)
75
+ - Added support for ``obs_publisher_did`` value in ObsCore config file. (`DM-51383 <https://rubinobs.atlassian.net/browse/DM-51383>`_)
76
+ - * Modified ``ObsCore`` records to place "exposure" in any visit fields if there is an exposure but no visit defined.
77
+ This required the addition of a new method to the ``RecordFactory`` which can be subclassed by other plugins.
78
+ * Added ability to hard code the ``s_xel1`` and ``s_xel2`` ObsCore fields per dataset type. (`DM-51495 <https://rubinobs.atlassian.net/browse/DM-51495>`_)
79
+ - Drop incomplete support for case-insensitive handling of identifiers in query expressions.
80
+
81
+ Some code in the query generation system was trying to allow dimension names to be case-insensitive, but was actually just inadvertently requiring all dimension names to be defined as lowercase.
82
+ Our Python-flavored user base probably expects case-sensitive dimension and dataset type names anyway.
83
+
84
+ Constants (e.g., ``AND`` or ``OVERLAPS``) in the query system are still case insensitive. (`DM-52339 <https://rubinobs.atlassian.net/browse/DM-52339>`_)
85
+ - ``Butler.registry.queryDatasets``, ``Butler.registry.queryDataIds``, and ``Butler.registry.queryDimensionRecords`` have been re-implemented using the same query framework backing ``Butler.query()`` and the various ``Butler.query_*()`` methods. Though the ``Butler.registry.*`` methods are not yet deprecated, users are encouraged to begin migrating to the equivalent ``Butler.query_*`` functions. The new implementation comes with a number of minor behavior changes:
86
+ - We no longer raise an exception if governor dimension values in a query constraint are not known to the registry. Instead, we return no results.
87
+ - Result rows are now deduplicated.
88
+ - ``findFirst`` searches are now supported in calibration collections. (`DM-52397 <https://rubinobs.atlassian.net/browse/DM-52397>`_)
89
+ - ``Butler.find_dataset()`` / ``Butler.registry.findDataset()`` have been re-implemented using the same query framework backing ``Butler.query()``. These methods now always return ``DatasetRef`` instances with ``dataId.hasFull() = True``. (`DM-52398 <https://rubinobs.atlassian.net/browse/DM-52398>`_)
90
+ - For EUPS users we now set the ``ARROW_DEFAULT_MEMORY_POOL`` environment variable to ``jemalloc``.
91
+ This works around a memory leak reported in https://github.com/apache/arrow/issues/45882 for pyarrow v18 and newer. (`DM-52412 <https://rubinobs.atlassian.net/browse/DM-52412>`_)
92
+ - Added a new ``Datastore`` API for retrieving the datastore records for datasets that might not have been written yet.
93
+ There is also a related API added to ``QuantumBackedButler``. (`DM-52653 <https://rubinobs.atlassian.net/browse/DM-52653>`_)
94
+ - Rewrote the default compression write recipes to match the new interfaces for FITS compression in ``afw`` and ``obs_base``. (`DM-52879 <https://rubinobs.atlassian.net/browse/DM-52879>`_)
95
+ - Added new options to ``DatasetProvenance`` to prevent excessive numbers of input datasets being recorded in file metadata.
96
+ The limit for parquet datasets was set to 2,000 inputs. (`DM-53326 <https://rubinobs.atlassian.net/browse/DM-53326>`_)
97
+ - Added ``lossy16`` compression recipe to replace ``lossyBasic`` (`DM-53420 <https://rubinobs.atlassian.net/browse/DM-53420>`_)
98
+ - Added a storage class and formatter declaration for the ``ProvenanceQuantumGraph`` class.
99
+
100
+ Allowed a ``ButlerLogRecords`` container to be passed to the log handler at construction. (`DM-53622 <https://rubinobs.atlassian.net/browse/DM-53622>`_)
101
+ - Added metrics recording for ``butler.ingest``. (`DM-53679 <https://rubinobs.atlassian.net/browse/DM-53679>`_)
102
+ - Added Butler storage class definitions for ``GuiderROI`` ``VignettingCorrection`` class (`OSW-1064 <https://rubinobs.atlassian.net/browse/OSW-1064>`_)
103
+
104
+ An API Removal or Deprecation
105
+ -----------------------------
106
+
107
+ - ``daf_butler`` no longer depends on the ``daf_relation`` library.
108
+ ``daf_relation``-related internal classes are no longer exported from the top-level module.
109
+ Butler query expression classes have moved from ``lsst.daf.butler.registry.queries`` to ``lsst.daf.butler.queries``. (`DM-52345 <https://rubinobs.atlassian.net/browse/DM-52345>`_)
110
+ - Removed deprecated ``DatasetQueryResults.materialize()`` method.
111
+ Removed deprecated ``offset`` parameter from the ``limit`` method in the ``DataCoordinateQueryResults``, ``DatasetQueryResults``, and ``DimensionRecordQueryResults`` classes.
112
+ Removed the deprecated feature where HTM and HEALPix spatial dimensions like ``htm11`` or ``healpix10`` could be used in data ID constraints passed to queries. The exception is ``htm7``, which will continue to work. Users should instead use region ``OVERLAPS`` constraints in query ``where`` expressions.
113
+ Removed support for ``<`` and ``>`` operators in ``Butler.registry.query*()`` ``where`` strings for comparisons of ``Timespan`` vs ``Timespan``, or ``Timespan`` vs ``Time``. Instead, use ``timespan.begin < ts`` or ``timespan.end > ts`` to explicitly indicate which timespan bound you are comparing with. (`DM-52397 <https://rubinobs.atlassian.net/browse/DM-52397>`_)
114
+
115
+
1
116
  Butler v29.1.0 (2025-06-13)
2
117
  ===========================
3
118
 
@@ -1566,7 +1566,7 @@ class Butler(LimitedButler): # numpydoc ignore=PR02
1566
1566
 
1567
1567
  @abstractmethod
1568
1568
  def transfer_dimension_records_from(
1569
- self, source_butler: LimitedButler | Butler, source_refs: Iterable[DatasetRef]
1569
+ self, source_butler: LimitedButler | Butler, source_refs: Iterable[DatasetRef | DataCoordinate]
1570
1570
  ) -> None:
1571
1571
  """Transfer dimension records to this Butler from another Butler.
1572
1572
 
@@ -1578,10 +1578,9 @@ class Butler(LimitedButler): # numpydoc ignore=PR02
1578
1578
  `Butler` whose registry will be used to expand data IDs. If the
1579
1579
  source refs contain coordinates that are used to populate other
1580
1580
  records then this will also need to be a full `Butler`.
1581
- source_refs : iterable of `DatasetRef`
1582
- Datasets defined in the source butler whose dimension records
1583
- should be transferred to this butler. In most circumstances.
1584
- transfer is faster if the dataset refs are expanded.
1581
+ source_refs : iterable of `DatasetRef` or `DataCoordinate`
1582
+ Datasets or data IDs defined in the source butler whose dimension
1583
+ records should be transferred to this butler.
1585
1584
  """
1586
1585
  raise NotImplementedError()
1587
1586
 
@@ -2227,3 +2226,7 @@ class Butler(LimitedButler): # numpydoc ignore=PR02
2227
2226
  @abstractmethod
2228
2227
  def close(self) -> None:
2229
2228
  raise NotImplementedError()
2229
+
2230
+ @abstractmethod
2231
+ def _expand_data_ids(self, data_ids: Iterable[DataCoordinate]) -> list[DataCoordinate]:
2232
+ raise NotImplementedError()
@@ -29,12 +29,15 @@ from __future__ import annotations
29
29
 
30
30
  from collections.abc import Callable, Iterator
31
31
  from contextlib import contextmanager
32
+ from typing import Concatenate, ParamSpec
32
33
 
33
34
  from pydantic import BaseModel
34
35
 
35
36
  from lsst.utils.logging import LsstLoggers
36
37
  from lsst.utils.timer import time_this
37
38
 
39
+ P = ParamSpec("P")
40
+
38
41
 
39
42
  class ButlerMetrics(BaseModel):
40
43
  """Metrics collected during Butler operations."""
@@ -45,18 +48,26 @@ class ButlerMetrics(BaseModel):
45
48
  time_in_get: float = 0.0
46
49
  """Wall-clock time, in seconds, spent in get()."""
47
50
 
51
+ time_in_ingest: float = 0.0
52
+ """Wall-clock time, in seconds, spent in ingest()."""
53
+
48
54
  n_get: int = 0
49
55
  """Number of datasets retrieved with get()."""
50
56
 
51
57
  n_put: int = 0
52
58
  """Number of datasets stored with put()."""
53
59
 
60
+ n_ingest: int = 0
61
+ """Number of datasets ingested."""
62
+
54
63
  def reset(self) -> None:
55
64
  """Reset all metrics."""
56
65
  self.time_in_put = 0.0
57
66
  self.time_in_get = 0.0
67
+ self.time_in_ingest = 0.0
58
68
  self.n_get = 0
59
69
  self.n_put = 0
70
+ self.n_ingest = 0
60
71
 
61
72
  def increment_get(self, duration: float) -> None:
62
73
  """Increment time for get().
@@ -80,13 +91,31 @@ class ButlerMetrics(BaseModel):
80
91
  self.time_in_put += duration
81
92
  self.n_put += 1
82
93
 
94
+ def increment_ingest(self, duration: float, n_datasets: int) -> None:
95
+ """Increment time and datasets for ingest().
96
+
97
+ Parameters
98
+ ----------
99
+ duration : `float`
100
+ Duration to add to the ingest() statistics.
101
+ n_datasets : `int`
102
+ Number of datasets to be ingested for this call.
103
+ """
104
+ self.time_in_ingest += duration
105
+ self.n_ingest += n_datasets
106
+
83
107
  @contextmanager
84
108
  def _timer(
85
- self, handler: Callable[[float], None], log: LsstLoggers | None = None, msg: str | None = None
109
+ self,
110
+ handler: Callable[Concatenate[float, P], None],
111
+ log: LsstLoggers | None = None,
112
+ msg: str | None = None,
113
+ *args: P.args,
114
+ **kwargs: P.kwargs,
86
115
  ) -> Iterator[None]:
87
116
  with time_this(log=log, msg=msg) as timer:
88
117
  yield
89
- handler(timer.duration)
118
+ handler(timer.duration, *args, **kwargs)
90
119
 
91
120
  @contextmanager
92
121
  def instrument_get(self, log: LsstLoggers | None = None, msg: str | None = None) -> Iterator[None]:
@@ -115,3 +144,21 @@ class ButlerMetrics(BaseModel):
115
144
  """
116
145
  with self._timer(self.increment_put, log=log, msg=msg):
117
146
  yield
147
+
148
+ @contextmanager
149
+ def instrument_ingest(
150
+ self, n_datasets: int, log: LsstLoggers | None = None, msg: str | None = None
151
+ ) -> Iterator[None]:
152
+ """Run code and increment ingest statistics.
153
+
154
+ Parameters
155
+ ----------
156
+ n_datasets : `int`
157
+ Number of datasets being ingested.
158
+ log : `logging.Logger` or `None`
159
+ Logger to use for any timing information.
160
+ msg : `str` or `None`
161
+ Any message to be included in log output.
162
+ """
163
+ with self._timer(self.increment_ingest, n_datasets=n_datasets, log=log, msg=msg):
164
+ yield
@@ -54,6 +54,7 @@ from ._config import Config
54
54
  from ._config_support import LookupKey, processLookupConfigs
55
55
  from ._file_descriptor import FileDescriptor
56
56
  from ._location import Location
57
+ from ._rubin.temporary_for_ingest import TemporaryForIngest
57
58
  from .dimensions import DataCoordinate, DimensionUniverse
58
59
  from .mapping_factory import MappingFactory
59
60
 
@@ -1031,13 +1032,7 @@ class FormatterV2:
1031
1032
  """
1032
1033
  cache_manager = self._ensure_cache(cache_manager)
1033
1034
 
1034
- # Always write to a temporary even if
1035
- # using a local file system -- that gives us atomic writes.
1036
- # If a process is killed as the file is being written we do not
1037
- # want it to remain in the correct place but in corrupt state.
1038
- # For local files write to the output directory not temporary dir.
1039
- prefix = uri.dirname() if uri.isLocal else None
1040
- with ResourcePath.temporary_uri(suffix=uri.getExtension(), prefix=prefix) as temporary_uri:
1035
+ with TemporaryForIngest.make_path(uri) as temporary_uri:
1041
1036
  # Need to configure the formatter to write to a different
1042
1037
  # location and that needs us to overwrite internals
1043
1038
  log.debug("Writing dataset to temporary location at %s", temporary_uri)
@@ -30,7 +30,9 @@ from __future__ import annotations
30
30
  __all__ = ("LabeledButlerFactory", "LabeledButlerFactoryProtocol")
31
31
 
32
32
  from collections.abc import Mapping
33
- from typing import Protocol
33
+ from contextlib import AbstractContextManager
34
+ from logging import getLogger
35
+ from typing import Any, Literal, Protocol, Self
34
36
 
35
37
  from lsst.resources import ResourcePathExpression
36
38
 
@@ -40,6 +42,8 @@ from ._butler_repo_index import ButlerRepoIndex
40
42
  from ._utilities.named_locks import NamedLocks
41
43
  from ._utilities.thread_safe_cache import ThreadSafeCache
42
44
 
45
+ _LOG = getLogger(__name__)
46
+
43
47
 
44
48
  class LabeledButlerFactoryProtocol(Protocol):
45
49
  """Callable to retrieve a butler from a label."""
@@ -47,7 +51,7 @@ class LabeledButlerFactoryProtocol(Protocol):
47
51
  def __call__(self, label: str) -> Butler: ...
48
52
 
49
53
 
50
- class LabeledButlerFactory:
54
+ class LabeledButlerFactory(AbstractContextManager):
51
55
  """Factory for efficiently instantiating Butler instances from the
52
56
  repository index file. This is intended for use from long-lived services
53
57
  that want to instantiate a separate Butler instance for each end user
@@ -60,6 +64,9 @@ class LabeledButlerFactory:
60
64
  files. If not provided, defaults to the global repository index
61
65
  configured by the ``DAF_BUTLER_REPOSITORY_INDEX`` environment variable
62
66
  -- see `ButlerRepoIndex`.
67
+ writeable : `bool`, optional
68
+ If `True`, Butler instances created by this factory will be writeable.
69
+ If `False` (the default), instances will be read-only.
63
70
 
64
71
  Notes
65
72
  -----
@@ -76,11 +83,12 @@ class LabeledButlerFactory:
76
83
  safely be used by separate threads.
77
84
  """
78
85
 
79
- def __init__(self, repositories: Mapping[str, str] | None = None) -> None:
86
+ def __init__(self, repositories: Mapping[str, str] | None = None, writeable: bool = False) -> None:
80
87
  if repositories is None:
81
88
  self._repositories = None
82
89
  else:
83
90
  self._repositories = dict(repositories)
91
+ self._writeable = writeable
84
92
 
85
93
  self._factories = ThreadSafeCache[str, _ButlerFactory]()
86
94
  self._initialization_locks = NamedLocks()
@@ -88,6 +96,16 @@ class LabeledButlerFactory:
88
96
  # This may be overridden by unit tests.
89
97
  self._preload_unsafe_direct_butler_caches = True
90
98
 
99
+ def __enter__(self) -> Self:
100
+ return self
101
+
102
+ def __exit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> Literal[False]:
103
+ try:
104
+ self.close()
105
+ except Exception:
106
+ _LOG.exception("An exception occurred during LabeledButlerFactory.close()")
107
+ return False
108
+
91
109
  def bind(self, access_token: str | None) -> LabeledButlerFactoryProtocol:
92
110
  """Create a callable factory function for generating Butler instances
93
111
  with out needing to specify access tokans again.
@@ -109,7 +127,7 @@ class LabeledButlerFactory:
109
127
 
110
128
  return create
111
129
 
112
- def create_butler(self, *, label: str, access_token: str | None) -> Butler:
130
+ def create_butler(self, label: str, *, access_token: str | None = None) -> Butler:
113
131
  """Create a Butler instance.
114
132
 
115
133
  Parameters
@@ -118,7 +136,7 @@ class LabeledButlerFactory:
118
136
  Label of the repository to instantiate, from the ``repositories``
119
137
  parameter to the `LabeledButlerFactory` constructor or the global
120
138
  repository index file.
121
- access_token : `str` | `None`
139
+ access_token : `str` | `None`, optional
122
140
  Gafaelfawr access token used to authenticate to a Butler server.
123
141
  This is required for any repositories configured to use
124
142
  `RemoteButler`. If you only use `DirectButler`, this may be
@@ -167,7 +185,9 @@ class LabeledButlerFactory:
167
185
 
168
186
  match butler_type:
169
187
  case ButlerType.DIRECT:
170
- return _DirectButlerFactory(config, self._preload_unsafe_direct_butler_caches)
188
+ return _DirectButlerFactory(
189
+ config, self._preload_unsafe_direct_butler_caches, self._writeable
190
+ )
171
191
  case ButlerType.REMOTE:
172
192
  return _RemoteButlerFactory(config)
173
193
  case _:
@@ -189,12 +209,12 @@ class _ButlerFactory(Protocol):
189
209
 
190
210
 
191
211
  class _DirectButlerFactory(_ButlerFactory):
192
- def __init__(self, config: ButlerConfig, preload_unsafe_caches: bool) -> None:
212
+ def __init__(self, config: ButlerConfig, preload_unsafe_caches: bool, writeable: bool) -> None:
193
213
  import lsst.daf.butler.direct_butler
194
214
 
195
215
  # Create a 'template' Butler that will be cloned when callers request
196
216
  # an instance.
197
- self._butler = Butler.from_config(config)
217
+ self._butler = Butler.from_config(config, writeable=writeable)
198
218
  assert isinstance(self._butler, lsst.daf.butler.direct_butler.DirectButler)
199
219
 
200
220
  # Load caches so that data is available in cloned instances without
@@ -0,0 +1,207 @@
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__ = ("TemporaryForIngest",)
31
+
32
+ import dataclasses
33
+ import glob
34
+ from contextlib import contextmanager
35
+ from typing import TYPE_CHECKING, Self, cast
36
+
37
+ from lsst.resources import ResourcePath
38
+
39
+ if TYPE_CHECKING:
40
+ from collections.abc import Iterator
41
+ from types import TracebackType
42
+
43
+ from .._butler import Butler
44
+ from .._dataset_ref import DatasetRef
45
+ from .._file_dataset import FileDataset
46
+ from .._limited_butler import LimitedButler
47
+
48
+
49
+ @dataclasses.dataclass
50
+ class TemporaryForIngest:
51
+ """A context manager for generating temporary paths that will be ingested
52
+ as butler datasets.
53
+
54
+ Notes
55
+ -----
56
+ Neither this class nor its `make_path` method run ingest automatically when
57
+ their context manager is exited; the `ingest` method must always be called
58
+ explicitly.
59
+ """
60
+
61
+ butler: Butler
62
+ """Full butler to obtain a predicted path from and ingest into."""
63
+
64
+ ref: DatasetRef
65
+ """Description of the dataset to ingest."""
66
+
67
+ dataset: FileDataset = dataclasses.field(init=False)
68
+ """The dataset that will be passed to `Butler.ingest`."""
69
+
70
+ @property
71
+ def path(self) -> ResourcePath:
72
+ """The temporary path.
73
+
74
+ Guaranteed to be a local POSIX path.
75
+ """
76
+ return cast(ResourcePath, self.dataset.path)
77
+
78
+ @property
79
+ def ospath(self) -> str:
80
+ """The temporary path as a complete filename."""
81
+ return self.path.ospath
82
+
83
+ @classmethod
84
+ @contextmanager
85
+ def make_path(cls, final_path: ResourcePath) -> Iterator[ResourcePath]:
86
+ """Return a temporary path context manager given the predicted final
87
+ path.
88
+
89
+ Parameters
90
+ ----------
91
+ final_path : `lsst.resources.ResourcePath`
92
+ Predicted final path.
93
+
94
+ Returns
95
+ -------
96
+ context : `contextlib.AbstractContextManager`
97
+ A context manager that yields the temporary
98
+ `~lsst.resources.ResourcePath` when entered and deletes that file
99
+ when exited.
100
+ """
101
+ # Always write to a temporary even if using a local file system -- that
102
+ # gives us atomic writes. If a process is killed as the file is being
103
+ # written we do not want it to remain in the correct place but in
104
+ # corrupt state. For local files write to the output directory not
105
+ # temporary dir.
106
+ prefix = final_path.dirname() if final_path.isLocal else None
107
+ if prefix is not None:
108
+ prefix.mkdir()
109
+ with ResourcePath.temporary_uri(
110
+ suffix=cls._get_temporary_suffix(final_path), prefix=prefix
111
+ ) as temporary_path:
112
+ yield temporary_path
113
+
114
+ def ingest(self, record_validation_info: bool = True) -> None:
115
+ """Ingest the file into the butler.
116
+
117
+ Parameters
118
+ ----------
119
+ record_validation_info : `bool`, optional
120
+ Whether to- record the file size and checksum upon ingest.
121
+ """
122
+ self.butler.ingest(self.dataset, transfer="move", record_validation_info=record_validation_info)
123
+
124
+ def __enter__(self) -> Self:
125
+ from .._file_dataset import FileDataset
126
+
127
+ final_path = self.butler.getURI(self.ref, predict=True).replace(fragment="")
128
+ prefix = final_path.dirname() if final_path.isLocal else None
129
+ if prefix is not None:
130
+ prefix.mkdir()
131
+ self._temporary_path_context = self.make_path(final_path)
132
+ temporary_path = self._temporary_path_context.__enter__()
133
+ self.dataset = FileDataset(temporary_path, [self.ref], formatter=None)
134
+ return self
135
+
136
+ def __exit__(
137
+ self,
138
+ exc_type: type[BaseException] | None,
139
+ exc_value: BaseException | None,
140
+ traceback: TracebackType | None,
141
+ ) -> bool | None:
142
+ return self._temporary_path_context.__exit__(exc_type, exc_value, traceback)
143
+
144
+ @classmethod
145
+ def find_orphaned_temporaries_by_path(cls, final_path: ResourcePath) -> list[ResourcePath]:
146
+ """Search for temporary files that were not successfully ingested.
147
+
148
+ Parameters
149
+ ----------
150
+ final_path : `lsst.resources.ResourcePath`
151
+ Final path a successfully-ingested file would have.
152
+
153
+ Returns
154
+ -------
155
+ paths : `list` [ `lsst.resources.ResourcePath` ]
156
+ Files that look like temporaries that might have been created while
157
+ trying to write the target dataset.
158
+
159
+ Notes
160
+ -----
161
+ Orphaned files are only possible when a context manager is interrupted
162
+ by a hard error that prevents any cleanup code from running (e.g.
163
+ sudden loss of power).
164
+ """
165
+ if not final_path.isLocal:
166
+ # We return true tempfile for non-local predicted paths, so orphans
167
+ # are not our problem (the OS etc. will take care of them).
168
+ return []
169
+ return [
170
+ ResourcePath(filename)
171
+ for filename in glob.glob(
172
+ f"{glob.escape(final_path.dirname().ospath)}*{glob.escape(cls._get_temporary_suffix(final_path))}"
173
+ )
174
+ if filename != final_path.ospath
175
+ ]
176
+
177
+ @classmethod
178
+ def find_orphaned_temporaries_by_ref(cls, ref: DatasetRef, butler: LimitedButler) -> list[ResourcePath]:
179
+ """Search for temporary files that were not successfully ingested.
180
+
181
+ Parameters
182
+ ----------
183
+ ref : `..DatasetRef`
184
+ A dataset reference the temporaries correspond to.
185
+ butler : `lsst.daf.butler.LimitedButler`
186
+ Butler that can be used to obtain a predicted URI for a dataset.
187
+
188
+ Returns
189
+ -------
190
+ paths : `list` [ `lsst.resources.ResourcePath` ]
191
+ Files that look like temporaries that might have been created while
192
+ trying to write the target dataset.
193
+
194
+ Notes
195
+ -----
196
+ Orphaned files are only possible when a context manager is interrupted
197
+ by a hard error that prevents any cleanup code from running (e.g.
198
+ sudden loss of power).
199
+ """
200
+ final_path = butler.getURI(ref, predict=True).replace(fragment="")
201
+ return cls.find_orphaned_temporaries_by_path(final_path)
202
+
203
+ @staticmethod
204
+ def _get_temporary_suffix(path: ResourcePath) -> str:
205
+ ext = path.getExtension()
206
+ basename = path.basename().removesuffix(ext)
207
+ return f"{basename}.tmp{ext}"
@@ -100,3 +100,4 @@ VisitBackgroundModel: lsst.daf.butler.formatters.json.JsonFormatter
100
100
  VignettingCorrection: lsst.ts.observatory.control.utils.extras.vignetting_storage.VignettingCorrectionFormatter
101
101
  SSPAuxiliaryFile: lsst.pipe.tasks.sspAuxiliaryFile.SSPAuxiliaryFileFormatter
102
102
  VisitGeometry: lsst.daf.butler.formatters.json.JsonFormatter
103
+ ProvenanceQuantumGraph: lsst.pipe.base.quantum_graph.formatter.ProvenanceFormatter
@@ -443,3 +443,18 @@ storageClasses:
443
443
  pytype: lsst.pipe.tasks.sspAuxiliaryFile.SSPAuxiliaryFile
444
444
  VisitGeometry:
445
445
  pytype: lsst.obs.base.visit_geometry.VisitGeometry
446
+ ProvenanceQuantumGraph:
447
+ pytype: lsst.pipe.base.quantum_graph.ProvenanceQuantumGraph
448
+ parameters:
449
+ - import_mode # lsst.pipe.base.pipeline_graph.TaskImportMode
450
+ - quanta # iterable of uuid.UUID; quanta to read
451
+ - datasets # iterable of uuid.UUID; datasets to read
452
+ - read_init_quanta # bool, defaults to True; whether to read pre-exec-init info
453
+ derivedComponents:
454
+ packages: Packages # ignores node parameters
455
+
456
+ # UUID keys can be quantum or data IDs (whichever is passed in via
457
+ # parameters). Nested lists are attempts to run the quantum (last is
458
+ # most recent).
459
+ logs: StructuredDataDict # dict[uuid.UUID, list[ButlerLogRecords]]
460
+ metadata: StructuredDataDict # dict[uuid.UUID, list[TaskMetadata]]
@@ -49,7 +49,7 @@ if TYPE_CHECKING:
49
49
  # Pydantic requires the possible value types to be explicitly enumerated in
50
50
  # order for `uuid.UUID` in particular to work. `typing.Any` does not work
51
51
  # here.
52
- _Record: TypeAlias = dict[str, int | str | uuid.UUID | None]
52
+ _Record: TypeAlias = dict[str, int | str | None]
53
53
 
54
54
 
55
55
  class SerializedDatastoreRecordData(pydantic.BaseModel):