amalgam-lang 10.4.1__py3-none-macosx_12_0_x86_64.whl → 12.0.0__py3-none-macosx_12_0_x86_64.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.
amalgam/api.py CHANGED
@@ -1,6 +1,8 @@
1
+ from __future__ import annotations
2
+
1
3
  from ctypes import (
2
- byref, cast, c_bool, c_char, c_char_p, c_double, c_size_t, c_uint64, c_void_p,
3
- cdll, POINTER, Structure
4
+ _Pointer, Array, byref, c_bool, c_char, c_char_p, c_double, c_size_t, c_uint64, c_void_p,
5
+ cast, cdll, POINTER, Structure
4
6
  )
5
7
  from datetime import datetime
6
8
  import gc
@@ -8,7 +10,7 @@ import logging
8
10
  from pathlib import Path
9
11
  import platform
10
12
  import re
11
- from typing import Any, List, Optional, Tuple, Union
13
+ import typing as t
12
14
  import warnings
13
15
 
14
16
  # Set to amalgam
@@ -21,6 +23,7 @@ class _LoadEntityStatus(Structure):
21
23
 
22
24
  This is implemented with ctypes for accessing binary Amalgam builds.
23
25
  """
26
+
24
27
  _fields_ = [
25
28
  ("loaded", c_bool),
26
29
  ("message", POINTER(c_char)),
@@ -34,8 +37,17 @@ class LoadEntityStatus:
34
37
 
35
38
  This is implemented with python types and is meant to wrap _LoadEntityStatus
36
39
  which uses ctypes and directly interacts with the Amalgam binaries.
40
+
41
+ Parameters
42
+ ----------
43
+ api : Amalgam
44
+ The Python Amalgam interface.
45
+ c_status : _LoadEntityStatus, optional
46
+ _LoadEntityStatus instance.
37
47
  """
38
- def __init__(self, api, c_status: _LoadEntityStatus = None):
48
+
49
+ def __init__(self, api: Amalgam, c_status: t.Optional[_LoadEntityStatus] = None):
50
+ """Initialize LoadEntityStatus."""
39
51
  if c_status is None:
40
52
  self.loaded = True
41
53
  self.message = ""
@@ -45,7 +57,15 @@ class LoadEntityStatus:
45
57
  self.message = api.char_p_to_bytes(c_status.message).decode("utf-8")
46
58
  self.version = api.char_p_to_bytes(c_status.version).decode("utf-8")
47
59
 
48
- def __str__(self):
60
+ def __str__(self) -> str:
61
+ """
62
+ Return a human-readable string representation.
63
+
64
+ Returns
65
+ -------
66
+ str
67
+ The human-readable string representation.
68
+ """
49
69
  return f"{self.loaded},\"{self.message}\",\"{self.version}\""
50
70
 
51
71
 
@@ -57,28 +77,34 @@ class Amalgam:
57
77
 
58
78
  Parameters
59
79
  ----------
60
- library_path : Path or str
61
- Path to either the amalgam DLL, DyLib or SO (Windows, MacOS or
62
- Linux, respectively). If not specified it will build a path to the
80
+ library_path : Path or str, optional
81
+ Path to either the amalgam DLL, DyLib or SO (Windows, MacOS
82
+ or Linux, respectively). If not specified it will build a path to the
63
83
  appropriate library bundled with the package.
64
84
 
65
85
  append_trace_file : bool, default False
66
86
  If True, new content will be appended to a trace file if the file
67
87
  already exists rather than creating a new file.
68
88
 
69
- execution_trace_dir : Union[str, None], default None
70
- A directory path for writing trace files.
89
+ arch : str, optional
90
+ The platform architecture of the embedded Amalgam library.
91
+ If not provided, it will be automatically detected.
92
+ (Note: arm64_8a architecture must be manually specified!)
93
+
94
+ execution_trace_dir : str, optional
95
+ A directory path for writing trace files. If ``None``, then
96
+ the current working directory will be used.
71
97
 
72
98
  execution_trace_file : str, default "execution.trace"
73
99
  The full or relative path to the execution trace used in debugging.
74
100
 
75
- gc_interval : int, default None
76
- If set, garbage collection will be forced at the specified interval
77
- of amalgam operations. Note that this reduces memory consumption at
78
- the compromise of performance. Only use if models are exceeding
79
- your host's process memory limit or if paging to disk. As an
80
- example, if this operation is set to 0 (force garbage collection
81
- every operation), it results in a performance impact of 150x.
101
+ gc_interval : int, optional
102
+ If set, garbage collection will be forced at the specified
103
+ interval of amalgam operations. Note that this reduces memory
104
+ consumption at the compromise of performance. Only use if models are
105
+ exceeding your host's process memory limit or if paging to disk. As an
106
+ example, if this operation is set to 0 (force garbage collection every
107
+ operation), it results in a performance impact of 150x.
82
108
  Default value does not force garbage collection.
