easycoder 251105.1__py2.py3-none-any.whl → 251215.2__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
easycoder/ec_handler.py CHANGED
@@ -1,4 +1,5 @@
1
- import json
1
+ import sys, json
2
+ from .ec_classes import FatalError, ECValue
2
3
 
3
4
  class Handler:
4
5
 
@@ -18,8 +19,9 @@ class Handler:
18
19
  self.nextIs = compiler.nextIs
19
20
  self.isSymbol = compiler.isSymbol
20
21
  self.nextIsSymbol = compiler.nextIsSymbol
21
- self.getSymbolRecord = compiler.getSymbolRecord
22
22
  self.compileVariable = compiler.compileVariable
23
+ self.compileSymbol = compiler.compileSymbol
24
+ self.getSymbolRecord = compiler.getSymbolRecord
23
25
  self.rewindTo = compiler.rewindTo
24
26
  self.warning = compiler.warning
25
27
  self.getCodeSize = compiler.getCodeSize
@@ -30,9 +32,15 @@ class Handler:
30
32
  self.compileConstant = compiler.compileConstant
31
33
 
32
34
  self.code = self.program.code
35
+ self.checkObjectType = self.program.checkObjectType
36
+ self.isObjectType = self.program.isObjectType
37
+ self.isObjectType = self.program.isObjectType
38
+ self.getInnerObject = self.program.getInnerObject
39
+ self.getItemType = self.program.getItemType
33
40
  self.evaluate = self.program.evaluate
34
- self.getVariable = self.program.getSymbolRecord
35
- self.getRuntimeValue = self.program.getRuntimeValue
41
+ self.getVariable = self.program.getVariable
42
+ self.getObject = self.program.getObject
43
+ self.textify = self.program.textify
36
44
  self.testCondition = self.program.condition.testCondition
37
45
  self.symbols = self.program.symbols
38
46
  self.stack = self.program.stack
@@ -40,10 +48,9 @@ class Handler:
40
48
  self.getSymbolValue = self.program.getSymbolValue
41
49
  self.putSymbolValue = self.program.putSymbolValue
42
50
  self.run = self.program.run
51
+ self.callback = self.program.callback
43
52
 
44
53
  self.nonNumericValueError = self.program.nonNumericValueError
45
- self.variableDoesNotHoldAValueError = self.program.variableDoesNotHoldAValueError
46
- self.noneValueError = self.program.noneValueError
47
54
 
48
55
  def nextPC(self):
49
56
  return self.program.pc + 1
@@ -66,10 +73,6 @@ class Handler:
66
73
  def conditionHandler(self, name):
67
74
  return getattr(self, f'c_{name}')
68
75
 
69
- @staticmethod
70
- def isJson(value):
71
- try:
72
- json.loads(value)
73
- except ValueError as e:
74
- return False
75
- return True
76
+ # Get the value of an unknown item (domain-specific)
77
+ def getUnknownValue(self, value):
78
+ return None # Unable to get value
easycoder/ec_program.py CHANGED
@@ -1,7 +1,15 @@
1
- import time, json, sys
1
+ import time, sys
2
2
  from copy import deepcopy
3
3
  from collections import deque
4
- from .ec_classes import Script, Token, FatalError, RuntimeError, Object
4
+ from .ec_classes import (
5
+ Script,
6
+ Token,
7
+ FatalError,
8
+ RuntimeError,
9
+ NoValueRuntimeError,
10
+ ECObject,
11
+ ECValue
12
+ )
5
13
  from .ec_compiler import Compiler
6
14
  from .ec_core import Core
7
15
  import importlib
@@ -16,26 +24,25 @@ def flush():
16
24
 
17
25
  class Program:
18
26
 
19
- def __init__(self, argv):
27
+ def __init__(self, arg):
20
28
  global queue
21
29
  print(f'EasyCoder version {version("easycoder")}')
22
- print(argv)
23
- if len(argv) == 0:
30
+ if len(arg) == 0:
24
31
  print('No script supplied')
25
32
  exit()
26
- if argv in ['-v', '--version']: return
27
- if argv[0:6] == 'debug ':
28
- scriptName = argv[6:]
33
+ if arg in ['-v', '--version']: return
34
+ if arg[0:6] == 'debug ':
35
+ print('Debug mode requested')
36
+ self.scriptName = arg[6:]
29
37
  self.debugging = True
30
38
  else:
31
- scriptName = argv
39
+ self.scriptName = arg
32
40
  self.debugging = False
