chemql-python 1.2.2__tar.gz → 1.2.4__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.
- {chemql_python-1.2.2/src/chemql_python.egg-info → chemql_python-1.2.4}/PKG-INFO +6 -6
- {chemql_python-1.2.2 → chemql_python-1.2.4}/README.md +5 -5
- {chemql_python-1.2.2 → chemql_python-1.2.4}/pyproject.toml +1 -1
- {chemql_python-1.2.2 → chemql_python-1.2.4}/src/chemql/__init__.py +161 -41
- {chemql_python-1.2.2 → chemql_python-1.2.4/src/chemql_python.egg-info}/PKG-INFO +6 -6
- {chemql_python-1.2.2 → chemql_python-1.2.4}/LICENSE +0 -0
- {chemql_python-1.2.2 → chemql_python-1.2.4}/setup.cfg +0 -0
- {chemql_python-1.2.2 → chemql_python-1.2.4}/src/chemql/__main__.py +0 -0
- {chemql_python-1.2.2 → chemql_python-1.2.4}/src/chemql/data/BondEnergies.json +0 -0
- {chemql_python-1.2.2 → chemql_python-1.2.4}/src/chemql/data/MoleculeBonds.json +0 -0
- {chemql_python-1.2.2 → chemql_python-1.2.4}/src/chemql/data/Molecules.json +0 -0
- {chemql_python-1.2.2 → chemql_python-1.2.4}/src/chemql/data/PeriodicTableJSON.json +0 -0
- {chemql_python-1.2.2 → chemql_python-1.2.4}/src/chemql/data/Reactions.json +0 -0
- {chemql_python-1.2.2 → chemql_python-1.2.4}/src/chemql/data/THIRD_PARTY_LICENSES/PeriodicTableJSON.txt +0 -0
- {chemql_python-1.2.2 → chemql_python-1.2.4}/src/chemql/data/THIRD_PARTY_LICENSES/RHEA.txt +0 -0
- {chemql_python-1.2.2 → chemql_python-1.2.4}/src/chemql/html/periodic_table.html +0 -0
- {chemql_python-1.2.2 → chemql_python-1.2.4}/src/chemql_python.egg-info/SOURCES.txt +0 -0
- {chemql_python-1.2.2 → chemql_python-1.2.4}/src/chemql_python.egg-info/dependency_links.txt +0 -0
- {chemql_python-1.2.2 → chemql_python-1.2.4}/src/chemql_python.egg-info/entry_points.txt +0 -0
- {chemql_python-1.2.2 → chemql_python-1.2.4}/src/chemql_python.egg-info/requires.txt +0 -0
- {chemql_python-1.2.2 → chemql_python-1.2.4}/src/chemql_python.egg-info/top_level.txt +0 -0
- {chemql_python-1.2.2 → chemql_python-1.2.4}/tests/test_external_molecule_lookup.py +0 -0
- {chemql_python-1.2.2 → chemql_python-1.2.4}/tests/test_public_api.py +0 -0
- {chemql_python-1.2.2 → chemql_python-1.2.4}/tests/test_reactions.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: chemql-python
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.4
|
|
4
4
|
Summary: A chemistry-focused query language and REPL
|
|
5
5
|
Author-email: Mohammad Rakibul Islam <rakibulofficial1017@gmail.com>
|
|
6
6
|
Requires-Python: >=3.10
|
|
@@ -17,15 +17,15 @@ Dynamic: license-file
|
|
|
17
17
|
shell commands in one interactive environment.**
|
|
18
18
|
|
|
19
19
|
ChemQL is a command-line chemistry query language for exploring chemical
|
|
20
|
-
elements, molecules, and reactions. Version 1.2.
|
|
20
|
+
elements, molecules, and reactions. Version 1.2.3 combines database-style
|
|
21
21
|
chemistry queries, reaction tools, Python interoperability, reusable functions
|
|
22
22
|
and macros, and a persistent shell in one scriptable environment. It combines a small SQL-inspired
|
|
23
23
|
query syntax with a persistent Python environment, reaction utilities,
|
|
24
24
|
optional external molecule lookup, and tools for running repeatable
|
|
25
25
|
scripts.
|
|
26
26
|
|
|
27
|
-
> **Version covered by this README:** 1.2.
|
|
28
|
-
> The examples below describe the ChemQL 1.2.
|
|
27
|
+
> **Version covered by this README:** 1.2.3\
|
|
28
|
+
> The examples below describe the ChemQL 1.2.3 source. Dataset
|
|
29
29
|
> contents and external-service availability can affect individual
|
|
30
30
|
> lookup results.
|
|
31
31
|
|
|
@@ -538,7 +538,7 @@ queried or inspected from Python.
|
|
|
538
538
|
|
|
539
539
|
## Preprocessor, functions, and macros
|
|
540
540
|
|
|
541
|
-
ChemQL 1.2.
|
|
541
|
+
ChemQL 1.2.3 adds three ways to reuse values and logic. These declarations
|
|
542
542
|
are processed in source order: definitions affect later lines, not earlier
|
|
543
543
|
ones. They persist during the current ChemQL process/session; they are not
|
|
544
544
|
saved automatically between separate launches.
|
|
@@ -833,7 +833,7 @@ redirect a file into the command.
|
|
|
833
833
|
``` bash
|
|
834
834
|
chemql --version
|
|
835
835
|
chemql --upgrade
|
|
836
|
-
chemql --upgrade 1.2.
|
|
836
|
+
chemql --upgrade 1.2.3
|
|
837
837
|
```
|
|
838
838
|
|
|
839
839
|
`--upgrade` installs the latest published `chemql-python` release; supplying a
|
|
@@ -4,15 +4,15 @@
|
|
|
4
4
|
shell commands in one interactive environment.**
|
|
5
5
|
|
|
6
6
|
ChemQL is a command-line chemistry query language for exploring chemical
|
|
7
|
-
elements, molecules, and reactions. Version 1.2.
|
|
7
|
+
elements, molecules, and reactions. Version 1.2.3 combines database-style
|
|
8
8
|
chemistry queries, reaction tools, Python interoperability, reusable functions
|
|
9
9
|
and macros, and a persistent shell in one scriptable environment. It combines a small SQL-inspired
|
|
10
10
|
query syntax with a persistent Python environment, reaction utilities,
|
|
11
11
|
optional external molecule lookup, and tools for running repeatable
|
|
12
12
|
scripts.
|
|
13
13
|
|
|
14
|
-
> **Version covered by this README:** 1.2.
|
|
15
|
-
> The examples below describe the ChemQL 1.2.
|
|
14
|
+
> **Version covered by this README:** 1.2.3\
|
|
15
|
+
> The examples below describe the ChemQL 1.2.3 source. Dataset
|
|
16
16
|
> contents and external-service availability can affect individual
|
|
17
17
|
> lookup results.
|
|
18
18
|
|
|
@@ -525,7 +525,7 @@ queried or inspected from Python.
|
|
|
525
525
|
|
|
526
526
|
## Preprocessor, functions, and macros
|
|
527
527
|
|
|
528
|
-
ChemQL 1.2.
|
|
528
|
+
ChemQL 1.2.3 adds three ways to reuse values and logic. These declarations
|
|
529
529
|
are processed in source order: definitions affect later lines, not earlier
|
|
530
530
|
ones. They persist during the current ChemQL process/session; they are not
|
|
531
531
|
saved automatically between separate launches.
|
|
@@ -820,7 +820,7 @@ redirect a file into the command.
|
|
|
820
820
|
``` bash
|
|
821
821
|
chemql --version
|
|
822
822
|
chemql --upgrade
|
|
823
|
-
chemql --upgrade 1.2.
|
|
823
|
+
chemql --upgrade 1.2.3
|
|
824
824
|
```
|
|
825
825
|
|
|
826
826
|
`--upgrade` installs the latest published `chemql-python` release; supplying a
|
|
@@ -47,7 +47,7 @@ __all__ = [
|
|
|
47
47
|
"__version__"
|
|
48
48
|
]
|
|
49
49
|
|
|
50
|
-
__version__ = "1.2.
|
|
50
|
+
__version__ = "1.2.4"
|
|
51
51
|
|
|
52
52
|
# Persistent preprocessor/function state for the current ChemQL session.
|
|
53
53
|
DEFINITIONS = {}
|
|
@@ -55,6 +55,7 @@ FUNCTIONS = {}
|
|
|
55
55
|
MACROS = {}
|
|
56
56
|
EXECUTION_HISTORY = []
|
|
57
57
|
_DEFINITION_NAME = r"[A-Za-z_][A-Za-z0-9_]*"
|
|
58
|
+
_NO_RETURN = object()
|
|
58
59
|
|
|
59
60
|
def _expand_definitions(line):
|
|
60
61
|
"""Replace @NAME literally, including inside strings, using current definitions."""
|
|
@@ -107,113 +108,217 @@ def _split_function_arguments(source):
|
|
|
107
108
|
if tail or source.strip():
|
|
108
109
|
args.append(tail)
|
|
109
110
|
return args
|
|
111
|
+
def is_block_header(line):
|
|
112
|
+
"""Return True only for actual ChemQL block headers."""
|
|
113
|
+
if not (line.startswith("[") and line.endswith("]")):
|
|
114
|
+
return False
|
|
115
|
+
|
|
116
|
+
code = line[1:-1].strip()
|
|
117
|
+
|
|
118
|
+
return (
|
|
119
|
+
code.startswith("if ")
|
|
120
|
+
or code.startswith("for ")
|
|
121
|
+
or code.startswith("while ")
|
|
122
|
+
)
|
|
110
123
|
|
|
111
124
|
def _call_function(name, arguments):
|
|
112
|
-
"""Call a ChemQL function, including
|
|
125
|
+
"""Call a ChemQL function, including let assignments and block syntax."""
|
|
113
126
|
if name not in FUNCTIONS:
|
|
114
127
|
raise NameError(f"Unknown ChemQL function `{name}`")
|
|
115
128
|
|
|
116
129
|
values = [evaluate_python(arg) for arg in arguments]
|
|
117
130
|
definition = FUNCTIONS[name]
|
|
131
|
+
|
|
118
132
|
saved_globals = python_globals.copy()
|
|
119
133
|
saved_chemql_variables = CHEMQL_VARIABLES.copy()
|
|
134
|
+
|
|
120
135
|
had_arguments = "arguments" in python_globals
|
|
121
136
|
saved_arguments = python_globals.get("arguments")
|
|
122
|
-
|
|
137
|
+
|
|
138
|
+
# Expose only the supplied arguments.
|
|
123
139
|
python_globals["arguments"] = list(values)
|
|
124
140
|
|
|
125
141
|
def substitute_parameters(source):
|
|
126
|
-
|
|
142
|
+
"""Replace \\1, \\2, etc. without corrupting \\10 or longer indices."""
|
|
127
143
|
return re.sub(
|
|
128
144
|
r"\\(\d+)",
|
|
129
|
-
lambda match:
|
|
130
|
-
|
|
145
|
+
lambda match: (
|
|
146
|
+
repr(values[int(match.group(1)) - 1])
|
|
147
|
+
if 0 < int(match.group(1)) <= len(values)
|
|
148
|
+
else match.group(0)
|
|
149
|
+
),
|
|
131
150
|
source,
|
|
132
151
|
)
|
|
133
152
|
|
|
134
153
|
def normalize_let_line(source):
|
|
135
|
-
"""Translate
|
|
136
|
-
match = re.fullmatch(
|
|
154
|
+
"""Translate let name = expression into a Python assignment."""
|
|
155
|
+
match = re.fullmatch(
|
|
156
|
+
r"\s*let\s+([A-Za-z_]\w*)\s*=\s*(.*?)\s*",
|
|
157
|
+
source,
|
|
158
|
+
)
|
|
159
|
+
|
|
137
160
|
if not match:
|
|
138
161
|
return source
|
|
162
|
+
|
|
139
163
|
variable, expression = match.groups()
|
|
140
164
|
expression = substitute_parameters(expression)
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
#
|
|
165
|
+
expression = _expand_definitions(expression)
|
|
166
|
+
|
|
167
|
+
# Translate simple ChemQL [variable] expressions into (variable).
|
|
144
168
|
expression = re.sub(
|
|
145
|
-
r"\[\s*([A-Za-z_]
|
|
169
|
+
r"\[\s*([A-Za-z_]\w*(?:\.[A-Za-z_]\w*)*)\s*\]",
|
|
146
170
|
r"(\1)",
|
|
147
171
|
expression,
|
|
148
172
|
)
|
|
173
|
+
|
|
149
174
|
return f"[{variable} = {expression}]"
|
|
150
175
|
|
|
151
|
-
|
|
152
|
-
|
|
176
|
+
def execute_function_lines(lines):
|
|
177
|
+
"""Execute function statements and propagate return values."""
|
|
153
178
|
i = 0
|
|
154
|
-
|
|
155
|
-
|
|
179
|
+
|
|
180
|
+
while i < len(lines):
|
|
181
|
+
line = lines[i].strip()
|
|
182
|
+
|
|
156
183
|
if not line:
|
|
157
184
|
i += 1
|
|
158
185
|
continue
|
|
159
186
|
|
|
160
|
-
#
|
|
187
|
+
# Multiline Python block.
|
|
161
188
|
if line == "[[[":
|
|
162
189
|
block = []
|
|
163
190
|
i += 1
|
|
164
|
-
|
|
165
|
-
|
|
191
|
+
|
|
192
|
+
while i < len(lines) and lines[i].strip() != "]]]":
|
|
193
|
+
source_line = substitute_parameters(lines[i])
|
|
194
|
+
source_line = _expand_definitions(source_line)
|
|
195
|
+
block.append(source_line)
|
|
166
196
|
i += 1
|
|
167
|
-
|
|
168
|
-
|
|
197
|
+
|
|
198
|
+
if i >= len(lines):
|
|
199
|
+
raise SyntaxError(
|
|
200
|
+
f"Missing `]]]` in function `{name}`"
|
|
201
|
+
)
|
|
202
|
+
|
|
169
203
|
evaluate_python("\n".join(block))
|
|
170
204
|
i += 1
|
|
171
205
|
continue
|
|
172
206
|
|
|
173
|
-
#
|
|
174
|
-
#
|
|
175
|
-
|
|
176
|
-
|
|
207
|
+
# Recognize block headers generically, while excluding
|
|
208
|
+
# closing and branch markers from being treated as headers.
|
|
209
|
+
# generic_header = re.match(
|
|
210
|
+
# r"^\[\s*(?!endblock\b|else\b|elif\b)"
|
|
211
|
+
# r"[A-Za-z_]\w*\b.*\]\s*$",
|
|
212
|
+
# line,
|
|
213
|
+
# )
|
|
214
|
+
|
|
215
|
+
if is_block_header(line):
|
|
216
|
+
end = find_endblock(lines, i + 1)
|
|
217
|
+
|
|
177
218
|
block_body = [
|
|
178
219
|
normalize_let_line(substitute_parameters(source_line))
|
|
179
|
-
for source_line in
|
|
220
|
+
for source_line in lines[i + 1:end]
|
|
180
221
|
]
|
|
222
|
+
|
|
181
223
|
code = line[1:-1].strip()
|
|
224
|
+
|
|
182
225
|
if code.startswith("for "):
|
|
183
226
|
execute_for_block(line, block_body)
|
|
227
|
+
|
|
184
228
|
elif code.startswith("while "):
|
|
185
229
|
execute_while_block(line, block_body)
|
|
230
|
+
|
|
186
231
|
elif code.startswith("if "):
|
|
187
|
-
|
|
232
|
+
# Expand parameters and definitions before evaluating.
|
|
233
|
+
condition = code[3:].strip()
|
|
234
|
+
condition = substitute_parameters(condition)
|
|
235
|
+
condition = _expand_definitions(condition)
|
|
236
|
+
|
|
237
|
+
# Find the top-level else branch.
|
|
238
|
+
else_index = next(
|
|
239
|
+
(
|
|
240
|
+
j
|
|
241
|
+
for j, source_line in enumerate(block_body)
|
|
242
|
+
if source_line.strip() == "[else]"
|
|
243
|
+
),
|
|
244
|
+
None,
|
|
245
|
+
)
|
|
246
|
+
|
|
247
|
+
if evaluate_python(condition):
|
|
248
|
+
selected_body = (
|
|
249
|
+
block_body
|
|
250
|
+
if else_index is None
|
|
251
|
+
else block_body[:else_index]
|
|
252
|
+
)
|
|
253
|
+
else:
|
|
254
|
+
selected_body = (
|
|
255
|
+
[]
|
|
256
|
+
if else_index is None
|
|
257
|
+
else block_body[else_index + 1:]
|
|
258
|
+
)
|
|
259
|
+
|
|
260
|
+
# Execute only the selected branch. A return exits
|
|
261
|
+
# this function immediately.
|
|
262
|
+
result = execute_function_lines(selected_body)
|
|
263
|
+
|
|
264
|
+
if result is not _NO_RETURN:
|
|
265
|
+
return result
|
|
266
|
+
|
|
188
267
|
else:
|
|
189
|
-
raise SyntaxError(
|
|
268
|
+
raise SyntaxError(
|
|
269
|
+
f"Unsupported function block `{code}`"
|
|
270
|
+
)
|
|
271
|
+
|
|
190
272
|
i = end + 1
|
|
191
273
|
continue
|
|
192
274
|
|
|
193
275
|
if line == "[endblock]":
|
|
194
|
-
raise SyntaxError(
|
|
276
|
+
raise SyntaxError(
|
|
277
|
+
f"Unexpected `[endblock]` in function `{name}`"
|
|
278
|
+
)
|
|
279
|
+
|
|
280
|
+
# Handle return statements inside the function.
|
|
281
|
+
if re.match(r"^return\b", line):
|
|
282
|
+
expression = re.sub(r"^return\b", "", line, count=1).strip()
|
|
195
283
|
|
|
196
|
-
if line.startswith("return"):
|
|
197
|
-
expression = line[len("return"):].strip()
|
|
198
284
|
if expression.startswith("[") and expression.endswith("]"):
|
|
199
|
-
expression = expression[1:-1]
|
|
285
|
+
expression = expression[1:-1].strip()
|
|
286
|
+
|
|
200
287
|
expression = substitute_parameters(expression)
|
|
288
|
+
expression = _expand_definitions(expression)
|
|
289
|
+
|
|
201
290
|
return evaluate_python(expression) if expression else None
|
|
202
291
|
|
|
203
292
|
normalized = normalize_let_line(line)
|
|
293
|
+
|
|
204
294
|
if normalized != line:
|
|
205
|
-
# The wrapper is ChemQL syntax; pass the assignment itself to Python.
|
|
206
295
|
evaluate_python(normalized[1:-1])
|
|
296
|
+
elif line.startswith("[") and line.endswith("]"):
|
|
297
|
+
expression = line[1:-1].strip()
|
|
298
|
+
expression = substitute_parameters(expression)
|
|
299
|
+
expression = _expand_definitions(expression)
|
|
300
|
+
evaluate_python(expression)
|
|
207
301
|
else:
|
|
208
|
-
|
|
302
|
+
expression = substitute_parameters(line)
|
|
303
|
+
expression = _expand_definitions(expression)
|
|
304
|
+
evaluate_python(expression)
|
|
305
|
+
|
|
209
306
|
i += 1
|
|
210
|
-
|
|
307
|
+
|
|
308
|
+
return _NO_RETURN
|
|
309
|
+
|
|
310
|
+
try:
|
|
311
|
+
result = execute_function_lines(definition["body"])
|
|
312
|
+
return None if result is _NO_RETURN else result
|
|
313
|
+
|
|
211
314
|
finally:
|
|
212
|
-
#
|
|
315
|
+
# Restore the caller's namespaces.
|
|
213
316
|
python_globals.clear()
|
|
214
317
|
python_globals.update(saved_globals)
|
|
318
|
+
|
|
215
319
|
CHEMQL_VARIABLES.clear()
|
|
216
320
|
CHEMQL_VARIABLES.update(saved_chemql_variables)
|
|
321
|
+
|
|
217
322
|
if had_arguments:
|
|
218
323
|
python_globals["arguments"] = saved_arguments
|
|
219
324
|
else:
|
|
@@ -2416,15 +2521,30 @@ def find_endblock(lines, start):
|
|
|
2416
2521
|
for i in range(start, len(lines)):
|
|
2417
2522
|
stripped = lines[i].strip()
|
|
2418
2523
|
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
elif stripped == "[endblock]":
|
|
2524
|
+
# Closing block.
|
|
2525
|
+
if stripped == "[endblock]":
|
|
2423
2526
|
depth -= 1
|
|
2424
2527
|
|
|
2425
2528
|
if depth == 0:
|
|
2426
2529
|
return i
|
|
2427
2530
|
|
|
2531
|
+
continue
|
|
2532
|
+
|
|
2533
|
+
# Branch markers do not start new blocks.
|
|
2534
|
+
if stripped in ("[else]", "[endif]", "[endfor]", "[endwhile]"):
|
|
2535
|
+
continue
|
|
2536
|
+
|
|
2537
|
+
# Recognize both validated Python headers and generic
|
|
2538
|
+
# ChemQL block headers, consistently with _call_function().
|
|
2539
|
+
generic_header = re.match(
|
|
2540
|
+
r"^\[\s*(?!endblock\b|else\b|elif\b)"
|
|
2541
|
+
r"[A-Za-z_]\w*\b.*\]\s*$",
|
|
2542
|
+
stripped,
|
|
2543
|
+
)
|
|
2544
|
+
|
|
2545
|
+
if is_block_header(stripped):
|
|
2546
|
+
depth += 1
|
|
2547
|
+
|
|
2428
2548
|
raise SyntaxError("Missing `[endblock]`")
|
|
2429
2549
|
|
|
2430
2550
|
def remove_comments(line):
|
|
@@ -2593,7 +2713,7 @@ def execute_if_block(header, body):
|
|
|
2593
2713
|
)
|
|
2594
2714
|
|
|
2595
2715
|
for section_header, section_body in sections:
|
|
2596
|
-
code = section_header[1:-1].strip()
|
|
2716
|
+
code = _expand_definitions(section_header[1:-1].strip())
|
|
2597
2717
|
|
|
2598
2718
|
if code.startswith("if "):
|
|
2599
2719
|
condition = code[3:].strip()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: chemql-python
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.4
|
|
4
4
|
Summary: A chemistry-focused query language and REPL
|
|
5
5
|
Author-email: Mohammad Rakibul Islam <rakibulofficial1017@gmail.com>
|
|
6
6
|
Requires-Python: >=3.10
|
|
@@ -17,15 +17,15 @@ Dynamic: license-file
|
|
|
17
17
|
shell commands in one interactive environment.**
|
|
18
18
|
|
|
19
19
|
ChemQL is a command-line chemistry query language for exploring chemical
|
|
20
|
-
elements, molecules, and reactions. Version 1.2.
|
|
20
|
+
elements, molecules, and reactions. Version 1.2.3 combines database-style
|
|
21
21
|
chemistry queries, reaction tools, Python interoperability, reusable functions
|
|
22
22
|
and macros, and a persistent shell in one scriptable environment. It combines a small SQL-inspired
|
|
23
23
|
query syntax with a persistent Python environment, reaction utilities,
|
|
24
24
|
optional external molecule lookup, and tools for running repeatable
|
|
25
25
|
scripts.
|
|
26
26
|
|
|
27
|
-
> **Version covered by this README:** 1.2.
|
|
28
|
-
> The examples below describe the ChemQL 1.2.
|
|
27
|
+
> **Version covered by this README:** 1.2.3\
|
|
28
|
+
> The examples below describe the ChemQL 1.2.3 source. Dataset
|
|
29
29
|
> contents and external-service availability can affect individual
|
|
30
30
|
> lookup results.
|
|
31
31
|
|
|
@@ -538,7 +538,7 @@ queried or inspected from Python.
|
|
|
538
538
|
|
|
539
539
|
## Preprocessor, functions, and macros
|
|
540
540
|
|
|
541
|
-
ChemQL 1.2.
|
|
541
|
+
ChemQL 1.2.3 adds three ways to reuse values and logic. These declarations
|
|
542
542
|
are processed in source order: definitions affect later lines, not earlier
|
|
543
543
|
ones. They persist during the current ChemQL process/session; they are not
|
|
544
544
|
saved automatically between separate launches.
|
|
@@ -833,7 +833,7 @@ redirect a file into the command.
|
|
|
833
833
|
``` bash
|
|
834
834
|
chemql --version
|
|
835
835
|
chemql --upgrade
|
|
836
|
-
chemql --upgrade 1.2.
|
|
836
|
+
chemql --upgrade 1.2.3
|
|
837
837
|
```
|
|
838
838
|
|
|
839
839
|
`--upgrade` installs the latest published `chemql-python` release; supplying a
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|