83
109
 
84
110
  library_postfix : str, optional
@@ -87,12 +113,12 @@ class Amalgam:
87
113
  it within library_path. If neither are available, -mt (multi-threaded)
88
114
  will be used.
89
115
 
90
- max_num_threads : int or None, default None
91
- If a multithreaded Amalgam binary is used, sets the maximum number
92
- of threads to the value specified. If 0, will use the number of
116
+ max_num_threads : int, optional
117
+ If a multithreaded Amalgam binary is used, sets the maximum
118
+ number of threads to the value specified. If 0, will use the number of
93
119
  visible logical cores. Default None will not attempt to set this value.
94
120
 
95
- sbf_datastore_enabled : bool or None, default None
121
+ sbf_datastore_enabled : bool, optional
96
122
  If true, sbf tree structures are enabled.
97
123
 
98
124
  trace : bool, optional
@@ -110,19 +136,20 @@ class Amalgam:
110
136
 
111
137
  def __init__( # noqa: C901
112
138
  self,
113
- library_path: Optional[Union[Path, str]] = None,
139
+ library_path: t.Optional[Path | str] = None,
114
140
  *,
115
- arch: Optional[str] = None,
141
+ arch: t.Optional[str] = None,
116
142
  append_trace_file: bool = False,
117
- execution_trace_dir: Optional[str] = None,
143
+ execution_trace_dir: t.Optional[str] = None,
118
144
  execution_trace_file: str = "execution.trace",
119
- gc_interval: Optional[int] = None,
120
- library_postfix: Optional[str] = None,
121
- max_num_threads: Optional[int] = None,
122
- sbf_datastore_enabled: Optional[bool] = None,
123
- trace: Optional[bool] = None,
145
+ gc_interval: t.Optional[int] = None,
146
+ library_postfix: t.Optional[str] = None,
147
+ max_num_threads: t.Optional[int] = None,
148
+ sbf_datastore_enabled: t.Optional[bool] = None,
149
+ trace: t.Optional[bool] = None,
124
150
  **kwargs
125
151
  ):
152
+ """Initialize Amalgam instance."""
126
153
  if len(kwargs):
127
154
  warnings.warn(f'Unexpected keyword arguments '
128
155
  f'[{", ".join(list(kwargs.keys()))}] '
@@ -177,7 +204,7 @@ class Amalgam:
177
204
  self.load_command_log_entry = None
178
205
 
179
206
  @classmethod
180
- def _get_allowed_postfixes(cls, library_dir: Path) -> List[str]:
207
+ def _get_allowed_postfixes(cls, library_dir: Path) -> list[str]:
181
208
  """
182
209
  Return list of all library postfixes allowed given library directory.
183
210
 
@@ -199,7 +226,7 @@ class Amalgam:
199
226
  return list(allowed_postfixes)
200
227
 
201
228
  @classmethod
202
- def _parse_postfix(cls, filename: str) -> Union[str, None]:
229
+ def _parse_postfix(cls, filename: str) -> str | None:
203
230
  """
204
231
  Determine library postfix given a filename.
205
232
 
@@ -222,10 +249,10 @@ class Amalgam:
222
249
  @classmethod
223
250
  def _get_library_path(
224
251
  cls,
225
- library_path: Optional[Union[Path, str]] = None,
226
- library_postfix: Optional[str] = None,
227
- arch: Optional[str] = None
228
- ) -> Tuple[Path, str]:
252
+ library_path: t.Optional[Path | str] = None,
253
+ library_postfix: t.Optional[str] = None,
254
+ arch: t.Optional[str] = None
255
+ ) -> tuple[Path, str]:
229
256
  """
230
257
  Return the full Amalgam library path and its library_postfix.
231
258
 
@@ -235,14 +262,15 @@ class Amalgam:
235
262
 
236
263
  Parameters
237
264
  ----------
238
- library_path : Path or str, default None
239
- Optional, The path to the Amalgam shared library.
240
- library_postfix : str, default "-mt"
241
- Optional, The library type as specified by a postfix to the word
265
+ library_path : Path or str, optional
266
+ The path to the Amalgam shared library.
267
+ library_postfix : str, optional
268
+ The library type as specified by a postfix to the word
242
269
  "amalgam" in the library's filename. E.g., the "-mt" in
243
- `amalgam-mt.dll`.
244
- arch : str, default None
245
- Optional, the platform architecture of the embedded Amalgam
270
+ `amalgam-mt.dll`. If left unspecified, "-mt" will be used where
271
+ supported, otherwise "-st".
272
+ arch : str, optional
273
+ The platform architecture of the embedded Amalgam
246
274
  library. If not provided, it will be automatically detected.
247
275
  (Note: arm64_8a architecture must be manually specified!)
248
276
 
@@ -367,7 +395,7 @@ class Amalgam:
367
395
  self.amlg.IsSBFDataStoreEnabled.restype = c_bool
368
396
  return self.amlg.IsSBFDataStoreEnabled()
369
397
 
370
- def set_amlg_flags(self, sbf_datastore_enabled: bool = True) -> None:
398
+ def set_amlg_flags(self, sbf_datastore_enabled: bool = True):
371
399
  """
