chemql-python 1.4.1__tar.gz → 1.5.0__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.4.1/src/chemql_python.egg-info → chemql_python-1.5.0}/PKG-INFO +159 -39
- {chemql_python-1.4.1 → chemql_python-1.5.0}/README.md +158 -38
- {chemql_python-1.4.1 → chemql_python-1.5.0}/pyproject.toml +1 -1
- {chemql_python-1.4.1 → chemql_python-1.5.0}/src/chemql/__init__.py +522 -77
- {chemql_python-1.4.1 → chemql_python-1.5.0}/src/chemql/stdlib/README.md +28 -0
- chemql_python-1.5.0/src/chemql/stdlib/decimal.cql +23 -0
- chemql_python-1.5.0/src/chemql/stdlib/fractions.cql +29 -0
- chemql_python-1.5.0/src/chemql/stdlib/pathlib.cql +38 -0
- chemql_python-1.5.0/src/chemql/stdlib/random.cql +29 -0
- {chemql_python-1.4.1 → chemql_python-1.5.0/src/chemql_python.egg-info}/PKG-INFO +159 -39
- {chemql_python-1.4.1 → chemql_python-1.5.0}/src/chemql_python.egg-info/SOURCES.txt +7 -1
- chemql_python-1.5.0/tests/test_public_api.py +87 -0
- chemql_python-1.5.0/tests/test_stdlib.py +49 -0
- chemql_python-1.5.0/tests/test_structured_types.py +181 -0
- chemql_python-1.4.1/tests/test_public_api.py +0 -28
- {chemql_python-1.4.1 → chemql_python-1.5.0}/LICENSE +0 -0
- {chemql_python-1.4.1 → chemql_python-1.5.0}/setup.cfg +0 -0
- {chemql_python-1.4.1 → chemql_python-1.5.0}/src/chemql/__main__.py +0 -0
- {chemql_python-1.4.1 → chemql_python-1.5.0}/src/chemql/data/BondEnergies.json +0 -0
- {chemql_python-1.4.1 → chemql_python-1.5.0}/src/chemql/data/MoleculeBonds.json +0 -0
- {chemql_python-1.4.1 → chemql_python-1.5.0}/src/chemql/data/Molecules.json +0 -0
- {chemql_python-1.4.1 → chemql_python-1.5.0}/src/chemql/data/PeriodicTableJSON.json +0 -0
- {chemql_python-1.4.1 → chemql_python-1.5.0}/src/chemql/data/Reactions.json +0 -0
- {chemql_python-1.4.1 → chemql_python-1.5.0}/src/chemql/data/THIRD_PARTY_LICENSES/PeriodicTableJSON.txt +0 -0
- {chemql_python-1.4.1 → chemql_python-1.5.0}/src/chemql/data/THIRD_PARTY_LICENSES/RHEA.txt +0 -0
- {chemql_python-1.4.1 → chemql_python-1.5.0}/src/chemql/html/periodic_table.html +0 -0
- {chemql_python-1.4.1 → chemql_python-1.5.0}/src/chemql/stdlib/collections.cql +0 -0
- {chemql_python-1.4.1 → chemql_python-1.5.0}/src/chemql/stdlib/datetime.cql +0 -0
- {chemql_python-1.4.1 → chemql_python-1.5.0}/src/chemql/stdlib/json.cql +0 -0
- {chemql_python-1.4.1 → chemql_python-1.5.0}/src/chemql/stdlib/math/statistics.cql +0 -0
- {chemql_python-1.4.1 → chemql_python-1.5.0}/src/chemql/stdlib/math.cql +0 -0
- {chemql_python-1.4.1 → chemql_python-1.5.0}/src/chemql/stdlib/text.cql +0 -0
- {chemql_python-1.4.1 → chemql_python-1.5.0}/src/chemql_python.egg-info/dependency_links.txt +0 -0
- {chemql_python-1.4.1 → chemql_python-1.5.0}/src/chemql_python.egg-info/entry_points.txt +0 -0
- {chemql_python-1.4.1 → chemql_python-1.5.0}/src/chemql_python.egg-info/requires.txt +0 -0
- {chemql_python-1.4.1 → chemql_python-1.5.0}/src/chemql_python.egg-info/top_level.txt +0 -0
- {chemql_python-1.4.1 → chemql_python-1.5.0}/tests/test_external_molecule_lookup.py +0 -0
- {chemql_python-1.4.1 → chemql_python-1.5.0}/tests/test_reactions.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: chemql-python
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.5.0
|
|
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.
|
|
22
|
+
- **Version:** `1.5.0`
|
|
23
23
|
- **PyPI distribution:** `chemql-python`
|
|
24
24
|
- **Python import / CLI name:** `chemql`
|
|
25
25
|
- **Author:** Mohammad Rakibul Islam
|
|
@@ -67,6 +67,9 @@ commands.
|
|
|
67
67
|
matching.
|
|
68
68
|
- Use Python statements, expressions, variables, control flow,
|
|
69
69
|
functions, macros, and structured values.
|
|
70
|
+
- Define enums with automatic or explicit values, and inherit structs
|
|
71
|
+
from structs, records, or Python classes; records can inherit from
|
|
72
|
+
other records.
|
|
70
73
|
- Execute shell commands and multiline shell blocks from the REPL.
|
|
71
74
|
- Export recorded commands and results.
|
|
72
75
|
- Use the command-line interface or import ChemQL from Python.
|
|
@@ -522,49 +525,55 @@ ChemQL provides `risk`, `fix`, `cleanup`, and `signal` for handling errors, resp
|
|
|
522
525
|
|
|
523
526
|
### `risk`
|
|
524
527
|
|
|
525
|
-
|
|
528
|
+
`risk` executes its body. If a command raises an exception, ChemQL stores
|
|
529
|
+
the error type name in the Python variable `error` and runs the optional
|
|
530
|
+
`fix` body. A returned string that happens to contain error-looking text
|
|
531
|
+
does not trigger `fix`.
|
|
526
532
|
|
|
527
533
|
```text
|
|
528
534
|
risk
|
|
529
|
-
[result = 10 /
|
|
535
|
+
[result = 10 / 2]
|
|
536
|
+
print(result)
|
|
537
|
+
fix
|
|
538
|
+
print(error)
|
|
539
|
+
cleanup
|
|
540
|
+
print("Always runs")
|
|
530
541
|
endrisk
|
|
531
542
|
```
|
|
532
543
|
|
|
533
|
-
This illustrates the idea of protecting potentially failing code. The exact behaviour depends on ChemQL's implementation of `risk`.
|
|
534
|
-
|
|
535
544
|
### `fix`
|
|
536
545
|
|
|
537
|
-
|
|
546
|
+
The `fix` section runs only when the `risk` section raises an exception.
|
|
547
|
+
The `error` variable contains the exception type name, such as
|
|
548
|
+
`ChemQLError`, `ValueError`, or the error name carried by `signal`.
|
|
538
549
|
|
|
539
550
|
```text
|
|
540
551
|
risk
|
|
541
552
|
[result = 10 / 0]
|
|
542
553
|
fix
|
|
543
|
-
|
|
554
|
+
print("Handled:", error)
|
|
544
555
|
endrisk
|
|
545
556
|
```
|
|
546
557
|
|
|
547
|
-
This example illustrates the intended relationship between `risk` and `fix`. Check the implementation for the precise syntax and whether execution continues after an error.
|
|
548
|
-
|
|
549
558
|
### `cleanup`
|
|
550
559
|
|
|
551
|
-
|
|
560
|
+
The optional `cleanup` section runs whether the `risk` section succeeds
|
|
561
|
+
or fails, after the risk body and any fix body.
|
|
552
562
|
|
|
553
563
|
```text
|
|
554
564
|
risk
|
|
555
|
-
|
|
565
|
+
print("Performing operation")
|
|
556
566
|
fix
|
|
557
|
-
|
|
567
|
+
print("Handling an error")
|
|
558
568
|
cleanup
|
|
559
|
-
|
|
569
|
+
print("Cleaning up")
|
|
560
570
|
endrisk
|
|
561
571
|
```
|
|
562
572
|
|
|
563
|
-
Cleanup logic is useful for keeping resource-management steps separate from the main operation and its error-handling logic.
|
|
564
|
-
|
|
565
573
|
### `signal`
|
|
566
574
|
|
|
567
|
-
Use `signal` to
|
|
575
|
+
Use `signal` to raise a named ChemQL error that can be handled by
|
|
576
|
+
`fix`.
|
|
568
577
|
|
|
569
578
|
```text
|
|
570
579
|
if temperature < 0
|
|
@@ -572,19 +581,18 @@ if temperature < 0
|
|
|
572
581
|
endif
|
|
573
582
|
```
|
|
574
583
|
|
|
575
|
-
A signal can make an invalid state or failed operation explicit instead of allowing execution to proceed silently.
|
|
576
|
-
|
|
577
584
|
### Summary
|
|
578
585
|
|
|
579
586
|
| Keyword | Purpose |
|
|
580
587
|
|---|---|
|
|
581
|
-
| `risk` |
|
|
582
|
-
| `fix` |
|
|
583
|
-
| `cleanup` |
|
|
584
|
-
| `signal` | Raises
|
|
588
|
+
| `risk` | Executes the protected body |
|
|
589
|
+
| `fix` | Runs when the risk body raises an exception |
|
|
590
|
+
| `cleanup` | Runs after the risk and fix bodies |
|
|
591
|
+
| `signal` | Raises a named error |
|
|
585
592
|
| `endrisk` | Ends the risk handler |
|
|
586
593
|
|
|
587
|
-
|
|
594
|
+
Without a `fix` section, an ordinary exception propagates. `cleanup`
|
|
595
|
+
still runs during exception propagation.
|
|
588
596
|
|
|
589
597
|
## Functions, definitions, and macros
|
|
590
598
|
|
|
@@ -647,7 +655,9 @@ command lists definitions in the current session.
|
|
|
647
655
|
|
|
648
656
|
## Structs and records
|
|
649
657
|
|
|
650
|
-
ChemQL
|
|
658
|
+
ChemQL 1.5.0 supports enums and inheritance in addition to required fields,
|
|
659
|
+
marked with a trailing `!` or the
|
|
660
|
+
`required` keyword:
|
|
651
661
|
|
|
652
662
|
```text
|
|
653
663
|
struct Fruit
|
|
@@ -661,8 +671,8 @@ apple.name
|
|
|
661
671
|
apple.price
|
|
662
672
|
let orange = Fruit{"Orange", 20} // you can use position rather than just keyword arguments
|
|
663
673
|
let banana = Fruit{"Banana", price = 10} // or you can even mix
|
|
664
|
-
|
|
665
674
|
```
|
|
675
|
+
|
|
666
676
|
```text
|
|
667
677
|
struct Vegetable
|
|
668
678
|
name!
|
|
@@ -678,26 +688,107 @@ Special methods such as `__add__` are intended for custom behaviour, but
|
|
|
678
688
|
do not assume every Python data-model feature or operator dispatch path
|
|
679
689
|
is fully implemented.
|
|
680
690
|
|
|
681
|
-
|
|
691
|
+
### Enums
|
|
692
|
+
|
|
693
|
+
An enum member without an explicit value receives an automatically generated
|
|
694
|
+
integer value. Automatic values continue from the preceding numeric value:
|
|
695
|
+
|
|
696
|
+
```text
|
|
697
|
+
enum Levels
|
|
698
|
+
LOW = 50
|
|
699
|
+
MEDIUM
|
|
700
|
+
HIGH
|
|
701
|
+
endenum
|
|
702
|
+
|
|
703
|
+
let selected = Levels.MEDIUM
|
|
704
|
+
[selected.value] // 51
|
|
705
|
+
```
|
|
706
|
+
|
|
707
|
+
### Inheritance
|
|
708
|
+
|
|
709
|
+
Structs can inherit fields and behavior from another struct, a record, or a
|
|
710
|
+
Python class available in ChemQL's Python globals. Records can inherit only
|
|
711
|
+
from other records:
|
|
712
|
+
|
|
713
|
+
```text
|
|
714
|
+
struct Animal
|
|
715
|
+
name!
|
|
716
|
+
endstruct
|
|
717
|
+
|
|
718
|
+
struct Dog from Animal
|
|
719
|
+
color!
|
|
720
|
+
isSmall = False
|
|
721
|
+
endstruct
|
|
722
|
+
|
|
723
|
+
let pet = Dog{"Rex", "brown"}
|
|
724
|
+
pet.name
|
|
725
|
+
pet.color
|
|
682
726
|
|
|
683
|
-
|
|
727
|
+
record Identity
|
|
728
|
+
id
|
|
729
|
+
endrecord
|
|
730
|
+
|
|
731
|
+
record Product from Identity
|
|
732
|
+
name
|
|
733
|
+
endrecord
|
|
734
|
+
|
|
735
|
+
let item = Product{7, "Copper"}
|
|
736
|
+
item.id
|
|
737
|
+
item.name
|
|
738
|
+
```
|
|
739
|
+
|
|
740
|
+
Structs may also extend a Python class defined or imported into the active
|
|
741
|
+
Python namespace. Built-in classes such as `int` can be named directly; a
|
|
742
|
+
bracketed Python expression such as `[int]` is also accepted. Initializer
|
|
743
|
+
parameters from ordinary Python classes become inherited constructor fields,
|
|
744
|
+
and the Python initializer is called when the ChemQL struct is constructed.
|
|
745
|
+
Native value types such as `int` keep their native constructor and value
|
|
746
|
+
behavior:
|
|
684
747
|
|
|
685
|
-
To declare functions accessible in the global scope you must use the `public` keyword, everything is private by default, you may still add the `private` keyword for fun
|
|
686
|
-
Example
|
|
687
748
|
```text
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
749
|
+
[[[
|
|
750
|
+
class PythonAnimal:
|
|
751
|
+
def __init__(self, name):
|
|
752
|
+
self.name = name
|
|
753
|
+
]]]
|
|
692
754
|
|
|
755
|
+
struct Pet from PythonAnimal
|
|
756
|
+
species = "unknown"
|
|
757
|
+
endstruct
|
|
693
758
|
|
|
759
|
+
let pet = Pet{"Milo", "cat"}
|
|
760
|
+
pet.name
|
|
761
|
+
pet.species
|
|
762
|
+
```
|
|
763
|
+
|
|
764
|
+
```text
|
|
765
|
+
struct Integer from int
|
|
766
|
+
endstruct
|
|
767
|
+
|
|
768
|
+
let answer = Integer{42}
|
|
769
|
+
[answer + 1] // 43
|
|
770
|
+
```
|
|
771
|
+
|
|
772
|
+
## Namespaces
|
|
773
|
+
|
|
774
|
+
Namespaces group functions, structs, records, and variables. Members are
|
|
775
|
+
private by default; use `public` to expose a member through the namespace:
|
|
776
|
+
|
|
777
|
+
```chemql
|
|
778
|
+
namespace geometry
|
|
779
|
+
public let PI = 3.141592653589793
|
|
780
|
+
public func circle_area
|
|
781
|
+
return [PI * \1 * \1]
|
|
782
|
+
endfunc
|
|
783
|
+
endnamespace
|
|
784
|
+
|
|
785
|
+
geometry::circle_area{2}
|
|
694
786
|
```
|
|
695
787
|
|
|
696
788
|
## Standard library
|
|
697
789
|
|
|
698
|
-
ChemQL loads reusable `.cql` packages with `load`. The loader searches the
|
|
699
|
-
directory and then
|
|
700
|
-
folder structure when extracting `chemql_stdlib.zip`.
|
|
790
|
+
ChemQL loads reusable `.cql` packages with `load`. The loader searches the
|
|
791
|
+
current directory first and then ChemQL's bundled `stdlib/` directory.
|
|
701
792
|
|
|
702
793
|
| Package | Purpose |
|
|
703
794
|
| --- | --- |
|
|
@@ -707,6 +798,10 @@ folder structure when extracting `chemql_stdlib.zip`.
|
|
|
707
798
|
| `collections` | `unique`, `flatten`, `zip`, `pairwise`, frequency counts, product |
|
|
708
799
|
| `datetime` | Current date/time, ISO dates, timestamps, weekday and date arithmetic |
|
|
709
800
|
| `json` | JSON serialization, pretty serialization, parsing and type inspection |
|
|
801
|
+
| `random` | Pseudo-random numbers and sequence sampling |
|
|
802
|
+
| `decimal` | Base-10 decimal arithmetic and quantization |
|
|
803
|
+
| `fractions` | Exact rational numbers and fraction arithmetic |
|
|
804
|
+
| `pathlib` | Path inspection and UTF-8 text file operations |
|
|
710
805
|
|
|
711
806
|
```chemql
|
|
712
807
|
load math
|
|
@@ -731,9 +826,30 @@ datetime::date_add_days{"2026-10-20", 7}
|
|
|
731
826
|
|
|
732
827
|
load json
|
|
733
828
|
json::loads{"{\"formula\": \"H2O\"}"}
|
|
829
|
+
|
|
830
|
+
load random
|
|
831
|
+
random::seed{42}
|
|
832
|
+
random::randint{1, 6}
|
|
833
|
+
|
|
834
|
+
load decimal
|
|
835
|
+
decimal::add{"0.1", "0.2"}
|
|
836
|
+
decimal::quantize{"3.14159", "0.01"}
|
|
837
|
+
|
|
838
|
+
load fractions
|
|
839
|
+
fractions::create{1, 3}
|
|
840
|
+
fractions::add{"1/3", "1/6"}
|
|
841
|
+
|
|
842
|
+
load pathlib
|
|
843
|
+
pathlib::name{"data/results.csv"}
|
|
844
|
+
pathlib::join{"data", "results.csv"}
|
|
734
845
|
```
|
|
735
846
|
|
|
736
847
|
These packages use Python's standard library only; they add no third-party dependencies.
|
|
848
|
+
Use `help{stdlib}` for the package index, `help{math}` for a module
|
|
849
|
+
overview, and `help{math::sqrt}` for function help. These help pages are
|
|
850
|
+
available before loading the package. `pathlib::read_text` and
|
|
851
|
+
`pathlib::write_text` access files with the permissions of the ChemQL
|
|
852
|
+
process.
|
|
737
853
|
|
|
738
854
|
## Built-in help
|
|
739
855
|
|
|
@@ -747,10 +863,14 @@ help{syntax}
|
|
|
747
863
|
help{errors}
|
|
748
864
|
help{files}
|
|
749
865
|
help{chemistry}
|
|
866
|
+
help{stdlib}
|
|
867
|
+
help{math}
|
|
868
|
+
help{math::sqrt}
|
|
750
869
|
```
|
|
751
870
|
|
|
752
|
-
Use `help{function_name}` for built-in documentation
|
|
753
|
-
|
|
871
|
+
Use `help{function_name}` for built-in documentation and
|
|
872
|
+
`help{module::function}` for standard-library function documentation. The
|
|
873
|
+
help index also lists the available standard-library packages.
|
|
754
874
|
|
|
755
875
|
## Shell integration and scripting
|
|
756
876
|
|
|
@@ -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.
|
|
9
|
+
- **Version:** `1.5.0`
|
|
10
10
|
- **PyPI distribution:** `chemql-python`
|
|
11
11
|
- **Python import / CLI name:** `chemql`
|
|
12
12
|
- **Author:** Mohammad Rakibul Islam
|
|
@@ -54,6 +54,9 @@ commands.
|
|
|
54
54
|
matching.
|
|
55
55
|
- Use Python statements, expressions, variables, control flow,
|
|
56
56
|
functions, macros, and structured values.
|
|
57
|
+
- Define enums with automatic or explicit values, and inherit structs
|
|
58
|
+
from structs, records, or Python classes; records can inherit from
|
|
59
|
+
other records.
|
|
57
60
|
- Execute shell commands and multiline shell blocks from the REPL.
|
|
58
61
|
- Export recorded commands and results.
|
|
59
62
|
- Use the command-line interface or import ChemQL from Python.
|
|
@@ -509,49 +512,55 @@ ChemQL provides `risk`, `fix`, `cleanup`, and `signal` for handling errors, resp
|
|
|
509
512
|
|
|
510
513
|
### `risk`
|
|
511
514
|
|
|
512
|
-
|
|
515
|
+
`risk` executes its body. If a command raises an exception, ChemQL stores
|
|
516
|
+
the error type name in the Python variable `error` and runs the optional
|
|
517
|
+
`fix` body. A returned string that happens to contain error-looking text
|
|
518
|
+
does not trigger `fix`.
|
|
513
519
|
|
|
514
520
|
```text
|
|
515
521
|
risk
|
|
516
|
-
[result = 10 /
|
|
522
|
+
[result = 10 / 2]
|
|
523
|
+
print(result)
|
|
524
|
+
fix
|
|
525
|
+
print(error)
|
|
526
|
+
cleanup
|
|
527
|
+
print("Always runs")
|
|
517
528
|
endrisk
|
|
518
529
|
```
|
|
519
530
|
|
|
520
|
-
This illustrates the idea of protecting potentially failing code. The exact behaviour depends on ChemQL's implementation of `risk`.
|
|
521
|
-
|
|
522
531
|
### `fix`
|
|
523
532
|
|
|
524
|
-
|
|
533
|
+
The `fix` section runs only when the `risk` section raises an exception.
|
|
534
|
+
The `error` variable contains the exception type name, such as
|
|
535
|
+
`ChemQLError`, `ValueError`, or the error name carried by `signal`.
|
|
525
536
|
|
|
526
537
|
```text
|
|
527
538
|
risk
|
|
528
539
|
[result = 10 / 0]
|
|
529
540
|
fix
|
|
530
|
-
|
|
541
|
+
print("Handled:", error)
|
|
531
542
|
endrisk
|
|
532
543
|
```
|
|
533
544
|
|
|
534
|
-
This example illustrates the intended relationship between `risk` and `fix`. Check the implementation for the precise syntax and whether execution continues after an error.
|
|
535
|
-
|
|
536
545
|
### `cleanup`
|
|
537
546
|
|
|
538
|
-
|
|
547
|
+
The optional `cleanup` section runs whether the `risk` section succeeds
|
|
548
|
+
or fails, after the risk body and any fix body.
|
|
539
549
|
|
|
540
550
|
```text
|
|
541
551
|
risk
|
|
542
|
-
|
|
552
|
+
print("Performing operation")
|
|
543
553
|
fix
|
|
544
|
-
|
|
554
|
+
print("Handling an error")
|
|
545
555
|
cleanup
|
|
546
|
-
|
|
556
|
+
print("Cleaning up")
|
|
547
557
|
endrisk
|
|
548
558
|
```
|
|
549
559
|
|
|
550
|
-
Cleanup logic is useful for keeping resource-management steps separate from the main operation and its error-handling logic.
|
|
551
|
-
|
|
552
560
|
### `signal`
|
|
553
561
|
|
|
554
|
-
Use `signal` to
|
|
562
|
+
Use `signal` to raise a named ChemQL error that can be handled by
|
|
563
|
+
`fix`.
|
|
555
564
|
|
|
556
565
|
```text
|
|
557
566
|
if temperature < 0
|
|
@@ -559,19 +568,18 @@ if temperature < 0
|
|
|
559
568
|
endif
|
|
560
569
|
```
|
|
561
570
|
|
|
562
|
-
A signal can make an invalid state or failed operation explicit instead of allowing execution to proceed silently.
|
|
563
|
-
|
|
564
571
|
### Summary
|
|
565
572
|
|
|
566
573
|
| Keyword | Purpose |
|
|
567
574
|
|---|---|
|
|
568
|
-
| `risk` |
|
|
569
|
-
| `fix` |
|
|
570
|
-
| `cleanup` |
|
|
571
|
-
| `signal` | Raises
|
|
575
|
+
| `risk` | Executes the protected body |
|
|
576
|
+
| `fix` | Runs when the risk body raises an exception |
|
|
577
|
+
| `cleanup` | Runs after the risk and fix bodies |
|
|
578
|
+
| `signal` | Raises a named error |
|
|
572
579
|
| `endrisk` | Ends the risk handler |
|
|
573
580
|
|
|
574
|
-
|
|
581
|
+
Without a `fix` section, an ordinary exception propagates. `cleanup`
|
|
582
|
+
still runs during exception propagation.
|
|
575
583
|
|
|
576
584
|
## Functions, definitions, and macros
|
|
577
585
|
|
|
@@ -634,7 +642,9 @@ command lists definitions in the current session.
|
|
|
634
642
|
|
|
635
643
|
## Structs and records
|
|
636
644
|
|
|
637
|
-
ChemQL
|
|
645
|
+
ChemQL 1.5.0 supports enums and inheritance in addition to required fields,
|
|
646
|
+
marked with a trailing `!` or the
|
|
647
|
+
`required` keyword:
|
|
638
648
|
|
|
639
649
|
```text
|
|
640
650
|
struct Fruit
|
|
@@ -648,8 +658,8 @@ apple.name
|
|
|
648
658
|
apple.price
|
|
649
659
|
let orange = Fruit{"Orange", 20} // you can use position rather than just keyword arguments
|
|
650
660
|
let banana = Fruit{"Banana", price = 10} // or you can even mix
|
|
651
|
-
|
|
652
661
|
```
|
|
662
|
+
|
|
653
663
|
```text
|
|
654
664
|
struct Vegetable
|
|
655
665
|
name!
|
|
@@ -665,26 +675,107 @@ Special methods such as `__add__` are intended for custom behaviour, but
|
|
|
665
675
|
do not assume every Python data-model feature or operator dispatch path
|
|
666
676
|
is fully implemented.
|
|
667
677
|
|
|
668
|
-
|
|
678
|
+
### Enums
|
|
679
|
+
|
|
680
|
+
An enum member without an explicit value receives an automatically generated
|
|
681
|
+
integer value. Automatic values continue from the preceding numeric value:
|
|
682
|
+
|
|
683
|
+
```text
|
|
684
|
+
enum Levels
|
|
685
|
+
LOW = 50
|
|
686
|
+
MEDIUM
|
|
687
|
+
HIGH
|
|
688
|
+
endenum
|
|
689
|
+
|
|
690
|
+
let selected = Levels.MEDIUM
|
|
691
|
+
[selected.value] // 51
|
|
692
|
+
```
|
|
693
|
+
|
|
694
|
+
### Inheritance
|
|
695
|
+
|
|
696
|
+
Structs can inherit fields and behavior from another struct, a record, or a
|
|
697
|
+
Python class available in ChemQL's Python globals. Records can inherit only
|
|
698
|
+
from other records:
|
|
699
|
+
|
|
700
|
+
```text
|
|
701
|
+
struct Animal
|
|
702
|
+
name!
|
|
703
|
+
endstruct
|
|
704
|
+
|
|
705
|
+
struct Dog from Animal
|
|
706
|
+
color!
|
|
707
|
+
isSmall = False
|
|
708
|
+
endstruct
|
|
709
|
+
|
|
710
|
+
let pet = Dog{"Rex", "brown"}
|
|
711
|
+
pet.name
|
|
712
|
+
pet.color
|
|
669
713
|
|
|
670
|
-
|
|
714
|
+
record Identity
|
|
715
|
+
id
|
|
716
|
+
endrecord
|
|
717
|
+
|
|
718
|
+
record Product from Identity
|
|
719
|
+
name
|
|
720
|
+
endrecord
|
|
721
|
+
|
|
722
|
+
let item = Product{7, "Copper"}
|
|
723
|
+
item.id
|
|
724
|
+
item.name
|
|
725
|
+
```
|
|
726
|
+
|
|
727
|
+
Structs may also extend a Python class defined or imported into the active
|
|
728
|
+
Python namespace. Built-in classes such as `int` can be named directly; a
|
|
729
|
+
bracketed Python expression such as `[int]` is also accepted. Initializer
|
|
730
|
+
parameters from ordinary Python classes become inherited constructor fields,
|
|
731
|
+
and the Python initializer is called when the ChemQL struct is constructed.
|
|
732
|
+
Native value types such as `int` keep their native constructor and value
|
|
733
|
+
behavior:
|
|
671
734
|
|
|
672
|
-
To declare functions accessible in the global scope you must use the `public` keyword, everything is private by default, you may still add the `private` keyword for fun
|
|
673
|
-
Example
|
|
674
735
|
```text
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
736
|
+
[[[
|
|
737
|
+
class PythonAnimal:
|
|
738
|
+
def __init__(self, name):
|
|
739
|
+
self.name = name
|
|
740
|
+
]]]
|
|
679
741
|
|
|
742
|
+
struct Pet from PythonAnimal
|
|
743
|
+
species = "unknown"
|
|
744
|
+
endstruct
|
|
680
745
|
|
|
746
|
+
let pet = Pet{"Milo", "cat"}
|
|
747
|
+
pet.name
|
|
748
|
+
pet.species
|
|
749
|
+
```
|
|
750
|
+
|
|
751
|
+
```text
|
|
752
|
+
struct Integer from int
|
|
753
|
+
endstruct
|
|
754
|
+
|
|
755
|
+
let answer = Integer{42}
|
|
756
|
+
[answer + 1] // 43
|
|
757
|
+
```
|
|
758
|
+
|
|
759
|
+
## Namespaces
|
|
760
|
+
|
|
761
|
+
Namespaces group functions, structs, records, and variables. Members are
|
|
762
|
+
private by default; use `public` to expose a member through the namespace:
|
|
763
|
+
|
|
764
|
+
```chemql
|
|
765
|
+
namespace geometry
|
|
766
|
+
public let PI = 3.141592653589793
|
|
767
|
+
public func circle_area
|
|
768
|
+
return [PI * \1 * \1]
|
|
769
|
+
endfunc
|
|
770
|
+
endnamespace
|
|
771
|
+
|
|
772
|
+
geometry::circle_area{2}
|
|
681
773
|
```
|
|
682
774
|
|
|
683
775
|
## Standard library
|
|
684
776
|
|
|
685
|
-
ChemQL loads reusable `.cql` packages with `load`. The loader searches the
|
|
686
|
-
directory and then
|
|
687
|
-
folder structure when extracting `chemql_stdlib.zip`.
|
|
777
|
+
ChemQL loads reusable `.cql` packages with `load`. The loader searches the
|
|
778
|
+
current directory first and then ChemQL's bundled `stdlib/` directory.
|
|
688
779
|
|
|
689
780
|
| Package | Purpose |
|
|
690
781
|
| --- | --- |
|
|
@@ -694,6 +785,10 @@ folder structure when extracting `chemql_stdlib.zip`.
|
|
|
694
785
|
| `collections` | `unique`, `flatten`, `zip`, `pairwise`, frequency counts, product |
|
|
695
786
|
| `datetime` | Current date/time, ISO dates, timestamps, weekday and date arithmetic |
|
|
696
787
|
| `json` | JSON serialization, pretty serialization, parsing and type inspection |
|
|
788
|
+
| `random` | Pseudo-random numbers and sequence sampling |
|
|
789
|
+
| `decimal` | Base-10 decimal arithmetic and quantization |
|
|
790
|
+
| `fractions` | Exact rational numbers and fraction arithmetic |
|
|
791
|
+
| `pathlib` | Path inspection and UTF-8 text file operations |
|
|
697
792
|
|
|
698
793
|
```chemql
|
|
699
794
|
load math
|
|
@@ -718,9 +813,30 @@ datetime::date_add_days{"2026-10-20", 7}
|
|
|
718
813
|
|
|
719
814
|
load json
|
|
720
815
|
json::loads{"{\"formula\": \"H2O\"}"}
|
|
816
|
+
|
|
817
|
+
load random
|
|
818
|
+
random::seed{42}
|
|
819
|
+
random::randint{1, 6}
|
|
820
|
+
|
|
821
|
+
load decimal
|
|
822
|
+
decimal::add{"0.1", "0.2"}
|
|
823
|
+
decimal::quantize{"3.14159", "0.01"}
|
|
824
|
+
|
|
825
|
+
load fractions
|
|
826
|
+
fractions::create{1, 3}
|
|
827
|
+
fractions::add{"1/3", "1/6"}
|
|
828
|
+
|
|
829
|
+
load pathlib
|
|
830
|
+
pathlib::name{"data/results.csv"}
|
|
831
|
+
pathlib::join{"data", "results.csv"}
|
|
721
832
|
```
|
|
722
833
|
|
|
723
834
|
These packages use Python's standard library only; they add no third-party dependencies.
|
|
835
|
+
Use `help{stdlib}` for the package index, `help{math}` for a module
|
|
836
|
+
overview, and `help{math::sqrt}` for function help. These help pages are
|
|
837
|
+
available before loading the package. `pathlib::read_text` and
|
|
838
|
+
`pathlib::write_text` access files with the permissions of the ChemQL
|
|
839
|
+
process.
|
|
724
840
|
|
|
725
841
|
## Built-in help
|
|
726
842
|
|
|
@@ -734,10 +850,14 @@ help{syntax}
|
|
|
734
850
|
help{errors}
|
|
735
851
|
help{files}
|
|
736
852
|
help{chemistry}
|
|
853
|
+
help{stdlib}
|
|
854
|
+
help{math}
|
|
855
|
+
help{math::sqrt}
|
|
737
856
|
```
|
|
738
857
|
|
|
739
|
-
Use `help{function_name}` for built-in documentation
|
|
740
|
-
|
|
858
|
+
Use `help{function_name}` for built-in documentation and
|
|
859
|
+
`help{module::function}` for standard-library function documentation. The
|
|
860
|
+
help index also lists the available standard-library packages.
|
|
741
861
|
|
|
742
862
|
## Shell integration and scripting
|
|
743
863
|
|