Coverage for gws-app/gws/spec/core.py: 100%
180 statements
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-24 12:46 +0200
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-24 12:46 +0200
1from typing import TypeAlias, Any
2import os
5class Error(Exception):
6 pass
9class GeneratorError(Error):
10 pass
13class ReadError(Error):
14 pass
17class LoadError(Error):
18 pass
21class c:
22 """Type kinds."""
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."""
67 EXT = 'EXT'
68 """Extension, a ``gws.ext`` alias."""
69 COMMAND = 'COMMAND'
70 """Command, a method decorated as ``gws.ext.command``."""
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."""
79class Type:
80 """Type data structure, repsents a GWS type."""
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."""
87 extName: str = ''
88 """Name of the extension that defines this, if any."""
90 title: str = ''
91 """Documentation title string for the type."""
92 doc: str = ''
93 """Documentation string for the type."""
94 ident: str = ''
95 """Source code identifier for the type, used in the documentation."""
96 name: str = ''
97 """Name of the type."""
98 pos: str = ''
99 """Source code position of the type definition."""
101 modName: str = ''
102 """Name of the module that defines this type."""
103 modPath: str = ''
104 """Path to the module that defines this type."""
106 tArg: TypeUid = ''
107 """For c.METHOD types, type uid of its last argument."""
108 tItem: TypeUid = ''
109 """For c.LIST, c.SET and c.DICT types, type uid of its item."""
110 tKey: TypeUid = ''
111 """For c.DICT types, type uid of its key."""
112 tModule: TypeUid = ''
113 """Type uid of the type's module."""
114 tOwner: TypeUid = ''
115 """For c.PROPERTY types, type uid of the type that owns this property."""
116 tReturn: TypeUid = ''
117 """For c.METHOD types, type uid of its return value."""
118 tTarget: TypeUid = ''
119 """For c.TYPE or c.EXT types, type uid of the target type."""
120 tValue: TypeUid = ''
121 """For c.PROPERTY types, type uid of the constant value."""
123 tArgs: list[TypeUid] = []
124 """For c.METHOD types, type uids of its arguments."""
125 tItems: list[TypeUid] = []
126 """For c.UNION or c.TUPLE types, type uids of its items."""
127 tSupers: list[TypeUid] = []
128 """For c.CLASS types, type uids of its super types."""
129 tMembers: dict[str, TypeUid] = {}
130 """For c.VARIANT types, type uids of its members."""
131 tProperties: dict[str, TypeUid] = {}
132 """For c.CLASS types, type uids of its properties."""
134 defaultValue: Any = None
135 """Default value for a property."""
136 defaultExpression: Any = None
137 """Default expression for a property."""
138 hasDefault: bool = False
139 """True if the type has a default value."""
140 constValue: Any = None
141 """Constant value for a constant type."""
143 enumDocs: dict = {}
144 """Documentation strings for the enum values."""
145 enumValues: dict = {}
146 """Enum values for the enum type."""
148 literalValues: list = []
149 """Literal values for the c.LITERAL type."""
151 isConfig: bool = False
152 """True if this type is a configuration type."""
155def make_type(args: dict):
156 typ = Type()
157 vars(typ).update(args)
158 return typ
161class Chunk:
162 """Source code chunk."""
164 name: str
165 """Name of the chunk."""
166 sourceDir: str
167 """Source directory of the chunk."""
168 bundleDir: str
169 """Directory to save the compiled chunk bundle."""
170 paths: dict[str, list[str]]
171 """Source code paths."""
172 exclude: list[str]
173 """List of patterns to exclude from the chunk."""
176class SpecData:
177 """Specs data structure."""
179 meta: dict
180 """Meta data for the specs."""
181 chunks: list[Chunk]
182 """List of chunks."""
183 serverTypes: list[Type]
184 """List of types used by the server (configuration types, request types and commands)."""
185 strings: dict[str, dict[str, str]]
186 """Documentation strings, translated to multiple languages."""
189class v:
190 """Constants for the Specs generator."""
192 APP_NAME = 'gws'
193 EXT_PREFIX = APP_NAME + '.ext'
194 EXT_DECL_PREFIX = EXT_PREFIX + '.new.'
195 EXT_CONFIG_PREFIX = EXT_PREFIX + '.config.'
196 EXT_PROPS_PREFIX = EXT_PREFIX + '.props.'
197 EXT_OBJECT_PREFIX = EXT_PREFIX + '.object.'
198 EXT_COMMAND_PREFIX = EXT_PREFIX + '.command.'
200 EXT_COMMAND_API_PREFIX = EXT_COMMAND_PREFIX + 'api.'
201 EXT_COMMAND_GET_PREFIX = EXT_COMMAND_PREFIX + 'get.'
202 EXT_COMMAND_CLI_PREFIX = EXT_COMMAND_PREFIX + 'cli.'
204 EXT_OBJECT_CLASS = 'Object'
205 EXT_CONFIG_CLASS = 'Config'
206 EXT_PROPS_CLASS = 'Props'
208 CLIENT_NAME = 'gc'
209 VARIANT_TAG = 'type'
210 """Tag property name for Variant types."""
211 DEFAULT_VARIANT_TAG = 'default'
212 """Default variant tag."""
214 ATOMS = ['any', 'bool', 'bytes', 'float', 'int', 'str']
216 BUILTINS = ATOMS + ['type', 'object', 'Exception', 'dict', 'list', 'set', 'tuple']
218 BUILTIN_TYPES = [
219 'Any',
220 'Callable',
221 'ContextManager',
222 'Dict',
223 'Enum',
224 'Iterable',
225 'Iterator',
226 'List',
227 'Literal',
228 'Optional',
229 'Protocol',
230 'Set',
231 'Tuple',
232 'TypeAlias',
233 'Union',
234 # imported in TYPE_CHECKING
235 'datetime.datetime',
236 'osgeo',
237 'sqlalchemy',
238 # vendor libs
239 'gws.lib.vendor',
240 'gws.lib.sa',
241 ]
243 # those star-imported in gws/__init__.py
244 GLOBAL_MODULES = [
245 APP_NAME + '.core.const',
246 APP_NAME + '.core.util',
247 ]
249 DEFAULT_EXT_SUPERS = {
250 'config': APP_NAME + '.core.types.ConfigWithAccess',
251 'props': APP_NAME + '.core.types.Props',
252 }
254 # prefix for gws.plugin class names
255 PLUGIN_PREFIX = APP_NAME + '.plugin'
257 # inline comment symbol
258 INLINE_COMMENT_SYMBOL = '#:'
260 # where we are
261 SELF_DIR = os.path.dirname(__file__)
263 # path to `/repository-root/app`
264 APP_DIR = os.path.abspath(SELF_DIR + '/../..')
266 EXCLUDE_PATHS = ['___', '/vendor/', 'test', 'core/ext', '__pycache__']
268 FILE_KINDS = [
269 ['.py', 'python'],
270 ['/index.ts', 'ts'],
271 ['/index.tsx', 'ts'],
272 ['/index.css.js', 'css'],
273 ['.theme.css.js', 'theme'],
274 ['/strings.ini', 'strings'],
275 ]
277 PLUGIN_DIR = '/gws/plugin'
279 SYSTEM_CHUNKS = [
280 [CLIENT_NAME, f'/js/src/{CLIENT_NAME}'],
281 [f'{APP_NAME}.core', '/gws/core'],
282 [f'{APP_NAME}.base', '/gws/base'],
283 [f'{APP_NAME}.gis', '/gws/gis'],
284 [f'{APP_NAME}.lib', '/gws/lib'],
285 [f'{APP_NAME}.server', '/gws/server'],
286 [f'{APP_NAME}.helper', '/gws/helper'],
287 ]