372
400
  Set various amalgam flags for data structure and compute features.
373
401
 
@@ -376,7 +404,7 @@ class Amalgam:
376
404
  sbf_datastore_enabled : bool, default True
377
405
  If true, sbf tree structures are enabled.
378
406
  """
379
- self.amlg.SetSBFDataStoreEnabled.argtype = [c_bool]
407
+ self.amlg.SetSBFDataStoreEnabled.argtypes = [c_bool]
380
408
  self.amlg.SetSBFDataStoreEnabled.restype = c_void_p
381
409
  self.amlg.SetSBFDataStoreEnabled(sbf_datastore_enabled)
382
410
 
@@ -396,7 +424,7 @@ class Amalgam:
396
424
 
397
425
  return result
398
426
 
399
- def set_max_num_threads(self, max_num_threads: int = 0) -> None:
427
+ def set_max_num_threads(self, max_num_threads: int = 0):
400
428
  """
401
429
  Set the maximum number of threads.
402
430
 
@@ -409,14 +437,14 @@ class Amalgam:
409
437
  of threads to the value specified. If 0, will use the number of
410
438
  visible logical cores.
411
439
  """
412
- self.amlg.SetMaxNumThreads.argtype = [c_size_t]
440
+ self.amlg.SetMaxNumThreads.argtypes = [c_size_t]
413
441
  self.amlg.SetMaxNumThreads.restype = c_void_p
414
442
 
415
443
  self._log_execution(f"SET_MAX_NUM_THREADS {max_num_threads}")
416
444
  result = self.amlg.SetMaxNumThreads(max_num_threads)
417
445
  self._log_reply(result)
418
446
 
419
- def reset_trace(self, file: str) -> None:
447
+ def reset_trace(self, file: str):
420
448
  """
421
449
  Close the open trace file and opens a new one with the specified name.
422
450
 
@@ -452,11 +480,11 @@ class Amalgam:
452
480
  self.trace.flush()
453
481
 
454
482
  def __str__(self) -> str:
455
- """Implement the str() method."""
483
+ """Return a human-readable string representation."""
456
484
  return (f"Amalgam Path:\t\t {self.library_path}\n"
457
485
  f"Amalgam GC Interval:\t {self.gc_interval}\n")
458
486
 
459
- def __del__(self) -> None:
487
+ def __del__(self):
460
488
  """Implement a "destructor" method to finalize log files, if any."""
