Skip to content

Commit efe3d46

Browse files
committed
Add shared_key option to DataQuery equality checks
1 parent ebc037e commit efe3d46

File tree

2 files changed

+32
-21
lines changed

2 files changed

+32
-21
lines changed

satpy/dataset/dataid.py

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,13 @@
1414
# You should have received a copy of the GNU General Public License along with
1515
# satpy. If not, see <http://www.gnu.org/licenses/>.
1616
"""Dataset identifying objects."""
17+
from __future__ import annotations
1718

1819
import logging
1920
import numbers
2021
from copy import copy, deepcopy
2122
from enum import Enum
23+
from functools import partial
2224
from typing import Any, NoReturn
2325

2426
import numpy as np
@@ -261,7 +263,7 @@ def __getitem__(self, key):
261263
"""Get an item."""
262264
return self._dict[key]
263265

264-
def __eq__(self, other):
266+
def __eq__(self, other: Any) -> bool:
265267
"""Compare the DataQuerys.
266268
267269
A DataQuery is considered equal to another DataQuery if all keys
@@ -271,6 +273,20 @@ def __eq__(self, other):
271273
contains additional elements. Any DataQuery elements with the value
272274
``"*"`` are ignored.
273275
276+
"""
277+
return self.equal(other, shared_keys=False)
278+
279+
def equal(self, other: Any, shared_keys: bool = False) -> bool:
280+
"""Compare this DataQuery to another DataQuery or a DataID.
281+
282+
Args:
283+
other: Other DataQuery or DataID to compare against.
284+
shared_keys: Limit keys being compared to those shared
285+
by both objects. If False (default), then all of the
286+
current query's keys are used when compared against
287+
a DataID. If compared against another DataQuery then
288+
all keys are compared between the two queries.
289+
274290
"""
275291
sdict = self._asdict()
276292
try:
@@ -287,6 +303,9 @@ def __eq__(self, other):
287303
if not o_is_id:
288304
# if another DataQuery, then compare both sets of keys
289305
keys_to_match |= set(odict.keys())
306+
if shared_keys:
307+
# only compare with the keys that both objects share
308+
keys_to_match &= set(odict.keys())
290309
if not keys_to_match:
291310
return False
292311

@@ -374,9 +393,10 @@ def __repr__(self):
374393
items = ("{}={}".format(key, repr(val)) for key, val in zip(self._fields, self._values))
375394
return self.__class__.__name__ + "(" + ", ".join(items) + ")"
376395

377-
def filter_dataids(self, dataid_container):
396+
def filter_dataids(self, dataid_container, shared_keys: bool = False):
378397
"""Filter DataIDs based on this query."""
379-
keys = list(filter(self.__eq__, dataid_container))
398+
func = partial(self.equal, shared_keys=shared_keys)
399+
keys = list(filter(func, dataid_container))
380400
return keys
381401

382402
def sort_dataids_with_preference(self, all_ids, preference):

satpy/dependency_tree.py

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -515,26 +515,17 @@ def _get_compositor_by_name(self, key: DataQuery) -> Compositor | None:
515515
name_query = DataQuery(name=key["name"])
516516
for sensor_name in sorted(self.compositors):
517517
sensor_data_dict = self.compositors[sensor_name]
518-
try:
519-
# get all IDs that have the minimum "distance" for our composite name
520-
all_comp_ids = sensor_data_dict.get_key(name_query, num_results=0)
521-
# Filter to those that don't disagree with the original query
522-
matching_comp_ids = []
523-
for comp_id in all_comp_ids:
524-
for query_key, query_val in key.to_dict().items():
525-
# TODO: Handle query_vals that are lists
526-
if comp_id.get(query_key, query_val) != query_val:
527-
break
528-
else:
529-
# all query keys match
530-
matching_comp_ids.append(comp_id)
531-
if len(matching_comp_ids) > 1:
532-
warnings.warn("Multiple compositors matching {name_query} to create {key} variant. "
533-
"Going to use the name-only 'base' compositor definition.")
534-
matching_comp_ids = matching_comp_ids[:1]
535-
except KeyError:
518+
# get all IDs that have the minimum "distance" for our composite name
519+
all_comp_ids = sensor_data_dict.get_key(name_query, num_results=0)
520+
if len(all_comp_ids) == 0:
536521
continue
537522

523+
# Filter to those that don't disagree with the original query
524+
matching_comp_ids = key.filter_dataids(all_comp_ids, shared_keys=True)
525+
if len(matching_comp_ids) > 1:
526+
warnings.warn("Multiple compositors matching {name_query} to create {key} variant. "
527+
"Going to use the name-only 'base' compositor definition.")
528+
matching_comp_ids = matching_comp_ids[:1]
538529
if len(matching_comp_ids) != 1:
539530
raise KeyError("Can't find compositor {key['name']} by name only.")
540531
comp_id = matching_comp_ids[0]

0 commit comments

Comments
 (0)