Coverage for gws-app/gws/spec/core.py: 100%

176 statements  

« prev     ^ index     » next       coverage.py v7.11.0, created at 2025-10-16 22:59 +0200

1from typing import TypeAlias, Any 

2import os 

3 

4 

5class Error(Exception): 

6 pass 

7 

8 

9class GeneratorError(Error): 

10 pass 

11 

12 

13class ReadError(Error): 

14 pass 

15 

16 

17class LoadError(Error): 

18 pass 

19 

20 

21class c: 

22 """Type kinds.""" 

23 

24 ATOM = 'ATOM' 

25 """Atomic, one of the built-in types.""" 

26 CLASS = 'CLASS' 

27 """Class, a user-defined type.""" 

28 CALLABLE = 'CALLABLE' 

29 """Callable, a callable argument.""" 

30 CONSTANT = 'CONSTANT' 

31 """Constant type.""" 

32 DICT = 'DICT' 

33 """Generic dictionary type.""" 

34 ENUM = 'ENUM' 

35 """Enum type.""" 

36 EXPR = 'EXPR' 

37 """Compile-time expression type.""" 

38 FUNCTION = 'FUNCTION' 

39 """Function, a callable type.""" 

40 LIST = 'LIST' 

41 """Generic list type.""" 

42 LITERAL = 'LITERAL' 

43 """Literal type.""" 

44 METHOD = 'METHOD' 

45 """Method, a callable type with a specific signature.""" 

46 MODULE = 'MODULE' 

47 """Module type.""" 

48 NONE = 'NONE' 

49 """None type.""" 

50 OPTIONAL = 'OPTIONAL' 

51 """Optional, a type that can be None.""" 

52 PROPERTY = 'PROPERTY' 

53 """Property, a type that is a property of a class.""" 

54 SET = 'SET' 

55 """Generic set type.""" 

56 TUPLE = 'TUPLE' 

57 """Generic tuple type.""" 

58 TYPE = 'TYPE' 

59 """Type alias.""" 

60 UNION = 'UNION' 

61 """Union, a type that can be one of several types.""" 

62 UNDEFINED = 'UNDEFINED' 

63 """Undefined, a type that is not defined.""" 

64 VARIANT = 'VARIANT' 

65 """Variant, a type that can be one of several types with a tag.""" 

66 

67 EXT = 'EXT' 

68 """Extension, a ``gws.ext`` alias.""" 

69 COMMAND = 'COMMAND' 

70 """Command, a method decorated as ``gws.ext.command``.""" 

71 

72 

73TypeKind: TypeAlias = str 

74"""Type kind, one of the constants in `c`.""" 

75TypeUid: TypeAlias = str 

76"""Type unique identifier, a string that identifies the type.""" 

77 

78 

79class Type: 

80 """Type data structure, repsents a GWS type.""" 

81 

82 c: TypeKind 

83 """Type class, one of the constants in `c`.""" 

84 uid: TypeUid 

85 """Type unique identifier, a string that identifies the type.""" 

86 

87 extName: str = '' 

88 """Name of the extension that defines this, if any.""" 

89 

90 doc: str = '' 

91 """Documentation string for the type.""" 

92 ident: str = '' 

93 """Source code identifier for the, used in the documentation.""" 

94 name: str = '' 

95 """Name of the type.""" 

96 pos: str = '' 

97 """Source code position of the type definition.""" 

98 

99 modName: str = '' 

100 """Name of the module that defines this type.""" 

101 modPath: str = '' 

102 """Path to the module that defines this type.""" 

103 

104 tArg: TypeUid = '' 

105 """For c.METHOD types, type uid of its last argument.""" 

106 tItem: TypeUid = '' 

107 """For c.LIST, c.SET and c.DICT types, type uid of its item.""" 

108 tKey: TypeUid = '' 

109 """For c.DICT types, type uid of its key.""" 

110 tModule: TypeUid = '' 

111 """Type uid of the type's module.""" 

112 tOwner: TypeUid = '' 

113 """For c.PROPERTY types, type uid of the type that owns this property.""" 

114 tReturn: TypeUid = '' 

115 """For c.METHOD types, type uid of its return value.""" 

116 tTarget: TypeUid = '' 

117 """For c.TYPE or c.EXT types, type uid of the target type.""" 

118 tValue: TypeUid = '' 

119 """For c.PROPERTY types, type uid of the constant value.""" 

120 

121 tArgs: list[TypeUid] = [] 

122 """For c.METHOD types, type uids of its arguments.""" 

123 tItems: list[TypeUid] = [] 

124 """For c.UNION or c.TUPLE types, type uids of its items.""" 

125 tSupers: list[TypeUid] = [] 

126 """For c.CLASS types, type uids of its super types.""" 

127 tMembers: dict[str, TypeUid] = {} 

128 """For c.VARIANT types, type uids of its members.""" 

129 tProperties: dict[str, TypeUid] = {} 

130 """For c.CLASS types, type uids of its properties.""" 

131 

132 defaultValue: Any = None 

133 """Default value for a property.""" 

134 defaultExpression: Any = None 

135 """Default expression for a property.""" 

136 hasDefault: bool = False 

137 """True if the type has a default value.""" 

138 constValue: Any = None 

139 """Constant value for a constant type.""" 

140 

141 enumDocs: dict = {} 

142 """Documentation strings for the enum values.""" 