461
489
  if (
462
490
  getattr(self, 'debug', False) and
@@ -467,7 +495,7 @@ class Amalgam:
467
495
  except Exception: # noqa - deliberately broad
468
496
  pass
469
497
 
470
- def _log_comment(self, comment: str) -> None:
498
+ def _log_comment(self, comment: str):
471
499
  """
472
500
  Log a comment into the execution trace file.
473
501
 
@@ -482,7 +510,7 @@ class Amalgam:
482
510
  self.trace.write("# NOTE >" + str(comment) + "\n")
483
511
  self.trace.flush()
484
512
 
485
- def _log_reply(self, reply: Any) -> None:
513
+ def _log_reply(self, reply: t.Any):
486
514
  """
487
515
  Log a raw reply from the amalgam process.
488
516
 
@@ -497,9 +525,9 @@ class Amalgam:
497
525
  self.trace.write("# RESULT >" + str(reply) + "\n")
498
526
  self.trace.flush()
499
527
 
500
- def _log_time(self, label: str) -> None:
528
+ def _log_time(self, label: str):
501
529
  """
502
- Log a labelled timestamp to the tracefile.
530
+ Log a labelled timestamp to the trace file.
503
531
 
504
532
  Parameters
505
533
  ----------
@@ -512,7 +540,7 @@ class Amalgam:
512
540
  f"{f'{dt:%f}'[:3]}\n")
513
541
  self.trace.flush()
514
542
 
515
- def _log_execution(self, execution_string: str) -> None:
543
+ def _log_execution(self, execution_string: str):
516
544
  """
517
545
  Log an execution string.
518
546
 
@@ -533,7 +561,7 @@ class Amalgam:
533
561
  self.trace.write(execution_string + "\n")
534
562
  self.trace.flush()
535
563
 
536
- def gc(self) -> None:
564
+ def gc(self):
537
565
  """Force garbage collection when called if self.force_gc is set."""
538
566
  if (
539
567
  self.gc_interval is not None
@@ -546,11 +574,11 @@ class Amalgam:
546
574
 
547
575
  def str_to_char_p(
548
576
  self,
549
- value: Union[str, bytes],
550
- size: Optional[int] = None
551
- ) -> c_char:
577
+ value: str | bytes,
578
+ size: t.Optional[int] = None
579
+ ) -> Array[c_char]:
552
580
  """
553
- Convert a string to a C char pointer.
581
+ Convert a string to an Array of C char.
554
582
 
555
583
  User must call `del` on returned buffer
556
584
 
@@ -558,14 +586,14 @@ class Amalgam:
558
586
  ----------
559
587
  value : str or bytes
560
588
  The value of the string.
561
- size : int or None
562
- The size of the string. If not provided, the length of the
563
- string is used.
589
+ size : int, optional
590
+ The size of the string. If not provided, the length of
591
+ the string is used.
564
592
 
565
593
  Returns
566
594
  -------
567
- c_char
568
- A C char pointer for the string.
595
+ Array of c_char
596
+ An Array of C char datatypes which form the given string
569
597
  """
570
598
  if isinstance(value, str):
571
599
  value = value.encode('utf-8')
@@ -574,27 +602,27 @@ class Amalgam:
574
602
  buf.value = value
575
603
  return buf
576
604
 
577
- def char_p_to_bytes(self, p: POINTER(c_char)) -> bytes:
605
+ def char_p_to_bytes(self, p: _Pointer[c_char] | c_char_p) -> bytes | None:
578
606
  """
579
- Copies a native C char pointer to bytes, cleaning up native memory correctly.
607
+ Copy native C char pointer to bytes, cleaning up memory correctly.
580
608
 
581
609
  Parameters
582
610
  ----------
583
- p : LP_char_p
584
- C pointer to string to convert
611
+ p : c_char_p
612
+ The char pointer to convert
585
613
 
586
614
  Returns
587
615
  -------
588
- bytes
589
- The byte-encoded string from C pointer
616
+ bytes or None
617
+ The byte-encoded char
590
618
  """
591
- bytes = cast(p, c_char_p).value
619
+ bytes_str = cast(p, c_char_p).value
592
620
 
593
- self.amlg.DeleteString.argtypes = c_char_p,
621
+ self.amlg.DeleteString.argtypes = [c_char_p]
594
622
  self.amlg.DeleteString.restype = None
595
623
  self.amlg.DeleteString(p)
596
624
 
597
- return bytes
625
+ return bytes_str
598
626
 
599
627
  def get_json_from_label(self, handle: str, label: str) -> bytes:
600
628
  """
@@ -613,7 +641,7 @@ class Amalgam:
613
641
  The byte-encoded json representation of the amalgam label.
614
642
  """
615
643
  self.amlg.GetJSONPtrFromLabel.restype = POINTER(c_char)
616
- self.amlg.GetJSONPtrFromLabel.argtype = [c_char_p, c_char_p]
644
+ self.amlg.GetJSONPtrFromLabel.argtypes = [c_char_p, c_char_p]
617
645
  handle_buf = self.str_to_char_p(handle)
618
646
  label_buf = self.str_to_char_p(label)
619
647
 
@@ -634,8 +662,8 @@ class Amalgam:
634
662
  self,
635
663
  handle: str,
636
664
  label: str,
637
- json: Union[str, bytes]
638
- ) -> None:
665
+ json: str | bytes
666
+ ):
639
667
  """
640
668
  Set a label in amalgam using json.
641
669
 
@@ -649,7 +677,7 @@ class Amalgam:
649
677
  The json representation of the label value.
650
678
  """
651
679
  self.amlg.SetJSONToLabel.restype = c_void_p
652
- self.amlg.SetJSONToLabel.argtype = [c_char_p, c_char_p, c_char_p]
680
+ self.amlg.SetJSONToLabel.argtypes = [c_char_p, c_char_p, c_char_p]
653
681
  handle_buf = self.str_to_char_p(handle)
654
682
  label_buf = self.str_to_char_p(label)
655
683
  json_buf = self.str_to_char_p(json)
@@ -710,7 +738,7 @@ class Amalgam:
710
738
  LoadEntityStatus
711
739
  Status of LoadEntity call.
712
740
  """
713
- self.amlg.LoadEntity.argtype = [
741
+ self.amlg.LoadEntity.argtypes = [
714
742
  c_char_p, c_char_p, c_bool, c_bool, c_bool, c_bool, c_char_p, c_char_p]
715
743
  self.amlg.LoadEntity.restype = _LoadEntityStatus
716
744
  handle_buf = self.str_to_char_p(handle)
@@ -757,7 +785,7 @@ class Amalgam:
757
785
  LoadEntityStatus
758
786
  Status of VerifyEntity call.
759
787
  """
