lsst-daf-butler 29.2025.1800__tar.gz → 29.2025.1900__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 (430) hide show
  1. {lsst_daf_butler-29.2025.1800/python/lsst_daf_butler.egg-info → lsst_daf_butler-29.2025.1900}/PKG-INFO +1 -1
  2. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/doc/lsst.daf.butler/queries.rst +12 -0
  3. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/datastores/fileDatastore.py +77 -36
  4. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/queries/_expression_strings.py +4 -0
  5. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/queries/expressions/_predicate.py +5 -0
  6. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/queries/expressions/check.py +5 -0
  7. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/queries/expressions/normalForm.py +5 -0
  8. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/queries/expressions/parser/exprTree.py +64 -20
  9. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/queries/expressions/parser/parserYacc.py +26 -9
  10. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/queries/expressions/parser/treeVisitor.py +13 -0
  11. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/tests/butler_queries.py +51 -0
  12. lsst_daf_butler-29.2025.1900/python/lsst/daf/butler/version.py +2 -0
  13. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900/python/lsst_daf_butler.egg-info}/PKG-INFO +1 -1
  14. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_exprParserYacc.py +18 -0
  15. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_normalFormExpression.py +5 -0
  16. lsst_daf_butler-29.2025.1800/python/lsst/daf/butler/version.py +0 -2
  17. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/COPYRIGHT +0 -0
  18. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/LICENSE +0 -0
  19. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/MANIFEST.in +0 -0
  20. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/README.md +0 -0
  21. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/bsd_license.txt +0 -0
  22. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/doc/lsst.daf.butler/CHANGES.rst +0 -0
  23. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/doc/lsst.daf.butler/concreteStorageClasses.rst +0 -0
  24. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/doc/lsst.daf.butler/configuring.rst +0 -0
  25. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/doc/lsst.daf.butler/datastores.rst +0 -0
  26. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/doc/lsst.daf.butler/dimensions.rst +0 -0
  27. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/doc/lsst.daf.butler/formatters.rst +0 -0
  28. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/doc/lsst.daf.butler/index.rst +0 -0
  29. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/doc/lsst.daf.butler/organizing.rst +0 -0
  30. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/doc/lsst.daf.butler/use-in-tests.rst +0 -0
  31. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/doc/lsst.daf.butler/writing-subcommands.rst +0 -0
  32. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/gpl-v3.0.txt +0 -0
  33. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/pyproject.toml +0 -0
  34. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/__init__.py +0 -0
  35. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/__init__.py +0 -0
  36. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/__init__.py +0 -0
  37. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/_butler.py +0 -0
  38. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/_butler_collections.py +0 -0
  39. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/_butler_config.py +0 -0
  40. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/_butler_instance_options.py +0 -0
  41. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/_butler_metrics.py +0 -0
  42. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/_butler_repo_index.py +0 -0
  43. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/_collection_type.py +0 -0
  44. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/_column_categorization.py +0 -0
  45. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/_column_tags.py +0 -0
  46. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/_column_type_info.py +0 -0
  47. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/_config.py +0 -0
  48. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/_config_support.py +0 -0
  49. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/_dataset_association.py +0 -0
  50. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/_dataset_existence.py +0 -0
  51. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/_dataset_provenance.py +0 -0
  52. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/_dataset_ref.py +0 -0
  53. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/_dataset_type.py +0 -0
  54. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/_deferredDatasetHandle.py +0 -0
  55. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/_exceptions.py +0 -0
  56. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/_exceptions_legacy.py +0 -0
  57. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/_file_dataset.py +0 -0
  58. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/_file_descriptor.py +0 -0
  59. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/_formatter.py +0 -0
  60. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/_labeled_butler_factory.py +0 -0
  61. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/_limited_butler.py +0 -0
  62. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/_location.py +0 -0
  63. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/_named.py +0 -0
  64. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/_quantum.py +0 -0
  65. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/_quantum_backed.py +0 -0
  66. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/_query_all_datasets.py +0 -0
  67. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/_registry_shim.py +0 -0
  68. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/_storage_class.py +0 -0
  69. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/_storage_class_delegate.py +0 -0
  70. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/_timespan.py +0 -0
  71. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/_topology.py +0 -0
  72. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/_utilities/__init__.py +0 -0
  73. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/_utilities/locked_object.py +0 -0
  74. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/_utilities/named_locks.py +0 -0
  75. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/_utilities/thread_safe_cache.py +0 -0
  76. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/arrow_utils.py +0 -0
  77. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/cli/__init__.py +0 -0
  78. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/cli/butler.py +0 -0
  79. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/cli/cliLog.py +0 -0
  80. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/cli/cmd/__init__.py +0 -0
  81. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/cli/cmd/_remove_collections.py +0 -0
  82. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/cli/cmd/_remove_runs.py +0 -0
  83. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/cli/cmd/commands.py +0 -0
  84. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/cli/opt/__init__.py +0 -0
  85. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/cli/opt/arguments.py +0 -0
  86. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/cli/opt/optionGroups.py +0 -0
  87. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/cli/opt/options.py +0 -0
  88. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/cli/progress.py +0 -0
  89. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/cli/utils.py +0 -0
  90. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/column_spec.py +0 -0
  91. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/configs/datastore.yaml +0 -0
  92. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/configs/datastores/composites.yaml +0 -0
  93. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/configs/datastores/fileDatastore.yaml +0 -0
  94. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/configs/datastores/formatters.yaml +0 -0
  95. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/configs/datastores/writeRecipes.yaml +0 -0
  96. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/configs/dimensions.yaml +0 -0
  97. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/configs/old_dimensions/daf_butler_universe0.yaml +0 -0
  98. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/configs/old_dimensions/daf_butler_universe1.yaml +0 -0
  99. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/configs/old_dimensions/daf_butler_universe2.yaml +0 -0
  100. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/configs/old_dimensions/daf_butler_universe3.yaml +0 -0
  101. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/configs/old_dimensions/daf_butler_universe4.yaml +0 -0
  102. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/configs/old_dimensions/daf_butler_universe5.yaml +0 -0
  103. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/configs/old_dimensions/daf_butler_universe6.yaml +0 -0
  104. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/configs/old_dimensions/daf_butler_universe7.yaml +0 -0
  105. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/configs/registry.yaml +0 -0
  106. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/configs/repo_transfer_formats.yaml +0 -0
  107. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/configs/storageClasses.yaml +0 -0
  108. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/datastore/__init__.py +0 -0
  109. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/datastore/_datastore.py +0 -0
  110. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/datastore/cache_manager.py +0 -0
  111. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/datastore/composites.py +0 -0
  112. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/datastore/constraints.py +0 -0
  113. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/datastore/file_templates.py +0 -0
  114. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/datastore/generic_base.py +0 -0
  115. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/datastore/record_data.py +0 -0
  116. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/datastore/stored_file_info.py +0 -0
  117. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/datastores/__init__.py +0 -0
  118. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/datastores/chainedDatastore.py +0 -0
  119. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/datastores/fileDatastoreClient.py +0 -0
  120. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/datastores/file_datastore/__init__.py +0 -0
  121. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/datastores/file_datastore/get.py +0 -0
  122. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/datastores/file_datastore/retrieve_artifacts.py +0 -0
  123. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/datastores/inMemoryDatastore.py +0 -0
  124. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/ddl.py +0 -0
  125. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/delegates/__init__.py +0 -0
  126. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/delegates/arrowtable.py +0 -0
  127. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/dimensions/__init__.py +0 -0
  128. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/dimensions/_config.py +0 -0
  129. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/dimensions/_coordinate.py +0 -0
  130. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/dimensions/_data_coordinate_iterable.py +0 -0
  131. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/dimensions/_database.py +0 -0
  132. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/dimensions/_elements.py +0 -0
  133. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/dimensions/_governor.py +0 -0
  134. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/dimensions/_group.py +0 -0
  135. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/dimensions/_packer.py +0 -0
  136. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/dimensions/_record_set.py +0 -0
  137. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/dimensions/_record_table.py +0 -0
  138. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/dimensions/_records.py +0 -0
  139. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/dimensions/_schema.py +0 -0
  140. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/dimensions/_skypix.py +0 -0
  141. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/dimensions/_universe.py +0 -0
  142. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/dimensions/construction.py +0 -0
  143. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/dimensions/record_cache.py +0 -0
  144. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/direct_butler/__init__.py +0 -0
  145. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/direct_butler/_direct_butler.py +0 -0
  146. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/direct_butler/_direct_butler_collections.py +0 -0
  147. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/direct_query_driver/__init__.py +0 -0
  148. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/direct_query_driver/_driver.py +0 -0
  149. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/direct_query_driver/_postprocessing.py +0 -0
  150. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/direct_query_driver/_query_analysis.py +0 -0
  151. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/direct_query_driver/_query_builder.py +0 -0
  152. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/direct_query_driver/_result_page_converter.py +0 -0
  153. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/direct_query_driver/_sql_builders.py +0 -0
  154. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/direct_query_driver/_sql_column_visitor.py +0 -0
  155. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/formatters/__init__.py +0 -0
  156. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/formatters/astropyTable.py +0 -0
  157. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/formatters/file.py +0 -0
  158. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/formatters/json.py +0 -0
  159. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/formatters/logs.py +0 -0
  160. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/formatters/matplotlib.py +0 -0
  161. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/formatters/packages.py +0 -0
  162. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/formatters/parquet.py +0 -0
  163. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/formatters/pickle.py +0 -0
  164. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/formatters/typeless.py +0 -0
  165. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/formatters/yaml.py +0 -0
  166. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/json.py +0 -0
  167. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/logging.py +0 -0
  168. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/mapping_factory.py +0 -0
  169. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/name_shrinker.py +0 -0
  170. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/nonempty_mapping.py +0 -0
  171. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/persistence_context.py +0 -0
  172. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/progress.py +0 -0
  173. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/py.typed +0 -0
  174. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/pydantic_utils.py +0 -0
  175. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/queries/__init__.py +0 -0
  176. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/queries/_base.py +0 -0
  177. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/queries/_data_coordinate_query_results.py +0 -0
  178. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/queries/_dataset_query_results.py +0 -0
  179. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/queries/_dimension_record_query_results.py +0 -0
  180. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/queries/_general_query_results.py +0 -0
  181. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/queries/_identifiers.py +0 -0
  182. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/queries/_query.py +0 -0
  183. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/queries/convert_args.py +0 -0
  184. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/queries/driver.py +0 -0
  185. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/queries/expression_factory.py +0 -0
  186. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/queries/overlaps.py +0 -0
  187. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/queries/predicate_constraints_summary.py +0 -0
  188. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/queries/result_specs.py +0 -0
  189. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/queries/tree/__init__.py +0 -0
  190. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/queries/tree/_base.py +0 -0
  191. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/queries/tree/_column_expression.py +0 -0
  192. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/queries/tree/_column_literal.py +0 -0
  193. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/queries/tree/_column_reference.py +0 -0
  194. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/queries/tree/_column_set.py +0 -0
  195. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/queries/tree/_predicate.py +0 -0
  196. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/queries/tree/_query_tree.py +0 -0
  197. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/queries/visitors.py +0 -0
  198. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/__init__.py +0 -0
  199. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/_caching_context.py +0 -0
  200. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/_collection_record_cache.py +0 -0
  201. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/_collection_summary.py +0 -0
  202. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/_collection_summary_cache.py +0 -0
  203. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/_config.py +0 -0
  204. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/_defaults.py +0 -0
  205. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/_exceptions.py +0 -0
  206. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/_registry.py +0 -0
  207. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/_registry_factory.py +0 -0
  208. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/attributes.py +0 -0
  209. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/bridge/__init__.py +0 -0
  210. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/bridge/ephemeral.py +0 -0
  211. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/bridge/monolithic.py +0 -0
  212. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/collections/__init__.py +0 -0
  213. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/collections/_base.py +0 -0
  214. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/collections/nameKey.py +0 -0
  215. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/collections/synthIntKey.py +0 -0
  216. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/connectionString.py +0 -0
  217. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/databases/__init__.py +0 -0
  218. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/databases/postgresql.py +0 -0
  219. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/databases/sqlite.py +0 -0
  220. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/datasets/__init__.py +0 -0
  221. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/datasets/byDimensions/__init__.py +0 -0
  222. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/datasets/byDimensions/_dataset_type_cache.py +0 -0
  223. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/datasets/byDimensions/_manager.py +0 -0
  224. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/datasets/byDimensions/summaries.py +0 -0
  225. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/datasets/byDimensions/tables.py +0 -0
  226. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/dimensions/__init__.py +0 -0
  227. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/dimensions/static.py +0 -0
  228. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/interfaces/__init__.py +0 -0
  229. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/interfaces/_attributes.py +0 -0
  230. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/interfaces/_bridge.py +0 -0
  231. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/interfaces/_collections.py +0 -0
  232. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/interfaces/_database.py +0 -0
  233. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/interfaces/_database_explain.py +0 -0
  234. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/interfaces/_datasets.py +0 -0
  235. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/interfaces/_dimensions.py +0 -0
  236. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/interfaces/_obscore.py +0 -0
  237. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/interfaces/_opaque.py +0 -0
  238. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/interfaces/_versioning.py +0 -0
  239. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/managers.py +0 -0
  240. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/nameShrinker.py +0 -0
  241. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/obscore/__init__.py +0 -0
  242. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/obscore/_config.py +0 -0
  243. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/obscore/_manager.py +0 -0
  244. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/obscore/_records.py +0 -0
  245. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/obscore/_schema.py +0 -0
  246. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/obscore/_spatial.py +0 -0
  247. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/obscore/default_spatial.py +0 -0
  248. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/obscore/pgsphere.py +0 -0
  249. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/opaque.py +0 -0
  250. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/queries/__init__.py +0 -0
  251. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/queries/_builder.py +0 -0
  252. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/queries/_query.py +0 -0
  253. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/queries/_query_backend.py +0 -0
  254. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/queries/_query_context.py +0 -0
  255. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/queries/_readers.py +0 -0
  256. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/queries/_results.py +0 -0
  257. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/queries/_sql_query_backend.py +0 -0
  258. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/queries/_sql_query_context.py +0 -0
  259. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/queries/_structs.py +0 -0
  260. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/queries/butler_sql_engine.py +0 -0
  261. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/queries/expressions/__init__.py +0 -0
  262. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/queries/expressions/categorize.py +0 -0
  263. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/queries/expressions/parser/__init__.py +0 -0
  264. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/queries/expressions/parser/parser.py +0 -0
  265. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/queries/expressions/parser/parserLex.py +0 -0
  266. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/queries/expressions/parser/ply/__init__.py +0 -0
  267. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/queries/expressions/parser/ply/lex.py +0 -0
  268. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/queries/expressions/parser/ply/yacc.py +0 -0
  269. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/queries/find_first_dataset.py +0 -0
  270. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/sql_registry.py +0 -0
  271. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/tests/__init__.py +0 -0
  272. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/tests/_database.py +0 -0
  273. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/tests/_registry.py +0 -0
  274. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/versions.py +0 -0
  275. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/registry/wildcards.py +0 -0
  276. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/remote_butler/__init__.py +0 -0
  277. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/remote_butler/_authentication.py +0 -0
  278. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/remote_butler/_collection_args.py +0 -0
  279. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/remote_butler/_config.py +0 -0
  280. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/remote_butler/_defaults.py +0 -0
  281. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/remote_butler/_errors.py +0 -0
  282. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/remote_butler/_factory.py +0 -0
  283. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/remote_butler/_http_connection.py +0 -0
  284. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/remote_butler/_query_driver.py +0 -0
  285. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/remote_butler/_query_results.py +0 -0
  286. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/remote_butler/_ref_utils.py +0 -0
  287. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/remote_butler/_registry.py +0 -0
  288. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/remote_butler/_remote_butler.py +0 -0
  289. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/remote_butler/_remote_butler_collections.py +0 -0
  290. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/remote_butler/registry/__init__.py +0 -0
  291. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/remote_butler/registry/_query_common.py +0 -0
  292. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/remote_butler/registry/_query_data_coordinates.py +0 -0
  293. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/remote_butler/registry/_query_datasets.py +0 -0
  294. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/remote_butler/registry/_query_dimension_records.py +0 -0
  295. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/remote_butler/server/__init__.py +0 -0
  296. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/remote_butler/server/_config.py +0 -0
  297. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/remote_butler/server/_dependencies.py +0 -0
  298. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/remote_butler/server/_factory.py +0 -0
  299. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/remote_butler/server/_server.py +0 -0
  300. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/remote_butler/server/handlers/_external.py +0 -0
  301. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/remote_butler/server/handlers/_external_query.py +0 -0
  302. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/remote_butler/server/handlers/_internal.py +0 -0
  303. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/remote_butler/server/handlers/_query_serialization.py +0 -0
  304. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/remote_butler/server/handlers/_query_streaming.py +0 -0
  305. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/remote_butler/server/handlers/_utils.py +0 -0
  306. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/remote_butler/server_models.py +0 -0
  307. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/repo_relocation.py +0 -0
  308. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/script/__init__.py +0 -0
  309. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/script/_associate.py +0 -0
  310. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/script/_pruneDatasets.py +0 -0
  311. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/script/butlerImport.py +0 -0
  312. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/script/certifyCalibrations.py +0 -0
  313. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/script/collectionChain.py +0 -0
  314. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/script/configDump.py +0 -0
  315. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/script/configValidate.py +0 -0
  316. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/script/createRepo.py +0 -0
  317. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/script/exportCalibs.py +0 -0
  318. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/script/ingest_files.py +0 -0
  319. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/script/ingest_zip.py +0 -0
  320. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/script/queryCollections.py +0 -0
  321. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/script/queryDataIds.py +0 -0
  322. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/script/queryDatasetTypes.py +0 -0
  323. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/script/queryDatasets.py +0 -0
  324. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/script/queryDimensionRecords.py +0 -0
  325. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/script/register_dataset_type.py +0 -0
  326. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/script/removeCollections.py +0 -0
  327. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/script/removeDatasetType.py +0 -0
  328. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/script/removeRuns.py +0 -0
  329. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/script/retrieveArtifacts.py +0 -0
  330. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/script/transferDatasets.py +0 -0
  331. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/tests/__init__.py +0 -0
  332. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/tests/_datasetsHelper.py +0 -0
  333. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/tests/_dummyRegistry.py +0 -0
  334. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/tests/_examplePythonTypes.py +0 -0
  335. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/tests/_testRepo.py +0 -0
  336. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/tests/cliCmdTestBase.py +0 -0
  337. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/tests/cliLogTestBase.py +0 -0
  338. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/tests/deferredFormatter.py +0 -0
  339. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/tests/dict_convertible_model.py +0 -0
  340. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/tests/hybrid_butler.py +0 -0
  341. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/tests/hybrid_butler_collections.py +0 -0
  342. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/tests/hybrid_butler_registry.py +0 -0
  343. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/tests/postgresql.py +0 -0
  344. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/tests/server.py +0 -0
  345. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/tests/server_utils.py +0 -0
  346. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/tests/testFormatters.py +0 -0
  347. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/tests/utils.py +0 -0
  348. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/time_utils.py +0 -0
  349. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/timespan_database_representation.py +0 -0
  350. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/transfers/__init__.py +0 -0
  351. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/transfers/_context.py +0 -0
  352. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/transfers/_interfaces.py +0 -0
  353. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/transfers/_yaml.py +0 -0
  354. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst/daf/butler/utils.py +0 -0
  355. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst_daf_butler.egg-info/SOURCES.txt +0 -0
  356. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst_daf_butler.egg-info/dependency_links.txt +0 -0
  357. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst_daf_butler.egg-info/entry_points.txt +0 -0
  358. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst_daf_butler.egg-info/requires.txt +0 -0
  359. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst_daf_butler.egg-info/top_level.txt +0 -0
  360. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/python/lsst_daf_butler.egg-info/zip-safe +0 -0
  361. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/setup.cfg +0 -0
  362. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_astropyTableFormatter.py +0 -0
  363. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_authentication.py +0 -0
  364. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_butler.py +0 -0
  365. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_butler_factory.py +0 -0
  366. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_cliCmdAssociate.py +0 -0
  367. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_cliCmdConfigDump.py +0 -0
  368. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_cliCmdConfigValidate.py +0 -0
  369. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_cliCmdCreate.py +0 -0
  370. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_cliCmdImport.py +0 -0
  371. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_cliCmdIngestFiles.py +0 -0
  372. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_cliCmdPruneDatasets.py +0 -0
  373. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_cliCmdQueryCollections.py +0 -0
  374. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_cliCmdQueryDataIds.py +0 -0
  375. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_cliCmdQueryDatasetTypes.py +0 -0
  376. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_cliCmdQueryDatasets.py +0 -0
  377. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_cliCmdQueryDimensionRecords.py +0 -0
  378. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_cliCmdRemoveCollections.py +0 -0
  379. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_cliCmdRemoveRuns.py +0 -0
  380. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_cliCmdRetrieveArtifacts.py +0 -0
  381. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_cliLog.py +0 -0
  382. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_cliPluginLoader.py +0 -0
  383. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_cliUtilSplitCommas.py +0 -0
  384. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_cliUtilSplitKv.py +0 -0
  385. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_cliUtilToUpper.py +0 -0
  386. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_cliUtils.py +0 -0
  387. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_column_spec.py +0 -0
  388. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_composites.py +0 -0
  389. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_config.py +0 -0
  390. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_connectionString.py +0 -0
  391. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_constraints.py +0 -0
  392. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_datasets.py +0 -0
  393. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_datastore.py +0 -0
  394. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_ddl.py +0 -0
  395. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_dimension_record_containers.py +0 -0
  396. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_dimensions.py +0 -0
  397. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_exprParserLex.py +0 -0
  398. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_expressions.py +0 -0
  399. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_formatter.py +0 -0
  400. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_location.py +0 -0
  401. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_logFormatter.py +0 -0
  402. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_logging.py +0 -0
  403. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_matplotlibFormatter.py +0 -0
  404. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_nonempty_mapping.py +0 -0
  405. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_obscore.py +0 -0
  406. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_packages.py +0 -0
  407. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_parquet.py +0 -0
  408. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_postgresql.py +0 -0
  409. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_progress.py +0 -0
  410. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_pydantic_utils.py +0 -0
  411. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_quantum.py +0 -0
  412. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_quantumBackedButler.py +0 -0
  413. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_query_direct_postgresql.py +0 -0
  414. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_query_direct_sqlite.py +0 -0
  415. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_query_interface.py +0 -0
  416. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_query_relations.py +0 -0
  417. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_query_remote.py +0 -0
  418. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_query_utilities.py +0 -0
  419. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_remote_butler.py +0 -0
  420. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_server.py +0 -0
  421. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_simpleButler.py +0 -0
  422. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_sqlite.py +0 -0
  423. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_storageClass.py +0 -0
  424. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_templates.py +0 -0
  425. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_testRepo.py +0 -0
  426. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_thread_utils.py +0 -0
  427. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_time_utils.py +0 -0
  428. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_timespan.py +0 -0
  429. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/tests/test_utils.py +0 -0
  430. {lsst_daf_butler-29.2025.1800 → lsst_daf_butler-29.2025.1900}/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.1800