33
41
 
34
- f = open(scriptName, 'r')
42
+ f = open(self.scriptName, 'r')
35
43
  source = f.read()
36
44
  f.close()
37
45
  queue = deque()
38
- self.argv = argv
39
46
  self.domains = []
40
47
  self.domainIndex = {}
41
48
  self.name = '<anon>'
@@ -47,15 +54,20 @@ class Program:
47
54
  self.stack = []
48
55
  self.script = Script(source)
49
56
  self.compiler = Compiler(self)
57
+ self.object = ECObject()
50
58
  self.value = self.compiler.value
51
59
  self.condition = self.compiler.condition
52
60
  self.graphics = None
61
+ self.psutil = None
53
62
  self.useClass(Core)
54
- self.externalControl = False
55
63
  self.ticker = 0
56
- self.usingGraphics = False
64
+ self.graphicsRunning = False
57
65
  self.debugger = None
58
- self.running = True
66
+ self.running = False
67
+ self.parent = None
68
+ self.message = None
69
+ self.onMessagePC = 0
70
+ self.breakpoint = False
59
71
 
60
72
  # This is called at 10msec intervals by the GUI code
61
73
  def flushCB(self):
@@ -79,7 +91,7 @@ class Program:
79
91
  f'{round((finishCompile - startCompile) * 1000)} ms')
80
92
  for name in self.symbols.keys():
81
93
  record = self.code[self.symbols[name]]
82
- if name[-1] != ':' and not record['used']:
94
+ if name[-1] != ':' and not 'used' in record:
83
95
  print(f'Variable "{name}" not used')
84
96
  else:
85
97
  print(f'Run {self.name}')
@@ -88,8 +100,8 @@ class Program:
88
100
  self.compiler.showWarnings()
89
101
 
90
102
  # If this is the main script and there's no graphics, run a main loop
91
- if parent == None and self.externalControl == False:
92
- while True:
103
+ if parent == None:
104
+ while not self.graphicsRunning:
93
105
  if self.running == True:
94
106
  flush()
95
107
  time.sleep(0.01)
@@ -98,13 +110,25 @@ class Program:
98
110
 
99
111
  # Use the graphics module
100
112
  def useGraphics(self):
101
- if not self.usingGraphics:
113
+ if self.graphics == None:
102
114
  print('Loading graphics module')
103
- from .ec_pyside import Graphics
115
+ from .ec_graphics import Graphics
104
116
  self.graphics = Graphics
105
117
  self.useClass(Graphics)
106
- self.usingGraphics = True
107
118
  return True
119
+
120
+ # Use the psutil module
121
+ def usePSUtil(self):
122
+ if self.psutil == None:
123
+ print('Loading psutil module')
124
+ from .ec_psutil import PSUtil
125
+ self.psutil = PSUtil
126
+ self.useClass(PSUtil)
127
+ return True
128
+
129
+ # Indicate that graphics are running
130
+ def startGraphics(self):
131
+ self.graphicsRunning = True
108
132
 
109
133
  # Import a plugin
110
134
  def importPlugin(self, source):
@@ -129,122 +153,203 @@ class Program:
129
153
  self.domains.append(handler)
130
154
  self.domainIndex[handler.getName()] = handler
131
155
 
156
+ # This is the runtime callback for event handlers
157
+ def callback(self, item, record, goto):
158
+ object = self.getObject(record)
159
+ values = object.getValues() # type: ignore
160
+ for i, v in enumerate(values):
161
+ if isinstance(v, ECValue): v = v.getContent()
162
+ if v == item:
163
+ object.setIndex(i) # type: ignore
164
+ self.run(goto)
165
+ return
166
+
132
167
  # Get the domain list
133
168
  def getDomains(self):
134
169
  return self.domains
170
+
171
+ def isSymbol(self, name):
172
+ return name in self.symbols
135
173
 
136
- def getSymbolRecord(self, name):
174
+ # Get the symbol record for a given name
175
+ def getVariable(self, name):
176
+ if isinstance(name, dict): name = name['name']
137
177
  try:
138
178
  target = self.code[self.symbols[name]]
139
- if target['import'] != None:
179
+ if 'import' in target:
140
180
  target = target['import']
141
181
  return target
142
182
  except:
143
183
  RuntimeError(self, f'Unknown symbol \'{name}\'')