760
- self.amlg.VerifyEntity.argtype = [c_char_p]
788
+ self.amlg.VerifyEntity.argtypes = [c_char_p]
761
789
  self.amlg.VerifyEntity.restype = _LoadEntityStatus
762
790
  amlg_path_buf = self.str_to_char_p(amlg_path)
763
791
 
@@ -806,7 +834,7 @@ class Amalgam:
806
834
  bool
807
835
  True if cloned successfully, False if not.
808
836
  """
809
- self.amlg.CloneEntity.argtype = [
837
+ self.amlg.CloneEntity.argtypes = [
810
838
  c_char_p, c_char_p, c_char_p, c_bool, c_char_p, c_char_p]
811
839
  handle_buf = self.str_to_char_p(handle)
812
840
  clone_handle_buf = self.str_to_char_p(clone_handle)
@@ -842,9 +870,9 @@ class Amalgam:
842
870
  *,
843
871
  update_persistence_location: bool = False,
844
872
  store_contained: bool = False
845
- ) -> None:
873
+ ):
846
874
  """
847
- Stores an entity to the file type specified within amlg_path.
875
+ Store entity to the file type specified within amlg_path.
848
876
 
849
877
  Parameters
850
878
  ----------
@@ -857,7 +885,7 @@ class Amalgam:
857
885
  store_contained : bool
858
886
  If set to true, contained entities will be stored.
859
887
  """
860
- self.amlg.StoreEntity.argtype = [
888
+ self.amlg.StoreEntity.argtypes = [
861
889
  c_char_p, c_char_p, c_bool, c_bool]
862
890
  handle_buf = self.str_to_char_p(handle)
863
891
  amlg_path_buf = self.str_to_char_p(amlg_path)
@@ -880,7 +908,7 @@ class Amalgam:
880
908
  def destroy_entity(
881
909
  self,
882
910
  handle: str
883
- ) -> None:
911
+ ):
884
912
  """
885
913
  Destroys an entity.
886
914
 
@@ -889,7 +917,7 @@ class Amalgam:
889
917
  handle : str
890
918
  The handle of the amalgam entity.
891
919
  """
892
- self.amlg.DestroyEntity.argtype = [c_char_p]
920
+ self.amlg.DestroyEntity.argtypes = [c_char_p]
893
921
  handle_buf = self.str_to_char_p(handle)
894
922
 
895
923
  self._log_execution(f"DESTROY_ENTITY \"{self.escape_double_quotes(handle)}\"")
@@ -905,7 +933,7 @@ class Amalgam:
905
933
  rand_seed: str
906
934
  ) -> bool:
907
935
  """
908
- Sets an entity's random seed.
936
+ Set entity's random seed.
909
937
 
910
938
  Parameters
911
939
  ----------
@@ -919,7 +947,7 @@ class Amalgam:
919
947
  bool
920
948
  True if the set was successful, false if not.
921
949
  """
922
- self.amlg.SetRandomSeed.argtype = [c_char_p, c_char_p]
950
+ self.amlg.SetRandomSeed.argtypes = [c_char_p, c_char_p]
923
951
  self.amlg.SetRandomSeed.restype = c_bool
924
952
 
925
953
  handle_buf = self.str_to_char_p(handle)
@@ -935,7 +963,7 @@ class Amalgam:
935
963
  self.gc()
936
964
  return result
937
965
 
938
- def get_entities(self) -> List[str]:
966
+ def get_entities(self) -> list[str]:
939
967
  """
940
968
  Get loaded top level entities.
941
969
 
@@ -944,7 +972,7 @@ class Amalgam:
944
972
  list of str
945
973
  The list of entity handles.
946
974
  """
947
- self.amlg.GetEntities.argtype = [POINTER(c_uint64)]
975
+ self.amlg.GetEntities.argtypes = [POINTER(c_uint64)]
948
976
  self.amlg.GetEntities.restype = POINTER(c_char_p)
949
977
  num_entities = c_uint64()
950
978
  entities = self.amlg.GetEntities(byref(num_entities))
@@ -960,7 +988,7 @@ class Amalgam:
960
988
  self,
961
989
  handle: str,
962
990
  label: str,
963
- json: Union[str, bytes]
991
+ json: str | bytes
964
992
  ) -> bytes:
965
993
  """
966
994
  Execute a label with parameters provided in json format.
@@ -980,7 +1008,7 @@ class Amalgam:
980
1008
  A byte-encoded json representation of the response.
