proteus 7.8.0__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.
proteus/pyson.py ADDED
@@ -0,0 +1,771 @@
1
+ # This file is part of Tryton. The COPYRIGHT file at the top level of
2
+ # this repository contains the full copyright notices and license terms.
3
+ import datetime
4
+ import json
5
+ from decimal import Decimal
6
+ from functools import reduce
7
+
8
+ from dateutil.relativedelta import relativedelta
9
+
10
+
11
+ class PYSON(object):
12
+
13
+ def pyson(self):
14
+ raise NotImplementedError
15
+
16
+ def types(self):
17
+ raise NotImplementedError
18
+
19
+ @staticmethod
20
+ def eval(dct, context):
21
+ raise NotImplementedError
22
+
23
+ def __invert__(self):
24
+ if self.types() != {bool}:
25
+ return Not(Bool(self))
26
+ else:
27
+ return Not(self)
28
+
29
+ def __and__(self, other):
30
+ if (isinstance(other, PYSON)
31
+ and other.types() != {bool}):
32
+ other = Bool(other)
33
+ if (isinstance(self, And)
34
+ and not isinstance(self, Or)):
35
+ return And(*self._statements, other)
36
+ if self.types() != {bool}:
37
+ return And(Bool(self), other)
38
+ else:
39
+ return And(self, other)
40
+
41
+ __rand__ = __and__
42
+
43
+ def __or__(self, other):
44
+ if (isinstance(other, PYSON)
45
+ and other.types() != {bool}):
46
+ other = Bool(other)
47
+ if isinstance(self, Or):
48
+ return Or(*self._statements, other)
49
+ if self.types() != {bool}:
50
+ return Or(Bool(self), other)
51
+ else:
52
+ return Or(self, other)
53
+
54
+ __ror__ = __or__
55
+
56
+ def __eq__(self, other):
57
+ return Equal(self, other)
58
+
59
+ def __ne__(self, other):
60
+ return Not(Equal(self, other))
61
+
62
+ def __gt__(self, other):
63
+ return Greater(self, other)
64
+
65
+ def __ge__(self, other):
66
+ return Greater(self, other, True)
67
+
68
+ def __lt__(self, other):
69
+ return Less(self, other)
70
+
71
+ def __le__(self, other):
72
+ return Less(self, other, True)
73
+
74
+ def get(self, k, d=''):
75
+ return Get(self, k, d)
76
+
77
+ def in_(self, obj):
78
+ return In(self, obj)
79
+
80
+ def contains(self, k):
81
+ return In(k, self)
82
+
83
+ def __repr__(self):
84
+ klass = self.__class__.__name__
85
+ return '%s(%s)' % (klass, ', '.join(map(repr, self.__repr_params__)))
86
+
87
+ @property
88
+ def __repr_params__(self):
89
+ return NotImplementedError
90
+
91
+
92
+ class PYSONEncoder(json.JSONEncoder):
93
+
94
+ def default(self, obj):
95
+ if isinstance(obj, PYSON):
96
+ return obj.pyson()
97
+ elif isinstance(obj, datetime.date):
98
+ if isinstance(obj, datetime.datetime):
99
+ return DateTime(obj.year, obj.month, obj.day,
100
+ obj.hour, obj.minute, obj.second, obj.microsecond
101
+ ).pyson()
102
+ else:
103
+ return Date(obj.year, obj.month, obj.day).pyson()
104
+ elif isinstance(obj, datetime.timedelta):
105
+ return TimeDelta(obj.days, obj.seconds, obj.microseconds)
106
+ elif isinstance(obj, Decimal):
107
+ return float(obj)
108
+ return super().default(obj)
109
+
110
+
111
+ class PYSONDecoder(json.JSONDecoder):
112
+
113
+ def __init__(self, context=None, noeval=False):
114
+ self.__context = context or {}
115
+ self.noeval = noeval
116
+ super().__init__(object_hook=self._object_hook)
117
+
118
+ def _object_hook(self, dct):
119
+ if '__class__' in dct:
120
+ klass = CONTEXT.get(dct['__class__'])
121
+ if klass:
122
+ if not self.noeval:
123
+ return klass.eval(dct, self.__context)
124
+ else:
125
+ dct = dct.copy()
126
+ del dct['__class__']
127
+ return klass(**dct)
128
+ return dct
129
+
130
+
131
+ class Eval(PYSON):
132
+
133
+ def __init__(self, v, d=''):
134
+ super().__init__()
135
+ self._value = v
136
+ self._default = d
137
+
138
+ @property
139
+ def __repr_params__(self):
140
+ return self._value, self._default
141
+
142
+ def pyson(self):
143
+ return {
144
+ '__class__': 'Eval',
145
+ 'v': self._value,
146
+ 'd': self._default,
147
+ }
148
+
149
+ def types(self):
150
+ if isinstance(self._default, PYSON):
151
+ return self._default.types()
152
+ else:
153
+ return {type(self._default)}
154
+
155
+ @staticmethod
156
+ def eval(dct, context):
157
+ if '.' in dct['v'] and dct['v'] not in context:
158
+ base, name = dct['v'].split('.', 1)
159
+ return Eval.eval({
160
+ 'v': name,
161
+ 'd': dct['d'],
162
+ }, context.get(base) or {})
163
+ return context.get(dct['v'], dct['d'])
164
+
165
+ @property
166
+ def basename(self):
167
+ name = self._value
168
+ if name.startswith('_parent_'):
169
+ name = name[len('_parent_'):]
170
+ if '.' in name:
171
+ name = name.split('.', 1)[0]
172
+ return name
173
+
174
+
175
+ class Not(PYSON):
176
+
177
+ def __init__(self, v):
178
+ super().__init__()
179
+ if isinstance(v, PYSON):
180
+ if v.types() != {bool}:
181
+ v = Bool(v)
182
+ elif not isinstance(v, bool):
183
+ v = bool(v)
184
+ self._value = v
185
+
186
+ @property
187
+ def __repr_params__(self):
188
+ return (self._value,)
189
+
190
+ def pyson(self):
191
+ return {
192
+ '__class__': 'Not',
193
+ 'v': self._value,
194
+ }
195
+
196
+ def types(self):
197
+ return {bool}
198
+
199
+ @staticmethod
200
+ def eval(dct, context):
201
+ return not dct['v']
202
+
203
+
204
+ class Bool(PYSON):
205
+
206
+ def __init__(self, v):
207
+ super().__init__()
208
+ self._value = v
209
+
210
+ @property
211
+ def __repr_params__(self):
212
+ return (self._value,)
213
+
214
+ def pyson(self):
215
+ return {
216
+ '__class__': 'Bool',
217
+ 'v': self._value,
218
+ }
219
+
220
+ def types(self):
221
+ return {bool}
222
+
223
+ @staticmethod
224
+ def eval(dct, context):
225
+ return bool(dct['v'])
226
+
227
+
228
+ class And(PYSON):
229
+
230
+ def __init__(self, *statements, **kwargs):
231
+ super().__init__()
232
+ statements = list(statements) + kwargs.get('s', [])
233
+ for i, statement in enumerate(list(statements)):
234
+ if isinstance(statement, PYSON):
235
+ if statement.types() != {bool}:
236
+ statements[i] = Bool(statement)
237
+ elif not isinstance(statement, bool):
238
+ statements[i] = bool(statement)
239
+ assert len(statements) >= 2, 'must have at least 2 statements'
240
+ self._statements = statements
241
+
242
+ @property
243
+ def __repr_params__(self):
244
+ return tuple(self._statements)
245
+
246
+ def pyson(self):
247
+ return {
248
+ '__class__': 'And',
249
+ 's': self._statements,
250
+ }
251
+
252
+ def types(self):
253
+ return {bool}
254
+
255
+ @staticmethod
256
+ def eval(dct, context):
257
+ return bool(reduce(lambda x, y: x and y, dct['s']))
258
+
259
+
260
+ class Or(And):
261
+
262
+ def pyson(self):
263
+ res = super().pyson()
264
+ res['__class__'] = 'Or'
265
+ return res
266
+
267
+ @staticmethod
268
+ def eval(dct, context):
269
+ return bool(reduce(lambda x, y: x or y, dct['s']))
270
+
271
+
272
+ class Equal(PYSON):
273
+
274
+ def __init__(self, s1, s2):
275
+ statement1, statement2 = s1, s2
276
+ super().__init__()
277
+ if isinstance(statement1, PYSON):
278
+ types1 = statement1.types()
279
+ else:
280
+ types1 = {type(s1)}
281
+ if isinstance(statement2, PYSON):
282
+ types2 = statement2.types()
283
+ else:
284
+ types2 = {type(s2)}
285
+ assert types1 == types2, 'statements must have the same type'
286
+ self._statement1 = statement1
287
+ self._statement2 = statement2
288
+
289
+ @property
290
+ def __repr_params__(self):
291
+ return (self._statement1, self._statement2)
292
+
293
+ def pyson(self):
294
+ return {
295
+ '__class__': 'Equal',
296
+ 's1': self._statement1,
297
+ 's2': self._statement2,
298
+ }
299
+
300
+ def types(self):
301
+ return {bool}
302
+
303
+ @staticmethod
304
+ def eval(dct, context):
305
+ return dct['s1'] == dct['s2']
306
+
307
+
308
+ class Greater(PYSON):
309
+
310
+ def __init__(self, s1, s2, e=False):
311
+ statement1, statement2, equal = s1, s2, e
312
+ super().__init__()
313
+ for i in (statement1, statement2):
314
+ if isinstance(i, PYSON):
315
+ assert i.types().issubset({
316
+ int, float, type(None),
317
+ datetime.datetime, datetime.date,
318
+ datetime.timedelta}), \
319
+ 'statement must be an integer, float, date or datetime'
320
+ else:
321
+ assert isinstance(i, (
322
+ int, float, type(None),
323
+ datetime.datetime, datetime.date,
324
+ datetime.timedelta)), \
325
+ 'statement must be an integer, float, date or datetime'
326
+ if isinstance(equal, PYSON):
327
+ if equal.types() != {bool}:
328
+ equal = Bool(equal)
329
+ elif not isinstance(equal, bool):
330
+ equal = bool(equal)
331
+ self._statement1 = statement1
332
+ self._statement2 = statement2
333
+ self._equal = equal
334
+
335
+ @property
336
+ def __repr_params__(self):
337
+ return (self._statement1, self._statement2, self._equal)
338
+
339
+ def pyson(self):
340
+ return {
341
+ '__class__': 'Greater',
342
+ 's1': self._statement1,
343
+ 's2': self._statement2,
344
+ 'e': self._equal,
345
+ }
346
+
347
+ def types(self):
348
+ return {bool}
349
+
350
+ @staticmethod
351
+ def _convert(dct):
352
+ for i in ('s1', 's2'):
353
+ if dct[i] is None:
354
+ dct[i] = 0.0
355
+ if not isinstance(dct[i], (int, float)):
356
+ dct = dct.copy()
357
+ stmt = dct[i]
358
+ if isinstance(stmt, datetime.datetime):
359
+ stmt = stmt.timestamp()
360
+ elif isinstance(stmt, datetime.date):
361
+ time = datetime.time(0, 0)
362
+ stmt = datetime.datetime.combine(stmt, time).timestamp()
363
+ elif isinstance(stmt, datetime.timedelta):
364
+ stmt = stmt.total_seconds()
365
+ dct[i] = float(stmt)
366
+ return dct
367
+
368
+ @staticmethod
369
+ def eval(dct, context):
370
+ if dct['s1'] is None or dct['s2'] is None:
371
+ return False
372
+ dct = Greater._convert(dct)
373
+ if dct['e']:
374
+ return dct['s1'] >= dct['s2']
375
+ else:
376
+ return dct['s1'] > dct['s2']
377
+
378
+
379
+ class Less(Greater):
380
+
381
+ def pyson(self):
382
+ res = super().pyson()
383
+ res['__class__'] = 'Less'
384
+ return res
385
+
386
+ @staticmethod
387
+ def eval(dct, context):
388
+ if dct['s1'] is None or dct['s2'] is None:
389
+ return False
390
+ dct = Less._convert(dct)
391
+ if dct['e']:
392
+ return dct['s1'] <= dct['s2']
393
+ else:
394
+ return dct['s1'] < dct['s2']
395
+
396
+
397
+ class If(PYSON):
398
+
399
+ def __init__(self, c, t, e=None):
400
+ condition, then_statement, else_statement = c, t, e
401
+ super().__init__()
402
+ if isinstance(condition, PYSON):
403
+ if condition.types() != {bool}:
404
+ condition = Bool(condition)
405
+ elif not isinstance(condition, bool):
406
+ condition = bool(condition)
407
+ self._condition = condition
408
+ self._then_statement = then_statement
409
+ self._else_statement = else_statement
410
+
411
+ @property
412
+ def __repr_params__(self):
413
+ return (self._condition, self._then_statement, self._else_statement)
414
+
415
+ def pyson(self):
416
+ return {
417
+ '__class__': 'If',
418
+ 'c': self._condition,
419
+ 't': self._then_statement,
420
+ 'e': self._else_statement,
421
+ }
422
+
423
+ def types(self):
424
+ if isinstance(self._then_statement, PYSON):
425
+ types = self._then_statement.types()
426
+ else:
427
+ types = {type(self._then_statement)}
428
+ if isinstance(self._else_statement, PYSON):
429
+ types |= self._else_statement.types()
430
+ else:
431
+ types |= {type(self._else_statement)}
432
+ return types
433
+
434
+ @staticmethod
435
+ def eval(dct, context):
436
+ if dct['c']:
437
+ return dct['t']
438
+ else:
439
+ return dct['e']
440
+
441
+
442
+ class Get(PYSON):
443
+
444
+ def __init__(self, v, k, d=''):
445
+ obj, key, default = v, k, d
446
+ super().__init__()
447
+ if isinstance(obj, PYSON):
448
+ assert obj.types() == {dict}, 'obj must be a dict'
449
+ else:
450
+ assert isinstance(obj, dict), 'obj must be a dict'
451
+ self._obj = obj
452
+ if isinstance(key, PYSON):
453
+ assert key.types() == {str}, 'key must be a string'
454
+ else:
455
+ assert isinstance(key, str), 'key must be a string'
456
+ self._key = key
457
+ self._default = default
458
+
459
+ @property
460
+ def __repr_params__(self):
461
+ return (self._obj, self._key, self._default)
462
+
463
+ def pyson(self):
464
+ return {
465
+ '__class__': 'Get',
466
+ 'v': self._obj,
467
+ 'k': self._key,
468
+ 'd': self._default,
469
+ }
470
+
471
+ def types(self):
472
+ if isinstance(self._default, PYSON):
473
+ return self._default.types()
474
+ else:
475
+ return {type(self._default)}
476
+
477
+ @staticmethod
478
+ def eval(dct, context):
479
+ return dct['v'].get(dct['k'], dct['d'])
480
+
481
+
482
+ class In(PYSON):
483
+
484
+ def __init__(self, k, v):
485
+ key, obj = k, v
486
+ super().__init__()
487
+ if isinstance(key, PYSON):
488
+ assert key.types().issubset({str, int}), \
489
+ 'key must be a string or an integer or a long'
490
+ else:
491
+ assert isinstance(key, (str, int)), \
492
+ 'key must be a string or an integer or a long'
493
+ if isinstance(obj, PYSON):
494
+ assert obj.types().issubset({dict, list}), \
495
+ 'obj must be a dict or a list'
496
+ if obj.types() == {dict}:
497
+ if isinstance(key, PYSON):
498
+ assert key.types() == {str}, 'key must be a string'
499
+ else:
500
+ assert isinstance(key, str), 'key must be a string'
501
+ else:
502
+ assert isinstance(obj, (dict, list))
503
+ if isinstance(obj, dict):
504
+ if isinstance(key, PYSON):
505
+ assert key.types() == {str}, 'key must be a string'
506
+ else:
507
+ assert isinstance(key, str), 'key must be a string'
508
+ self._key = key
509
+ self._obj = obj
510
+
511
+ @property
512
+ def __repr_params__(self):
513
+ return (self._key, self._obj)
514
+
515
+ def pyson(self):
516
+ return {
517
+ '__class__': 'In',
518
+ 'k': self._key,
519
+ 'v': self._obj,
520
+ }
521
+
522
+ def types(self):
523
+ return {bool}
524
+
525
+ @staticmethod
526
+ def eval(dct, context):
527
+ if dct['v']:
528
+ return dct['k'] in dct['v']
529
+ else:
530
+ return False
531
+
532
+
533
+ class Date(PYSON):
534
+
535
+ def __init__(self, year=None, month=None, day=None,
536
+ delta_years=0, delta_months=0, delta_days=0, start=None, **kwargs):
537
+ year = kwargs.get('y', year)
538
+ month = kwargs.get('M', month)
539
+ day = kwargs.get('d', day)
540
+ delta_years = kwargs.get('dy', delta_years)
541
+ delta_months = kwargs.get('dM', delta_months)
542
+ delta_days = kwargs.get('dd', delta_days)
543
+ super().__init__()
544
+ for i in (year, month, day, delta_years, delta_months, delta_days):
545
+ if isinstance(i, PYSON):
546
+ assert i.types().issubset({int, type(None)}), \
547
+ '%s must be an integer or None' % (i,)
548
+ else:
549
+ assert isinstance(i, (int, type(None))), \
550
+ '%s must be an integer or None' % (i,)
551
+ self._year = year
552
+ self._month = month
553
+ self._day = day
554
+ self._delta_years = delta_years
555
+ self._delta_months = delta_months
556
+ self._delta_days = delta_days
557
+ self._start = start
558
+
559
+ @property
560
+ def __repr_params__(self):
561
+ return (self._year, self._month, self._day,
562
+ self._delta_years, self._delta_months, self._delta_days,
563
+ self._start)
564
+
565
+ def pyson(self):
566
+ return {
567
+ '__class__': 'Date',
568
+ 'y': self._year,
569
+ 'M': self._month,
570
+ 'd': self._day,
571
+ 'dy': self._delta_years,
572
+ 'dM': self._delta_months,
573
+ 'dd': self._delta_days,
574
+ 'start': self._start,
575
+ }
576
+
577
+ def types(self):
578
+ return {datetime.date}
579
+
580
+ @staticmethod
581
+ def eval(dct, context):
582
+ today = dct.get('start')
583
+ if isinstance(today, datetime.datetime):
584
+ today = today.date()
585
+ if not isinstance(today, datetime.date):
586
+ today = datetime.date.today()
587
+ return today + relativedelta(
588
+ year=dct['y'],
589
+ month=dct['M'],
590
+ day=dct['d'],
591
+ years=dct['dy'],
592
+ months=dct['dM'],
593
+ days=dct['dd'],
594
+ )
595
+
596
+
597
+ class DateTime(Date):
598
+
599
+ def __init__(self, year=None, month=None, day=None,
600
+ hour=None, minute=None, second=None, microsecond=None,
601
+ delta_years=0, delta_months=0, delta_days=0,
602
+ delta_hours=0, delta_minutes=0, delta_seconds=0,
603
+ delta_microseconds=0, start=None, **kwargs):
604
+ hour = kwargs.get('h', hour)
605
+ minute = kwargs.get('m', minute)
606
+ second = kwargs.get('s', second)
607
+ microsecond = kwargs.get('ms', microsecond)
608
+ delta_hours = kwargs.get('dh', delta_hours)
609
+ delta_minutes = kwargs.get('dm', delta_minutes)
610
+ delta_seconds = kwargs.get('ds', delta_seconds)
611
+ delta_microseconds = kwargs.get('dms', delta_microseconds)
612
+ super().__init__(year=year, month=month, day=day,
613
+ delta_years=delta_years, delta_months=delta_months,
614
+ delta_days=delta_days, start=start, **kwargs)
615
+ for i in (hour, minute, second, microsecond,
616
+ delta_hours, delta_minutes, delta_seconds, delta_microseconds):
617
+ if isinstance(i, PYSON):
618
+ assert i.types() == {int, type(None)}, \
619
+ '%s must be an integer or None' % (i,)
620
+ else:
621
+ assert isinstance(i, (int, type(None))), \
622
+ '%s must be an integer or None' % (i,)
623
+ self._hour = hour
624
+ self._minute = minute
625
+ self._second = second
626
+ self._microsecond = microsecond
627
+ self._delta_hours = delta_hours
628
+ self._delta_minutes = delta_minutes
629
+ self._delta_seconds = delta_seconds
630
+ self._delta_microseconds = delta_microseconds
631
+
632
+ @property
633
+ def __repr_params__(self):
634
+ date_params = super().__repr_params__
635
+ return (date_params[:3]
636
+ + (self._hour, self._minute, self._second, self._microsecond)
637
+ + date_params[3:-1]
638
+ + (self._delta_hours, self._delta_minutes, self._delta_seconds,
639
+ self._delta_microseconds)
640
+ + date_params[-1:])
641
+
642
+ def pyson(self):
643
+ res = super().pyson()
644
+ res['__class__'] = 'DateTime'
645
+ res['h'] = self._hour
646
+ res['m'] = self._minute
647
+ res['s'] = self._second
648
+ res['ms'] = self._microsecond
649
+ res['dh'] = self._delta_hours
650
+ res['dm'] = self._delta_minutes
651
+ res['ds'] = self._delta_seconds
652
+ res['dms'] = self._delta_microseconds
653
+ return res
654
+
655
+ def types(self):
656
+ return {datetime.datetime}
657
+
658
+ @staticmethod
659
+ def eval(dct, context):
660
+ now = dct.get('start')
661
+ if (isinstance(now, datetime.date)
662
+ and not isinstance(now, datetime.datetime)):
663
+ now = datetime.datetime.combine(now, datetime.time())
664
+ if not isinstance(now, datetime.datetime):
665
+ now = datetime.datetime.now(
666
+ datetime.timezone.utc).replace(tzinfo=None)
667
+ return now + relativedelta(
668
+ year=dct['y'],
669
+ month=dct['M'],
670
+ day=dct['d'],
671
+ hour=dct['h'],
672
+ minute=dct['m'],
673
+ second=dct['s'],
674
+ microsecond=dct['ms'],
675
+ years=dct['dy'],
676
+ months=dct['dM'],
677
+ days=dct['dd'],
678
+ hours=dct['dh'],
679
+ minutes=dct['dm'],
680
+ seconds=dct['ds'],
681
+ microseconds=dct['dms'],
682
+ )
683
+
684
+
685
+ class TimeDelta(PYSON):
686
+
687
+ def __init__(self, days=0, seconds=0, microseconds=0):
688
+ for i in [days, seconds, microseconds]:
689
+ if isinstance(i, PYSON):
690
+ assert i.types().issubset({int, float}), \
691
+ '%s must be an integer' % (i,)
692
+ else:
693
+ assert isinstance(i, (int, float)), \
694
+ '%s must be an integer' % (i,)
695
+ self._days = days
696
+ self._seconds = seconds
697
+ self._microseconds = microseconds
698
+
699
+ @property
700
+ def __repr_params__(self):
701
+ return self._days, self._seconds, self._microseconds
702
+
703
+ def pyson(self):
704
+ return {
705
+ '__class__': 'TimeDelta',
706
+ 'd': self._days,
707
+ 's': self._seconds,
708
+ 'm': self._microseconds,
709
+ }
710
+
711
+ def types(self):
712
+ return {datetime.timedelta}
713
+
714
+ @staticmethod
715
+ def eval(dct, context):
716
+ return datetime.timedelta(
717
+ days=dct['d'],
718
+ seconds=dct['s'],
719
+ microseconds=dct['m'],
720
+ )
721
+
722
+
723
+ class Len(PYSON):
724
+
725
+ def __init__(self, v):
726
+ super().__init__()
727
+ if isinstance(v, PYSON):
728
+ assert v.types().issubset({dict, list, str}), \
729
+ 'value must be a dict or a list or a string'
730
+ else:
731
+ assert isinstance(v, (dict, list, str)), \
732
+ 'value must be a dict or list or a string'
733
+ self._value = v
734
+
735
+ @property
736
+ def __repr_params__(self):
737
+ return (self._value,)
738
+
739
+ def pyson(self):
740
+ return {
741
+ '__class__': 'Len',
742
+ 'v': self._value,
743
+ }
744
+
745
+ def types(self):
746
+ return {int}
747
+
748
+ @staticmethod
749
+ def eval(dct, context):
750
+ return len(dct['v'])
751
+
752
+
753
+ CONTEXT = {
754
+ 'Eval': Eval,
755
+ 'Not': Not,
756
+ 'Bool': Bool,
757
+ 'And': And,
758
+ 'Or': Or,
759
+ 'Equal': Equal,
760
+ 'Greater': Greater,
761
+ 'Less': Less,
762
+ 'If': If,
763
+ 'Get': Get,
764
+ 'In': In,
765
+ 'Date': Date,
766
+ 'DateTime': DateTime,
767
+ 'TimeDelta': TimeDelta,
768
+ 'Len': Len,
769
+ 'true': True,
770
+ 'false': False,
771
+ }