Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-28 09:36:47

0001 """
0002 Type of a spec column whose unset value reads back as the "NULL" sentinel.
0003 
0004 JobSpec, FileSpec and DatasetSpec install their columns as None and override
0005 __getattribute__ to substitute the string "NULL" for a column that is still None. A read
0006 therefore yields the column type or that sentinel, while a write takes the column type or
0007 None -- two types for one attribute, which only a descriptor can express.
0008 
0009 Declaring a column as SpecColumn[int] instead of `int | str` gives a type checker both
0010 halves:
0011 
0012     job.PandaID            # int | str
0013     job.PandaID = 5        # ok
0014     job.PandaID = None     # ok, and reads back as "NULL"
0015     job.PandaID = "5"      # error, which `int | str` could not catch
0016 
0017 The declarations carry no value, so nothing here runs beyond building the generic alias
0018 when the spec module is imported; the columns are still installed by __init__.
0019 
0020 The "NULL" sentinel is legacy debt. When it goes, every SpecColumn[T] becomes T | None and
0021 this module is deleted.
0022 """
0023 
0024 from typing import Generic, Literal, TypeVar
0025 
0026 _T = TypeVar("_T")
0027 
0028 # the sentinel __getattribute__ substitutes for a column that is still None
0029 Null = Literal["NULL"]
0030 
0031 
0032 class SpecColumn(Generic[_T]):
0033     """A spec column: read as _T or the "NULL" sentinel, written as _T, None or that
0034     sentinel -- writing it back is how a column is copied from one spec to another, and
0035     valuesMap() turns it into a NULL bind value just as it does for None."""
0036 
0037     def __get__(self, obj: object, objtype: "type | None" = None) -> "_T | Null":
0038         # never reached: the descriptor is only ever a type. The columns themselves are
0039         # installed on the instance by the spec's __init__.
0040         raise NotImplementedError
0041 
0042     def __set__(self, obj: object, value: "_T | Null | None") -> None:
0043         raise NotImplementedError