981
1009
  """
982
1010
  self.amlg.ExecuteEntityJsonPtr.restype = POINTER(c_char)
983
- self.amlg.ExecuteEntityJsonPtr.argtype = [
1011
+ self.amlg.ExecuteEntityJsonPtr.argtypes = [
984
1012
  c_char_p, c_char_p, c_char_p]
985
1013
  handle_buf = self.str_to_char_p(handle)
986
1014
  label_buf = self.str_to_char_p(label)
@@ -1004,199 +1032,6 @@ class Amalgam:
1004
1032
 
1005
1033
  return result
1006
1034
 
1007
- def set_number_value(self, handle: str, label: str, value: float) -> None:
1008
- """
1009
- Set a numeric value to a label in an amalgam entity.
1010
-
1011
- Parameters
1012
- ----------
1013
- handle : str
1014
- The handle of the amalgam entity.
1015
- label : str
1016
- The label to set.
1017
- value : float
1018
- A numeric value to assign to a label.
1019
- """
1020
- self.amlg.SetNumberValue.restype = c_void_p
1021
- self.amlg.SetNumberValue.argtype = [c_char_p, c_char_p, c_double]
1022
- handle_buf = self.str_to_char_p(handle)
1023
- label_buf = self.str_to_char_p(label)
1024
- val = c_double(value)
1025
-
1026
- self.amlg.SetNumberValue(handle_buf, label_buf, val)
1027
-
1028
- del handle_buf
1029
- del label_buf
1030
- del val
1031
- self.gc()
1032
-
1033
- def get_number_value(self, handle: str, label: str) -> float:
1034
- """
1035
- Retrieve the numeric value of a label in an amalgam entity.
1036
-
1037
- Parameters
1038
- ----------
1039
- handle : str
1040
- The handle of the amalgam entity.
1041
- label : str
1042
- The label to execute.
1043
-
1044
- Returns
1045
- -------
1046
- float
1047
- The numeric value of the label.
1048
- """
1049
- self.amlg.GetNumberValue.restype = c_double
1050
- self.amlg.GetNumberValue.argtype = [c_char_p, c_char_p]
1051
- handle_buf = self.str_to_char_p(handle)
1052
- label_buf = self.str_to_char_p(label)
1053
-
1054
- result = self.amlg.GetNumberValue(handle_buf, label_buf)
1055
-
1056
- del handle_buf
1057
- del label_buf
1058
-
1059
- return result
1060
-
1061
- def set_string_value(
1062
- self,
1063
- handle: str,
1064
- label: str,
1065
- value: Union[str, bytes]
1066
- ) -> None:
1067
- """
1068
- Set a string value to a label in an amalgam entity.
1069
-
1070
- Parameters
1071
- ----------
1072
- handle : str
1073
- The handle of the amalgam entity.
1074
- label : str
1075
- The label to set.
1076
- value : str or bytes
1077
- A string value.
1078
- """
1079
- self.amlg.SetStringValue.restype = c_void_p
1080
- self.amlg.SetStringValue.argtype = [c_char_p, c_char_p, c_char_p]
1081
- handle_buf = self.str_to_char_p(handle)
1082
- label_buf = self.str_to_char_p(label)
1083
- val_buf = self.str_to_char_p(value)
1084
-
1085
- self.amlg.SetStringValue(handle_buf, label_buf, val_buf)
1086
-
1087
- del handle_buf
1088
- del label_buf
1089
- del val_buf
1090
- self.gc()
1091
-
1092
- def get_string_value(self, handle: str, label: str) -> Union[bytes, None]:
1093
- """
1094
- Retrieve a string value from a label in an amalgam entity.
1095
-
1096
- Parameters
1097
- ----------
1098
- handle : str
1099
- The handle of the amalgam entity.
1100
- label : str
1101
- The label to retrieve.
1102
-
1103
- Returns
1104
- -------
1105
- bytes or None
1106
- The byte-encoded string value of the label in the amalgam entity.
1107
- """
1108
- self.amlg.GetStringListPtr.restype = POINTER(c_char_p)
1109
- self.amlg.GetStringListPtr.argtype = [c_char_p, c_char_p]
1110
- handle_buf = self.str_to_char_p(handle)
1111
- label_buf = self.str_to_char_p(label)
1112
-
1113
- size = self.amlg.GetStringListLength(handle_buf, label_buf)
1114
- value_buf = self.amlg.GetStringListPtr(handle_buf, label_buf)
1115
- result = None
1116
- if value_buf is not None and size > 0:
1117
- result = value_buf[0]
1118
-
1119
- del handle_buf
1120
- del label_buf
1121
- del value_buf
1122
- self.gc()
1123
-
1124
- return result
1125
-
1126
- def set_string_list(
1127
- self,
1128
- handle: str,
1129
- label: str,
1130
- value: List[Union[str, bytes]]
1131
- ) -> None:
1132
- """
1133
- Set a list of strings to an amalgam entity.
1134
-
1135
- Parameters
1136
- ----------
1137
- handle : str
1138
- The handle of the amalgam entity.
1139
- label : str
1140
- The label to set.
1141
- value : list of str or list of bytes
1142
- A 1d list of string values.
1143
- """
1144
- self.amlg.SetStringList.restype = c_void_p
1145
- self.amlg.SetStringList.argtype = [
1146
- c_char_p, c_char_p, POINTER(c_char_p), c_size_t]
1147
-
1148
- size = len(value)
1149
- value_buf = (c_char_p * size)()
1150
- for i in range(size):
1151
- if isinstance(value[i], bytes):
1152
- value_buf[i] = c_char_p(value[i])
1153
- else:
1154
- value_buf[i] = c_char_p(value[i].encode('utf-8'))
1155
-
1156
- handle_buf = self.str_to_char_p(handle)
1157
- label_buf = self.str_to_char_p(label)
1158
- self.amlg.SetStringList(handle_buf, label_buf, value_buf, size)
1159
-
1160
- del handle_buf
1161
- del label_buf
1162
- del value_buf
1163
- self.gc()
1164
-
1165
- def get_string_list(self, handle: str, label: str) -> List[bytes]:
1166
- """
1167
- Retrieve a list of numbers from a label in an amalgam entity.
1168
-
1169
- Parameters
1170
- ----------
1171
- handle : str
1172
- The handle of the amalgam entity.
1173
- label : str
1174
- The label to execute.
1175
-
1176
- Returns
1177
- -------
1178
- list of bytes
1179
- A 1d list of byte-encoded string values from the label in the
1180
- amalgam entity.
1181
- """
1182
- self.amlg.GetStringListLength.restype = c_size_t
1183
- self.amlg.GetStringListLength.argtype = [c_char_p, c_char_p]
1184
- self.amlg.GetStringListPtr.restype = POINTER(c_char_p)
1185
- self.amlg.GetStringListPtr.argtype = [c_char_p, c_char_p]
1186
- handle_buf = self.str_to_char_p(handle)
1187
- label_buf = self.str_to_char_p(label)
1188
-
1189
- size = self.amlg.GetStringListLength(handle_buf, label_buf)
1190
- value_buf = self.amlg.GetStringListPtr(handle_buf, label_buf)
1191
- value = [value_buf[i] for i in range(size)]
1192
-
1193
- del handle_buf
1194
- del label_buf
1195
- del value_buf
1196
- self.gc()
1197
-
1198
- return value
1199
-
1200
1035
  def get_version_string(self) -> bytes:
1201
1036
  """
