opak 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.
- opak-0.1.0/PKG-INFO +12 -0
- opak-0.1.0/README.md +1 -0
- opak-0.1.0/opak/__init__.py +258 -0
- opak-0.1.0/opak.egg-info/PKG-INFO +12 -0
- opak-0.1.0/opak.egg-info/SOURCES.txt +8 -0
- opak-0.1.0/opak.egg-info/dependency_links.txt +1 -0
- opak-0.1.0/opak.egg-info/requires.txt +1 -0
- opak-0.1.0/opak.egg-info/top_level.txt +1 -0
- opak-0.1.0/pyproject.toml +15 -0
- opak-0.1.0/setup.cfg +4 -0
opak-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: opak
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Open PAcKer
|
|
5
|
+
Author-email: nzturn <nzturn@gmail.com>
|
|
6
|
+
Classifier: Programming Language :: Python :: 3
|
|
7
|
+
Classifier: Framework :: Jupyter
|
|
8
|
+
Requires-Python: >=3.10
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
Requires-Dist: numpy
|
|
11
|
+
|
|
12
|
+
# Open PAcKer
|
opak-0.1.0/README.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Open PAcKer
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
__all__ = ['encode', 'decode', 'json_patch', 'msgpack_patch']
|
|
3
|
+
|
|
4
|
+
from base64 import b64decode, b64encode
|
|
5
|
+
from typing import TYPE_CHECKING, Any, Callable
|
|
6
|
+
from numpy import frombuffer, generic, ndarray
|
|
7
|
+
from numpy.lib.format import descr_to_dtype, dtype_to_descr
|
|
8
|
+
import pickle,inspect,sys
|
|
9
|
+
cast = True
|
|
10
|
+
try:
|
|
11
|
+
from oasm import table
|
|
12
|
+
except:
|
|
13
|
+
table = None
|
|
14
|
+
|
|
15
|
+
if TYPE_CHECKING: # pragma: no cover
|
|
16
|
+
from _typeshed import SupportsRead
|
|
17
|
+
|
|
18
|
+
def encode(
|
|
19
|
+
o: Any, *, b64: bool = False, chain: Callable[[Any], dict[str, Any]] | None = None
|
|
20
|
+
) -> dict[str, Any]:
|
|
21
|
+
"""Encodes numpy objects to a dict-serializable dictionary.
|
|
22
|
+
|
|
23
|
+
Args:
|
|
24
|
+
o (object): The object to encode.
|
|
25
|
+
chain (Callable[[Any], dict[str, Any]] | None): A fallback encoder function to handle objects that are not numpy objects.
|
|
26
|
+
|
|
27
|
+
Returns:
|
|
28
|
+
dict[str, Any]: The dict-serializable dictionary representation of the numpy object, or the result of the fallback encoder if present and if the object is not a numpy object.
|
|
29
|
+
|
|
30
|
+
Raises:
|
|
31
|
+
TypeError: If the object is not dict serializable.
|
|
32
|
+
"""
|
|
33
|
+
if isinstance(o, (ndarray, generic)):
|
|
34
|
+
if o.dtype == 'O':
|
|
35
|
+
data = o.dumps()
|
|
36
|
+
elif o.flags['C_CONTIGUOUS']:
|
|
37
|
+
data = o.data
|
|
38
|
+
else:
|
|
39
|
+
data = o.tobytes()
|
|
40
|
+
return {
|
|
41
|
+
"__numpy__": b64encode(data).decode() if b64 else bytes(data),
|
|
42
|
+
"dtype": dtype_to_descr(o.dtype),
|
|
43
|
+
"shape": list(o.shape),
|
|
44
|
+
}
|
|
45
|
+
elif isinstance(o, complex):
|
|
46
|
+
return {'__complex__':o.__repr__()}
|
|
47
|
+
elif cast and (type(o) is type or type(o).__name__ == 'function'):
|
|
48
|
+
try:
|
|
49
|
+
return {'':[o.__name__,inspect.getsource(o)]}|(
|
|
50
|
+
{} if type(o) is type else o.__dict__)
|
|
51
|
+
except:
|
|
52
|
+
pass
|
|
53
|
+
elif table is not None and isinstance(o, table):
|
|
54
|
+
return table.to_dict(o)
|
|
55
|
+
|
|
56
|
+
module = getattr(o,'__module__',None)
|
|
57
|
+
name = getattr(o,'__name__',None)
|
|
58
|
+
if cast and (module is not None and name is not None):
|
|
59
|
+
return {'':module+'.'+name}
|
|
60
|
+
return o if chain is None else chain(o)
|
|
61
|
+
|
|
62
|
+
env = globals()
|
|
63
|
+
def decode(dct: dict, b64: bool = False, chain: Callable[[Any], dict[str, Any]] | None = None) -> dict | ndarray | generic:
|
|
64
|
+
"""Custom object hook function for decoding dict objects into numpy arrays.
|
|
65
|
+
|
|
66
|
+
Args:
|
|
67
|
+
dct (dict): The dictionary to decode.
|
|
68
|
+
|
|
69
|
+
Returns:
|
|
70
|
+
dict | np.ndarray | np.generic: The decoded numpy object or the original dictionary.
|
|
71
|
+
"""
|
|
72
|
+
if "__numpy__" in dct:
|
|
73
|
+
data = dct['__numpy__']
|
|
74
|
+
if b64:
|
|
75
|
+
data = b64decode(data)
|
|
76
|
+
dtype = descr_to_dtype(dct['dtype'])
|
|
77
|
+
if dtype == 'O':
|
|
78
|
+
return pickle.loads(data)
|
|
79
|
+
else:
|
|
80
|
+
obj = frombuffer(data,dtype)
|
|
81
|
+
return obj.reshape(shape) if (shape := dct['shape']) else obj[0]
|
|
82
|
+
elif '__complex__' in dct:
|
|
83
|
+
return complex(dct['__complex__'])
|
|
84
|
+
elif cast and ('' in dct):
|
|
85
|
+
obj = dct['']
|
|
86
|
+
if type(obj) is str:
|
|
87
|
+
obj = obj.split('.')
|
|
88
|
+
module = sys.modules.get('.'.join(obj[:-1]),None)
|
|
89
|
+
return None if module is None else getattr(module,obj[-1],None)
|
|
90
|
+
else:
|
|
91
|
+
obj,src = obj
|
|
92
|
+
if obj == '<lambda>':
|
|
93
|
+
obj = eval('lambda '+'lambda'.join(src.split('lambda')[1:]).strip(),env)
|
|
94
|
+
else:
|
|
95
|
+
exec(src,env)
|
|
96
|
+
obj = env[obj]
|
|
97
|
+
del dct['']
|
|
98
|
+
if type(obj) is not type:
|
|
99
|
+
obj.__dict__.update(dct)
|
|
100
|
+
return obj
|
|
101
|
+
if table is not None:
|
|
102
|
+
dct = table.from_dict(dct)
|
|
103
|
+
return dct if chain is None else chain(dct)
|
|
104
|
+
|
|
105
|
+
import json
|
|
106
|
+
_dumps = json.dumps
|
|
107
|
+
_loads = json.loads
|
|
108
|
+
_dump = json.dump
|
|
109
|
+
|
|
110
|
+
def _encoder(
|
|
111
|
+
*args: Any,
|
|
112
|
+
default: Callable[[Any], Any] | None = None,
|
|
113
|
+
user_cls: type[json.JSONEncoder] | None = None,
|
|
114
|
+
**kwargs: Any,
|
|
115
|
+
) -> json.JSONEncoder:
|
|
116
|
+
"""Ensures cooperation with the provided `default` and/or `cls` by manipulating the JSONEncoder."""
|
|
117
|
+
if user_cls is None:
|
|
118
|
+
user_cls = json.JSONEncoder
|
|
119
|
+
elif default is None:
|
|
120
|
+
encoder = user_cls(*args, **kwargs)
|
|
121
|
+
encoder.default = lambda obj:encode(obj,b64=True,chain=encoder.default) # type: ignore[method-assign]
|
|
122
|
+
return encoder
|
|
123
|
+
return user_cls(
|
|
124
|
+
*args, default=lambda obj:encode(obj,b64=True,chain=default), **kwargs
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
def dumps(*args: Any, cls: type[json.JSONEncoder] | None = None, **kwargs: Any) -> str:
|
|
128
|
+
kwargs["user_cls"] = cls
|
|
129
|
+
return _dumps(*table.to_dict(args), cls=_encoder, **kwargs) # type: ignore[arg-type]
|
|
130
|
+
|
|
131
|
+
def loads(
|
|
132
|
+
*args: Any, object_hook: Callable[[dict], Any] | None = None, **kwargs: Any
|
|
133
|
+
) -> Any:
|
|
134
|
+
return _loads(
|
|
135
|
+
*args,
|
|
136
|
+
object_hook=lambda dct:decode(dct,b64=True,chain=object_hook),
|
|
137
|
+
**kwargs,
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
def dump(*args: Any, cls: type[json.JSONEncoder] | None = None, **kwargs: Any) -> None:
|
|
141
|
+
kwargs["user_cls"] = cls
|
|
142
|
+
return _dump(*table.to_dict(args), cls=_encoder, **kwargs) # type: ignore[arg-type]
|
|
143
|
+
|
|
144
|
+
def load(fp: SupportsRead[str | bytes], **kwargs: Any) -> Any:
|
|
145
|
+
return loads(fp.read(), **kwargs)
|
|
146
|
+
|
|
147
|
+
def json_patch() -> None:
|
|
148
|
+
"""Monkey patch json module to support encoding/decoding NumPy arrays/scalars."""
|
|
149
|
+
json.dumps = dumps
|
|
150
|
+
json.loads = loads
|
|
151
|
+
json.dump = dump
|
|
152
|
+
json.load = load
|
|
153
|
+
|
|
154
|
+
try:
|
|
155
|
+
import msgpack
|
|
156
|
+
from msgpack import Packer as _Packer, Unpacker as _Unpacker, \
|
|
157
|
+
unpack as _unpack, unpackb as _unpackb
|
|
158
|
+
except:
|
|
159
|
+
_Packer = object
|
|
160
|
+
_Unpacker = object
|
|
161
|
+
|
|
162
|
+
class Packer(_Packer):
|
|
163
|
+
def __init__(self,
|
|
164
|
+
default=None,
|
|
165
|
+
use_single_float=False,
|
|
166
|
+
autoreset=True,
|
|
167
|
+
use_bin_type=True,
|
|
168
|
+
strict_types=True,
|
|
169
|
+
datetime=False,
|
|
170
|
+
unicode_errors=None):
|
|
171
|
+
super(Packer, self).__init__(default=lambda obj:encode(obj,chain=default),
|
|
172
|
+
use_single_float=use_single_float,
|
|
173
|
+
autoreset=autoreset,
|
|
174
|
+
use_bin_type=use_bin_type,
|
|
175
|
+
strict_types=strict_types,
|
|
176
|
+
datetime=datetime,
|
|
177
|
+
unicode_errors=unicode_errors)
|
|
178
|
+
|
|
179
|
+
class Unpacker(_Unpacker):
|
|
180
|
+
def __init__(self,
|
|
181
|
+
file_like=None,
|
|
182
|
+
read_size=0,
|
|
183
|
+
use_list=True,
|
|
184
|
+
raw=False,
|
|
185
|
+
timestamp=0,
|
|
186
|
+
strict_map_key=True,
|
|
187
|
+
object_hook=None,
|
|
188
|
+
object_pairs_hook=None,
|
|
189
|
+
list_hook=None,
|
|
190
|
+
unicode_errors=None,
|
|
191
|
+
max_buffer_size=100 * 1024 * 1024,
|
|
192
|
+
ext_hook=msgpack.ExtType,
|
|
193
|
+
max_str_len=-1,
|
|
194
|
+
max_bin_len=-1,
|
|
195
|
+
max_array_len=-1,
|
|
196
|
+
max_map_len=-1,
|
|
197
|
+
max_ext_len=-1):
|
|
198
|
+
super(Unpacker, self).__init__(file_like=file_like,
|
|
199
|
+
read_size=read_size,
|
|
200
|
+
use_list=use_list,
|
|
201
|
+
raw=raw,
|
|
202
|
+
timestamp=timestamp,
|
|
203
|
+
strict_map_key=strict_map_key,
|
|
204
|
+
object_hook=lambda dct:decode(dct,chain=object_hook),
|
|
205
|
+
object_pairs_hook=object_pairs_hook,
|
|
206
|
+
list_hook=list_hook,
|
|
207
|
+
unicode_errors=unicode_errors,
|
|
208
|
+
max_buffer_size=max_buffer_size,
|
|
209
|
+
ext_hook=ext_hook,
|
|
210
|
+
max_str_len=max_str_len,
|
|
211
|
+
max_bin_len=max_bin_len,
|
|
212
|
+
max_array_len=max_array_len,
|
|
213
|
+
max_map_len=max_map_len,
|
|
214
|
+
max_ext_len=max_ext_len)
|
|
215
|
+
|
|
216
|
+
def pack(o, stream, **kwargs):
|
|
217
|
+
"""
|
|
218
|
+
Pack an object and write it to a stream.
|
|
219
|
+
"""
|
|
220
|
+
packer = Packer(**kwargs)
|
|
221
|
+
stream.write(packer.pack(o))
|
|
222
|
+
|
|
223
|
+
def packb(o, **kwargs):
|
|
224
|
+
"""
|
|
225
|
+
Pack an object and return the packed bytes.
|
|
226
|
+
"""
|
|
227
|
+
return Packer(**kwargs).pack(o)
|
|
228
|
+
|
|
229
|
+
def unpack(stream, **kwargs):
|
|
230
|
+
"""
|
|
231
|
+
Unpack a packed object from a stream.
|
|
232
|
+
"""
|
|
233
|
+
object_hook = kwargs.get('object_hook')
|
|
234
|
+
kwargs['object_hook'] = lambda dct:decode(dct,chain=object_hook)
|
|
235
|
+
return _unpack(stream, **kwargs)
|
|
236
|
+
|
|
237
|
+
def unpackb(packed, **kwargs):
|
|
238
|
+
"""
|
|
239
|
+
Unpack a packed object.
|
|
240
|
+
"""
|
|
241
|
+
object_hook = kwargs.get('object_hook')
|
|
242
|
+
kwargs['object_hook'] = lambda dct:decode(dct,chain=object_hook)
|
|
243
|
+
return _unpackb(packed, **kwargs)
|
|
244
|
+
|
|
245
|
+
def msgpack_patch():
|
|
246
|
+
"""
|
|
247
|
+
Monkey patch msgpack module to enable support for serializing numpy types.
|
|
248
|
+
"""
|
|
249
|
+
setattr(msgpack, 'Packer', Packer)
|
|
250
|
+
setattr(msgpack, 'Unpacker', Unpacker)
|
|
251
|
+
setattr(msgpack, 'load', unpack)
|
|
252
|
+
setattr(msgpack, 'loads', unpackb)
|
|
253
|
+
setattr(msgpack, 'dump', pack)
|
|
254
|
+
setattr(msgpack, 'dumps', packb)
|
|
255
|
+
setattr(msgpack, 'pack', pack)
|
|
256
|
+
setattr(msgpack, 'packb', packb)
|
|
257
|
+
setattr(msgpack, 'unpack', unpack)
|
|
258
|
+
setattr(msgpack, 'unpackb', unpackb)
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: opak
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Open PAcKer
|
|
5
|
+
Author-email: nzturn <nzturn@gmail.com>
|
|
6
|
+
Classifier: Programming Language :: Python :: 3
|
|
7
|
+
Classifier: Framework :: Jupyter
|
|
8
|
+
Requires-Python: >=3.10
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
Requires-Dist: numpy
|
|
11
|
+
|
|
12
|
+
# Open PAcKer
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
numpy
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
opak
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "opak"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "Open PAcKer"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.10"
|
|
7
|
+
authors = [
|
|
8
|
+
{ name = "nzturn", email = "nzturn@gmail.com" },
|
|
9
|
+
]
|
|
10
|
+
classifiers = [
|
|
11
|
+
"Programming Language :: Python :: 3",
|
|
12
|
+
"Framework :: Jupyter",
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
dependencies = ["numpy"]
|
opak-0.1.0/setup.cfg
ADDED