vunit-python-bridge 0.1.0__py3-none-any.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.
Files changed (34) hide show
  1. vunit_python_bridge/__init__.py +92 -0
  2. vunit_python_bridge/bin/vunit_python_bridge-cp310-win_amd64.dll +0 -0
  3. vunit_python_bridge/bin/vunit_python_bridge-cp311-win_amd64.dll +0 -0
  4. vunit_python_bridge/bin/vunit_python_bridge-cp312-win_amd64.dll +0 -0
  5. vunit_python_bridge/bin/vunit_python_bridge-cp313-win_amd64.dll +0 -0
  6. vunit_python_bridge/bin/vunit_python_bridge-cp314-win_amd64.dll +0 -0
  7. vunit_python_bridge/bridge.py +171 -0
  8. vunit_python_bridge/foreign_application.py +90 -0
  9. vunit_python_bridge/hdl/src/python_bridge_pkg.vhd.in +91 -0
  10. vunit_python_bridge/hdl/src/python_context.vhd +13 -0
  11. vunit_python_bridge/hdl/src/python_ffi_pkg_bridge.vhd +507 -0
  12. vunit_python_bridge/hdl/src/python_pkg.vhd +1087 -0
  13. vunit_python_bridge/hdl/src/python_pkg_vhpi.vhd +270 -0
  14. vunit_python_bridge/hdl/tools/generate_python_pkg.py +386 -0
  15. vunit_python_bridge/hdl/tools/python_pkg.vhd.in +765 -0
  16. vunit_python_bridge/native/arguments.c +191 -0
  17. vunit_python_bridge/native/bridge.h +117 -0
  18. vunit_python_bridge/native/config.c +201 -0
  19. vunit_python_bridge/native/error.c +120 -0
  20. vunit_python_bridge/native/fli.c +98 -0
  21. vunit_python_bridge/native/interpreter.c +271 -0
  22. vunit_python_bridge/native/operations.c +239 -0
  23. vunit_python_bridge/native/vhpi/python_pkg.c +125 -0
  24. vunit_python_bridge/native/vhpi/python_pkg.h +31 -0
  25. vunit_python_bridge/native/vhpi/python_pkg_vhpi.c +366 -0
  26. vunit_python_bridge/native_library.py +455 -0
  27. vunit_python_bridge/runtime.py +645 -0
  28. vunit_python_bridge/simulator_hooks.py +141 -0
  29. vunit_python_bridge/vunit_pkg.toml +17 -0
  30. vunit_python_bridge-0.1.0.dist-info/METADATA +116 -0
  31. vunit_python_bridge-0.1.0.dist-info/RECORD +34 -0
  32. vunit_python_bridge-0.1.0.dist-info/WHEEL +5 -0
  33. vunit_python_bridge-0.1.0.dist-info/licenses/LICENSE +373 -0
  34. vunit_python_bridge-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,92 @@