1202
1037
  Get the version string of the amalgam dynamic library.
@@ -1232,7 +1067,7 @@ class Amalgam:
1232
1067
  @staticmethod
1233
1068
  def escape_double_quotes(s: str) -> str:
1234
1069
  """
1235
- Get the string with backslashes preceeding contained double quotes.
1070
+ Get the string with backslashes preceding contained double quotes.
1236
1071
 
1237
1072
  Parameters
1238
1073
  ----------
Binary file
Binary file
Binary file
@@ -1,3 +1,3 @@
1
1
  {
2
- "version": "51.4.1"
2
+ "version": "54.0.0"
3
3
  }
amalgam/lib/version.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "version": {
3
- "amalgam": "51.4.1",
4
- "amalgam_sha": "3672a26c78d6dcc2f3a9def3cbf26dcfa7b9e156",
5
- "amalgam_url": "https://github.com/howsoai/amalgam/releases/tag/51.4.1",
3
+ "amalgam": "54.0.0",
4
+ "amalgam_sha": "7d51deac4e5fd97c813c5c23a366a559913f5262",
5
+ "amalgam_url": "https://github.com/howsoai/amalgam/releases/tag/54.0.0",
6
6
  "amalgam_build_date": "",
7
7
  "amalgam_display_title": ""
8
8
  }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: amalgam-lang
3
- Version: 10.4.1
3
+ Version: 12.0.0
4
4
  Summary: A direct interface with Amalgam compiled DLL or so.
5
5
  Author: Howso Incorporated
6
6
  Author-email: support@howso.com
@@ -753,6 +753,11 @@ The wrapper handles the Amalgam language binary (so/dll/dylib) automatically for
753
753
  amlg = Amalgam(library_path="/path/to/amalgam-mt.so")
754
754
  ```
755
755
 
756
+ ## Testing
757
+ There is a `Pytest` unit test suite located in `amalgam/test`. The tests in `test_standalone.py` will only execute if an `Amalgam` binary is located in the default expected path of `amalgam/lib/{os}/{architecture}`.
758
+
759
+ To specify whether `test_standalone.py` should use single-threaded or multi-threaded `Amalgam` (assuming the appropriate binary is in the above path), set the `AMALGAM_LIBRARY_POSTFIX` environment variable to the desired postfix, e.g., `-st` or `-mt`.
760
+
756
761
  ## License
757
762
 
758
763
  [License](LICENSE.txt)
@@ -0,0 +1,13 @@
1
+ amalgam/__init__.py,sha256=oHu7Zr4eGDUqj93pLwz8t7gLa8lpAx6Q-xbGiJ3nJx0,18
2
+ amalgam/api.py,sha256=IWS--0NCnhsadMYSna2gLllNxG_i3HpymY3eXbugwDU,36796
3
+ amalgam/lib/version.json,sha256=KO3uhOlJvvs6p4aUi7N9GFKOBT7YksAVYMUStRYo_eg,250
4
+ amalgam/lib/darwin/amd64/amalgam-mt-noavx.dylib,sha256=6342n0WTt0YIjKca-STuqarAGaVataO5UXgR7dZ2FRg,2994384
5
+ amalgam/lib/darwin/amd64/amalgam-mt.dylib,sha256=nXnEvODfeNsXQydNd7qfjl99zuEpcyQPNCFDvyLXS98,2940904
6
+ amalgam/lib/darwin/amd64/amalgam-omp.dylib,sha256=3lEuExdY3qminSin-xv38342SSjppt15wkKdIVSb7oc,3324680
7
+ amalgam/lib/darwin/amd64/amalgam-st.dylib,sha256=ScuH5CaJ16P5HsPp7S7I6tJrvqRBAYb_JamEB3KKPa0,2822456
8
+ amalgam/lib/darwin/amd64/docs/version.json,sha256=8rii1FbVYrPfX-FZhrjjqZAiEFHC2xJq_OOL2-WTR9E,25
9
+ amalgam_lang-12.0.0.dist-info/LICENSE.txt,sha256=2xqHuoHohba7gpcZZKtOICRjzeKsQANXG8WoV9V35KM,33893
10
+ amalgam_lang-12.0.0.dist-info/METADATA,sha256=aPV_QuyaRPZpcMc0WXOr7Kufk1NjmGdwwx-DldON-kQ,43834
11
+ amalgam_lang-12.0.0.dist-info/WHEEL,sha256=mguMlWGMX-VHnMpKOjjQidIo1ssRlCFu4a4mBpz1s2M,91
12
+ amalgam_lang-12.0.0.dist-info/top_level.txt,sha256=rmPHU144SyaB25u5-FAQyECAQnJ39NvuJEcKXMRcdBo,8
13
+ amalgam_lang-12.0.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.40.0)
2
+ Generator: setuptools (70.1.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,13 +0,0 @@
1
- amalgam/__init__.py,sha256=oHu7Zr4eGDUqj93pLwz8t7gLa8lpAx6Q-xbGiJ3nJx0,18
2
- amalgam/api.py,sha256=ni3a4vRa90ITImg4uI4zd3CBaxC5pb_LXBT1xs9i88c,41742
3
- amalgam/lib/version.json,sha256=ne0Xe6jPEIVEQgh7P0NWbTIeXWZPVrD8rSqtKsSe1u8,250
4
- amalgam/lib/darwin/amd64/amalgam-mt-noavx.dylib,sha256=HhTucmx6PqPXbeHCP1c78mG6mH3ZsJ7x93rsC7ERaPU,3048968
5
- amalgam/lib/darwin/amd64/amalgam-mt.dylib,sha256=srtCzXAveZ-XBl-iXs1yhJ_rQfH6AAA7HnKqezR6MC0,2979104
6
- amalgam/lib/darwin/amd64/amalgam-omp.dylib,sha256=kO3aKbsfXKf4H1EbBLdpk-fp7rVAhWYvtDauS8FrDlA,3362896
7
- amalgam/lib/darwin/amd64/amalgam-st.dylib,sha256=6-AxESZc6oOFEcB_rAq4QPx2mLtb3YKq2izLrI3h3GM,2877072
8
- amalgam/lib/darwin/amd64/docs/version.json,sha256=iKjvZ70DlRowMIpa3SK8UqxNFik0A5bs005Nw6jh9oA,25
9
- amalgam_lang-10.4.1.dist-info/LICENSE.txt,sha256=2xqHuoHohba7gpcZZKtOICRjzeKsQANXG8WoV9V35KM,33893
10
- amalgam_lang-10.4.1.dist-info/METADATA,sha256=CVvRFPYiUjFdis60Qadj6I75SuXZjRRvKWiaAfCD4iY,43353
11
- amalgam_lang-10.4.1.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
12
- amalgam_lang-10.4.1.dist-info/top_level.txt,sha256=rmPHU144SyaB25u5-FAQyECAQnJ39NvuJEcKXMRcdBo,8
13
- amalgam_lang-10.4.1.dist-info/RECORD,,