Coverage for python/lsst/pipe/base/_datasetQueryConstraints.py: 50%
74 statements
« prev ^ index » next coverage.py v7.4.4, created at 2024-04-20 02:43 -0700
« prev ^ index » next coverage.py v7.4.4, created at 2024-04-20 02:43 -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"""Symbols defined in this package should be imported from
29`all_dimensions_quantum_graph_builder` instead; it only appears in the docs
30due to limitations in Sphinx.
31"""
33from __future__ import annotations
35__all__ = ("DatasetQueryConstraintVariant",)
37import sys
38import warnings
39from collections.abc import Iterable, Iterator
40from typing import Protocol
42from lsst.utils.introspection import find_outside_stacklevel
45class DatasetQueryConstraintVariant(Iterable, Protocol):
46 """Base for all the valid variants for controlling
47 constraining graph building queries based on dataset type existence.
49 ALL variant corresponds to using all input dataset types to constrain
50 a query.
52 OFF variant corresponds to not using any dataset types to constrain a
53 graph building query.
55 LIST variant should be used when one or more specific names should be used
56 in constraining a graph building query.
58 Normally the ALL and OFF variants are used as as Singletons, attempting to
59 instantiate them (i.e. ALL()) will return in singleton class itself.
61 LIST is used as a constructor to the contents (i.e. List(['a', 'b'])).
62 Using the LIST variant directly as a singleton will behave the same as if
63 it were an empty instance.
65 Variants can be directly used, or automatically be selected by using the
66 `fromExpression` class method given a valid string.
67 """
69 ALL: "type[_ALL]"
70 OFF: "type[_OFF]"
71 LIST: "type[_LIST]"
73 @classmethod
74 def __subclasshook__(cls, subclass):
75 if subclass == cls.ALL or subclass == cls.OFF or subclass == cls.LIST:
76 return True
77 return False
79 @classmethod
80 def fromExpression(cls, expression: str) -> "DatasetQueryConstraintVariant":
81 """Select and return the correct Variant that corresponds to the input
82 expression.
84 Parameters
85 ----------
86 expression : `str`
87 Input expression. Valid values are ``all`` for all inputs dataset
88 types in pipeline, ``off`` to not consider dataset type existence
89 as a constraint, single or comma-separated list of dataset type
90 names.
92 Returns
93 -------
94 variant : `DatasetQueryConstraintVariant`
95 Correct variant for this expression.
96 """
97 if not isinstance(expression, str):
98 raise ValueError("Expression must be a string")
99 elif expression == "all":
100 return cls.ALL
101 elif expression == "off":
102 return cls.OFF
103 else:
104 if " " in expression:
105 warnings.warn(
106 "Whitespace found in expression will be trimmed",
107 RuntimeWarning,
108 stacklevel=find_outside_stacklevel("lsst.pipe.base"),
109 )
110 expression = expression.replace(" ", "")
111 members = expression.split(",")
112 return cls.LIST(members)
115if sys.version_info.minor < 12: 115 ↛ 119line 115 didn't jump to line 119, because the condition on line 115 was never false
116 MetaMeta = type
117else:
119 class MetaMeta(type(Protocol)):
120 def __init__(cls, *args, **kwargs):
121 return super().__init__(cls, *args, **kwargs)
124class _ALLMETA(DatasetQueryConstraintVariant, type(Protocol), metaclass=MetaMeta):
125 def __iter__(self) -> Iterator: # noqa: N804
126 raise NotImplementedError("This variant cannot be iterated")
129class _ALL(metaclass=_ALLMETA):
130 def __new__(cls):
131 return cls
134class _OFFMETA(DatasetQueryConstraintVariant, type(Protocol), metaclass=MetaMeta):
135 def __iter__(self) -> Iterator: # noqa: N804
136 raise NotImplementedError("This variant cannot be iterated")
139class _OFF(metaclass=_OFFMETA):
140 def __new__(cls):
141 return cls
144class _LISTMETA(type(Protocol), metaclass=MetaMeta):
145 def __iter__(self): # noqa: N804
146 return iter(tuple())
148 def __len__(self): # noqa: N804
149 return 0
151 def __eq__(self, o: object) -> bool: # noqa: N804
152 if isinstance(o, self):
153 return True
154 return super().__eq__(o)
157class _LIST(DatasetQueryConstraintVariant, metaclass=_LISTMETA):
158 def __init__(self, members: Iterable[str]):
159 self.members = list(members)
161 def __len__(self) -> int:
162 return len(self.members)
164 def __iter__(self) -> Iterable[str]:
165 return iter(self.members)
167 def __repr__(self) -> str:
168 return repr(self.members)
170 def __str__(self) -> str:
171 return str(self.members)
173 def __eq__(self, o: object) -> bool:
174 if isinstance(o, type(self)):
175 return self.members == o.members
176 return super().__eq__(o)
179def suppressInit(self):
180 raise NotImplementedError(
181 "DatasetQueryConstraintVariants cannot be directly instantiated. "
182 "Please use the variants or the fromExpression class method"
183 )
186DatasetQueryConstraintVariant.__init__ = suppressInit
187DatasetQueryConstraintVariant.ALL = _ALL
188DatasetQueryConstraintVariant.OFF = _OFF
189DatasetQueryConstraintVariant.LIST = _LIST