aridity 98__tar.gz → 100__tar.gz
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.
- {aridity-98 → aridity-100}/PKG-INFO +10 -4
- aridity-100/aridity/grammar.py +211 -0
- {aridity-98 → aridity-100}/aridity/model.py +24 -29
- {aridity-98 → aridity-100}/aridity/repl.py +3 -17
- {aridity-98 → aridity-100}/aridity/scope.py +2 -3
- {aridity-98 → aridity-100}/aridity/search.py +2 -1
- {aridity-98 → aridity-100}/aridity/util.py +0 -3
- {aridity-98 → aridity-100}/aridity.egg-info/PKG-INFO +10 -4
- aridity-100/aridity.egg-info/requires.txt +1 -0
- {aridity-98 → aridity-100}/setup.py +2 -2
- aridity-98/aridity/grammar.py +0 -114
- aridity-98/aridity.egg-info/requires.txt +0 -2
- {aridity-98 → aridity-100}/README.md +0 -0
- {aridity-98 → aridity-100}/aridity/__init__.py +0 -0
- {aridity-98 → aridity-100}/aridity/arid_config.py +0 -0
- {aridity-98 → aridity-100}/aridity/config.py +0 -0
- {aridity-98 → aridity-100}/aridity/directives.py +0 -0
- {aridity-98 → aridity-100}/aridity/functions.py +0 -0
- {aridity-98 → aridity-100}/aridity/keyring.py +0 -0
- {aridity-98 → aridity-100}/aridity/processtemplate.py +0 -0
- {aridity-98 → aridity-100}/aridity/resolve.py +0 -0
- {aridity-98 → aridity-100}/aridity/stacks.py +0 -0
- {aridity-98 → aridity-100}/aridity.egg-info/SOURCES.txt +0 -0
- {aridity-98 → aridity-100}/aridity.egg-info/dependency_links.txt +0 -0
- {aridity-98 → aridity-100}/aridity.egg-info/entry_points.txt +0 -0
- {aridity-98 → aridity-100}/aridity.egg-info/top_level.txt +0 -0
- {aridity-98 → aridity-100}/setup.cfg +0 -0
|
@@ -1,13 +1,19 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
2
|
Name: aridity
|
|
3
|
-
Version:
|
|
3
|
+
Version: 100
|
|
4
4
|
Summary: DRY config and template system, easily extensible with Python
|
|
5
5
|
Home-page: https://pypi.org/project/aridity/
|
|
6
6
|
Author: foyono
|
|
7
7
|
Author-email: shrovis@foyono.com
|
|
8
8
|
Description-Content-Type: text/markdown
|
|
9
|
-
Requires-Dist: foyndation>=
|
|
10
|
-
|
|
9
|
+
Requires-Dist: foyndation>=16
|
|
10
|
+
Dynamic: author
|
|
11
|
+
Dynamic: author-email
|
|
12
|
+
Dynamic: description
|
|
13
|
+
Dynamic: description-content-type
|
|
14
|
+
Dynamic: home-page
|
|
15
|
+
Dynamic: requires-dist
|
|
16
|
+
Dynamic: summary
|
|
11
17
|
|
|
12
18
|
# aridity
|
|
13
19
|
DRY config and template system, easily extensible with Python.
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
from .model import Blank, Boolean, Boundary, Call, Concat, Entry, Indeterminate, nullmonitor, Number, Suffix, Text
|
|
2
|
+
from decimal import Decimal
|
|
3
|
+
import re
|
|
4
|
+
|
|
5
|
+
class ParseException(Exception): pass
|
|
6
|
+
|
|
7
|
+
booleans = {t: Boolean(b).augment(textvalue = t) for b in map(bool, range(2)) for t in [str(b).lower()]}
|
|
8
|
+
brackets = {x: y for pair in ['()', '[]'] for x, y in [pair, reversed(pair)]}
|
|
9
|
+
dollar = re.compile('[$]')
|
|
10
|
+
dollarorbracket = re.compile(r'[$()[\]]')
|
|
11
|
+
dollarorbracketorws = re.compile(r'[$()[\]\s]')
|
|
12
|
+
dollaroropenorws = re.compile(r'([$([])|\s')
|
|
13
|
+
eolornotws = re.compile(r'(\r\n|[\r\n])|\S')
|
|
14
|
+
notws = re.compile(r'\S')
|
|
15
|
+
numbermatch = re.compile('-?(?:[0-9]+(?:[.][0-9]*)?|[.][0-9]+)').fullmatch
|
|
16
|
+
|
|
17
|
+
def _scalar(text):
|
|
18
|
+
try:
|
|
19
|
+
return booleans[text]
|
|
20
|
+
except KeyError:
|
|
21
|
+
m = numbermatch(text)
|
|
22
|
+
if m is None:
|
|
23
|
+
return Text(text)
|
|
24
|
+
if '.' in text:
|
|
25
|
+
val = Decimal(text)
|
|
26
|
+
else:
|
|
27
|
+
val = int(text)
|
|
28
|
+
if not val and '-' == text[0]:
|
|
29
|
+
val = Decimal(text) # Preserve sign.
|
|
30
|
+
return Number(val).augment(textvalue = text)
|
|
31
|
+
|
|
32
|
+
class Parser:
|
|
33
|
+
|
|
34
|
+
def __init__(self, monitor):
|
|
35
|
+
self.monitor = monitor
|
|
36
|
+
|
|
37
|
+
def _join(self, parts):
|
|
38
|
+
n = len(parts)
|
|
39
|
+
if 0 == n:
|
|
40
|
+
return Indeterminate
|
|
41
|
+
if 1 == n:
|
|
42
|
+
return parts[0]
|
|
43
|
+
return Concat(parts, self.monitor)
|
|
44
|
+
|
|
45
|
+
def _templateparts(self, text):
|
|
46
|
+
eye = 0
|
|
47
|
+
parts = []
|
|
48
|
+
while eye < len(text):
|
|
49
|
+
m = dollar.search(text, eye)
|
|
50
|
+
if m is None:
|
|
51
|
+
parts.append(Text(text[eye:]))
|
|
52
|
+
break
|
|
53
|
+
fence = m.start()
|
|
54
|
+
if eye < fence:
|
|
55
|
+
parts.append(Text(text[eye:fence]))
|
|
56
|
+
call, eye = self._readcall(text, fence)
|
|
57
|
+
parts.append(call)
|
|
58
|
+
return parts
|
|
59
|
+
|
|
60
|
+
def readtemplate(self, text):
|
|
61
|
+
return self._join(self._templateparts(text))
|
|
62
|
+
|
|
63
|
+
def readparts(self, text):
|
|
64
|
+
eye = 0
|
|
65
|
+
parts = []
|
|
66
|
+
while eye < len(text):
|
|
67
|
+
m = eolornotws.search(text, eye)
|
|
68
|
+
if m is None:
|
|
69
|
+
parts.append(Blank(text[eye:]))
|
|
70
|
+
break
|
|
71
|
+
fence = m.start()
|
|
72
|
+
if eye < fence:
|
|
73
|
+
parts.append(Blank(text[eye:fence]))
|
|
74
|
+
if m.group(1) is None:
|
|
75
|
+
chunk, eye = self._readchunk(text, fence, None)
|
|
76
|
+
parts.append(chunk)
|
|
77
|
+
else:
|
|
78
|
+
parts.append(Boundary)
|
|
79
|
+
eye = m.end()
|
|
80
|
+
return parts
|
|
81
|
+
|
|
82
|
+
def readsuffix(self, text):
|
|
83
|
+
return Suffix(Entry(self.readparts(text)))
|
|
84
|
+
|
|
85
|
+
def _readcall(self, text, eye):
|
|
86
|
+
eye += 1
|
|
87
|
+
names = []
|
|
88
|
+
while True:
|
|
89
|
+
m = dollaroropenorws.search(text, eye)
|
|
90
|
+
openchar = m.group(1)
|
|
91
|
+
if openchar is None:
|
|
92
|
+
raise ParseException
|
|
93
|
+
names.append(text[eye:m.start()])
|
|
94
|
+
eye = m.end()
|
|
95
|
+
if '$' != openchar:
|
|
96
|
+
break
|
|
97
|
+
k = len(names) - 1
|
|
98
|
+
if '.' == names[k]:
|
|
99
|
+
args, eye = self._readspan(text, eye, False, openchar)
|
|
100
|
+
call = Text('') if not args else Concat(args, self.monitor)
|
|
101
|
+
elif "'" == names[k]:
|
|
102
|
+
args, eye = self._readspan(text, eye, True, openchar)
|
|
103
|
+
call = Text('') if not args else args[0] if 1 == len(args) else Concat(args, self.monitor)
|
|
104
|
+
else:
|
|
105
|
+
args, eye = self._readargs(text, eye, openchar)
|
|
106
|
+
call = Call(names[k], args)
|
|
107
|
+
while k:
|
|
108
|
+
k -= 1
|
|
109
|
+
if '.' != names[k]:
|
|
110
|
+
call = Call(names[k], [call])
|
|
111
|
+
return call, eye + 1
|
|
112
|
+
|
|
113
|
+
def _readargs(self, text, eye, openchar):
|
|
114
|
+
closechar = brackets[openchar]
|
|
115
|
+
args = []
|
|
116
|
+
while True:
|
|
117
|
+
m = notws.search(text, eye)
|
|
118
|
+
c = m.group()
|
|
119
|
+
eye = m.start()
|
|
120
|
+
if closechar == c:
|
|
121
|
+
break
|
|
122
|
+
chunk, eye = self._readchunk(text, eye, openchar)
|
|
123
|
+
args.append(chunk)
|
|
124
|
+
return args, eye
|
|
125
|
+
|
|
126
|
+
def _readspan(self, text, eye, literal, openchar):
|
|
127
|
+
closechar = brackets[openchar]
|
|
128
|
+
mark = eye
|
|
129
|
+
parts = []
|
|
130
|
+
depth = 0
|
|
131
|
+
while True:
|
|
132
|
+
m = dollarorbracket.search(text, eye)
|
|
133
|
+
if m is None:
|
|
134
|
+
raise ParseException
|
|
135
|
+
c = m.group()
|
|
136
|
+
if '$' == c:
|
|
137
|
+
if literal:
|
|
138
|
+
eye = m.end()
|
|
139
|
+
else:
|
|
140
|
+
fence = m.start()
|
|
141
|
+
if mark < fence:
|
|
142
|
+
parts.append(Text(text[mark:fence]))
|
|
143
|
+
call, eye = self._readcall(text, fence)
|
|
144
|
+
parts.append(call)
|
|
145
|
+
mark = eye
|
|
146
|
+
continue
|
|
147
|
+
if closechar == c:
|
|
148
|
+
if depth:
|
|
149
|
+
depth -= 1
|
|
150
|
+
eye = m.end()
|
|
151
|
+
continue
|
|
152
|
+
fence = m.start()
|
|
153
|
+
if mark < fence:
|
|
154
|
+
parts.append(Text(text[mark:fence]))
|
|
155
|
+
mark = eye = fence
|
|
156
|
+
break
|
|
157
|
+
if openchar == c:
|
|
158
|
+
depth += 1
|
|
159
|
+
eye = m.end()
|
|
160
|
+
continue
|
|
161
|
+
eye = m.end()
|
|
162
|
+
return parts, eye
|
|
163
|
+
|
|
164
|
+
def _readchunk(self, text, eye, openchar):
|
|
165
|
+
closechar = brackets.get(openchar)
|
|
166
|
+
mark = eye
|
|
167
|
+
parts = []
|
|
168
|
+
depth = 0
|
|
169
|
+
while True:
|
|
170
|
+
if eye == len(text):
|
|
171
|
+
if mark < eye:
|
|
172
|
+
parts.append(_scalar(text[mark:eye]))
|
|
173
|
+
break
|
|
174
|
+
m = dollarorbracketorws.search(text, eye)
|
|
175
|
+
if m is None:
|
|
176
|
+
parts.append(_scalar(text[mark:]))
|
|
177
|
+
mark = eye = len(text)
|
|
178
|
+
break
|
|
179
|
+
c = m.group()
|
|
180
|
+
if '$' == c:
|
|
181
|
+
fence = m.start()
|
|
182
|
+
if mark < fence:
|
|
183
|
+
parts.append(Text(text[mark:fence]))
|
|
184
|
+
call, eye = self._readcall(text, fence)
|
|
185
|
+
parts.append(call)
|
|
186
|
+
mark = eye
|
|
187
|
+
continue
|
|
188
|
+
if closechar == c:
|
|
189
|
+
if depth:
|
|
190
|
+
depth -= 1
|
|
191
|
+
eye = m.end()
|
|
192
|
+
continue
|
|
193
|
+
fence = m.start()
|
|
194
|
+
if mark < fence:
|
|
195
|
+
parts.append(_scalar(text[mark:fence]))
|
|
196
|
+
mark = eye = fence
|
|
197
|
+
break
|
|
198
|
+
if openchar == c:
|
|
199
|
+
depth += 1
|
|
200
|
+
eye = m.end()
|
|
201
|
+
continue
|
|
202
|
+
if c not in brackets:
|
|
203
|
+
fence = m.start()
|
|
204
|
+
if mark < fence:
|
|
205
|
+
parts.append(_scalar(text[mark:fence]))
|
|
206
|
+
mark = eye = fence
|
|
207
|
+
break
|
|
208
|
+
eye = m.end()
|
|
209
|
+
return self._join(parts), eye
|
|
210
|
+
|
|
211
|
+
staticparser = Parser(nullmonitor)
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
from .util import Burial
|
|
2
2
|
from contextlib import contextmanager
|
|
3
|
-
from foyndation import dotpy, Forkable, rmsuffix
|
|
3
|
+
from foyndation import dotpy, Forkable, rmsuffix, singleton, solo
|
|
4
4
|
from importlib import import_module
|
|
5
5
|
from importlib.resources import files
|
|
6
6
|
from io import TextIOWrapper
|
|
7
|
-
from itertools import chain
|
|
7
|
+
from itertools import chain
|
|
8
8
|
from parabject import dereference, UnknownParabjectException
|
|
9
9
|
from pathlib import PurePath
|
|
10
10
|
import numbers, os, re
|
|
@@ -124,14 +124,12 @@ class Blank(BaseSimpleValue):
|
|
|
124
124
|
def plus(self, that):
|
|
125
125
|
return Text(self.textvalue + that.textvalue)
|
|
126
126
|
|
|
127
|
-
|
|
127
|
+
@singleton
|
|
128
|
+
class Boundary:
|
|
128
129
|
|
|
129
130
|
ignorable = True
|
|
130
131
|
boundary = True
|
|
131
132
|
|
|
132
|
-
def __init__(self, scalar):
|
|
133
|
-
self.scalar = scalar
|
|
134
|
-
|
|
135
133
|
class BaseScalar(BaseSimpleValue):
|
|
136
134
|
|
|
137
135
|
ignorable = False
|
|
@@ -197,6 +195,7 @@ class Text(BaseScalar, Forkable):
|
|
|
197
195
|
def plus(self, that):
|
|
198
196
|
return self._of(self.textvalue + that.textvalue)
|
|
199
197
|
|
|
198
|
+
@singleton
|
|
200
199
|
class Indeterminate(BaseSimpleValue): # XXX: Base class needed?
|
|
201
200
|
|
|
202
201
|
binaryvalue = b''
|
|
@@ -208,8 +207,6 @@ class Indeterminate(BaseSimpleValue): # XXX: Base class needed?
|
|
|
208
207
|
def totext(self):
|
|
209
208
|
return Text('')
|
|
210
209
|
|
|
211
|
-
Indeterminate = Indeterminate()
|
|
212
|
-
|
|
213
210
|
class ResidualHoleException(Exception): pass
|
|
214
211
|
|
|
215
212
|
class Hole(BaseScalar):
|
|
@@ -345,29 +342,22 @@ class Call(Resolvable):
|
|
|
345
342
|
|
|
346
343
|
ignorable = False
|
|
347
344
|
|
|
348
|
-
def __init__(self, name, args
|
|
345
|
+
def __init__(self, name, args):
|
|
349
346
|
self.name = name
|
|
350
347
|
self.args = args
|
|
351
|
-
self.brackets = brackets
|
|
352
348
|
|
|
353
349
|
def _functionvalue(self, scope):
|
|
354
350
|
return scope.resolved(self.name).functionvalue
|
|
355
351
|
|
|
356
|
-
def _resolvables(self):
|
|
357
|
-
for a in self.args:
|
|
358
|
-
if not a.ignorable:
|
|
359
|
-
yield a
|
|
360
|
-
|
|
361
352
|
def resolve(self, scope):
|
|
362
|
-
return self._functionvalue(scope)(scope.getresolvecontext(), *self.
|
|
353
|
+
return self._functionvalue(scope)(scope.getresolvecontext(), *self.args)
|
|
363
354
|
|
|
364
355
|
def resolvemulti(self, j, scope):
|
|
365
356
|
f = self._functionvalue(scope.getresolvecontext())
|
|
366
357
|
if star != f:
|
|
367
|
-
yield j, f(scope, *self.
|
|
358
|
+
yield j, f(scope, *self.args)
|
|
368
359
|
else:
|
|
369
|
-
|
|
370
|
-
for k, o in resolvable.resolve(scope).resolveditems():
|
|
360
|
+
for k, o in solo(self.args).resolve(scope).resolveditems(): # XXX: Support multiple args?
|
|
371
361
|
yield (j, k), o
|
|
372
362
|
|
|
373
363
|
class Directive(Resolved):
|
|
@@ -409,26 +399,18 @@ class Stream(Resolved):
|
|
|
409
399
|
CommandReader(self.streamvalue, prefix).pipeto(scope)
|
|
410
400
|
|
|
411
401
|
def processtemplate(self, scope):
|
|
412
|
-
from .grammar import
|
|
402
|
+
from .grammar import Parser
|
|
413
403
|
with scope.staticscope().indent.push() as monitor:
|
|
414
|
-
return
|
|
404
|
+
return Parser(monitor).readtemplate(self.streamvalue.read()).resolve(scope)
|
|
415
405
|
|
|
416
406
|
class Entry(Struct, Forkable):
|
|
417
407
|
|
|
418
|
-
@classmethod
|
|
419
|
-
def pa(cls, s, l, t):
|
|
420
|
-
return cls(t.asList())
|
|
421
|
-
|
|
422
408
|
def __init__(self, resolvables):
|
|
423
409
|
self.resolvables = resolvables
|
|
424
410
|
|
|
425
411
|
def size(self):
|
|
426
412
|
return sum(1 for r in self.resolvables if not r.ignorable)
|
|
427
413
|
|
|
428
|
-
def word(self, i):
|
|
429
|
-
word, = islice((r for r in self.resolvables if not r.ignorable), i, i + 1)
|
|
430
|
-
return word
|
|
431
|
-
|
|
432
414
|
def words(self):
|
|
433
415
|
return [r for r in self.resolvables if not r.ignorable]
|
|
434
416
|
|
|
@@ -467,6 +449,19 @@ class Entry(Struct, Forkable):
|
|
|
467
449
|
def plus(self, that):
|
|
468
450
|
return self._of([*self.resolvables, *that.resolvables])
|
|
469
451
|
|
|
452
|
+
class MalformedEntryException(Exception): pass
|
|
453
|
+
|
|
454
|
+
class Suffix:
|
|
455
|
+
|
|
456
|
+
def __init__(self, entry):
|
|
457
|
+
self.indent = entry.indent()
|
|
458
|
+
self.entry = entry
|
|
459
|
+
|
|
460
|
+
def closing(self, contextindent):
|
|
461
|
+
if any(x != y for x, y in zip(self.indent, contextindent)):
|
|
462
|
+
raise MalformedEntryException(self.entry)
|
|
463
|
+
return len(self.indent) <= len(contextindent)
|
|
464
|
+
|
|
470
465
|
def wrap(value):
|
|
471
466
|
'Attempt to wrap the given value in a model object of the most specific type.'
|
|
472
467
|
try:
|
|
@@ -1,24 +1,10 @@
|
|
|
1
|
-
from .grammar import
|
|
2
|
-
from .model import Entry
|
|
3
|
-
from pyparsing import ParseException
|
|
1
|
+
from .grammar import ParseException, staticparser
|
|
2
|
+
from .model import Entry, Suffix
|
|
4
3
|
|
|
5
4
|
class DanglingStackException(Exception): pass
|
|
6
5
|
|
|
7
6
|
class NoSuchIndentException(Exception): pass
|
|
8
7
|
|
|
9
|
-
class MalformedEntryException(Exception): pass
|
|
10
|
-
|
|
11
|
-
class Suffix:
|
|
12
|
-
|
|
13
|
-
def __init__(self, entry):
|
|
14
|
-
self.indent = entry.indent()
|
|
15
|
-
self.entry = entry
|
|
16
|
-
|
|
17
|
-
def closing(self, contextindent):
|
|
18
|
-
if any(x != y for x, y in zip(self.indent, contextindent)):
|
|
19
|
-
raise MalformedEntryException(self.entry)
|
|
20
|
-
return len(self.indent) <= len(contextindent)
|
|
21
|
-
|
|
22
8
|
class Command:
|
|
23
9
|
|
|
24
10
|
def __init__(self, entry):
|
|
@@ -40,7 +26,7 @@ class CommandReader:
|
|
|
40
26
|
|
|
41
27
|
def _readcommands(self, line):
|
|
42
28
|
try:
|
|
43
|
-
suffix =
|
|
29
|
+
suffix = staticparser.readsuffix(''.join([*self.stack, line]))
|
|
44
30
|
del self.stack[:]
|
|
45
31
|
except ParseException:
|
|
46
32
|
self.stack.append(line)
|
|
@@ -5,7 +5,7 @@ from .resolve import AnchorResolveContext
|
|
|
5
5
|
from .search import Query
|
|
6
6
|
from .stacks import IndentStack, SimpleStack, ThreadLocalResolvable
|
|
7
7
|
from .util import NoSuchPathException, UnsupportedEntryException
|
|
8
|
-
from foyndation import solo
|
|
8
|
+
from foyndation import singleton, solo
|
|
9
9
|
from itertools import chain
|
|
10
10
|
import os, sys, threading
|
|
11
11
|
|
|
@@ -234,6 +234,7 @@ class Star(Function, Directive):
|
|
|
234
234
|
def _star(self, prefix, suffix, scope):
|
|
235
235
|
scope.getorcreatesubscope(prefix.topath(scope) + (self.protokey,)).execute(suffix)
|
|
236
236
|
|
|
237
|
+
@singleton
|
|
237
238
|
class StaticScope(Scope):
|
|
238
239
|
|
|
239
240
|
rootscopekey = OpaqueKey()
|
|
@@ -266,8 +267,6 @@ class StaticScope(Scope):
|
|
|
266
267
|
setattr(threadlocals, name, stack)
|
|
267
268
|
return stack
|
|
268
269
|
|
|
269
|
-
StaticScope = StaticScope()
|
|
270
|
-
|
|
271
270
|
class ScalarScope(Scope):
|
|
272
271
|
|
|
273
272
|
def __init__(self, parents, scalarobj):
|
|
@@ -1,13 +1,19 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
2
|
Name: aridity
|
|
3
|
-
Version:
|
|
3
|
+
Version: 100
|
|
4
4
|
Summary: DRY config and template system, easily extensible with Python
|
|
5
5
|
Home-page: https://pypi.org/project/aridity/
|
|
6
6
|
Author: foyono
|
|
7
7
|
Author-email: shrovis@foyono.com
|
|
8
8
|
Description-Content-Type: text/markdown
|
|
9
|
-
Requires-Dist: foyndation>=
|
|
10
|
-
|
|
9
|
+
Requires-Dist: foyndation>=16
|
|
10
|
+
Dynamic: author
|
|
11
|
+
Dynamic: author-email
|
|
12
|
+
Dynamic: description
|
|
13
|
+
Dynamic: description-content-type
|
|
14
|
+
Dynamic: home-page
|
|
15
|
+
Dynamic: requires-dist
|
|
16
|
+
Dynamic: summary
|
|
11
17
|
|
|
12
18
|
# aridity
|
|
13
19
|
DRY config and template system, easily extensible with Python.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
foyndation>=16
|
|
@@ -49,13 +49,13 @@ class SourceInfo:
|
|
|
49
49
|
sourceinfo = SourceInfo('.')
|
|
50
50
|
setup(
|
|
51
51
|
name = 'aridity',
|
|
52
|
-
version = '
|
|
52
|
+
version = '100',
|
|
53
53
|
description = 'DRY config and template system, easily extensible with Python',
|
|
54
54
|
url = 'https://pypi.org/project/aridity/',
|
|
55
55
|
author = 'foyono',
|
|
56
56
|
author_email = 'shrovis@foyono.com',
|
|
57
57
|
py_modules = [],
|
|
58
|
-
install_requires = ['foyndation>=
|
|
58
|
+
install_requires = ['foyndation>=16'],
|
|
59
59
|
package_data = {'': ['*.pxd', '*.pyx', '*.pyxbld', '*.arid', '*.aridt']},
|
|
60
60
|
entry_points = {'console_scripts': ['aridity=aridity.__init__:main', 'arid-config=aridity.arid_config:main', 'processtemplate=aridity.processtemplate:main']},
|
|
61
61
|
**sourceinfo.setup_kwargs(),
|
aridity-98/aridity/grammar.py
DELETED
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
from .model import Blank, Boolean, Boundary, Call, Concat, Entry, nullmonitor, Number, Text
|
|
2
|
-
from decimal import Decimal
|
|
3
|
-
from functools import partial, reduce
|
|
4
|
-
from pyparsing import Forward, Literal, MatchFirst, NoMatch, OneOrMore, Optional, Regex, Suppress, ZeroOrMore
|
|
5
|
-
import operator, re
|
|
6
|
-
|
|
7
|
-
class AnyScalar:
|
|
8
|
-
|
|
9
|
-
numbermatch = re.compile('-?(?:[0-9]+(?:[.][0-9]*)?|[.][0-9]+)').fullmatch
|
|
10
|
-
booleans = {t: Boolean(b).augment(textvalue = t) for b in map(bool, range(2)) for t in [str(b).lower()]}
|
|
11
|
-
|
|
12
|
-
@classmethod
|
|
13
|
-
def pa(cls, s, l, t):
|
|
14
|
-
text, = t
|
|
15
|
-
try:
|
|
16
|
-
return cls.booleans[text]
|
|
17
|
-
except KeyError:
|
|
18
|
-
m = cls.numbermatch(text)
|
|
19
|
-
if m is None:
|
|
20
|
-
return Text(text)
|
|
21
|
-
if '.' in text:
|
|
22
|
-
val = Decimal(text)
|
|
23
|
-
else:
|
|
24
|
-
val = int(text)
|
|
25
|
-
if not val and '-' == text[0]:
|
|
26
|
-
val = Decimal(text) # Preserve sign.
|
|
27
|
-
return Number(val).augment(textvalue = text)
|
|
28
|
-
|
|
29
|
-
def _gettext(notchars, pa):
|
|
30
|
-
return Regex(fr"[^$\s{re.escape(notchars)}]+").leaveWhitespace().setParseAction(pa)
|
|
31
|
-
|
|
32
|
-
def _getarg(callchain, scalarpa, boundarychars):
|
|
33
|
-
gettext = partial(_gettext, boundarychars)
|
|
34
|
-
opttext = Optional(gettext(Text.pa))
|
|
35
|
-
return (OneOrMore(opttext + callchain) + opttext | gettext(scalarpa)).setParseAction(Concat.smartpa)
|
|
36
|
-
|
|
37
|
-
def _bracketed(callchain, blankpa, scalarpa, o, c):
|
|
38
|
-
gettext = partial(_gettext, o + c)
|
|
39
|
-
bracketed = Forward()
|
|
40
|
-
chainorbrackets = callchain | (Literal(o).setParseAction(Text.pa) + bracketed + Literal(c).setParseAction(Text.pa)).leaveWhitespace()
|
|
41
|
-
opttext = Optional(gettext(Text.pa))
|
|
42
|
-
concat = OneOrMore(opttext + chainorbrackets) + opttext
|
|
43
|
-
optblank = _getoptblank(blankpa, '')
|
|
44
|
-
bracketed << ZeroOrMore(optblank + (concat | gettext(scalarpa)).setParseAction(Concat.smartpa)) + optblank
|
|
45
|
-
return bracketed
|
|
46
|
-
|
|
47
|
-
def _literalbracketed(o, c):
|
|
48
|
-
bracketed = Forward()
|
|
49
|
-
brackets = (Literal(o) + bracketed + Literal(c)).leaveWhitespace()
|
|
50
|
-
opttext = Regex(f"[^{re.escape(o + c)}]*").leaveWhitespace()
|
|
51
|
-
bracketed << ZeroOrMore(opttext + brackets) + opttext
|
|
52
|
-
return bracketed
|
|
53
|
-
|
|
54
|
-
def _getoptblank(pa, boundarychars):
|
|
55
|
-
return Optional(Regex(fr"[^\S{re.escape(boundarychars)}]+").leaveWhitespace().setParseAction(pa))
|
|
56
|
-
|
|
57
|
-
class Parser:
|
|
58
|
-
|
|
59
|
-
def __init__(self, g, singleton = True):
|
|
60
|
-
self.g = g.parseWithTabs()
|
|
61
|
-
self.singleton = singleton
|
|
62
|
-
|
|
63
|
-
def __call__(self, text):
|
|
64
|
-
result = self.g.parseString(text, parseAll = True).asList()
|
|
65
|
-
if self.singleton:
|
|
66
|
-
result, = result
|
|
67
|
-
return result
|
|
68
|
-
|
|
69
|
-
def _principalcallpa(s, l, t):
|
|
70
|
-
return Call(t[0], t[2:-1], t[1] + t[-1])
|
|
71
|
-
|
|
72
|
-
def _additionalcallpa(s, l, t):
|
|
73
|
-
return Call(t[0], t[1:], ['', ''])
|
|
74
|
-
|
|
75
|
-
class GFactory:
|
|
76
|
-
|
|
77
|
-
bracketpairs = '()', '[]'
|
|
78
|
-
identifier = Regex(fr"[^\s${''.join(re.escape(o) for o, _ in bracketpairs)}]*")
|
|
79
|
-
|
|
80
|
-
def __init__(self, scalarpa = AnyScalar.pa, boundarychars = '\r\n', ormorecls = OneOrMore, monitor = nullmonitor):
|
|
81
|
-
self.scalarpa = scalarpa
|
|
82
|
-
self.boundarychars = boundarychars
|
|
83
|
-
self.ormorecls = ormorecls
|
|
84
|
-
self.monitor = monitor
|
|
85
|
-
|
|
86
|
-
def templatepa(self, s, l, t):
|
|
87
|
-
return Concat(t, self.monitor)
|
|
88
|
-
|
|
89
|
-
def _bracketspa(self, s, l, t):
|
|
90
|
-
return Concat(t[1:-1] or [Text('')], self.monitor)
|
|
91
|
-
|
|
92
|
-
def create(self, pa):
|
|
93
|
-
def itercalls():
|
|
94
|
-
def getbrackets(blankpa, scalarpa):
|
|
95
|
-
return Literal(o) + _bracketed(callchain, blankpa, scalarpa, o, c) + Literal(c)
|
|
96
|
-
for o, c in self.bracketpairs:
|
|
97
|
-
yield (Suppress(Regex("[$](?:lit|')")) + Suppress(o) + _literalbracketed(o, c) + Suppress(c)).setParseAction(Text.joinpa)
|
|
98
|
-
yield (Suppress(Regex('[$](?:pass|[.])')) + getbrackets(Text.pa, Text.pa)).setParseAction(self._bracketspa)
|
|
99
|
-
yield (Suppress('$') + self.identifier + getbrackets(Blank.pa, AnyScalar.pa)).setParseAction(_principalcallpa)
|
|
100
|
-
yield (Suppress('$') + self.identifier + callchain).setParseAction(_additionalcallpa)
|
|
101
|
-
optblank = _getoptblank(Blank.pa, self.boundarychars)
|
|
102
|
-
callchain = Forward()
|
|
103
|
-
callchain << MatchFirst(itercalls()).leaveWhitespace()
|
|
104
|
-
return reduce(operator.add, [
|
|
105
|
-
self.ormorecls(optblank + _getarg(callchain, self.scalarpa, self.boundarychars)),
|
|
106
|
-
optblank,
|
|
107
|
-
Optional(Regex(f"[{re.escape(self.boundarychars)}]+").leaveWhitespace().setParseAction(Boundary.pa) if self.boundarychars else NoMatch()),
|
|
108
|
-
]).setParseAction(pa)
|
|
109
|
-
|
|
110
|
-
commandparser = Parser(GFactory(ormorecls = ZeroOrMore).create(Entry.pa))
|
|
111
|
-
|
|
112
|
-
def templateparser(monitor):
|
|
113
|
-
gfactory = GFactory(scalarpa = Text.pa, boundarychars = '', monitor = monitor)
|
|
114
|
-
return Parser(gfactory.create(gfactory.templatepa) | Regex('^$').setParseAction(Text.pa))
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|