143 enumValues: dict = {} 

144 """Enum values for the enum type.""" 

145 

146 literalValues: list = [] 

147 """Literal values for the c.LITERAL type.""" 

148 

149 

150def make_type(args: dict): 

151 typ = Type() 

152 vars(typ).update(args) 

153 return typ 

154 

155 

156class Chunk: 

157 """Source code chunk.""" 

158 

159 name: str 

160 """Name of the chunk.""" 

161 sourceDir: str 

162 """Source directory of the chunk.""" 

163 bundleDir: str 

164 """Directory to save the compiled chunk bundle.""" 

165 paths: dict[str, list[str]] 

166 """Source code paths.""" 

167 exclude: list[str] 

168 """List of patterns to exclude from the chunk.""" 

169 

170 

171class SpecData: 

172 """Specs data structure.""" 

173 

174 meta: dict 

175 """Meta data for the specs.""" 

176 chunks: list[Chunk] 

177 """List of chunks.""" 

178 serverTypes: list[Type] 

179 """List of types used by the server (configuration types, request types and commands).""" 

180 strings: dict 

181 """Documentation strings, translated to multiple languages.""" 

182 

183 

184class v: 

185 """Constants for the Specs generator.""" 

186 

187 APP_NAME = 'gws' 

188 EXT_PREFIX = APP_NAME + '.ext' 

189 EXT_DECL_PREFIX = EXT_PREFIX + '.new.' 

190 EXT_CONFIG_PREFIX = EXT_PREFIX + '.config.' 

191 EXT_PROPS_PREFIX = EXT_PREFIX + '.props.' 

192 EXT_OBJECT_PREFIX = EXT_PREFIX + '.object.' 

193 EXT_COMMAND_PREFIX = EXT_PREFIX + '.command.' 

194 

195 EXT_COMMAND_API_PREFIX = EXT_COMMAND_PREFIX + 'api.' 

196 EXT_COMMAND_GET_PREFIX = EXT_COMMAND_PREFIX + 'get.' 

197 EXT_COMMAND_CLI_PREFIX = EXT_COMMAND_PREFIX + 'cli.' 

198 

199 EXT_OBJECT_CLASS = 'Object' 

200 EXT_CONFIG_CLASS = 'Config' 

201 EXT_PROPS_CLASS = 'Props' 

202 

203 CLIENT_NAME = 'gc' 

204 VARIANT_TAG = 'type' 

205 """Tag property name for Variant types.""" 

206 DEFAULT_VARIANT_TAG = 'default' 

207 """Default variant tag.""" 

208 

209 ATOMS = ['any', 'bool', 'bytes', 'float', 'int', 'str'] 

210 

211 BUILTINS = ATOMS + ['type', 'object', 'Exception', 'dict', 'list', 'set', 'tuple'] 

212 

213 BUILTIN_TYPES = [ 

214 'Any', 

215 'Callable', 

216 'ContextManager', 

217 'Dict', 

218 'Enum', 

219 'Iterable', 

220 'Iterator', 

221 'List', 

222 'Literal', 

223 'Optional', 

224 'Protocol', 

225 'Set', 

226 'Tuple', 

227 'TypeAlias', 

228 'Union', 

229 # imported in TYPE_CHECKING 

230 'datetime.datetime', 

231 'osgeo', 

232 'sqlalchemy', 

233 # vendor libs 

234 'gws.lib.vendor', 

235 'gws.lib.sa', 

236 ] 

237 

238 # those star-imported in gws/__init__.py 

239 GLOBAL_MODULES = [ 

240 APP_NAME + '.core.const', 

241 APP_NAME + '.core.util', 

242 ] 

243 

244 DEFAULT_EXT_SUPERS = { 

245 'config': APP_NAME + '.core.types.ConfigWithAccess', 

246 'props': APP_NAME + '.core.types.Props', 

247 } 

248 

249 # prefix for gws.plugin class names 

250 PLUGIN_PREFIX = APP_NAME + '.plugin' 

251 

252 # inline comment symbol 

253 INLINE_COMMENT_SYMBOL = '#:' 

254 

255 # where we are 

256 SELF_DIR = os.path.dirname(__file__) 

257 

258 # path to `/repository-root/app` 

259 APP_DIR = os.path.abspath(SELF_DIR + '/../..') 

260 

261 EXCLUDE_PATHS = ['___', '/vendor/', 'test', 'core/ext', '__pycache__'] 

262 

263 FILE_KINDS = [ 

264 ['.py', 'python'], 

265 ['/index.ts', 'ts'], 

266 ['/index.tsx', 'ts'], 

267 ['/index.css.js', 'css'], 

268 ['.theme.css.js', 'theme'], 

269 ['/strings.ini', 'strings'], 

270 ] 

271 

272 PLUGIN_DIR = '/gws/plugin' 

273 

274 SYSTEM_CHUNKS = [ 

275 [CLIENT_NAME, f'/js/src/{CLIENT_NAME}'], 

276 [f'{APP_NAME}.core', '/gws/core'], 

277 [f'{APP_NAME}.base', '/gws/base'], 

278 [f'{APP_NAME}.gis', '/gws/gis'], 

279 [f'{APP_NAME}.lib', '/gws/lib'], 

280 [f'{APP_NAME}.server', '/gws/server'], 

281 [f'{APP_NAME}.helper', '/gws/helper'], 

282 ]