184
+
185
+ # Get the object represented by a symbol record
186
+ def getObject(self, record):
187
+ if isinstance(record, dict) and 'object' in record:
188
+ return record['object']
189
+ return record
190
+
191
+ # Check if an object is an instance of a given class
192
+ # This can either be variable record (a dict) or an instance of ECObject
193
+ def isObjectType(self, object, classes):
194
+ if isinstance(object, dict) and 'object' in object and isinstance(object['object'], ECObject):
195
+ object = object['object']
196
+ return isinstance(object, classes)
197
+
198
+ # Check if the object is an instance of one of a set of classes. Compile and runtime
199
+ def checkObjectType(self, object, classes):
200
+ if isinstance(object, dict): return
201
+ if not isinstance(object, classes):
202
+ if self.running:
203
+ raise RuntimeError(self, f"Objects of type {type(object)} are not instances of {classes}")
204
+ else:
205
+ raise FatalError(self.compiler, f"Objects of type {type(object)} are not instances of {classes}")
206
+
207
+ # Get the inner (non-EC) object from a name, record or object
208
+ def getInnerObject(self, object):
209
+ if isinstance(object, dict): object = object['object']
210
+ elif isinstance(object, str):
211
+ record = self.getVariable(object) # type: ignore
212
+ object = self.getObject(record) # type: ignore
213
+ value = object.getValue() # type: ignore
214
+ if isinstance(value, ECValue) and value.getType() == 'object':
215
+ return value.getContent()
216
+ else: return value
144
217
 
145
- def doValue(self, value):
146
- if value == None:
147
- RuntimeError(self, f'Undefined value (variable not initialized?)')
148
-
218
+ def constant(self, content, numeric):
149
219
  result = {}
150
- valType = value['type']
151
- if valType in ['boolean', 'int', 'text', 'object']:
152
- result = value
220
+ result['type'] = 'int' if numeric else 'str'
221
+ result['content'] = content
222
+ return result
223
+
224
+ # Test if an item is a string or a number
225
+ def getItemType(self, value):
226
+ return 'int' if isinstance(value, int) else 'str'
227
+
228
+ # Get the value of an item that may be an ECValue or a raw value. Return as an ECValue
229
+ def getValueOf(self, item):
230
+ value = ECValue()
231
+ if isinstance(item, ECValue):
232
+ if item.getType() == 'object':
233
+ return item.getContent()
234
+ else: value = item
235
+ else:
236
+ varType = type(item).__name__
237
+ if varType in ['int', 'str', 'bool', 'float', 'list', 'dict']:
238
+ if varType == 'int': value.setValue(type='int', content=item)
239
+ elif varType == 'str': value.setValue(type='str', content=item)
240
+ elif varType == 'bool': value.setValue(type='boolean', content=item)
241
+ elif varType == 'float': value.setValue(type='str', content=str(item))
242
+ elif varType == 'list': value.setValue(type='list', content=item)
243
+ elif varType == 'dict': value.setValue(type='dict', content=item)
244
+ else: value.setValue(None)
245
+ return value
246
+
247
+ # Runtime function to evaluate an ECObject or ECValue. Returns another ECValue
248
+ # This function may be called recursively by value handlers.
249
+ def evaluate(self, item):
250
+ if isinstance(item, ECObject):
251
+ value = item.getValue()
252
+ if value == None:
253
+ raise RuntimeError(self, f'Symbol {item.getName()} not initialized')
254
+ else: value = item
255
+ try:
256
+ valType = value.getType() # type: ignore
257
+ except:
258
+ RuntimeError(self, 'Value does not hold a valid ECValue')
259
+ result = ECValue(type=valType)
260
+
261
+ if valType in ('str', 'int', 'boolean', 'list', 'dict'):
262
+ # Simple value - just return the content
263
+ result.setContent(value.getContent()) # type: ignore
264
+
265
+ elif valType == 'object':
266
+ # Object other than ECVariable
267
+ record = self.getVariable(value.getName())
268
+ object = self.getObject(record) # type: ignore
269
+ result = object.getContent() # type: ignore
270
+
271
+ elif valType == 'symbol': # type: ignore
272
+ # If it's a symbol, get its value
273
+ record = self.getVariable(value.getContent()) # type: ignore
274
+ if not 'object' in record: return None # type: ignore
275
+ variable = self.getObject(record) # type: ignore
276
+ result = variable.getValue() # type: ignore
277
+ if isinstance(result, ECValue): return self.evaluate(result)
278
+ if isinstance(result, ECObject): return result.getValue()
279
+ else:
280
+ # See if one of the domains can handle this value
281
+ value = result
282
+ result = None
283
+ for domain in self.domains:
284
+ result = domain.getUnknownValue(value)
285
+ if result != None: break
286
+
153
287
  elif valType == 'cat':