3
+ Version: 29.2025.1900
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
@@ -136,6 +136,16 @@ Time literals
136
136
  time scale. For detailed description of supported time specification
137
137
  check section :ref:`time-literals-syntax`.
138
138
 
139
+ UUID literals
140
+ UUID values are produced by ``UUID()`` function which accepts a string
141
+ representation of the UUID. The string can have any format acceptable
142
+ by Python ``uuid.UUID()`` method.
143
+
144
+ Examples:
145
+
146
+ - ``UUID('12345678-1234-5678-1234-567812345678')``
147
+ - ``UUID('12345678123456781234567812345678')``
148
+
139
149
  Range literals
140
150
  This sort of literal is allowed inside ``IN`` expressions only. It consists
141
151
  of two integer literals separated by double dots and optionally followed by
@@ -442,6 +452,8 @@ Few examples of valid expressions using some of the constructs:
442
452
 
443
453
  ingest_date < T'2020-11-06 21:10:00'
444
454
 
455
+ flat.dataset_id = UUID('e15ab039-bc8b-4135-87c5-90902a7c0b22')
456
+
445
457
 
446
458
  .. _daf_butler_query_ordering:
447
459
 
@@ -422,6 +422,32 @@ class FileDatastore(GenericBaseDatastore[StoredFileInfo]):
422
422
  raise