1
+ # This Source Code Form is subject to the terms of the Mozilla Public
2
+ # License, v. 2.0. If a copy of the MPL was not distributed with this file,
3
+ # You can obtain one at http://mozilla.org/MPL/2.0/.
4
+ #
5
+ # Copyright (c) 2014-2026, Lars Asplund lars.anders.asplund@gmail.com
6
+
7
+
8
+ """
9
+ The VUnit package making Python callable from VHDL.
10
+
11
+ ``vu.add_package("vunit-python-bridge", allow_setup=True)`` compiles
12
+ ``python_pkg``/``python_context`` into the ``python_bridge`` library and sets up the foreign
13
+ language interface implementing them for the selected simulator:
14
+
15
+ * NVC, GHDL (VHPIDIRECT) and Questa/ModelSim (FLI) are served by the VUnit Python bridge, a
16
+ small C library (native/*.c) embedding CPython in the simulator process.
17
+ * Riviera-PRO/Active-HDL are served by a VHPI application built with the simulator's own
18
+ compiler driver.
19
+
20
+ Modules:
21
+
22
+ * bridge: setup of the bridge, its configuration and its generated VHDL.
23
+ * native_library: compiles and caches the library on Linux and macOS, selects the prebuilt
24
+ DLL on Windows.
25
+ * foreign_application: builds the VHPI application.
26
+ * simulator_hooks: makes NVC and GHDL find the library.
27
+ * runtime: runs inside the simulator's embedded interpreter.
28
+ """
29
+
30
+ from pathlib import Path
31
+
32
+ VHDL_PATH = Path(__file__).parent.resolve() / "hdl" / "src"
33
+
34
+ # The foreign language interface implementing the package for a simulator. VUnit says which
35
+ # simulator was selected, the package says how it is served: NVC and GHDL both go through
36
+ # VHPIDIRECT but bind the library differently, Questa/ModelSim goes through the FLI and
37
+ # Riviera-PRO/Active-HDL through a VHPI application of their own.
38
+ FOREIGN_LANGUAGE_INTERFACES = {
39
+ "nvc": "VHPIDIRECT_NVC",
40
+ "ghdl": "VHPIDIRECT_GHDL",
41
+ "modelsim": "FLI",
42
+ "rivierapro": "VHPI",
43
+ "activehdl": "VHPI",
44
+ }
45
+
46
+ # The simulators of the table, named as a user knows them
47
+ SUPPORTED_SIMULATORS = "NVC, GHDL, Questa/ModelSim, Riviera-PRO or Active-HDL"
48
+
49
+
50
+ def setup(context):
51
+ """
52
+ Complete the addition of the package.
53
+
54
+ ``vunit_pkg.toml`` lists the sources both variants of the package share, this adds the
55
+ foreign language interface of the selected simulator: the VHPI application for
56
+ Riviera-PRO/Active-HDL, the VUnit Python bridge for everyone else.
57
+ """
58
+ # pylint: disable=import-outside-toplevel
59
+ from .bridge import setup as setup_bridge
60
+ from .foreign_application import setup_vhpi_application
61
+ from . import simulator_hooks
62
+
63
+ simulator_name = context.simulator_name
64
+ if simulator_name is None:
65
+ raise RuntimeError(
66
+ f"The vunit-python-bridge package requires {SUPPORTED_SIMULATORS} but no simulator was found"
67
+ )
68
+
69
+ interface = FOREIGN_LANGUAGE_INTERFACES.get(simulator_name)
70
+ if interface is None:
71
+ raise RuntimeError(
72
+ f"The vunit-python-bridge package requires {SUPPORTED_SIMULATORS}, "
73
+ f"it has no foreign language interface for {simulator_name}"
74
+ )
75
+
76
+ if interface == "VHPI":
77
+ # Riviera-PRO/Active-HDL, the simulators served by the VHPI application
78
+ context.add_source_files(context.library.name, [VHDL_PATH / "python_pkg_vhpi.vhd"])
79
+ setup_vhpi_application(context.output_path, simulator_name, context.simulator_prefix)
80
+ return
81
+
82
+ bridge = setup_bridge(
83
+ context.output_path,
84
+ context.run_script_path,
85
+ simulator_name,
86
+ context.simulator_prefix,
87
+ context.simulator_backend,
88
+ )
89
+
90
+ context.add_source_files(context.library.name, list(bridge.vhdl_files))
91
+
92
+ simulator_hooks.register(context, bridge)
@@ -0,0 +1,171 @@
1
+ # This Source Code Form is subject to the terms of the Mozilla Public
2
+ # License, v. 2.0. If a copy of the MPL was not distributed with this file,
3
+ # You can obtain one at http://mozilla.org/MPL/2.0/.
4
+ #
5
+ # Copyright (c) 2014-2026, Lars Asplund lars.anders.asplund@gmail.com
6
+
7
+
8
+ """
9
+ Setup of the Python bridge of a project: native library, configuration and generated VHDL.
10
+ """
11
+
12
+ import os
13
+ import re
14
+ import sys
15
+ from pathlib import Path
16
+ from typing import List, NamedTuple, Optional
17
+
18
+ from .native_library import (
19
+ PACKAGE_PATH,
20
+ PythonBridgeError,
21
+ check_python_build,
22
+ check_windows_64bit_simulator,
23
+ prepare_library,
24
+ windows_python_dll,
25
+ )
26
+
27
+ RUNTIME_SOURCE = PACKAGE_PATH / "runtime.py"
28
+ VHDL_SOURCE_PATH = PACKAGE_PATH / "hdl" / "src"
29
+ BRIDGE_PACKAGE_TEMPLATE = VHDL_SOURCE_PATH / "python_bridge_pkg.vhd.in"
30
+ CONFIG_FILE_NAME = "vunit_python_bridge.cfg"
31
+
32
+ # The simulators the bridge serves, reaching it through VHPIDIRECT and through the FLI.
33
+ # The rest of the simulators of the package are served by the VHPI application.
34
+ FLI_SIMULATORS = ("modelsim",)
35
+ BRIDGE_SIMULATORS = ("nvc", "ghdl") + FLI_SIMULATORS
36
+
37
+ # GHDL backends that link the design ahead of time. For these the library
38
+ # token in the VHPIDIRECT attribute is passed to the linker instead of being
39
+ # dlopen()ed at run time.
40
+ GHDL_LINKING_BACKENDS = ("llvm", "gcc")
41
+
42
+ # {foreign:<entry point>} placeholder of the bridge package template
43
+ FOREIGN_PATTERN = re.compile(r"\{foreign:(\w+)\}")
44
+ # The subprogram declarations of the template, whose bodies are generated
45
+ SUBPROGRAM_PATTERN = re.compile(r"^ (impure function|procedure) (\w+)(\([^)]*\))?( return \w+)?;", re.MULTILINE)
46
+
47
+
48
+ class PythonBridge(NamedTuple):
49
+ """
50
+ A prepared bridge: the native library and the generated VHDL.
51
+ """
52
+
53
+ library_file: Path
54
+ vhdl_files: List[Path]
55
+
56
+
57
+ def setup(
58
+ output_path,
59
+ run_script_path: Optional[Path],
60
+ simulator_name: Optional[str] = None,
61
+ simulator_prefix: Optional[str] = None,
62
+ simulator_backend: Optional[str] = None,
63
+ ) -> PythonBridge:
64
+ """
65
+ Prepare the Python bridge for a project. Called by the package setup function.
66
+
67
+ :param run_script_path: The run script or None. The runtime puts its directory, or the current
68
+ directory without a run script, first on sys.path, like python does.
69
+ :param simulator_name: The name of the selected simulator, None for no simulator.
70
+ :param simulator_prefix: The path its executables were found in.
71
+ :param simulator_backend: How the installation found there was built, which for GHDL
72
+ is the code generator deciding how the library is bound.
73
+ :returns: The bridge. Its vhdl_files are to be added to the package library.
74
+ """
75
+ if simulator_name is not None and simulator_name not in BRIDGE_SIMULATORS:
76
+ raise PythonBridgeError(
77
+ f"The vunit-python-bridge package requires NVC, GHDL or Questa/ModelSim, "
78
+ f"it is not supported for {simulator_name}"
79
+ )
80
+
81
+ check_python_build()
82
+ check_windows_64bit_simulator(simulator_name, simulator_prefix)
83
+
84
+ is_fli = simulator_name in FLI_SIMULATORS
85
+ if is_fli and simulator_prefix is None:
86
+ raise PythonBridgeError(
87
+ f"The FLI variant of the bridge is built against the {simulator_name} installation, but it was not found"
88
+ )
89
+
90
+ root = Path(output_path) / "python_bridge"
91
+ library_file = prepare_library(root, Path(simulator_prefix) if is_fli else None)
92
+ run_script_dir = str(Path.cwd() if run_script_path is None else Path(run_script_path).resolve().parent)
93
+ _write_if_changed(library_file.parent / CONFIG_FILE_NAME, _config_text(run_script_dir))
94
+
95
+ # The foreign attribute string of an entry point: the name of its wrapper in native/fli.c
96
+ # and the library, by absolute path since Questa accepts it, for the FLI; the VHPIDIRECT
97
+ # library token and the entry point itself for NVC and GHDL.
98
+ foreign = (
99
+ f"fli_{{entry_point}} {library_file!s}"
100
+ if is_fli
101
+ else f"VHPIDIRECT {_vhpidirect_token(simulator_name, simulator_backend, library_file)} {{entry_point}}"
102
+ )
103
+ bridge_package = root / "vhdl" / "python_bridge_pkg.vhd"
104
+ _write_if_changed(bridge_package, _render_bridge_package(foreign))
105
+
106
+ return PythonBridge(
107
+ library_file,
108
+ [
109
+ bridge_package,
110
+ VHDL_SOURCE_PATH / "python_ffi_pkg_bridge.vhd",
111
+ ],
112
+ )
113
+
114
+
115
+ def _vhpidirect_token(simulator_name, simulator_backend: Optional[str], library_file: Path) -> str:
116
+ """
117
+ The library token of the VHPIDIRECT attributes: the file name the simulator dlopen()s,
118
+ or the linker flag of the GHDL backends that link the design ahead of time.
119
+ """
120
+ if simulator_name == "ghdl" and simulator_backend in GHDL_LINKING_BACKENDS:
121
+ return "-lvunit_python_bridge"
122
+ return library_file.name
123
+
124
+
125
+ def _render_bridge_package(foreign: str) -> str:
126
+ """
127
+ The generated python_bridge_pkg.vhd: the declarations of the template with the foreign
128
+ attribute of every subprogram, and a body reporting a failure for each of them since the
129
+ bodies are replaced by the foreign implementations and never executed.
130
+ """
131
+ template = BRIDGE_PACKAGE_TEMPLATE.read_text(encoding="utf-8")
132
+ declarations = FOREIGN_PATTERN.sub(lambda match: foreign.format(entry_point=match.group(1)), template)
133
+ stubs = []
134
+ for kind, name, parameters, result in SUBPROGRAM_PATTERN.findall(declarations):
135
+ stubs.append(f" {kind} {name}{parameters}{result} is\n begin")
136
+ stubs.append(f' report "VUnit Python bridge: foreign subprogram {name} is not bound" severity failure;')
137
+ if result:
138
+ stubs.append(f" return {'0.0' if result.endswith('real') else '1'};")
139
+ stubs.append(" end;\n")
140
+ return declarations + "\npackage body python_bridge_pkg is\n" + "\n".join(stubs) + "end package body;\n"
141
+
142
+
143
+ def _config_text(run_script_dir: str) -> str:
144
+ """
145
+ Content of the configuration file read by the bridge library at run time.
146
+ """
147
+ lines = {
148
+ "executable": sys.executable,
149
+ "prefix": sys.prefix,
150
+ "runtime": str(RUNTIME_SOURCE),
151
+ "run_script_dir": run_script_dir,
152
+ }
153
+ if sys.platform == "win32":
154
+ lines["python_dll"] = windows_python_dll()
155
+ for key, value in lines.items():
156
+ if "\n" in value or "\r" in value:
157
+ raise PythonBridgeError(f"VHDL Python support cannot handle line breaks in the path {value!r}")
158
+ return "".join(f"{key}={value}\n" for key, value in lines.items())
159
+
160
+
161
+ def _write_if_changed(path: Path, text: str) -> None:
162
+ """
163
+ Write a file unless it already has the given content, keeping timestamps stable.
164
+ """
165
+ data = text.encode("utf-8")
166
+ if path.is_file() and path.read_bytes() == data:
167
+ return
168
+ path.parent.mkdir(parents=True, exist_ok=True)
169
+ tmp = path.with_name(path.name + f".{os.getpid()}.tmp")
170
+ tmp.write_bytes(data)
171
+ os.replace(tmp, path)
@@ -0,0 +1,90 @@
1
+ # This Source Code Form is subject to the terms of the Mozilla Public
2
+ # License, v. 2.0. If a copy of the MPL was not distributed with this file,
3
+ # You can obtain one at http://mozilla.org/MPL/2.0/.
4
+ #
5
+ # Copyright (c) 2014-2026, Lars Asplund lars.anders.asplund@gmail.com
6
+
7
+ """
8
+ Building the foreign language application implementing ``python_pkg``/``python_context``
9
+ for the simulators the VUnit Python bridge does not serve.
10
+
11
+ ``setup_vhpi_application`` is called by the setup function of the package for
12
+ Riviera-PRO/Active-HDL (VHPI). The application is built under the output path on first use and
13
+ rebuilt when its sources, the Python running VUnit or the simulator change.
14
+ """
15
+
16
+ from pathlib import Path
17
+ import os
18
+ import sys
19
+ import hashlib
20
+
21
+ from .native_library import (
22
+ add_python_dll_to_path,
23
+ check_windows_64bit_simulator,
24
+ compile_library,
25
+ python_dev_paths,
26
+ windows_gcc,
27
+ )
28
+
29
+ SRC_PATH = Path(__file__).parent.resolve() / "native" / "vhpi"
30
+
31
+
32
+ def setup_vhpi_application(output_path, simulator_name, simulator_prefix):
33
+ """
34
+ Build the VHPI application for Riviera-PRO/Active-HDL under the output path, unless the one
35
+ already there was built from the same sources for the same Python and simulator.
36
+
37
+ :param simulator_prefix: The path the executables of the simulator were found in, which is
38
+ where its ccomp compiler driver is.
39
+ """
40
+ if simulator_prefix is None:
41
+ raise RuntimeError(f"The VHPI application is built with the ccomp of {simulator_name}, but it was not found")
42
+
43
+ check_windows_64bit_simulator(simulator_name, simulator_prefix)
44
+ target = Path(output_path) / simulator_name / "libraries" / "python.dll"
45
+ sources = [SRC_PATH / "python_pkg_vhpi.c", SRC_PATH / "python_pkg.c"]
46
+ simulator_prefix = Path(simulator_prefix).resolve()
47
+ fingerprint = _fingerprint(sources, simulator_prefix)
48
+ fingerprint_file = target.with_suffix(target.suffix + ".fingerprint")
49
+ if target.exists() and fingerprint_file.exists() and fingerprint_file.read_text(encoding="utf-8") == fingerprint:
50
+ return
51
+
52
+ target.parent.mkdir(parents=True, exist_ok=True)
53
+ fingerprint_file.unlink(missing_ok=True)
54
+ _build_vhpi(target, sources, simulator_prefix)
55
+ fingerprint_file.write_text(fingerprint, encoding="utf-8")
56
+
57
+
58
+ def _fingerprint(sources, simulator_prefix):
59
+ """
60
+ Everything the built application depends on: the C sources and headers, the Python that is
61
+ embedded and the simulator whose headers and libraries are used.
62
+ """
63
+ digest = hashlib.sha256()
64
+ for path in sorted(sources) + sorted(SRC_PATH.glob("*.h")):
65
+ digest.update(path.name.encode("utf-8") + b"\0" + path.read_bytes() + b"\0")
66
+ for item in [sys.executable, sys.prefix, sys.version, sys.platform, str(simulator_prefix)]:
67
+ digest.update(item.encode("utf-8") + b"\0")
68
+ return digest.hexdigest()
69
+
70
+
71
+ def _build_vhpi(target, sources, simulator_prefix):
72
+ """
73
+ Compile the VHPI application with the ccomp compiler driver of Riviera-PRO/Active-HDL.
74
+ """
75
+ python_include, python_libs = python_dev_paths()
76
+ ccomp = simulator_prefix / ("ccomp.exe" if sys.platform == "win32" else "ccomp")
77
+ env = None
78
+ if sys.platform == "win32":
79
+ add_python_dll_to_path()
80
+ # Riviera-PRO bundles a MinGW gcc under <installation>/mingw, other installations may not.
81
+ # ponytail: untested (no Aldec license), assumes ccomp finds gcc on PATH when none is bundled
82
+ gcc = windows_gcc(simulator_prefix)
83
+ if gcc is not None:
84
+ env = dict(os.environ, PATH=os.pathsep.join([str(Path(gcc[0]).parent), os.environ.get("PATH", "")]))
85
+ # One argument per item: subprocess quotes them, quotes added here would reach ccomp literally
86
+ args = [str(ccomp), "-vhpi", "-dbg", "-verbose", "-o", str(target)]
87
+ args += ["-l", f"python{sys.version_info[0]}{sys.version_info[1]}", "-l", "python3", "-l", "_tkinter"]
88
+ args += ["-I", str(python_include), "-I", str(SRC_PATH), "-L", str(python_libs)]
89
+ args += [str(path) for path in sources]
90
+ compile_library(args, target, target, env)
@@ -0,0 +1,91 @@
1
+ -- This Source Code Form is subject to the terms of the Mozilla Public
2
+ -- License, v. 2.0. If a copy of the MPL was not distributed with this file,
3
+ -- You can obtain one at http://mozilla.org/MPL/2.0/.
4
+ --
5
+ -- Copyright (c) 2014-2026, Lars Asplund lars.anders.asplund@gmail.com
6
+ --
7
+ -- PRIVATE foreign subprograms of the VUnit Python bridge (src/vunit_python_bridge/native).
8
+ --
9
+ -- This file is a template. The setup function of the package substitutes every
10
+ -- {foreign:<entry point>} placeholder with the foreign attribute string of the
11
+ -- selected simulator -- "VHPIDIRECT <library> <entry point>" for NVC and GHDL,
12
+ -- "fli_<entry point> <library>" for the FLI of Questa/ModelSim -- and adds the
13
+ -- result to the python_bridge library, together with a generated package body
14
+ -- whose subprograms are never executed. The public API is
15
+ -- python_pkg/python_ffi_pkg, which is implemented on top of this package.
16
+ --
17
+ -- Only scalars and constrained arrays cross the foreign interface since their
18
+ -- ABI is identical for NVC and GHDL on all platforms and is translated to the
19
+ -- FLI parameter passing conventions by native/fli.c.
20
+
21
+ package python_bridge_pkg is
22
+ constant chunk_length : positive := 1024;
23
+ subtype string_chunk_t is string(1 to chunk_length);
24
+ subtype integer_chunk_t is integer_vector(0 to chunk_length - 1);
25
+ subtype real_chunk_t is real_vector(0 to chunk_length - 1);
26
+
27
+ -- Start the interpreter. Idempotent.
28
+ impure function vpy_setup return integer;
29
+ attribute foreign of vpy_setup : function is "{foreign:vpy_setup}";
30
+
31
+ -- Flush Python's streams and drop the last result and the staged values.
32
+ -- The interpreter is not finalized: later operations keep working.
33
+ impure function vpy_cleanup return integer;
34
+ attribute foreign of vpy_cleanup : function is "{foreign:vpy_cleanup}";
35
+
36
+ impure function vpy_buffer_clear return integer;
37
+ attribute foreign of vpy_buffer_clear : function is "{foreign:vpy_buffer_clear}";
38
+
39
+ impure function vpy_buffer_append(chunk : string_chunk_t; length : integer) return integer;
40
+ attribute foreign of vpy_buffer_append : function is "{foreign:vpy_buffer_append}";
41
+
42
+ -- Start an operation in the session named by the buffer ("default" is __main__).
43
+ impure function vpy_begin return integer;
44
+ attribute foreign of vpy_begin : function is "{foreign:vpy_begin}";
45
+
46
+ -- Execute the buffer as Python source (is_file = 0) or as a file name (is_file = 1).
47
+ impure function vpy_execute(is_file : integer) return integer;
48
+ attribute foreign of vpy_execute : function is "{foreign:vpy_execute}";
49
+
50
+ -- Evaluate the buffer as a Python expression and convert the value to the
51
+ -- VHDL type given by kind. width is the length of a std_ulogic_vector,
52
+ -- signed or unsigned result, -1 when it is not known.
53
+ impure function vpy_eval(kind, width : integer) return integer;
54
+ attribute foreign of vpy_eval : function is "{foreign:vpy_eval}";
55
+
56
+ impure function vpy_push_array(length, width, height, depth, bit_width, is_signed : integer) return integer;
57
+ attribute foreign of vpy_push_array : function is "{foreign:vpy_push_array}";
58
+
59
+ impure function vpy_array_write(chunk : integer_chunk_t; length : integer) return integer;
60
+ attribute foreign of vpy_array_write : function is "{foreign:vpy_array_write}";
61
+
62
+ -- Stage the pushed array and return its id (>= 1), -1 on error. Python
63
+ -- source code refers to the value as __vunit__.staged(<id>).
64
+ impure function vpy_stage return integer;
65
+ attribute foreign of vpy_stage : function is "{foreign:vpy_stage}";
66
+
67
+ impure function vpy_result_integer return integer;
68
+ attribute foreign of vpy_result_integer : function is "{foreign:vpy_result_integer}";
69
+
70
+ impure function vpy_result_real return real;
71
+ attribute foreign of vpy_result_real : function is "{foreign:vpy_result_real}";
72
+
73
+ impure function vpy_result_meta(idx : integer) return integer;
74
+ attribute foreign of vpy_result_meta : function is "{foreign:vpy_result_meta}";
75
+
76
+ impure function vpy_error_length return integer;
77
+ attribute foreign of vpy_error_length : function is "{foreign:vpy_error_length}";
78
+
79
+ procedure vpy_result_read_string(chunk : out string_chunk_t; offset, length : integer);
80
+ attribute foreign of vpy_result_read_string : procedure is "{foreign:vpy_result_read_string}";
81
+
82
+ procedure vpy_result_read_integers(chunk : out integer_chunk_t; offset, length : integer);
83
+ attribute foreign of vpy_result_read_integers : procedure is "{foreign:vpy_result_read_integers}";
84
+
85
+ procedure vpy_result_read_reals(chunk : out real_chunk_t; offset, length : integer);
86
+ attribute foreign of vpy_result_read_reals : procedure is "{foreign:vpy_result_read_reals}";
87
+
88
+ procedure vpy_error_read(chunk : out string_chunk_t; offset, length : integer);
89
+ attribute foreign of vpy_error_read : procedure is "{foreign:vpy_error_read}";
90
+ end package;
91
+
@@ -0,0 +1,13 @@
1
+ -- This package provides a dictionary types and operations
2
+ --
3
+ -- This Source Code Form is subject to the terms of the Mozilla Public
4
+ -- License, v. 2.0. If a copy of the MPL was not distributed with this file,
5
+ -- You can obtain one at http://mozilla.org/MPL/2.0/.
6
+ --
7
+ -- Copyright (c) 2014-2026, Lars Asplund lars.anders.asplund@gmail.com
8
+
9
+ context python_context is
10
+ library python_bridge;
11
+ use python_bridge.python_pkg.all;
12
+ use python_bridge.python_ffi_pkg.all;
13
+ end context;