Coverage for python/felis/types.py: 90%

37 statements  

« prev     ^ index     » next       coverage.py v7.5.0, created at 2024-05-01 15:16 -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/>. 

21 

22from __future__ import annotations 

23 

24from typing import Any 

25 

26 

27class FelisType: 

28 """Base class for types that represent Felis column types. 

29 

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 """ 

35 

36 felis_name: str 

37 votable_name: str 

38 is_numeric: bool 

39 is_sized: bool 

40 is_timestamp: bool 

41 

42 _types: dict[str, type[FelisType]] = {} 

43 

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 

62 

63 @classmethod 

64 def felis_type(cls, felis_name: str) -> type[FelisType]: 

65 """Return specific Felis type for a given type name. 

66 

67 Parameters 

68 ---------- 

69 felis_name : `str` 

70 name of the felis type as defined in felis schema. 

71 

72 Returns 

73 ------- 

74 felis_type : `type` 

75 One of subclasses of `FelisType`. 

76 

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 

86 

87 

88class Boolean(FelisType, felis_name="boolean", votable_name="boolean", is_numeric=False): 

89 """Felis definition of boolean type.""" 

90 

91 

92class Byte(FelisType, felis_name="byte", votable_name="unsignedByte", is_numeric=True): 

93 """Felis definition of byte type.""" 

94 

95 

96class Short(FelisType, felis_name="short", votable_name="short", is_numeric=True): 

97 """Felis definition of short integer type.""" 

98 

99 

100class Int(FelisType, felis_name="int", votable_name="int", is_numeric=True): 

101 """Felis definition of integer type.""" 

102 

103 

104class Long(FelisType, felis_name="long", votable_name="long", is_numeric=True): 

105 """Felis definition of long integer type.""" 

106 

107 

108class Float(FelisType, felis_name="float", votable_name="float", is_numeric=True): 

109 """Felis definition of single precision floating type.""" 

110 

111 

112class Double(FelisType, felis_name="double", votable_name="double", is_numeric=True): 

113 """Felis definition of double precision floating type.""" 

114 

115 

116class Char(FelisType, felis_name="char", votable_name="char", is_sized=True): 

117 """Felis definition of character type.""" 

118 

119 

120class String(FelisType, felis_name="string", votable_name="char", is_sized=True): 

121 """Felis definition of string type.""" 

122 

123 

124class Unicode(FelisType, felis_name="unicode", votable_name="unicodeChar", is_sized=True): 

125 """Felis definition of unicode string type.""" 

126 

127 

128class Text(FelisType, felis_name="text", votable_name="char"): 

129 """Felis definition of text type.""" 

130 

131 

132class Binary(FelisType, felis_name="binary", votable_name="unsignedByte", is_sized=True): 

133 """Felis definition of binary type.""" 

134 

135 

136class Timestamp(FelisType, felis_name="timestamp", votable_name="char", is_timestamp=True): 

137 """Felis definition of timestamp type."""