423
423
  log.debug("Successfully deleted file: %s", location.uri)
424
424
 
425
+ def _delete_artifacts(self, locations: list[Location]) -> None:
426
+ """Delete multiple artifacts from the datastore."""
427
+ # Filter out all artifacts that are direct.
428
+ n_locations = len(locations)
429
+ filtered = [loc.uri for loc in locations if not loc.pathInStore.isabs()]
430
+ n_direct = n_locations - len(filtered)
431
+ if n_direct > 0:
432
+ log.info(
433
+ "Not deleting %d artifact%s out of %d using absolute URIs",
434
+ n_direct,
435
+ "s" if n_direct != 1 else "",
436
+ n_locations,
437
+ )
438
+ if not filtered:
439
+ return
440
+
441
+ try:
442
+ ResourcePath.mremove(filtered, do_raise=True)
443
+ except* FileNotFoundError as e:
444
+ # File not there is counted as "success" because we don't want
445
+ # the file to be there.
446
+ n_except = len(e.exceptions)
447
+ s = "s" if n_except != 1 else ""
448
+ log.debug("%d artifact%s did not exist and so could not be deleted.", n_except, s)
449
+ log.debug("Successfully deleted %d file%s", len(filtered), "s" if len(filtered) != 1 else "")
450
+
425
451
  def addStoredItemInfo(
426
452
  self,
427
453
  refs: Iterable[DatasetRef],
@@ -2596,6 +2622,7 @@ class FileDatastore(GenericBaseDatastore[StoredFileInfo]):
2596
2622
  else:
2597
2623
  artifacts_to_keep = slow_artifacts_to_keep
2598
2624
 
2625
+ artifacts_to_delete: list[Location] = []
2599
2626
  for ref, info in trashed_list:
2600
2627
  # Should not happen for this implementation but need
2601
2628
  # to keep mypy happy.
@@ -2609,42 +2636,56 @@ class FileDatastore(GenericBaseDatastore[StoredFileInfo]):
2609
2636
  # Only trashed refs still known to datastore will be returned.
2610
2637
  location = info.file_location(self.locationFactory)
2611
2638
 
2612
- # Point of no return for this artifact
2613
- log.debug("Removing artifact %s from datastore %s", location.uri, self.name)
2614
- try:
2615
- self._delete_artifact(location)
2616
- except FileNotFoundError:
2617
- # If the file itself has been deleted there is nothing
2618
- # we can do about it. It is possible that trash has
2619
- # been run in parallel in another process or someone
2620
- # decided to delete the file. It is unlikely to come
2621
- # back and so we should still continue with the removal
2622
- # of the entry from the trash table. It is also possible
2623
- # we removed it in a previous iteration if it was
2624
- # a multi-dataset artifact. The delete artifact method
2625
- # will log a debug message in this scenario.
2626
- # Distinguishing file missing before trash started and
2627
- # file already removed previously as part of this trash
2628
- # is not worth the distinction with regards to potential
2629
- # memory cost.
2630
- pass
2631
- except Exception as e:
2632
- if ignore_errors:
2633
- # Use a debug message here even though it's not
2634
- # a good situation. In some cases this can be
2635
- # caused by a race between user A and user B
2636
- # and neither of them has permissions for the
2637
- # other's files. Butler does not know about users
2638
- # and trash has no idea what collections these
2639
- # files were in (without guessing from a path).
2640
- log.debug(
2641
- "Encountered error removing artifact %s from datastore %s: %s",
2642
- location.uri,
2643
- self.name,
2644
- e,
2645
- )
2646
- else:
2647
- raise
2639
+ artifacts_to_delete.append(location)
2640
+
2641
+ # Now do the deleting.
2642
+ s_del = "s" if len(artifacts_to_delete) != 1 else ""
2643
+ log.debug(
2644
+ "Now removing %d file artifact%s from datastore %s",
2645
+ len(artifacts_to_delete),
2646
+ s_del,
2647
+ self.name,
2648
+ )
2649
+
2650
+ try:
2651
+ self._delete_artifacts(artifacts_to_delete)
2652
+ except* FileNotFoundError:
2653
+ # If the file itself has been deleted there is nothing
2654
+ # we can do about it. It is possible that trash has
2655
+ # been run in parallel in another process or someone
2656
+ # decided to delete the file. It is unlikely to come
2657
+ # back and so we should still continue with the removal
2658
+ # of the entry from the trash table. It is also possible
2659
+ # we removed it in a previous iteration if it was
2660
+ # a multi-dataset artifact. The delete artifact method
2661
+ # will log a debug message in this scenario.
2662
+ # Distinguishing file missing before trash started and
2663
+ # file already removed previously as part of this trash
2664
+ # is not worth the distinction with regards to potential
2665
+ # memory cost. These should already be caught but just in case
2666
+ # filter them out here.
2667
+ pass
2668
+ except* Exception as e:
2669
+ if ignore_errors:
2670
+ # Use a debug message here even though it's not
2671
+ # a good situation. In some cases this can be
2672
+ # caused by a race between user A and user B
2673
+ # and neither of them has permissions for the
2674
+ # other's files. Butler does not know about users
2675
+ # and trash has no idea what collections these
2676
+ # files were in (without guessing from a path).
2677
+ s_err = "s" if len(e.exceptions) != 1 else ""
2678
+ log.debug(
2679
+ "Encountered %d error%s removing %d artifact%s from datastore %s: %s",
2680
+ len(e.exceptions),
2681
+ s_err,
2682
+ len(artifacts_to_delete),
2683
+ s_del,
2684
+ self.name,
2685
+ e,
2686
+ )
2687
+ else:
2688
+ raise
2648
2689
 
2649
2690
  @transactional
2650
2691
  def transfer_from(
@@ -29,6 +29,7 @@ from __future__ import annotations
29
29
 
30
30
  from collections.abc import Set
31
31
  from typing import Literal, NamedTuple, TypeAlias
32
+ from uuid import UUID
32
33
 
33
34
  import astropy.time
34
35
 
@@ -268,6 +269,9 @@ class _ConversionVisitor(TreeVisitor[_VisitorResult]):
268
269
  def visitTimeLiteral(self, value: astropy.time.Time, node: Node) -> _VisitorResult:
269
270
  return _make_literal(value)
270
271
 
272
+ def visitUuidLiteral(self, value: UUID, node: Node) -> _VisitorResult:
273
+ return _make_literal(value)
274
+
271
275
  def visitTupleNode(self, items: tuple[_VisitorResult, ...], node: Node) -> _VisitorResult:
272
276
  if len(items) != 2:
273
277
  raise InvalidQueryError(f"Timespan tuple should have exactly two items (begin, end) in '{node}'")
@@ -34,6 +34,7 @@ import types
34
34
  import warnings
35
35
  from collections.abc import Mapping, Set
36
36
  from typing import Any, cast
37
+ from uuid import UUID
37
38
 
38
39
  import astropy.time
39
40
  import astropy.utils.exceptions
@@ -468,6 +469,10 @@ class PredicateConversionVisitor(TreeVisitor[VisitorResult]):
468
469
  # Docstring inherited.
469
470
  return ColumnExpression.literal(value, dtype=astropy.time.Time)
470
471
 
472
+ def visitUuidLiteral(self, value: UUID, node: Node) -> VisitorResult:
473
+ # Docstring inherited.
474
+ return ColumnExpression.literal(value, dtype=UUID)
475
+
471
476
  def visitTupleNode(self, items: tuple[VisitorResult, ...], node: Node) -> VisitorResult:
472
477
  # Docstring inherited.
473
478
  match items:
@@ -35,6 +35,7 @@ __all__ = (
35
35
  import dataclasses
36
36
  from collections.abc import Mapping, Sequence, Set
37
37
  from typing import TYPE_CHECKING, Any
38
+ from uuid import UUID
38
39
 
39
40
  from ...._column_tags import DatasetColumnTag, DimensionKeyColumnTag, DimensionRecordColumnTag
40
41
  from ....dimensions import DataCoordinate, DataIdValue, Dimension, DimensionGroup, DimensionUniverse
@@ -209,6 +210,10 @@ class InspectionVisitor(TreeVisitor[TreeSummary]):
209
210
  # Docstring inherited from TreeVisitor.visitTimeLiteral
210
211
  return TreeSummary()
211
212
 
213
+ def visitUuidLiteral(self, value: UUID, node: Node) -> TreeSummary:
214
+ # Docstring inherited from TreeVisitor.visitUuidLiteral
215
+ return TreeSummary()
216
+
212
217
  def visitIdentifier(self, name: str, node: Node) -> TreeSummary:
213
218
  # Docstring inherited from TreeVisitor.visitIdentifier
214
219
  if name in self.bind:
@@ -37,6 +37,7 @@ import enum
37
37
  from abc import ABC, abstractmethod
38
38
  from collections.abc import Iterator, Sequence
39
39
  from typing import Generic, TypeVar
40
+ from uuid import UUID
40
41
 
41
42
  import astropy.time
42
43
 
@@ -1030,6 +1031,10 @@ class TransformationVisitor(TreeVisitor[TransformationWrapper]):
1030
1031
  # Docstring inherited from TreeVisitor.visitTimeLiteral
1031
1032
  return Opaque(node, PrecedenceTier.TOKEN)
1032
1033
 
1034
+ def visitUuidLiteral(self, value: UUID, node: Node) -> TransformationWrapper:
1035
+ # Docstring inherited from TreeVisitor.visitUuidLiteral
1036
+ return Opaque(node, PrecedenceTier.TOKEN)
1037
+
1033
1038
  def visitRangeLiteral(
1034
1039
  self, start: int, stop: int, stride: int | None, node: Node
1035
1040
  ) -> TransformationWrapper:
@@ -59,6 +59,7 @@ __all__ = [
59
59
  # -------------------------------
60
60
  from abc import ABC, abstractmethod
61
61
  from typing import TYPE_CHECKING, Any
62
+ from uuid import UUID
62
63
 
63
64
  # -----------------------------
64
65
  # Imports for other modules --
@@ -114,6 +115,10 @@ class Node(ABC):
114
115
  """
115
116
 
116
117
 
118
+ class LiteralNode(Node):
119
+ """Intermediate base class for nodes representing literals of any knid."""
120
+
121
+
117
122
  class BinaryOp(Node):
118
123
  """Node representing binary operator.
119
124
 
@@ -131,7 +136,7 @@ class BinaryOp(Node):
131
136
  """
132
137
 
133
138
  def __init__(self, lhs: Node, op: str, rhs: Node):
134
- Node.__init__(self, (lhs, rhs))
139
+ super().__init__((lhs, rhs))
135
140
  self.lhs = lhs
136
141
  self.op = op
137
142
  self.rhs = rhs
@@ -161,7 +166,7 @@ class UnaryOp(Node):
161
166
  """
162
167
 
163
168
  def __init__(self, op: str, operand: Node):
164
- Node.__init__(self, (operand,))
169
+ super().__init__((operand,))
165
170
  self.op = op
166
171
  self.operand = operand
167
172
 
@@ -174,7 +179,7 @@ class UnaryOp(Node):
174
179
  return "{op} {operand}".format(**vars(self))
175
180
 
176
181
 
177
- class StringLiteral(Node):
182
+ class StringLiteral(LiteralNode):
178
183
  """Node representing string literal.
179
184
 
180
185
  Parameters
@@ -184,7 +189,7 @@ class StringLiteral(Node):
184
189
  """
185
190
 
186
191
  def __init__(self, value: str):
187
- Node.__init__(self)
192
+ super().__init__()
188
193
  self.value = value
189
194
 
190
195
  def visit(self, visitor: TreeVisitor) -> Any:
@@ -195,7 +200,7 @@ class StringLiteral(Node):
195
200
  return "'{value}'".format(**vars(self))
196
201
 
197
202
 
198
- class TimeLiteral(Node):
203
+ class TimeLiteral(LiteralNode):
199
204
  """Node representing time literal.
200
205
 
201
206
  Parameters
@@ -205,7 +210,7 @@ class TimeLiteral(Node):
205
210
  """
206
211
 
207
212
  def __init__(self, value: astropy.time.Time):
208
- Node.__init__(self)
213
+ super().__init__()
209
214
  self.value = value
210
215
 
211
216
  def visit(self, visitor: TreeVisitor) -> Any:
@@ -216,8 +221,8 @@ class TimeLiteral(Node):
216
221
  return "'{value}'".format(**vars(self))
217
222
 
218
223
 
219
- class NumericLiteral(Node):
220
- """Node representing string literal.
224
+ class NumericLiteral(LiteralNode):
225
+ """Node representing a numeric literal.
221
226
 
222
227
  We do not convert literals to numbers, their text representation
223
228
  is stored literally.
@@ -229,7 +234,7 @@ class NumericLiteral(Node):
229
234
  """
230
235
 
231
236
  def __init__(self, value: str):
232
- Node.__init__(self)
237
+ super().__init__()
233
238
  self.value = value
234
239
 
235
240
  def visit(self, visitor: TreeVisitor) -> Any:
@@ -240,11 +245,32 @@ class NumericLiteral(Node):
240
245
  return "{value}".format(**vars(self))
241
246
 
242
247
 
248
+ class UuidLiteral(LiteralNode):
249
+ """Node representing a UUID literal.
250
+
251
+ Parameters
252
+ ----------
253
+ value : `UUID`
254
+ Literal value.
255
+ """
256
+
257
+ def __init__(self, value: UUID):
258
+ super().__init__()
259
+ self.value = value
260
+
261
+ def visit(self, visitor: TreeVisitor) -> Any:
262
+ # Docstring inherited from Node.visit
263
+ return visitor.visitUuidLiteral(self.value, self)
264
+
265
+ def __str__(self) -> str:
266
+ return str(self.value)
267
+
268
+
243
269
  class Identifier(Node):
244
270
  """Node representing identifier.
245
271
 
246
- Value of the identifier is its name, it may contain zero or one dot
247
- character.
272
+ Value of the identifier is its name, it may contain zero, one, or two dot
273
+ characters.
248
274
 
249
275
  Parameters
250
276
  ----------
@@ -253,7 +279,7 @@ class Identifier(Node):
253
279
  """
254
280
 
255
281
  def __init__(self, name: str):
256
- Node.__init__(self)
282
+ super().__init__()
257
283
  self.name = name
258
284
 
259
285
  def visit(self, visitor: TreeVisitor) -> Any:
@@ -276,7 +302,7 @@ class BindName(Node):
276
302
  """
277
303
 
278
304
  def __init__(self, name: str):
279
- Node.__init__(self)
305
+ super().__init__()
280
306
  self.name = name
281
307
 
282
308
  def visit(self, visitor: TreeVisitor) -> Any:
@@ -287,7 +313,7 @@ class BindName(Node):
287
313
  return "{name}".format(**vars(self))
288
314
 
289
315
 
290
- class RangeLiteral(Node):
316
+ class RangeLiteral(LiteralNode):
291
317
  """Node representing range literal appearing in `IN` list.
292
318
 
293
319
  Range literal defines a range of integer numbers with start and
@@ -308,6 +334,7 @@ class RangeLiteral(Node):
308
334
  """
309
335
 
310
336
  def __init__(self, start: int, stop: int, stride: int | None = None):
337
+ super().__init__()
311
338
  self.start = start
312
339
  self.stop = stop
313
340
  self.stride = stride
@@ -335,7 +362,13 @@ class IsIn(Node):
335
362
  """
336
363
 
337
364
  def __init__(self, lhs: Node, values: list[Node], not_in: bool = False):
338
- Node.__init__(self, (lhs,) + tuple(values))
365
+ # All values must be literals or binds (and we allow simple identifiers
366
+ # as binds).
367
+ for node in values:
368
+ node = _strip_parens(node)
369
+ if not isinstance(node, LiteralNode | BindName | Identifier):
370
+ raise TypeError(f"Unsupported type of expression in IN operator: {node}")
371
+ super().__init__((lhs,) + tuple(values))
339
372
  self.lhs = lhs
340
373
  self.values = values
341
374
  self.not_in = not_in
@@ -364,7 +397,7 @@ class Parens(Node):
364
397
  """
365
398
 
366
399
  def __init__(self, expr: Node):
367
- Node.__init__(self, (expr,))
400
+ super().__init__((expr,))
368
401
  self.expr = expr
369
402
 
370
403
  def visit(self, visitor: TreeVisitor) -> Any:
@@ -390,7 +423,7 @@ class TupleNode(Node):
390
423
  """
391
424
 
392
425
  def __init__(self, items: tuple[Node, ...]):
393
- Node.__init__(self, items)
426
+ super().__init__(items)
394
427
  self.items = items
395
428
 
396
429
  def visit(self, visitor: TreeVisitor) -> Any:
@@ -415,7 +448,7 @@ class FunctionCall(Node):
415
448
  """
416
449
 
417
450
  def __init__(self, function: str, args: list[Node]):
418
- Node.__init__(self, tuple(args))
451
+ super().__init__(tuple(args))
419
452
  self.name = function
420
453
  self.args = args[:]
421
454
 
@@ -441,7 +474,7 @@ class PointNode(Node):
441
474
  """
442
475
 
443
476
  def __init__(self, ra: Node, dec: Node):
444
- Node.__init__(self, (ra, dec))
477
+ super().__init__((ra, dec))
445
478
  self.ra = ra
446
479
  self.dec = dec
447
480
 
@@ -469,7 +502,7 @@ class GlobNode(Node):
469
502
  """
470
503
 
471
504
  def __init__(self, expression: Identifier, pattern: StringLiteral | BindName):
472
- Node.__init__(self, (expression, pattern))
505
+ super().__init__((expression, pattern))
473
506
  self.expression = expression
474
507
  self.pattern = pattern
475
508
 
@@ -516,6 +549,17 @@ def function_call(function: str, args: list[Node]) -> Node:
516
549
  if not isinstance(pattern, StringLiteral | BindName):
517
550
  raise TypeError("glob() second argument must be a string or a bind name (prefixed with colon)")
518
551
  return GlobNode(expression, pattern)
552
+ elif function.upper() == "UUID":
553
+ if len(args) != 1:
554
+ raise ValueError("UUID() requires a single arguments (uuid-string)")
555
+ argument = _strip_parens(args[0])
556
+ # Potentially we could allow BindName as argument but it's too
557
+ # complicated and people should use bind with UUID instead.
558
+ if not isinstance(argument, StringLiteral):
559
+ raise TypeError("UUID() argument must be a string literal")
560
+ # This will raise ValueError if string is not good.
561
+ uuid = UUID(argument.value)
562
+ return UuidLiteral(uuid)
519
563
  else:
520
564
  # generic function call
521
565
  return FunctionCall(function, args)
@@ -354,8 +354,8 @@ class ParserYacc:
354
354
 
355
355
  @classmethod
356
356
  def p_predicate(cls, p: YaccProduction) -> None:
357
- """predicate : bit_expr IN LPAREN literal_or_id_list RPAREN
358
- | bit_expr NOT IN LPAREN literal_or_id_list RPAREN
357
+ """predicate : bit_expr IN LPAREN literal_or_bind_list RPAREN
358
+ | bit_expr NOT IN LPAREN literal_or_bind_list RPAREN
359
359
  | bit_expr
360
360
  """
361
361
  if len(p) == 6:
@@ -365,22 +365,39 @@ class ParserYacc:
365
365
  else:
366
366
  p[0] = p[1]
367
367
 
368
+ @classmethod
369
+ def p_simple_id(cls, p: YaccProduction) -> None:
370
+ """simple_id : SIMPLE_IDENTIFIER"""
371
+ p[0] = Identifier(p[1])
372
+
373
+ @classmethod
374
+ def p_qualified_id(cls, p: YaccProduction) -> None:
375
+ """qualified_id : QUALIFIED_IDENTIFIER"""
376
+ p[0] = Identifier(p[1])
377
+
368
378
  @classmethod
369
379
  def p_identifier(cls, p: YaccProduction) -> None:
370
- """identifier : SIMPLE_IDENTIFIER
371
- | QUALIFIED_IDENTIFIER
380
+ """identifier : simple_id
381
+ | qualified_id
372
382
  """
373
- p[0] = Identifier(p[1])
383
+ p[0] = p[1]
374
384
 
375
385
  @classmethod
376
386
  def p_literal_or_id_list(cls, p: YaccProduction) -> None:
377
- """literal_or_id_list : literal_or_id_list COMMA literal
378
- | literal_or_id_list COMMA identifier
379
- | literal_or_id_list COMMA bind_name
387
+ """literal_or_bind_list : literal_or_bind_list COMMA literal
388
+ | literal_or_bind_list COMMA simple_id
389
+ | literal_or_bind_list COMMA bind_name
390
+ | literal_or_bind_list COMMA function_call
380
391
  | literal
381
- | identifier
392
+ | simple_id
382
393
  | bind_name
394
+ | function_call
383
395
  """
396
+ # This expression is only used in IN() operator and it is supposed to
397
+ # include only literals and bind names (and identifiers as we still
398
+ # allow simple identifiers as bind names). UUID literal is implemented
399
+ # via UUID() function call, so we need to allow function calls here
400
+ # too. IsIn will check that all operands are literals or binds.
384
401
  if len(p) == 2:
385
402
  p[0] = [p[1]]
386
403
  else:
@@ -31,6 +31,7 @@ __all__ = ["TreeVisitor"]
31
31
 
32
32
  from abc import ABC, abstractmethod
33
33
  from typing import TYPE_CHECKING, Generic, TypeVar
34
+ from uuid import UUID
34
35
 
35
36
  if TYPE_CHECKING:
36
37
  import astropy.time
@@ -80,6 +81,18 @@ class TreeVisitor(Generic[T], ABC):
80
81
  Corresponding tree node, mostly useful for diagnostics.
81
82
  """
82
83
 
84
+ @abstractmethod
85
+ def visitUuidLiteral(self, value: UUID, node: Node) -> T:
86
+ """Visit UuidLiteral node.
87
+
88
+ Parameters
89
+ ----------
90
+ value : `UUID`
91
+ The value associated with the visited node, the value is UUID.
92
+ node : `Node`
93
+ Corresponding tree node, mostly useful for diagnostics.
94
+ """
95
+
83
96
  @abstractmethod
84
97
  def visitTimeLiteral(self, value: astropy.time.Time, node: Node) -> T:
85
98
  """Visit TimeLiteral node.
@@ -2469,6 +2469,57 @@ class ButlerQueryTests(ABC, TestCaseMixin):
2469
2469
  with self.assertRaisesRegex(InvalidQueryError, "Failed to parse expression"):
2470
2470
  butler.query_dimension_records("detector", instrument="Cam1", where="GLOB(full_name, full_name)")
2471
2471
 
2472
+ def test_dataset_id_queries(self) -> None:
2473
+ """Test queries on dataset_id."""
2474
+ butler = self.make_butler("base.yaml", "datasets.yaml")
2475
+
2476
+ dataset_id = UUID("e15ab039-bc8b-4135-87c5-90902a7c0b22")
2477
+
2478
+ refs = butler.query_datasets(
2479
+ "bias",
2480
+ "imported_g",
2481
+ instrument="Cam1",
2482
+ where="dataset_id = :ID",
2483
+ bind={"ID": dataset_id},
2484
+ )
2485
+ self.assertEqual({ref.id for ref in refs}, {dataset_id})
2486
+
2487
+ dataset_ids = {
2488
+ UUID("87f3e68d-258d-41b7-8ea5-edf3557ccb30"),
2489
+ UUID("dc0ef017-dc94-4118-b431-d65b1ef89a5f"),
2490
+ UUID("e255067d-dcc5-4f39-9824-0baa5817d3e5"),
2491
+ }
2492
+ refs = butler.query_datasets(
2493
+ "bias",
2494
+ "imported_r",
2495
+ instrument="Cam1",
2496
+ where="bias.dataset_id IN (:IDS)",
2497
+ bind={"IDS": dataset_ids},
2498
+ )
2499
+ self.assertEqual({ref.id for ref in refs}, dataset_ids)
2500
+
2501
+ refs = butler.query_datasets(
2502
+ "bias",
2503
+ "imported_g",
2504
+ instrument="Cam1",
2505
+ where="dataset_id = UUID('e15ab039-bc8b-4135-87c5-90902a7c0b22')",
2506
+ )
2507
+ self.assertEqual({ref.id for ref in refs}, {dataset_id})
2508
+
2509
+ refs = butler.query_datasets(
2510
+ "bias",
2511
+ "imported_r",
2512
+ instrument="Cam1",
2513
+ where=(
2514
+ "bias.dataset_id IN ("
2515
+ "UUID('87f3e68d-258d-41b7-8ea5-edf3557ccb30'), "
2516
+ "UUID('dc0ef017-dc94-4118-b431-d65b1ef89a5f'), "
2517
+ "UUID('e255067d-dcc5-4f39-9824-0baa5817d3e5')"
2518
+ ")"
2519
+ ),
2520
+ )
2521
+ self.assertEqual({ref.id for ref in refs}, dataset_ids)
2522
+
2472
2523
 
2473
2524
  def _get_exposure_ids_from_dimension_records(dimension_records: Iterable[DimensionRecord]) -> list[int]:
2474
2525
  output = []
@@ -0,0 +1,2 @@
1
+ __all__ = ["__version__"]
2
+ __version__ = "29.2025.1900"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lsst-daf-butler
3
- Version: 29.2025.1800
3
+ Version: 29.2025.1900
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
@@ -53,6 +53,9 @@ class _Visitor(TreeVisitor):
53
53
  def visitTimeLiteral(self, value, node):
54
54
  return f"T({value})"
55
55
 
56
+ def visitUuidLiteral(self, value, node):
57
+ return f"UUID({value})"
58
+
56
59
  def visitRangeLiteral(self, start, stop, stride, node):
57
60
  if stride is None:
58
61
  return f"R({start}..{stop})"
@@ -355,6 +358,21 @@ class ParserYaccTestCase(unittest.TestCase):
355
358
  self.assertIsInstance(tree.values[2], exprTree.Identifier)
356
359
  self.assertIsInstance(tree.values[3], exprTree.NumericLiteral)
357
360
 
361
+ expr = (
362
+ "id in ("
363
+ "UUID('38a42b54-0822-4dce-93b7-47e9b0d8ad66'), "
364
+ "UUID('782fb690-281a-4787-9b6e-f5324a9b6369'), "
365
+ ":uuid"
366
+ ")"
367
+ )
368
+ tree = parser.parse(expr)
369
+ self.assertIsInstance(tree, exprTree.IsIn)
370
+ self.assertIsInstance(tree.lhs, exprTree.Identifier)
371
+ self.assertEqual(len(tree.values), 3)
372
+ self.assertIsInstance(tree.values[0], exprTree.UuidLiteral)
373
+ self.assertIsInstance(tree.values[1], exprTree.UuidLiteral)
374
+ self.assertIsInstance(tree.values[2], exprTree.BindName)
375
+
358
376
  # parens on right hand side are required
359
377
  with self.assertRaises(ParseError):
360
378
  parser.parse("point(1, 2) in region1")