288
+ # Handle concatenation
154
289
  content = ''
155
- for part in value['value']:
156
- val = self.doValue(part)
157
- if val == None:
158
- val = ''
159
- if val != '':
160
- val = str(val['content'])
161
- if val == None:
162
- val = ''
163
- content += val
164
- result['type'] = 'text'
165
- result['content'] = content
166
- elif valType == 'symbol':
167
- name = value['name']
168
- symbolRecord = self.getSymbolRecord(name)
169
- # if symbolRecord['hasValue']:
170
- if symbolRecord:
171
- handler = self.domainIndex[symbolRecord['domain']].valueHandler('symbol')
172
- result = handler(symbolRecord)
173
- # else:
174
- # # Call the given domain to handle a value
175
- # # domain = self.domainIndex[value['domain']]
176
- # handler = domain.valueHandler(value['type'])
177
- # if handler: result = handler(value)
290
+ for part in value.getContent(): # pyright: ignore[reportOptionalMemberAccess]
291
+ val = self.evaluate(part) # pyright: ignore[reportAttributeAccessIssue]
292
+ if val != None:
293
+ if isinstance(val, ECValue): val = str(val.getContent())
294
+ if val == None: val = ''
295
+ else: content += val
296
+ result.setValue(type='str', content=content)
297
+
178
298
  else:
179
299
  # Call the given domain to handle a value
180
- domain = self.domainIndex[value['domain']]
181
- handler = domain.valueHandler(value['type'])
300
+ domainName = value.getDomain() # type: ignore
301
+ if domainName == None: domainName = 'core'
302
+ domain = self.domainIndex[domainName]
303
+ handler = domain.valueHandler(value.getType()) # type: ignore
182
304
  if handler: result = handler(value)
183
305
 
184
306
  return result
185
307
 
186
- def constant(self, content, numeric):
187
- result = {}
188
- result['type'] = 'int' if numeric else 'text'
189
- result['content'] = content
190
- return result
191
-
192
- def evaluate(self, value):
193
- if value == None:
194
- result = {}
195
- result['type'] = 'text'
196
- result['content'] = ''
197
- return result
198
-
199
- result = self.doValue(value)
200
- if result:
201
- return result
202
- return None
203
-
204
- def getValue(self, value):
205
- result = self.evaluate(value)
206
- if result:
207
- return result.get('content') # type: ignore[union-attr]
208
- return None
209
-
210
- def getRuntimeValue(self, value):
308
+ # Get the runtime value of a value object (as a string or integer)
309
+ def textify(self, value):
211
310
  if value is None:
212
311
  return None
213
- v = self.evaluate(value)
214
- if v != None:
215
- content = v['content']
216
- if v['type'] == 'boolean':
217
- return True if content else False
218
- if v['type'] in ['int', 'float', 'text', 'object']:
219
- return content
220
- return ''
221
- return None
222
-
223
- def getSymbolContent(self, symbolRecord):
224
- if len(symbolRecord['value']) == 0:
225
- return None
226
- try: return symbolRecord['value'][symbolRecord['index']]
227
- except: RuntimeError(self, f'Cannot get content of symbol "{symbolRecord["name"]}"')
228
-
229
- def getSymbolValue(self, symbolRecord):
230
- if len(symbolRecord['value']) == 0:
312
+
313
+ if isinstance(value, dict):
314
+ value = value['object']
315
+ if isinstance(value, ECObject):
316
+ value = value.getValue()
317
+ if isinstance(value, ECValue): # type: ignore
318
+ v = self.evaluate(value) # type: ignore
319
+ else:
320
+ v = value
321
+ if v is None: return None
322
+ if isinstance(v, ECValue):
323
+ if v.getType() == 'object':
324
+ return value.getContent() # type: ignore
325
+ return v.getContent()
326
+ return v
327
+
328
+ # Get the content of a symbol
329
+ def getSymbolContent(self, record):
330
+ if len(record['value']) == 0:
231
331
  return None
