polyplug-abi 0.1.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.
@@ -0,0 +1,20 @@
1
+ Metadata-Version: 2.4
2
+ Name: polyplug-abi
3
+ Version: 0.1.0
4
+ Summary: ABI types for the polyplug plugin runtime
5
+ License: MIT
6
+ Project-URL: Homepage, https://github.com/polyplug/polyplug
7
+ Project-URL: Documentation, https://github.com/polyplug/polyplug#readme
8
+ Project-URL: Repository, https://github.com/polyplug/polyplug.git
9
+ Project-URL: Issues, https://github.com/polyplug/polyplug/issues
10
+ Keywords: polyplug,plugin,abi,ffi
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Typing :: Typed
20
+ Requires-Python: >=3.10
@@ -0,0 +1,159 @@
1
+ """polyplug_abi — ABI types for the polyplug plugin runtime.
2
+
3
+ This package provides the frozen ABI types that match the Rust ABI exactly.
4
+ """
5
+
6
+ from __future__ import annotations
7
+
8
+ from enum import IntEnum
9
+ from typing import Optional
10
+
11
+ from polyplug_abi.abi import (
12
+ POLYPLUG_ABI_VERSION,
13
+ AbiErrorCode,
14
+ Compatibility,
15
+ StringView,
16
+ Buffer,
17
+ Version,
18
+ AbiError,
19
+ GuestContractHandle,
20
+ GuestContractInstance,
21
+ HostContractInstance,
22
+ HostContractInterface,
23
+ VmLoaderData,
24
+ NativeDispatch,
25
+ VmDispatch,
26
+ GuestContractInterface,
27
+ HostApi,
28
+ PluginDescriptor,
29
+ BundleInitContext,
30
+ Array,
31
+ DependencyInfo,
32
+ RuntimeConfig,
33
+ DispatchType,
34
+ DispatchMechanisms,
35
+ ArenaOverflowBlock,
36
+ CallArena,
37
+ LogLevel,
38
+ fnv1a_64,
39
+ guest_contract_id,
40
+ host_contract_id,
41
+ bundle_id,
42
+ FNV_OFFSET,
43
+ FNV_PRIME,
44
+ )
45
+ from polyplug_abi.string_view_helper import (
46
+ to_str,
47
+ strip_prefix,
48
+ starts_with,
49
+ ends_with,
50
+ split,
51
+ bytes_as_view,
52
+ )
53
+
54
+
55
+ class ReloadPhaseType(IntEnum):
56
+ """Type tag for ReloadPhase variants."""
57
+
58
+ Preparing = 0
59
+ Reloaded = 1
60
+ Failed = 2
61
+ Unloading = 3
62
+
63
+
64
+ class ReloadPhase:
65
+ """Python representation of hot-reload phase notification.
66
+
67
+ Mirrors the ABI ``ReloadPhase`` struct exactly — there is no retry-count
68
+ field in the ABI.
69
+
70
+ Attributes:
71
+ type: The phase type (Preparing, Reloaded, Failed, or Unloading), or
72
+ the raw ``int`` discriminant when the runtime reports a phase this
73
+ SDK version does not know (the conversion is total — see
74
+ ``polyplug.runtime``).
75
+ bundle_id: The FNV-1a hash of the bundle name.
76
+ bundle_name: The human-readable bundle name.
77
+ reason: Failure reason string (valid only for Failed).
78
+ """
79
+
80
+ def __init__(
81
+ self,
82
+ type: ReloadPhaseType | int,
83
+ bundle_id: int,
84
+ bundle_name: str,
85
+ reason: Optional[str] = None,
86
+ ) -> None:
87
+ self.type: ReloadPhaseType | int = type
88
+ self.bundle_id: int = bundle_id
89
+ self.bundle_name: str = bundle_name
90
+ self.reason: Optional[str] = reason
91
+
92
+ def is_preparing(self) -> bool:
93
+ """Return True if this is a Preparing phase."""
94
+ return self.type == ReloadPhaseType.Preparing
95
+
96
+ def is_reloaded(self) -> bool:
97
+ """Return True if this is a Reloaded phase."""
98
+ return self.type == ReloadPhaseType.Reloaded
99
+
100
+ def is_failed(self) -> bool:
101
+ """Return True if this is a Failed phase."""
102
+ return self.type == ReloadPhaseType.Failed
103
+
104
+ def is_unloading(self) -> bool:
105
+ """Return True if this is an Unloading phase."""
106
+ return self.type == ReloadPhaseType.Unloading
107
+
108
+ def __repr__(self) -> str:
109
+ type_name: str = (
110
+ self.type.name
111
+ if isinstance(self.type, ReloadPhaseType)
112
+ else f"Unknown({self.type})"
113
+ )
114
+ return (
115
+ f"ReloadPhase(type={type_name}, bundle_id={self.bundle_id}, "
116
+ f"bundle_name={self.bundle_name!r}, reason={self.reason!r})"
117
+ )
118
+
119
+
120
+ __all__ = [
121
+ "POLYPLUG_ABI_VERSION",
122
+ "AbiErrorCode",
123
+ "Compatibility",
124
+ "StringView",
125
+ "Buffer",
126
+ "Version",
127
+ "AbiError",
128
+ "GuestContractHandle",
129
+ "GuestContractInstance",
130
+ "HostContractInstance",
131
+ "HostContractInterface",
132
+ "VmLoaderData",
133
+ "NativeDispatch",
134
+ "VmDispatch",
135
+ "GuestContractInterface",
136
+ "HostApi",
137
+ "PluginDescriptor",
138
+ "BundleInitContext",
139
+ "Array",
140
+ "DependencyInfo",
141
+ "RuntimeConfig",
142
+ "DispatchType",
143
+ "DispatchMechanisms",
144
+ "LogLevel",
145
+ "fnv1a_64",
146
+ "guest_contract_id",
147
+ "host_contract_id",
148
+ "bundle_id",
149
+ "FNV_OFFSET",
150
+ "FNV_PRIME",
151
+ "ReloadPhaseType",
152
+ "ReloadPhase",
153
+ "to_str",
154
+ "strip_prefix",
155
+ "starts_with",
156
+ "ends_with",
157
+ "split",
158
+ "bytes_as_view",
159
+ ]
@@ -0,0 +1,7 @@
1
+ # Re-export all types from the auto-generated abi module.
2
+ # The canonical file is at sdks/python/abi/abi.py.
3
+ # This shared package makes the types available via `from polyplug_abi import ...`.
4
+ try:
5
+ from abi.abi import * # noqa: F401,F403
6
+ except ImportError:
7
+ from polyplug.abi.abi import * # noqa: F401,F403
@@ -0,0 +1,113 @@
1
+ """polyplug_abi — String helper functions for StringView."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import ctypes
6
+
7
+ from polyplug_abi.abi import StringView
8
+
9
+
10
+ def to_str(sv: StringView) -> str:
11
+ """Convert StringView to Python str.
12
+
13
+ A null/zero-length view decodes to ``""``. A non-null view whose bytes are
14
+ NOT valid UTF-8 raises ``UnicodeDecodeError`` — the strict ``bytes.decode``
15
+ never silently substitutes replacement characters for a readable-but-invalid
16
+ view.
17
+
18
+ Args:
19
+ sv: StringView from polyplug ABI
20
+
21
+ Returns:
22
+ Python string (UTF-8 decoded)
23
+
24
+ Raises:
25
+ UnicodeDecodeError: if the viewed bytes are not valid UTF-8.
26
+ """
27
+ if not sv.ptr or sv.len == 0:
28
+ return ""
29
+ data = ctypes.cast(sv.ptr, ctypes.POINTER(ctypes.c_char * sv.len)).contents
30
+ return bytes(data).decode("utf-8")
31
+
32
+
33
+ def strip_prefix(sv: StringView, prefix: str) -> str:
34
+ """Strip prefix from StringView if present, otherwise return original string.
35
+
36
+ Args:
37
+ sv: StringView from polyplug ABI
38
+ prefix: Prefix string to strip
39
+
40
+ Returns:
41
+ String with prefix removed if it was present, otherwise original string
42
+ """
43
+ s: str = to_str(sv)
44
+ if s.startswith(prefix):
45
+ return s[len(prefix) :]
46
+ return s
47
+
48
+
49
+ def starts_with(sv: StringView, prefix: str) -> bool:
50
+ """Check if StringView starts with prefix.
51
+
52
+ Args:
53
+ sv: StringView from polyplug ABI
54
+ prefix: Prefix string to check for
55
+
56
+ Returns:
57
+ True if the string starts with the prefix, False otherwise
58
+ """
59
+ return to_str(sv).startswith(prefix)
60
+
61
+
62
+ def ends_with(sv: StringView, suffix: str) -> bool:
63
+ """Check if StringView ends with suffix.
64
+
65
+ Args:
66
+ sv: StringView from polyplug ABI
67
+ suffix: Suffix string to check for
68
+
69
+ Returns:
70
+ True if the string ends with the suffix, False otherwise
71
+ """
72
+ return to_str(sv).endswith(suffix)
73
+
74
+
75
+ def split(sv: StringView, delimiter: str) -> list[str]:
76
+ """Split StringView by a literal delimiter, keeping empty segments.
77
+
78
+ Args:
79
+ sv: StringView from polyplug ABI
80
+ delimiter: Literal delimiter string to split by
81
+
82
+ Returns:
83
+ [] for a null/empty view, [s] for an empty delimiter, otherwise the
84
+ segments around every occurrence of the delimiter (empties kept)
85
+ """
86
+ s: str = to_str(sv)
87
+ if not s:
88
+ return []
89
+ if not delimiter:
90
+ return [s]
91
+ return s.split(delimiter)
92
+
93
+
94
+ def bytes_as_view(data: bytes) -> StringView:
95
+ """Build a borrowed ``StringView`` over a bytes object's internal buffer.
96
+
97
+ The caller MUST keep ``data`` alive for as long as the view is read —
98
+ ctypes does not root ``data`` through the view's raw pointer field. Bind
99
+ the bytes to a local (or other owner) that outlives every read of the
100
+ view; never build a view over a temporary such as ``s.encode("utf-8")``
101
+ passed inline. Empty bytes produce a null view (``ptr=None, len=0``),
102
+ which is legal at the ABI boundary.
103
+
104
+ Args:
105
+ data: caller-owned UTF-8 bytes backing the view.
106
+
107
+ Returns:
108
+ StringView borrowing ``data``'s buffer (null view for empty bytes).
109
+ """
110
+ if not data:
111
+ return StringView(ptr=None, len=0)
112
+ addr: int = ctypes.cast(ctypes.c_char_p(data), ctypes.c_void_p).value or 0
113
+ return StringView(ptr=addr, len=len(data))
@@ -0,0 +1,20 @@
1
+ Metadata-Version: 2.4
2
+ Name: polyplug-abi
3
+ Version: 0.1.0
4
+ Summary: ABI types for the polyplug plugin runtime
5
+ License: MIT
6
+ Project-URL: Homepage, https://github.com/polyplug/polyplug
7
+ Project-URL: Documentation, https://github.com/polyplug/polyplug#readme
8
+ Project-URL: Repository, https://github.com/polyplug/polyplug.git
9
+ Project-URL: Issues, https://github.com/polyplug/polyplug/issues
10
+ Keywords: polyplug,plugin,abi,ffi
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Typing :: Typed
20
+ Requires-Python: >=3.10
@@ -0,0 +1,8 @@
1
+ pyproject.toml
2
+ polyplug_abi/__init__.py
3
+ polyplug_abi/abi.py
4
+ polyplug_abi/string_view_helper.py
5
+ polyplug_abi.egg-info/PKG-INFO
6
+ polyplug_abi.egg-info/SOURCES.txt
7
+ polyplug_abi.egg-info/dependency_links.txt
8
+ polyplug_abi.egg-info/top_level.txt
@@ -0,0 +1 @@
1
+ polyplug_abi
@@ -0,0 +1,32 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "polyplug-abi"
7
+ version = "0.1.0"
8
+ description = "ABI types for the polyplug plugin runtime"
9
+ requires-python = ">=3.10"
10
+ license = { text = "MIT" }
11
+ keywords = ["polyplug", "plugin", "abi", "ffi"]
12
+ classifiers = [
13
+ "Development Status :: 3 - Alpha",
14
+ "Intended Audience :: Developers",
15
+ "License :: OSI Approved :: MIT License",
16
+ "Programming Language :: Python :: 3",
17
+ "Programming Language :: Python :: 3.10",
18
+ "Programming Language :: Python :: 3.11",
19
+ "Programming Language :: Python :: 3.12",
20
+ "Programming Language :: Python :: 3.13",
21
+ "Typing :: Typed",
22
+ ]
23
+
24
+ [project.urls]
25
+ Homepage = "https://github.com/polyplug/polyplug"
26
+ Documentation = "https://github.com/polyplug/polyplug#readme"
27
+ Repository = "https://github.com/polyplug/polyplug.git"
28
+ Issues = "https://github.com/polyplug/polyplug/issues"
29
+
30
+ [tool.setuptools.packages.find]
31
+ where = ["."]
32
+ include = ["polyplug_abi*"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+