Coverage for gws-app/gws/spec/generator/base.py: 51%
98 statements
« prev ^ index » next coverage.py v7.8.0, created at 2025-04-17 01:37 +0200
« prev ^ index » next coverage.py v7.8.0, created at 2025-04-17 01:37 +0200
1import os
2import sys
4from . import util
6from gws.spec.core import *
8ATOMS = ['any', 'bool', 'bytes', 'float', 'int', 'str']
10BUILTINS = ATOMS + ['type', 'object', 'Exception', 'dict', 'list', 'set', 'tuple']
12BUILTIN_TYPES = [
13 'Any',
14 'Callable',
15 'ContextManager',
16 'Dict',
17 'Enum',
18 'Iterable',
19 'Iterator',
20 'List',
21 'Literal',
22 'Optional',
23 'Protocol',
24 'Set',
25 'Tuple',
26 'TypeAlias',
27 'Union',
29 # imported in TYPE_CHECKING
30 'datetime.datetime',
31 'osgeo',
32 'sqlalchemy',
34 # vendor libs
35 'gws.lib.vendor',
36 'gws.lib.sa',
37]
39# those star-imported in gws/__init__.py
40GLOBAL_MODULES = [
41 APP_NAME + '.core.const',
42 # APP_NAME + '.core.data',
43 # APP_NAME + '.core.tree',
44 # APP_NAME + '.core.types',
45 APP_NAME + '.core.util',
46 # APP_NAME + '.core.error',
47 # APP_NAME + '.core'
48]
50DEFAULT_EXT_SUPERS = {
51 'config': APP_NAME + '.core.types.ConfigWithAccess',
52 'props': APP_NAME + '.core.types.Props',
53}
55# prefix for gws.plugin class names
56PLUGIN_PREFIX = APP_NAME + '.plugin'
58# comment prefix for Variant aliases
59VARIANT_COMMENT_PREFIX = 'variant:'
61# inline comment symbol
62INLINE_COMMENT_SYMBOL = '#:'
64# where we are
65SELF_DIR = os.path.dirname(__file__)
67# path to `/repository-root/app`
68APP_DIR = os.path.abspath(SELF_DIR + '/../../..')
70EXCLUDE_PATHS = ['___', '/vendor/', 'test', 'core/ext', '__pycache__']
72FILE_KINDS = [
73 ['.py', 'python'],
74 ['/index.ts', 'ts'],
75 ['/index.tsx', 'ts'],
76 ['/index.css.js', 'css'],
77 ['.theme.css.js', 'theme'],
78 ['/strings.ini', 'strings'],
79]
81PLUGIN_DIR = '/gws/plugin'
83SYSTEM_CHUNKS = [
84 [APP_NAME + '', '/js/src/gws'],
85 [APP_NAME + '.core', '/gws/core'],
86 [APP_NAME + '.base', '/gws/base'],
87 [APP_NAME + '.gis', '/gws/gis'],
88 [APP_NAME + '.lib', '/gws/lib'],
89 [APP_NAME + '.server', '/gws/server'],
90 [APP_NAME + '.helper', '/gws/helper'],
92]
95class Data: # type: ignore
96 def __init__(self, **kwargs):
97 vars(self).update(kwargs)
99 def __repr__(self):
100 return repr(vars(self))
102 def get(self, k, default=None):
103 return vars(self).get(k, default)
105 def __getattr__(self, item):
106 return None
109class _Logger:
110 level = 'INFO'
111 levels = 'ERROR', 'WARNING', 'INFO', 'DEBUG'
113 def set_level(self, level):
114 self.level = level
116 def log(self, level, *args):
117 if self.levels.index(level) <= self.levels.index(self.level):
118 msg = f'[spec] {level}: ' + ' '.join(str(a) for a in args)
119 sys.stdout.write(msg + '\n')
120 sys.stdout.flush()
122 def error(self, *args): self.log('ERROR', *args)
124 def warning(self, *args): self.log('WARNING', *args)
126 def info(self, *args): self.log('INFO', *args)
128 def debug(self, *args): self.log('DEBUG', *args)
131log = _Logger()
134class Generator(Data):
135 meta: dict
136 types: dict[str, Type]
137 specs = {}
138 typescript = ''
139 strings = {}
141 configRef = {}
143 rootDir = ''
144 selfDir = ''
145 outDir = ''
146 manifestPath = ''
148 debug = False
150 chunks: list[dict]
152 def __init__(self):
153 super().__init__()
154 self.aliases = {}
155 self.types = {}
157 def new_type(self, c, **kwargs):
158 if kwargs.get('name'):
159 t = Type(**kwargs)
160 t.c = c
161 t.uid = t.name
162 return t
164 uid = c + ',' + _auto_uid(c, kwargs)
165 if uid in self.types:
166 return self.types[uid]
168 t = Type(**kwargs)
169 t.c = c
170 t.uid = uid
171 return t
173 def dump(self, tag):
174 if self.debug:
175 util.write_json(self.outDir + '/' + tag + '.debug.json', self)
178def _auto_uid(c, d):
179 comma = ','
180 if c == C.DICT:
181 return d['tKey'] + comma + d['tValue']
182 if c == C.LIST:
183 return d['tItem']
184 if c == C.SET:
185 return d['tItem']
186 if c == C.LITERAL:
187 return comma.join(repr(v) for v in d['literalValues'])
188 if c == C.OPTIONAL:
189 return d['tTarget']
190 if c == C.TUPLE:
191 return comma.join(d['tItems'])
192 if c == C.UNION:
193 return comma.join(sorted(d['tItems']))
194 if c == C.EXT:
195 return d['extName']
196 if c == C.VARIANT:
197 if 'tMembers' in d:
198 return comma.join(sorted(d['tMembers'].values()))
199 return comma.join(sorted(d['tItems']))
201 return ''