Coverage for python/felis/types.py: 90%
37 statements
« prev ^ index » next coverage.py v7.5.0, created at 2024-04-30 02:49 -0700
« prev ^ index » next coverage.py v7.5.0, created at 2024-04-30 02:49 -0700
1# This file is part of felis.
2#
3# Developed for the LSST Data Management System.
4# This product includes software developed by the LSST Project
5# (https://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 program is free software: you can redistribute it and/or modify
10# it under the terms of the GNU General Public License as published by
11# the Free Software Foundation, either version 3 of the License, or
12# (at your option) any later version.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with this program. If not, see <https://www.gnu.org/licenses/>.
22from __future__ import annotations
24from typing import Any
27class FelisType:
28 """Base class for types that represent Felis column types.
30 This class plays a role of a metaclass without being an actual metaclass.
31 It provides a method to retrieve a class (type) given Felis type name.
32 There should be no instances of this class (or sub-classes), the utility
33 of the class hierarchy is in the type system itself.
34 """
36 felis_name: str
37 votable_name: str
38 is_numeric: bool
39 is_sized: bool
40 is_timestamp: bool
42 _types: dict[str, type[FelisType]] = {}
44 @classmethod
45 def __init_subclass__(
46 cls,
47 /,
48 felis_name: str,
49 votable_name: str,
50 is_numeric: bool = False,
51 is_sized: bool = False,
52 is_timestamp: bool = False,
53 **kwargs: Any,
54 ):
55 super().__init_subclass__(**kwargs)
56 cls.felis_name = felis_name
57 cls.votable_name = votable_name
58 cls.is_numeric = is_numeric
59 cls.is_sized = is_sized
60 cls.is_timestamp = is_timestamp
61 cls._types[felis_name] = cls
63 @classmethod
64 def felis_type(cls, felis_name: str) -> type[FelisType]:
65 """Return specific Felis type for a given type name.
67 Parameters
68 ----------
69 felis_name : `str`
70 name of the felis type as defined in felis schema.
72 Returns
73 -------
74 felis_type : `type`
75 One of subclasses of `FelisType`.
77 Raises
78 ------
79 TypeError
80 Raised if ``felis_name`` does not correspond to a known type.
81 """
82 try:
83 return cls._types[felis_name]
84 except KeyError:
85 raise TypeError(f"Unknown felis type {felis_name!r}") from None
88class Boolean(FelisType, felis_name="boolean", votable_name="boolean", is_numeric=False):
89 """Felis definition of boolean type."""
92class Byte(FelisType, felis_name="byte", votable_name="unsignedByte", is_numeric=True):
93 """Felis definition of byte type."""
96class Short(FelisType, felis_name="short", votable_name="short", is_numeric=True):
97 """Felis definition of short integer type."""
100class Int(FelisType, felis_name="int", votable_name="int", is_numeric=True):
101 """Felis definition of integer type."""
104class Long(FelisType, felis_name="long", votable_name="long", is_numeric=True):
105 """Felis definition of long integer type."""
108class Float(FelisType, felis_name="float", votable_name="float", is_numeric=True):
109 """Felis definition of single precision floating type."""
112class Double(FelisType, felis_name="double", votable_name="double", is_numeric=True):
113 """Felis definition of double precision floating type."""
116class Char(FelisType, felis_name="char", votable_name="char", is_sized=True):
117 """Felis definition of character type."""
120class String(FelisType, felis_name="string", votable_name="char", is_sized=True):
121 """Felis definition of string type."""
124class Unicode(FelisType, felis_name="unicode", votable_name="unicodeChar", is_sized=True):
125 """Felis definition of unicode string type."""
128class Text(FelisType, felis_name="text", votable_name="char"):
129 """Felis definition of text type."""
132class Binary(FelisType, felis_name="binary", votable_name="unsignedByte", is_sized=True):
133 """Felis definition of binary type."""
136class Timestamp(FelisType, felis_name="timestamp", votable_name="char", is_timestamp=True):
137 """Felis definition of timestamp type."""