Coverage for python/lsst/pipe/base/_datasetQueryConstraints.py: 50%
74 statements
« prev ^ index » next coverage.py v7.4.3, created at 2024-03-14 10:49 -0700
« prev ^ index » next coverage.py v7.4.3, created at 2024-03-14 10:49 -0700
1# This file is part of pipe_base.
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/>.
28"""Module Defining variants for valid values used to constrain datasets in a
29graph building query.
30"""
32from __future__ import annotations
34__all__ = ("DatasetQueryConstraintVariant",)
36import sys
37import warnings
38from collections.abc import Iterable, Iterator
39from typing import Protocol
41from lsst.utils.introspection import find_outside_stacklevel
44class DatasetQueryConstraintVariant(Iterable, Protocol):
45 """Base for all the valid variants for controlling
46 constraining graph building queries based on dataset type existence.
48 ALL variant corresponds to using all input dataset types to constrain
49 a query.
51 OFF variant corresponds to not using any dataset types to constrain a
52 graph building query.
54 LIST variant should be used when one or more specific names should be used
55 in constraining a graph building query.
57 Normally the ALL and OFF variants are used as as Singletons, attempting to
58 instantiate them (i.e. ALL()) will return in singleton class itself.
60 LIST is used as a constructor to the contents (i.e. List(['a', 'b'])).
61 Using the LIST variant directly as a singleton will behave the same as if
62 it were an empty instance.
64 Variants can be directly used, or automatically be selected by using the
65 `fromExpression` class method given a valid string.
66 """
68 ALL: "type[_ALL]"
69 OFF: "type[_OFF]"
70 LIST: "type[_LIST]"
72 @classmethod
73 def __subclasshook__(cls, subclass):
74 if subclass == cls.ALL or subclass == cls.OFF or subclass == cls.LIST:
75 return True
76 return False
78 @classmethod
79 def fromExpression(cls, expression: str) -> "DatasetQueryConstraintVariant":
80 """Select and return the correct Variant that corresponds to the input
81 expression.
83 Parameters
84 ----------
85 expression : `str`
86 Input expression. Valid values are ``all`` for all inputs dataset
87 types in pipeline, ``off`` to not consider dataset type existence
88 as a constraint, single or comma-separated list of dataset type
89 names.
91 Returns
92 -------
93 variant : `DatasetQueryConstraintVariant`
94 Correct variant for this expression.
95 """
96 if not isinstance(expression, str):
97 raise ValueError("Expression must be a string")
98 elif expression == "all":
99 return cls.ALL
100 elif expression == "off":
101 return cls.OFF
102 else:
103 if " " in expression:
104 warnings.warn(
105 "Whitespace found in expression will be trimmed",
106 RuntimeWarning,
107 stacklevel=find_outside_stacklevel("lsst.pipe.base"),
108 )
109 expression = expression.replace(" ", "")
110 members = expression.split(",")
111 return cls.LIST(members)
114if sys.version_info.minor < 12: 114 ↛ 118line 114 didn't jump to line 118, because the condition on line 114 was never false
115 MetaMeta = type
116else:
118 class MetaMeta(type(Protocol)):
119 def __init__(cls, *args, **kwargs):
120 return super().__init__(cls, *args, **kwargs)
123class _ALLMETA(DatasetQueryConstraintVariant, type(Protocol), metaclass=MetaMeta):
124 def __iter__(self) -> Iterator: # noqa: N804
125 raise NotImplementedError("This variant cannot be iterated")
128class _ALL(metaclass=_ALLMETA):
129 def __new__(cls):
130 return cls
133class _OFFMETA(DatasetQueryConstraintVariant, type(Protocol), metaclass=MetaMeta):
134 def __iter__(self) -> Iterator: # noqa: N804
135 raise NotImplementedError("This variant cannot be iterated")
138class _OFF(metaclass=_OFFMETA):
139 def __new__(cls):
140 return cls
143class _LISTMETA(type(Protocol), metaclass=MetaMeta):
144 def __iter__(self): # noqa: N804
145 return iter(tuple())
147 def __len__(self): # noqa: N804
148 return 0
150 def __eq__(self, o: object) -> bool: # noqa: N804
151 if isinstance(o, self):
152 return True
153 return super().__eq__(o)
156class _LIST(DatasetQueryConstraintVariant, metaclass=_LISTMETA):
157 def __init__(self, members: Iterable[str]):
158 self.members = list(members)
160 def __len__(self) -> int:
161 return len(self.members)
163 def __iter__(self) -> Iterable[str]:
164 return iter(self.members)
166 def __repr__(self) -> str:
167 return repr(self.members)
169 def __str__(self) -> str:
170 return str(self.members)
172 def __eq__(self, o: object) -> bool:
173 if isinstance(o, type(self)):
174 return self.members == o.members
175 return super().__eq__(o)
178def suppressInit(self):
179 raise NotImplementedError(
180 "DatasetQueryConstraintVariants cannot be directly instantiated. "
181 "Please use the variants or the fromExpression class method"
182 )
185DatasetQueryConstraintVariant.__init__ = suppressInit
186DatasetQueryConstraintVariant.ALL = _ALL
187DatasetQueryConstraintVariant.OFF = _OFF
188DatasetQueryConstraintVariant.LIST = _LIST