232
- try: value = symbolRecord['value'][symbolRecord['index']]
233
- except: RuntimeError(self, f'Cannot get value of symbol "{symbolRecord["name"]}"')
234
- copy = deepcopy(value)
332
+ try: return record['value'][record['index']]
333
+ except: raise RuntimeError(self, f'Cannot get content of symbol "{record["name"]}"')
334
+
335
+ # Get the value of a symbol as an ECValue
336
+ def getSymbolValue(self, record):
337
+ object = self.getObject(record)
338
+ self.checkObjectType(object, ECObject)
339
+ value = object.getValue() # type: ignore
340
+ if value is None:
341
+ raise NoValueRuntimeError(self, f'Symbol "{record["name"]}" has no value')
342
+ # copy = deepcopy(value)
343
+ copy = ECValue(domain=value.getDomain(),type=value.getType(),content=deepcopy(value.getContent()))
235
344
  return copy
236
345
 
237
- def putSymbolValue(self, symbolRecord, value):
238
- if symbolRecord['locked']:
239
- name = symbolRecord['name']
240
- RuntimeError(self, f'Symbol "{name}" is locked')
241
- if symbolRecord['value'] == None or symbolRecord['value'] == []:
242
- symbolRecord['value'] = [value]
243
- else:
244
- index = symbolRecord['index']
245
- if index == None:
246
- index = 0
247
- symbolRecord['value'][index] = value
346
+ # Set the value of a symbol to either an ECValue or a raw value
347
+ def putSymbolValue(self, record, value):
348
+ variable = self.getObject(record)
349
+ if variable.isLocked(): # type: ignore
350
+ name = record['name']
351
+ raise RuntimeError(self, f'Symbol "{name}" is locked')
352
+ variable.setValue(self.getValueOf(value)) # type: ignore
248
353
 
249
354
  def encode(self, value):
250
355
  return value
@@ -321,12 +426,21 @@ class Program:
321
426
  self.pc = pc
322
427
  while self.running:
323
428
  command = self.code[self.pc]
429
+
430
+ # Check if debugger wants to halt before executing this command
431
+ if self.debugger != None:
432
+ # pc==1 is the first real command (pc==0 is the debug loader)
433
+ is_first = (self.pc == 1)
434
+ if self.debugger.checkIfHalt(is_first):
435
+ # Debugger says halt - break out and wait for user
436
+ break
437
+
324
438
  domainName = command['domain']
325
439
  if domainName == None:
326
440
  self.pc += 1
327
441
  else:
328
442
  keyword = command['keyword']
329
- if self.debugStep and command['debug']:
443
+ if self.debugStep and 'debug' in command:
330
444
  lino = command['lino'] + 1
331
445
  line = self.script.lines[command['lino']].strip()
332
446
  print(f'{self.name}: Line {lino}: {domainName}:{keyword}: {line}')
@@ -335,7 +449,12 @@ class Program:
335
449
  if handler:
336
450
  command = self.code[self.pc]
337
451
  command['program'] = self
338
- self.pc = handler(command)
452
+ if self.breakpoint:
453
+ pass # Place a breakpoint here for a debugger to catch
454
+ try:
455
+ self.pc = handler(command)
456
+ except Exception as e:
457
+ raise RuntimeError(self, f'Error during execution of {domainName}:{keyword}: {str(e)}')
339
458
  # Deal with 'exit'
340
459
  if self.pc == -1:
341
460
  queue = deque()
@@ -345,69 +464,52 @@ class Program:
345
464
  break
346
465
  elif self.pc == None or self.pc == 0 or self.pc >= len(self.code):
347
466
  break
348
- elif self.debugger != None and not self.debugger.continueExecution():
349
- break
350
467
 
351
468
  # Run the script at a given PC value
352
469
  def run(self, pc):
353
470
  global queue
354
- item = Object()
355
- item.program = self
356
- item.pc = pc
471
+ item = ECValue()
472
+ item.program = self # type: ignore
473
+ item.pc = pc # type: ignore
357
474
  queue.append(item)
475
+ self.running = True
358
476
 
359
477
  def kill(self):
360
478
  self.running = False
361
479
  if self.parent != None: self.parent.program.kill()
362
480
 
363
- def setExternalControl(self):
364
- self.externalControl = True
365
-
366
481
  def nonNumericValueError(self):
367
482
  FatalError(self.compiler, 'Non-numeric value')
368
483
 
369
- def variableDoesNotHoldAValueError(self, name):
370
- raise FatalError(self.compiler, f'Variable "{name}" does not hold a value')
371
-
372
- def noneValueError(self, name):
373
- raise FatalError(self.compiler, f'Value is None')
374
-
375
484
  def compare(self, value1, value2):
