chemql-python 1.0.1__tar.gz → 1.0.3__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.0.1 → chemql_python-1.0.3}/PKG-INFO +1 -1
- {chemql_python-1.0.1 → chemql_python-1.0.3}/pyproject.toml +1 -1
- {chemql_python-1.0.1 → chemql_python-1.0.3}/src/chemql/__init__.py +64 -33
- {chemql_python-1.0.1 → chemql_python-1.0.3}/src/chemql_python.egg-info/PKG-INFO +1 -1
- {chemql_python-1.0.1 → chemql_python-1.0.3}/LICENSE +0 -0
- {chemql_python-1.0.1 → chemql_python-1.0.3}/README.md +0 -0
- {chemql_python-1.0.1 → chemql_python-1.0.3}/setup.cfg +0 -0
- {chemql_python-1.0.1 → chemql_python-1.0.3}/src/chemql/__main__.py +0 -0
- {chemql_python-1.0.1 → chemql_python-1.0.3}/src/chemql/data/BondEnergies.json +0 -0
- {chemql_python-1.0.1 → chemql_python-1.0.3}/src/chemql/data/MoleculeBonds.json +0 -0
- {chemql_python-1.0.1 → chemql_python-1.0.3}/src/chemql/data/Molecules.json +0 -0
- {chemql_python-1.0.1 → chemql_python-1.0.3}/src/chemql/data/PeriodicTableJSON.json +0 -0
- {chemql_python-1.0.1 → chemql_python-1.0.3}/src/chemql/data/Reactions.json +0 -0
- {chemql_python-1.0.1 → chemql_python-1.0.3}/src/chemql/data/THIRD_PARTY_LICENSES/PeriodicTableJSON.txt +0 -0
- {chemql_python-1.0.1 → chemql_python-1.0.3}/src/chemql/data/THIRD_PARTY_LICENSES/RHEA.txt +0 -0
- {chemql_python-1.0.1 → chemql_python-1.0.3}/src/chemql/html/periodic_table.html +0 -0
- {chemql_python-1.0.1 → chemql_python-1.0.3}/src/chemql_python.egg-info/SOURCES.txt +0 -0
- {chemql_python-1.0.1 → chemql_python-1.0.3}/src/chemql_python.egg-info/dependency_links.txt +0 -0
- {chemql_python-1.0.1 → chemql_python-1.0.3}/src/chemql_python.egg-info/entry_points.txt +0 -0
- {chemql_python-1.0.1 → chemql_python-1.0.3}/src/chemql_python.egg-info/requires.txt +0 -0
- {chemql_python-1.0.1 → chemql_python-1.0.3}/src/chemql_python.egg-info/top_level.txt +0 -0
- {chemql_python-1.0.1 → chemql_python-1.0.3}/tests/test_external_molecule_lookup.py +0 -0
- {chemql_python-1.0.1 → chemql_python-1.0.3}/tests/test_public_api.py +0 -0
- {chemql_python-1.0.1 → chemql_python-1.0.3}/tests/test_reactions.py +0 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import json
|
|
2
2
|
import math
|
|
3
3
|
import shlex
|
|
4
|
+
import os
|
|
4
5
|
import re
|
|
5
6
|
import ast
|
|
6
7
|
import argparse
|
|
@@ -36,73 +37,98 @@ __all__ = [
|
|
|
36
37
|
"search",
|
|
37
38
|
"union",
|
|
38
39
|
"intersection",
|
|
40
|
+
"__version__"
|
|
39
41
|
]
|
|
40
42
|
|
|
43
|
+
__version__ = "1.0.3"
|
|
41
44
|
|
|
42
45
|
|
|
43
46
|
_shell_process = None
|
|
44
47
|
|
|
45
48
|
|
|
49
|
+
def enable_ansi():
|
|
50
|
+
"""Enable ANSI escape code support on Windows and Unix-like terminals."""
|
|
51
|
+
if os.name == 'nt':
|
|
52
|
+
import ctypes
|
|
53
|
+
kernel32 = ctypes.windll.kernel32
|
|
54
|
+
# STD_OUTPUT_HANDLE = -11
|
|
55
|
+
handle = kernel32.GetStdHandle(-11)
|
|
56
|
+
mode = ctypes.c_ulong()
|
|
57
|
+
if kernel32.GetConsoleMode(handle, ctypes.byref(mode)):
|
|
58
|
+
# ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004
|
|
59
|
+
new_mode = mode.value | 0x0004
|
|
60
|
+
kernel32.SetConsoleMode(handle, new_mode)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
enable_ansi()
|
|
64
|
+
|
|
46
65
|
def get_shell():
|
|
47
|
-
"""Start Bash once and reuse the same session."""
|
|
48
66
|
global _shell_process
|
|
49
67
|
|
|
50
68
|
if _shell_process is None or _shell_process.poll() is not None:
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
69
|
+
if os.name == "nt":
|
|
70
|
+
_shell_process = subprocess.Popen(
|
|
71
|
+
["cmd.exe", "/D", "/Q", "/K", "prompt $S"],
|
|
72
|
+
stdin=subprocess.PIPE,
|
|
73
|
+
stdout=subprocess.PIPE,
|
|
74
|
+
stderr=subprocess.STDOUT,
|
|
75
|
+
text=True,
|
|
76
|
+
bufsize=1,
|
|
77
|
+
)
|
|
78
|
+
else:
|
|
79
|
+
_shell_process = subprocess.Popen(
|
|
80
|
+
["bash", "--noprofile", "--norc"],
|
|
81
|
+
stdin=subprocess.PIPE,
|
|
82
|
+
stdout=subprocess.PIPE,
|
|
83
|
+
stderr=subprocess.STDOUT,
|
|
84
|
+
text=True,
|
|
85
|
+
bufsize=1,
|
|
86
|
+
)
|
|
59
87
|
|
|
60
88
|
return _shell_process
|
|
61
89
|
|
|
62
90
|
|
|
63
91
|
def run_shell_command(command):
|
|
64
|
-
"""Run a command in the persistent Bash session."""
|
|
65
92
|
shell = get_shell()
|
|
93
|
+
|
|
94
|
+
command = command.replace("\r\n", "\n").replace("\r", "\n").rstrip("\n")
|
|
66
95
|
marker = f"__CHEMQL_END_{uuid.uuid4().hex}__"
|
|
67
96
|
|
|
68
97
|
try:
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
98
|
+
if os.name == "nt":
|
|
99
|
+
# Run the command, then print a unique completion marker.
|
|
100
|
+
shell.stdin.write( #type:ignore
|
|
101
|
+
f"{command}\r\n"
|
|
102
|
+
f"echo {marker}\r\n"
|
|
103
|
+
)
|
|
104
|
+
else:
|
|
105
|
+
shell.stdin.write( #type:ignore
|
|
106
|
+
f"{command}\n"
|
|
107
|
+
f"printf '\\n%s\\n' '{marker}'\n"
|
|
108
|
+
)
|
|
109
|
+
|
|
73
110
|
shell.stdin.flush() #type:ignore
|
|
74
111
|
|
|
75
112
|
output = []
|
|
76
|
-
exit_code = None
|
|
77
113
|
|
|
78
114
|
while True:
|
|
79
115
|
line = shell.stdout.readline() #type:ignore
|
|
80
116
|
|
|
81
117
|
if not line:
|
|
82
|
-
|
|
118
|
+
return "\n".join(output) or "Shell session terminated."
|
|
83
119
|
|
|
84
|
-
line = line.rstrip("\n")
|
|
120
|
+
line = line.rstrip("\r\n")
|
|
85
121
|
|
|
86
|
-
if
|
|
87
|
-
exit_code = int(line[len(marker) + 1:])
|
|
122
|
+
if marker in line:
|
|
88
123
|
break
|
|
89
124
|
|
|
90
125
|
output.append(line)
|
|
91
126
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
if exit_code is None:
|
|
95
|
-
return result or "Shell session terminated."
|
|
96
|
-
|
|
97
|
-
if exit_code != 0 and not result:
|
|
98
|
-
return f"Command exited with status {exit_code}"
|
|
99
|
-
|
|
100
|
-
return result
|
|
127
|
+
return "\n".join(output).strip()
|
|
101
128
|
|
|
102
129
|
except (BrokenPipeError, OSError) as exc:
|
|
103
130
|
return f"Shell error: {exc}"
|
|
104
131
|
|
|
105
|
-
|
|
106
132
|
def close_shell():
|
|
107
133
|
"""Clean up the persistent shell on exit."""
|
|
108
134
|
global _shell_process
|
|
@@ -2533,6 +2559,9 @@ def execute(arguments, query_text=None, positions=None):
|
|
|
2533
2559
|
if arguments[0].lower() == "sorry":
|
|
2534
2560
|
return "\033[34mIt's ok, everybody makes mistakes👌\033[0m"
|
|
2535
2561
|
|
|
2562
|
+
if arguments[0].lower() == "version":
|
|
2563
|
+
return __version__
|
|
2564
|
+
|
|
2536
2565
|
if arguments[0] == "conditions":
|
|
2537
2566
|
if len(arguments) != 1:
|
|
2538
2567
|
return "Usage: conditions"
|
|
@@ -3117,7 +3146,7 @@ class ChemqlLexer(Lexer):
|
|
|
3117
3146
|
first_word = words[0] if words else ""
|
|
3118
3147
|
|
|
3119
3148
|
# search / source / list / return / clear / exit
|
|
3120
|
-
if first_word in {"search", "source", "list", "clear", "exit", "findel", "findmol", "findre", "set", "add", "remove", "react", "balance", "conditions", "view", "help", "dump"}:
|
|
3149
|
+
if first_word in {"search", "source", "list", "clear", "exit", "findel", "findmol", "findre", "set", "add", "remove", "react", "balance", "conditions", "view", "help", "dump", "version"}:
|
|
3121
3150
|
command_start = line.find(first_word)
|
|
3122
3151
|
command_end = command_start + len(first_word)
|
|
3123
3152
|
|
|
@@ -3365,7 +3394,7 @@ class ChemqlCompleter(Completer):
|
|
|
3365
3394
|
commands = (
|
|
3366
3395
|
"search", "source", "list", "clear", "return", "exit",
|
|
3367
3396
|
"findel", "findmol", "findre", "set", "add", "remove",
|
|
3368
|
-
"react", "balance", "conditions",
|
|
3397
|
+
"react", "balance", "conditions", "version", "help", "view"
|
|
3369
3398
|
)
|
|
3370
3399
|
|
|
3371
3400
|
if not command_words:
|
|
@@ -3582,7 +3611,7 @@ def main():
|
|
|
3582
3611
|
"-v",
|
|
3583
3612
|
"--version",
|
|
3584
3613
|
action="version",
|
|
3585
|
-
version=
|
|
3614
|
+
version=__version__,
|
|
3586
3615
|
)
|
|
3587
3616
|
|
|
3588
3617
|
|
|
@@ -3604,7 +3633,9 @@ def main():
|
|
|
3604
3633
|
)
|
|
3605
3634
|
sys.exit(upgrade_package(version_target))
|
|
3606
3635
|
|
|
3607
|
-
|
|
3636
|
+
if args.command is not None:
|
|
3637
|
+
process_lines(args.command.splitlines())
|
|
3638
|
+
return
|
|
3608
3639
|
elif args.file:
|
|
3609
3640
|
with open(args.file) as f:
|
|
3610
3641
|
code = f.read()
|
|
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
|
|
File without changes
|