bare-script 0.9.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.
bare_script/model.py ADDED
@@ -0,0 +1,257 @@
1
+ # Licensed under the MIT License
2
+ # https://github.com/craigahobbs/bare-script-py/blob/main/LICENSE
3
+
4
+ """
5
+ The BareScript runtime model and related utilities
6
+ """
7
+
8
+ from schema_markdown import parse_schema_markdown, validate_type
9
+
10
+
11
+ #
12
+ # The BareScript type model
13
+ #
14
+ BARE_SCRIPT_TYPES = parse_schema_markdown('''\
15
+ # A BareScript script
16
+ struct BareScript
17
+
18
+ # The script's statements
19
+ ScriptStatement[] statements
20
+
21
+
22
+ # A script statement
23
+ union ScriptStatement
24
+
25
+ # An expression
26
+ ExpressionStatement expr
27
+
28
+ # A jump statement
29
+ JumpStatement jump
30
+
31
+ # A return statement
32
+ ReturnStatement return
33
+
34
+ # A label definition
35
+ string label
36
+
37
+ # A function definition
38
+ FunctionStatement function
39
+
40
+ # An include statement
41
+ IncludeStatement include
42
+
43
+
44
+ # An expression statement
45
+ struct ExpressionStatement
46
+
47
+ # The variable name to assign the expression value
48
+ optional string name
49
+
50
+ # The expression to evaluate
51
+ Expression expr
52
+
53
+
54
+ # A jump statement
55
+ struct JumpStatement
56
+
57
+ # The label to jump to
58
+ string label
59
+
60
+ # The test expression
61
+ optional Expression expr
62
+
63
+
64
+ # A return statement
65
+ struct ReturnStatement
66
+
67
+ # The expression to return
68
+ optional Expression expr
69
+
70
+
71
+ # A function definition statement
72
+ struct FunctionStatement
73
+
74
+ # If true, the function is defined as async
75
+ optional bool async
76
+
77
+ # The function name
78
+ string name
79
+
80
+ # The function's argument names
81
+ optional string[len > 0] args
82
+
83
+ # If true, the function's last argument is the array of all remaining arguments
84
+ optional bool lastArgArray
85
+
86
+ # The function's statements
87
+ ScriptStatement[] statements
88
+
89
+
90
+ # An include statement
91
+ struct IncludeStatement
92
+
93
+ # The list of include scripts to load and execute in the global scope
94
+ IncludeScript[len > 0] includes
95
+
96
+
97
+ # An include script
98
+ struct IncludeScript
99
+
100
+ # The include script URL
101
+ string url
102
+
103
+ # If true, this is a system include
104
+ optional bool system
105
+
106
+
107
+ # An expression
108
+ union Expression
109
+
110
+ # A number literal
111
+ float number
112
+
113
+ # A string literal
114
+ string string
115
+
116
+ # A variable value
117
+ string variable
118
+
119
+ # A function expression
120
+ FunctionExpression function
121
+
122
+ # A binary expression
123
+ BinaryExpression binary
124
+
125
+ # A unary expression
126
+ UnaryExpression unary
127
+
128
+ # An expression group
129
+ Expression group
130
+
131
+
132
+ # A binary expression
133
+ struct BinaryExpression
134
+
135
+ # The binary expression operator
136
+ BinaryExpressionOperator op
137
+
138
+ # The left expression
139
+ Expression left
140
+
141
+ # The right expression
142
+ Expression right
143
+
144
+
145
+ # A binary expression operator
146
+ enum BinaryExpressionOperator
147
+
148
+ # Exponentiation
149
+ "**"
150
+
151
+ # Multiplication
152
+ "*"
153
+
154
+ # Division
155
+ "/"
156
+
157
+ # Remainder
158
+ "%"
159
+
160
+ # Addition
161
+ "+"
162
+
163
+ # Subtraction
164
+ "-"
165
+
166
+ # Less than or equal
167
+ "<="
168
+
169
+ # Less than
170
+ "<"
171
+
172
+ # Greater than or equal
173
+ ">="
174
+
175
+ # Greater than
176
+ ">"
177
+
178
+ # Equal
179
+ "=="
180
+
181
+ # Not equal
182
+ "!="
183
+
184
+ # Logical AND
185
+ "&&"
186
+
187
+ # Logical OR
188
+ "||"
189
+
190
+
191
+ # A unary expression
192
+ struct UnaryExpression
193
+
194
+ # The unary expression operator
195
+ UnaryExpressionOperator op
196
+
197
+ # The expression
198
+ Expression expr
199
+
200
+
201
+ # A unary expression operator
202
+ enum UnaryExpressionOperator
203
+
204
+ # Unary negation
205
+ "-"
206
+
207
+ # Logical NOT
208
+ "!"
209
+
210
+
211
+ # A function expression
212
+ struct FunctionExpression
213
+
214
+ # The function name
215
+ string name
216
+
217
+ # The function arguments
218
+ optional Expression[] args
219
+ ''')
220
+
221
+
222
+ def validate_script(script):
223
+ """
224
+ Validate a BareScript script model
225
+
226
+ :param script: The `BareScript model <https://craigahobbs.github.io/bare-script-py/model/#var.vName='BareScript'>`__
227
+ :type script: dict
228
+ :return: The validated BareScript model
229
+ :rtype: dict
230
+ :raises ~schema_markdown.ValidationError: A validation error occurred
231
+ """
232
+ return validate_type(BARE_SCRIPT_TYPES, 'BareScript', script)
233
+
234
+
235
+ def validate_expression(expr):
236
+ """
237
+ Validate an expression model
238
+
239
+ :param script: The `expression model <https://craigahobbs.github.io/bare-script-py/model/#var.vName='Expression'>`__
240
+ :type script: dict
241
+ :return: The validated expression model
242
+ :rtype: dict
243
+ :raises ~schema_markdown.ValidationError: A validation error occurred
244
+ """
245
+ return validate_type(BARE_SCRIPT_TYPES, 'Expression', expr)
246
+
247
+
248
+ def lint_script(script):
249
+ """
250
+ Lint a BareScript script model
251
+
252
+ :param script: The `BareScript model <https://craigahobbs.github.io/bare-script-py/model/#var.vName='BareScript'>`__
253
+ :type script: dict
254
+ :return: The list of lint warnings
255
+ :rtype: list[str]
256
+ """
257
+ return [] if script else []
bare_script/options.py ADDED
@@ -0,0 +1,108 @@
1
+ # Licensed under the MIT License
2
+ # https://github.com/craigahobbs/bare-script-py/blob/main/LICENSE
3
+
4
+ """
5
+ BareScript runtime option function implementations
6
+ """
7
+
8
+ import os
9
+ from pathlib import Path
10
+ import re
11
+ import urllib.request
12
+
13
+
14
+ def fetch_http(request):
15
+ """
16
+ A :func:`fetch function <fetch_fn>` implementation that fetches resources using HTTP GET and POST
17
+ """
18
+
19
+ body = request.get('body')
20
+ req = urllib.request.Request(
21
+ request['url'],
22
+ data=body.encode('utf-8') if body is not None else None,
23
+ headers=request.get('headers', {})
24
+ )
25
+ with urllib.request.urlopen(req) as response:
26
+ return response.read().decode('utf-8')
27
+
28
+
29
+ def fetch_read_only(request):
30
+ """
31
+ A :func:`fetch function <fetch_fn>` implementation that fetches resources that uses HTTP GET
32
+ and POST for URLs, otherwise read-only file system access
33
+ """
34
+
35
+ # HTTP GET/POST?
36
+ url = request['url']
37
+ if _R_URL.match(url):
38
+ return fetch_http(request)
39
+
40
+ # File write?
41
+ body = request.get('body')
42
+ if body is not None:
43
+ return None
44
+
45
+ # File read
46
+ with open(url, 'r', encoding='utf-8') as fh:
47
+ return fh.read()
48
+
49
+
50
+ def fetch_read_write(request):
51
+ """
52
+ A :func:`fetch function <fetch_fn>` implementation that fetches resources that uses HTTP GET
53
+ and POST for URLs, otherwise read-write file system access
54
+ """
55
+
56
+ # HTTP GET/POST?
57
+ url = request['url']
58
+ if _R_URL.match(url):
59
+ return fetch_http(request)
60
+
61
+ # File write?
62
+ body = request.get('body')
63
+ if body is not None:
64
+ with open(url, 'w', encoding='utf-8') as fh:
65
+ fh.write(url)
66
+ return '{}'
67
+
68
+ # File read
69
+ with open(url, 'r', encoding='utf-8') as fh:
70
+ return fh.read()
71
+
72
+
73
+ def log_print(message):
74
+ """
75
+ A :func:`log function <log_fn>` implementation that uses print
76
+ """
77
+
78
+ print(message)
79
+
80
+
81
+ def url_file_relative(file_, url):
82
+ """
83
+ A :func:`URL function <url_fn>` implementation that fixes up file-relative paths
84
+
85
+ :param file_: The URL or OS path to which relative URLs are relative
86
+ :param url: The URL or POSIX path to resolve
87
+ :return: The resolved URL
88
+ """
89
+
90
+ # URL?
91
+ if re.match(_R_URL, url):
92
+ return url
93
+
94
+ # Absolute POSIX path? If so, convert to OS path
95
+ if url.startswith('/'):
96
+ return str(Path(url))
97
+
98
+ # URL is relative POSIX path...
99
+
100
+ # Is relative-file a URL?
101
+ if re.match(_R_URL, file_):
102
+ return f'{file_[:file_.rfind("/") + 1]}{url}'
103
+
104
+ # The relative-file is an OS path...
105
+ return os.path.join(os.path.dirname(file_), str(Path(url)))
106
+
107
+
108
+ _R_URL = re.compile(r'^[a-z]+:')