chemql-python 1.5.9__tar.gz → 1.5.10__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.5.9 → chemql_python-1.5.10}/PKG-INFO +2 -2
- {chemql_python-1.5.9 → chemql_python-1.5.10}/README.md +1 -1
- {chemql_python-1.5.9 → chemql_python-1.5.10}/pyproject.toml +1 -1
- {chemql_python-1.5.9 → chemql_python-1.5.10}/src/chemql/__init__.py +111 -4
- {chemql_python-1.5.9 → chemql_python-1.5.10}/src/chemql_python.egg-info/PKG-INFO +2 -2
- {chemql_python-1.5.9 → chemql_python-1.5.10}/LICENSE +0 -0
- {chemql_python-1.5.9 → chemql_python-1.5.10}/setup.cfg +0 -0
- {chemql_python-1.5.9 → chemql_python-1.5.10}/src/chemql/__main__.py +0 -0
- {chemql_python-1.5.9 → chemql_python-1.5.10}/src/chemql/codecql.py +0 -0
- {chemql_python-1.5.9 → chemql_python-1.5.10}/src/chemql/colors.json +0 -0
- {chemql_python-1.5.9 → chemql_python-1.5.10}/src/chemql/data/BondEnergies.json +0 -0
- {chemql_python-1.5.9 → chemql_python-1.5.10}/src/chemql/data/MoleculeBonds.json +0 -0
- {chemql_python-1.5.9 → chemql_python-1.5.10}/src/chemql/data/Molecules.json +0 -0
- {chemql_python-1.5.9 → chemql_python-1.5.10}/src/chemql/data/PeriodicTableJSON.json +0 -0
- {chemql_python-1.5.9 → chemql_python-1.5.10}/src/chemql/data/Reactions.json +0 -0
- {chemql_python-1.5.9 → chemql_python-1.5.10}/src/chemql/data/THIRD_PARTY_LICENSES/PeriodicTableJSON.txt +0 -0
- {chemql_python-1.5.9 → chemql_python-1.5.10}/src/chemql/data/THIRD_PARTY_LICENSES/RHEA.txt +0 -0
- {chemql_python-1.5.9 → chemql_python-1.5.10}/src/chemql/html/periodic_table.html +0 -0
- {chemql_python-1.5.9 → chemql_python-1.5.10}/src/chemql/stdlib/README.md +0 -0
- {chemql_python-1.5.9 → chemql_python-1.5.10}/src/chemql/stdlib/collections.cql +0 -0
- {chemql_python-1.5.9 → chemql_python-1.5.10}/src/chemql/stdlib/datetime.cql +0 -0
- {chemql_python-1.5.9 → chemql_python-1.5.10}/src/chemql/stdlib/decimal.cql +0 -0
- {chemql_python-1.5.9 → chemql_python-1.5.10}/src/chemql/stdlib/fractions.cql +0 -0
- {chemql_python-1.5.9 → chemql_python-1.5.10}/src/chemql/stdlib/json.cql +0 -0
- {chemql_python-1.5.9 → chemql_python-1.5.10}/src/chemql/stdlib/math/statistics.cql +0 -0
- {chemql_python-1.5.9 → chemql_python-1.5.10}/src/chemql/stdlib/math.cql +0 -0
- {chemql_python-1.5.9 → chemql_python-1.5.10}/src/chemql/stdlib/pathlib.cql +0 -0
- {chemql_python-1.5.9 → chemql_python-1.5.10}/src/chemql/stdlib/random.cql +0 -0
- {chemql_python-1.5.9 → chemql_python-1.5.10}/src/chemql/stdlib/text.cql +0 -0
- {chemql_python-1.5.9 → chemql_python-1.5.10}/src/chemql_python.egg-info/SOURCES.txt +0 -0
- {chemql_python-1.5.9 → chemql_python-1.5.10}/src/chemql_python.egg-info/dependency_links.txt +0 -0
- {chemql_python-1.5.9 → chemql_python-1.5.10}/src/chemql_python.egg-info/entry_points.txt +0 -0
- {chemql_python-1.5.9 → chemql_python-1.5.10}/src/chemql_python.egg-info/requires.txt +0 -0
- {chemql_python-1.5.9 → chemql_python-1.5.10}/src/chemql_python.egg-info/top_level.txt +0 -0
- {chemql_python-1.5.9 → chemql_python-1.5.10}/tests/test_codecql.py +0 -0
- {chemql_python-1.5.9 → chemql_python-1.5.10}/tests/test_external_molecule_lookup.py +0 -0
- {chemql_python-1.5.9 → chemql_python-1.5.10}/tests/test_public_api.py +0 -0
- {chemql_python-1.5.9 → chemql_python-1.5.10}/tests/test_reactions.py +0 -0
- {chemql_python-1.5.9 → chemql_python-1.5.10}/tests/test_stdlib.py +0 -0
- {chemql_python-1.5.9 → chemql_python-1.5.10}/tests/test_structured_types.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: chemql-python
|
|
3
|
-
Version: 1.5.
|
|
3
|
+
Version: 1.5.10
|
|
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
|
|
@@ -19,7 +19,7 @@ SQL-inspired syntax, inspect elements and molecules, look up reactions,
|
|
|
19
19
|
balance equations, and combine chemistry queries with Python and shell
|
|
20
20
|
commands.
|
|
21
21
|
|
|
22
|
-
- **Version:** `1.5.
|
|
22
|
+
- **Version:** `1.5.10`
|
|
23
23
|
- **PyPI distribution:** `chemql-python`
|
|
24
24
|
- **Python import / CLI name:** `chemql`
|
|
25
25
|
- **Author:** Mohammad Rakibul Islam
|
|
@@ -6,7 +6,7 @@ SQL-inspired syntax, inspect elements and molecules, look up reactions,
|
|
|
6
6
|
balance equations, and combine chemistry queries with Python and shell
|
|
7
7
|
commands.
|
|
8
8
|
|
|
9
|
-
- **Version:** `1.5.
|
|
9
|
+
- **Version:** `1.5.10`
|
|
10
10
|
- **PyPI distribution:** `chemql-python`
|
|
11
11
|
- **Python import / CLI name:** `chemql`
|
|
12
12
|
- **Author:** Mohammad Rakibul Islam
|
|
@@ -64,7 +64,7 @@ __all__ = [
|
|
|
64
64
|
"__version__"
|
|
65
65
|
]
|
|
66
66
|
|
|
67
|
-
__version__ = "1.5.
|
|
67
|
+
__version__ = "1.5.10"
|
|
68
68
|
|
|
69
69
|
# Persistent preprocessor/function state for the current ChemQL session.
|
|
70
70
|
DEFINITIONS = {}
|
|
@@ -3738,12 +3738,50 @@ def execute_query_block(text):
|
|
|
3738
3738
|
return execute_query_text(text)
|
|
3739
3739
|
|
|
3740
3740
|
|
|
3741
|
+
def _run_python_in_active_namespace(compiled, mode):
|
|
3742
|
+
"""Run compiled Python with the active ChemQL namespace's members visible.
|
|
3743
|
+
|
|
3744
|
+
Namespace members are temporarily overlaid on the shared Python globals so
|
|
3745
|
+
private helpers (for example ``_gui_add_button``) resolve inside functions
|
|
3746
|
+
belonging to their package, without permanently leaking those names into the
|
|
3747
|
+
caller's Python/ChemQL global scope.
|
|
3748
|
+
"""
|
|
3749
|
+
namespace = _CURRENT_NAMESPACE
|
|
3750
|
+
if namespace is None:
|
|
3751
|
+
if mode == "eval":
|
|
3752
|
+
return eval(compiled, python_globals)
|
|
3753
|
+
exec(compiled, python_globals)
|
|
3754
|
+
return None
|
|
3755
|
+
|
|
3756
|
+
members = {}
|
|
3757
|
+
members.update(namespace._chemql_private)
|
|
3758
|
+
for member_name in namespace._chemql_public:
|
|
3759
|
+
if member_name in namespace.__dict__:
|
|
3760
|
+
members[member_name] = namespace.__dict__[member_name]
|
|
3761
|
+
|
|
3762
|
+
missing = object()
|
|
3763
|
+
previous = {name: python_globals.get(name, missing) for name in members}
|
|
3764
|
+
python_globals.update(members)
|
|
3765
|
+
try:
|
|
3766
|
+
if mode == "eval":
|
|
3767
|
+
return eval(compiled, python_globals)
|
|
3768
|
+
exec(compiled, python_globals)
|
|
3769
|
+
return None
|
|
3770
|
+
finally:
|
|
3771
|
+
for name, old_value in previous.items():
|
|
3772
|
+
if old_value is missing:
|
|
3773
|
+
python_globals.pop(name, None)
|
|
3774
|
+
else:
|
|
3775
|
+
python_globals[name] = old_value
|
|
3776
|
+
|
|
3777
|
+
|
|
3741
3778
|
def evaluate_python(code):
|
|
3742
3779
|
"""Evaluate Python, with {{ query }} expressions available inside it.
|
|
3743
3780
|
|
|
3744
3781
|
If the Python is an expression, its value is returned.
|
|
3745
3782
|
Otherwise it is executed and None is returned.
|
|
3746
3783
|
"""
|
|
3784
|
+
code = code.strip()
|
|
3747
3785
|
query_values = {}
|
|
3748
3786
|
rewritten = []
|
|
3749
3787
|
i = 0
|
|
@@ -3785,10 +3823,13 @@ def evaluate_python(code):
|
|
|
3785
3823
|
if isinstance(node, ast.Name) and isinstance(node.ctx, ast.Store):
|
|
3786
3824
|
if isinstance(node.ctx, ast.Store) and node.id.isidentifier() and not node.id.startswith("__chemql_"):
|
|
3787
3825
|
CHEMQL_VARIABLES.add(node.id)
|
|
3788
|
-
|
|
3789
|
-
|
|
3826
|
+
return _run_python_in_active_namespace(
|
|
3827
|
+
compile(module, "<embedded-python>", "exec"), "exec"
|
|
3828
|
+
)
|
|
3790
3829
|
|
|
3791
|
-
return
|
|
3830
|
+
return _run_python_in_active_namespace(
|
|
3831
|
+
compile(tree, "<embedded-python>", "eval"), "eval"
|
|
3832
|
+
)
|
|
3792
3833
|
|
|
3793
3834
|
|
|
3794
3835
|
def is_python_block_header(text):
|
|
@@ -4448,10 +4489,32 @@ def _ensure_package_namespace(package_name, allow_namespace_only=False):
|
|
|
4448
4489
|
if path is not None and CHEMQL_PACKAGE_BINDINGS.get(package_name) != package_name:
|
|
4449
4490
|
source_lines = path.read_text(encoding="utf-8").splitlines()
|
|
4450
4491
|
old_namespace, old_visibility = _CURRENT_NAMESPACE, _CURRENT_VISIBILITY
|
|
4492
|
+
# A package's Python blocks execute in the shared Python globals. Keep
|
|
4493
|
+
# a snapshot so names created by any supported Python syntax (single-line
|
|
4494
|
+
# blocks, multiline blocks, imports, assignments, defs, and classes) can
|
|
4495
|
+
# be attached to the package namespace after its source has executed.
|
|
4496
|
+
globals_before_package = python_globals.copy()
|
|
4451
4497
|
try:
|
|
4452
4498
|
globals()["_CURRENT_NAMESPACE"] = namespace
|
|
4453
4499
|
globals()["_CURRENT_VISIBILITY"] = "private"
|
|
4454
4500
|
process_lines(source_lines)
|
|
4501
|
+
|
|
4502
|
+
# Capture Python names introduced or replaced by this package. Do
|
|
4503
|
+
# not overwrite explicit ChemQL members, and do not capture runtime
|
|
4504
|
+
# internals or temporary values used by embedded-query expansion.
|
|
4505
|
+
existing_members = (
|
|
4506
|
+
set(namespace._chemql_public)
|
|
4507
|
+
| set(namespace._chemql_private)
|
|
4508
|
+
)
|
|
4509
|
+
ignored_prefixes = ("__chemql_",)
|
|
4510
|
+
for member_name, member_value in list(python_globals.items()):
|
|
4511
|
+
if member_name.startswith(ignored_prefixes):
|
|
4512
|
+
continue
|
|
4513
|
+
if member_name in {"__builtins__", "math", "error"}:
|
|
4514
|
+
continue
|
|
4515
|
+
if member_name not in globals_before_package or globals_before_package.get(member_name) is not member_value:
|
|
4516
|
+
if member_name not in existing_members:
|
|
4517
|
+
namespace._set_member(member_name, member_value, False)
|
|
4455
4518
|
except Exception:
|
|
4456
4519
|
# Do not mark a partially executed package as successfully loaded.
|
|
4457
4520
|
NAMESPACES.pop(package_name, None)
|
|
@@ -5245,6 +5308,50 @@ def process_lines(lines):
|
|
|
5245
5308
|
try:
|
|
5246
5309
|
with contextlib.redirect_stdout(captured):
|
|
5247
5310
|
value = evaluate_python(code)
|
|
5311
|
+
|
|
5312
|
+
# Python names declared inside a package's Python block must
|
|
5313
|
+
# also belong to that package's private namespace. Otherwise
|
|
5314
|
+
# a ChemQL function such as `GUI::addButton` cannot resolve
|
|
5315
|
+
# `_gui_add_button` when it executes in the package context.
|
|
5316
|
+
if _CURRENT_NAMESPACE is not None:
|
|
5317
|
+
try:
|
|
5318
|
+
python_module = ast.parse(code, mode="exec")
|
|
5319
|
+
declared_names = set()
|
|
5320
|
+
|
|
5321
|
+
def collect_target_names(target):
|
|
5322
|
+
if isinstance(target, ast.Name):
|
|
5323
|
+
declared_names.add(target.id)
|
|
5324
|
+
elif isinstance(target, (ast.Tuple, ast.List)):
|
|
5325
|
+
for element in target.elts:
|
|
5326
|
+
collect_target_names(element)
|
|
5327
|
+
|
|
5328
|
+
for node in python_module.body:
|
|
5329
|
+
if isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef, ast.ClassDef)):
|
|
5330
|
+
declared_names.add(node.name)
|
|
5331
|
+
elif isinstance(node, ast.Import):
|
|
5332
|
+
for alias in node.names:
|
|
5333
|
+
declared_names.add(alias.asname or alias.name.split(".")[0])
|
|
5334
|
+
elif isinstance(node, ast.ImportFrom):
|
|
5335
|
+
for alias in node.names:
|
|
5336
|
+
if alias.name != "*":
|
|
5337
|
+
declared_names.add(alias.asname or alias.name)
|
|
5338
|
+
elif isinstance(node, (ast.Assign, ast.AnnAssign, ast.AugAssign)):
|
|
5339
|
+
targets = node.targets if isinstance(node, ast.Assign) else [node.target]
|
|
5340
|
+
for target in targets:
|
|
5341
|
+
collect_target_names(target)
|
|
5342
|
+
|
|
5343
|
+
for declared_name in declared_names:
|
|
5344
|
+
if declared_name in python_globals:
|
|
5345
|
+
_CURRENT_NAMESPACE._set_member(
|
|
5346
|
+
declared_name,
|
|
5347
|
+
python_globals[declared_name],
|
|
5348
|
+
_CURRENT_VISIBILITY == "public",
|
|
5349
|
+
)
|
|
5350
|
+
except (SyntaxError, AttributeError):
|
|
5351
|
+
# The Python block already executed successfully; name
|
|
5352
|
+
# capture is best-effort and must not mask its result.
|
|
5353
|
+
pass
|
|
5354
|
+
|
|
5248
5355
|
output = captured.getvalue()
|
|
5249
5356
|
if value is not None:
|
|
5250
5357
|
output += str(value)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: chemql-python
|
|
3
|
-
Version: 1.5.
|
|
3
|
+
Version: 1.5.10
|
|
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
|
|
@@ -19,7 +19,7 @@ SQL-inspired syntax, inspect elements and molecules, look up reactions,
|
|
|
19
19
|
balance equations, and combine chemistry queries with Python and shell
|
|
20
20
|
commands.
|
|
21
21
|
|
|
22
|
-
- **Version:** `1.5.
|
|
22
|
+
- **Version:** `1.5.10`
|
|
23
23
|
- **PyPI distribution:** `chemql-python`
|
|
24
24
|
- **Python import / CLI name:** `chemql`
|
|
25
25
|
- **Author:** Mohammad Rakibul Islam
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{chemql_python-1.5.9 → chemql_python-1.5.10}/src/chemql_python.egg-info/dependency_links.txt
RENAMED
|
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
|