376
- val1 = self.evaluate(value1)
377
- val2 = self.evaluate(value2)
378
- if val1 == None or val2 == None:
485
+ if value1 == None or value2 == None:
486
+ RuntimeError(self, 'Cannot compare a value with None')
487
+ v1 = self.textify(value1)
488
+ v2 = self.textify(value2)
489
+ if v1 == None or v2 == None:
490
+ raise RuntimeError(self, 'Both items must have a value for comparison')
491
+ if type(v1) == str and type(v2) == str:
492
+ # String comparison
493
+ if v1 < v2: return -1
494
+ if v1 > v2: return 1
379
495
  return 0
380
- v1 = val1['content']
381
- v2 = val2['content']
382
- # if v1 == None and v2 != None or v1 != None and v2 == None:
383
- # return 0
384
- if v1 == None and v2 != None: return -1
385
- elif v2 == None and v1 != None: return 1
386
- if v1 != None and val1['type'] == 'int':
387
- if not val2['type'] == 'int':
388
- if type(v2) is str:
389
- try:
390
- v2 = int(v2)
391
- except:
392
- lino = self.code[self.pc]['lino'] + 1
393
- RuntimeError(None, f'Line {lino}: \'{v2}\' is not an integer')
394
- else:
395
- if v2 != None and val2['type'] == 'int':
396
- v2 = str(v2)
397
- if v1 == None:
398
- v1 = ''
399
- if v2 == None:
400
- v2 = ''
401
- if type(v1) == int:
402
- if type(v2) != int:
403
- v1 = f'{v1}'
404
- if type(v2) == int:
405
- if type(v1) != int:
406
- v2 = f'{v2}'
407
- if v1 > v2: # type: ignore[operator]
408
- return 1
496
+
497
+ if type(v1) is str:
498
+ try:
499
+ v1 = int(v1)
500
+ except:
501
+ print(f'{v1} is not an integer')
502
+ return None
503
+ if type(v2) is str:
504
+ try:
505
+ v2 = int(v2)
506
+ except:
507
+ print(f'{v2} is not an integer')
508
+ return None
409
509
  if v1 < v2: # type: ignore[operator]
410
510
  return -1
511
+ if v1 > v2: # type: ignore[operator]
512
+ return 1
411
513
  return 0
412
514
 
413
515
  # Set up a message handler
@@ -421,16 +523,8 @@ class Program:
421
523
 
422
524
  # This is the program launcher
423
525
  def Main():
424
- print(sys.argv)
425
526
  if (len(sys.argv) > 1):
426
- # Check if 'debug' is the first argument
427
- if sys.argv[1] == 'debug' and len(sys.argv) > 2:
428
- # Create program with debug flag
429
- program = Program(sys.argv[2])
430
- program.debugging = True
431
- program.start()
432
- else:
433
- Program(sys.argv[1]).start()
527
+ Program(' '.join(sys.argv[1:])).start()
434
528
  else:
435
529
  Program('-v')
436
530
 
easycoder/ec_psutil.py ADDED
@@ -0,0 +1,48 @@
1
+ from easycoder import Handler, ECValue
2
+ import os
3
+ from psutil import Process
4
+
5
+ class PSUtil(Handler):
6
+
7
+ def __init__(self, compiler):
8
+ Handler.__init__(self, compiler)
9
+
10
+ def getName(self):
11
+ return 'psutil'
12
+
13
+ #############################################################################
14
+ # Keyword handlers
15
+
16
+ #############################################################################
17
+ # Compile a value in this domain
18
+ def compileValue(self):
19
+ value = ECValue(domain=self.getName())
20
+ if self.tokenIs('the'):
21
+ self.nextToken()
22
+ token = self.getToken()
23
+ if token in ['mem', 'memory']:
24
+ value.setType('memory')
25
+ return value
26
+ return None
27
+
28
+ #############################################################################
29
+ # Modify a value or leave it unchanged.
30
+ def modifyValue(self, value):
31
+ return value
32
+
33
+ #############################################################################
34
+ # Value handlers
35
+
36
+ def v_memory(self, v):
37
+ process: Process = Process(os.getpid())
38
+ megabytes: float = process.memory_info().rss / (1024 * 1024)
39
+ return ECValue(domain=self.getName(), type='float', content=megabytes)
40
+
41
+ #############################################################################
42
+ # Compile a condition
43
+ def compileCondition(self):
44
+ condition = {}
45
+ return condition
46
+
47
+ #############################################################################
48
+ # Condition handlers