pybare 1.2.3__tar.gz → 1.2.5__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.
- {pybare-1.2.3/pybare.egg-info → pybare-1.2.5}/PKG-INFO +33 -6
- {pybare-1.2.3 → pybare-1.2.5}/README.md +4 -0
- pybare-1.2.5/bare/_examples/customer.bin +0 -0
- pybare-1.2.5/bare/_examples/employee.bin +0 -0
- pybare-1.2.5/bare/_examples/people.bin +0 -0
- pybare-1.2.5/bare/_examples/terminated.bin +1 -0
- {pybare-1.2.3 → pybare-1.2.5}/bare/barearray.py +11 -2
- {pybare-1.2.3 → pybare-1.2.5}/bare/barestruct.py +6 -5
- {pybare-1.2.3 → pybare-1.2.5}/bare/map.py +4 -1
- {pybare-1.2.3 → pybare-1.2.5}/bare/misc.py +5 -2
- {pybare-1.2.3 → pybare-1.2.5}/bare/test_barearray.py +29 -18
- {pybare-1.2.3 → pybare-1.2.5}/bare/test_barestruct.py +6 -0
- {pybare-1.2.3 → pybare-1.2.5}/bare/test_data.py +7 -3
- {pybare-1.2.3 → pybare-1.2.5}/bare/test_encoder.py +8 -3
- {pybare-1.2.3 → pybare-1.2.5}/bare/test_map.py +21 -13
- {pybare-1.2.3 → pybare-1.2.5}/bare/test_misc.py +10 -2
- pybare-1.2.5/bare/test_number.py +51 -0
- {pybare-1.2.3 → pybare-1.2.5}/bare/test_union.py +63 -32
- {pybare-1.2.3 → pybare-1.2.5}/bare/util.py +6 -5
- pybare-1.2.5/pyproject.toml +36 -0
- pybare-1.2.3/PKG-INFO +0 -99
- pybare-1.2.3/bare/test_number.py +0 -43
- pybare-1.2.3/pybare.egg-info/SOURCES.txt +0 -25
- pybare-1.2.3/pybare.egg-info/dependency_links.txt +0 -1
- pybare-1.2.3/pybare.egg-info/top_level.txt +0 -1
- pybare-1.2.3/setup.cfg +0 -4
- pybare-1.2.3/setup.py +0 -24
- {pybare-1.2.3 → pybare-1.2.5}/LICENSE +0 -0
- {pybare-1.2.3 → pybare-1.2.5}/bare/__init__.py +0 -0
- {pybare-1.2.3 → pybare-1.2.5}/bare/baretype.py +0 -0
- {pybare-1.2.3 → pybare-1.2.5}/bare/data.py +0 -0
- {pybare-1.2.3 → pybare-1.2.5}/bare/number.py +0 -0
- {pybare-1.2.3 → pybare-1.2.5}/bare/union.py +0 -0
|
@@ -1,21 +1,46 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: pybare
|
|
3
|
-
Version: 1.2.
|
|
4
|
-
Summary: A
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
Version: 1.2.5
|
|
4
|
+
Summary: A BARE Encoding Library and Data Validation Library for Python.
|
|
5
|
+
Author-Email: Noah Pederson <noah@packetlost.dev>
|
|
6
|
+
License: Copyright 2020 Noah Pederson
|
|
7
|
+
|
|
8
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
9
|
+
this software and associated documentation files (the "Software"), to deal in
|
|
10
|
+
the Software without restriction, including without limitation the rights to
|
|
11
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
12
|
+
of the Software, and to permit persons to whom the Software is furnished to do
|
|
13
|
+
so, subject to the following conditions:
|
|
14
|
+
|
|
15
|
+
The above copyright notice and this permission notice shall be included in all
|
|
16
|
+
copies or substantial portions of the Software.
|
|
17
|
+
|
|
18
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
19
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
20
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
21
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
22
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
23
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
24
|
+
SOFTWARE.
|
|
25
|
+
|
|
26
|
+
Classifier: Development Status :: 4 - Beta
|
|
27
|
+
Classifier: Intended Audience :: Developers
|
|
8
28
|
Classifier: Programming Language :: Python :: 3.10
|
|
9
29
|
Classifier: Programming Language :: Python :: 3.11
|
|
10
30
|
Classifier: Programming Language :: Python :: 3.12
|
|
11
31
|
Classifier: License :: OSI Approved :: MIT License
|
|
12
32
|
Classifier: Operating System :: OS Independent
|
|
33
|
+
Project-URL: Homepage, https://sr.ht/~chiefnoah/pybare/
|
|
34
|
+
Project-URL: Repository, https://git.sr.ht/~chiefnoah/pybare
|
|
35
|
+
Project-URL: Issues, https://todo.sr.ht/~chiefnoah/pybare
|
|
36
|
+
Project-URL: Changelog, https://git.sr.ht/~chiefnoah/pybare/tree/master/item/CHANGELOG.md
|
|
13
37
|
Requires-Python: >=3.10
|
|
14
38
|
Description-Content-Type: text/markdown
|
|
15
|
-
License-File: LICENSE
|
|
16
39
|
|
|
17
40
|
# PyBARE
|
|
18
41
|
[](https://builds.sr.ht/~chiefnoah/pybare?)
|
|
42
|
+
[](https://pybare.ngp.computer)
|
|
19
44
|
|
|
20
45
|
A declarative implementation of the [BARE](https://baremessages.org/) message
|
|
21
46
|
format for Python 3.10+
|
|
@@ -40,6 +65,8 @@ pip install pybare
|
|
|
40
65
|
pybare fully implements all BARE types for both encoding and decoding. This
|
|
41
66
|
includes reading multiple messages from the same `BinaryIO` stream.
|
|
42
67
|
|
|
68
|
+
It is well tested and in use on production systems.
|
|
69
|
+
|
|
43
70
|
## Gotchas
|
|
44
71
|
|
|
45
72
|
We use "Array" / "array" instead of "List" / "list" to avoid conflicts with Python's
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# PyBARE
|
|
2
2
|
[](https://builds.sr.ht/~chiefnoah/pybare?)
|
|
3
|
+
[](https://pybare.ngp.computer)
|
|
3
5
|
|
|
4
6
|
A declarative implementation of the [BARE](https://baremessages.org/) message
|
|
5
7
|
format for Python 3.10+
|
|
@@ -24,6 +26,8 @@ pip install pybare
|
|
|
24
26
|
pybare fully implements all BARE types for both encoding and decoding. This
|
|
25
27
|
includes reading multiple messages from the same `BinaryIO` stream.
|
|
26
28
|
|
|
29
|
+
It is well tested and in use on production systems.
|
|
30
|
+
|
|
27
31
|
## Gotchas
|
|
28
32
|
|
|
29
33
|
We use "Array" / "array" instead of "List" / "list" to avoid conflicts with Python's
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
import io
|
|
3
3
|
from collections import UserList
|
|
4
|
-
from typing import (
|
|
5
|
-
|
|
4
|
+
from typing import (
|
|
5
|
+
Any,
|
|
6
|
+
BinaryIO,
|
|
7
|
+
ClassVar,
|
|
8
|
+
Generic,
|
|
9
|
+
Iterable,
|
|
10
|
+
Optional,
|
|
11
|
+
Type,
|
|
12
|
+
TypeVar,
|
|
13
|
+
_ProtocolMeta,
|
|
14
|
+
)
|
|
6
15
|
|
|
7
16
|
from .baretype import BAREType
|
|
8
17
|
from .number import UInt
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
import io
|
|
4
|
+
from typing import Any, BinaryIO, Dict, Type, TypeVar, _ProtocolMeta
|
|
4
5
|
|
|
5
|
-
from .util import Field
|
|
6
6
|
from .baretype import BAREType
|
|
7
|
+
from .util import Field
|
|
7
8
|
|
|
8
9
|
__all__ = ["Struct", "struct"]
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
T = TypeVar("T")
|
|
12
13
|
|
|
14
|
+
|
|
13
15
|
class StructMeta(_ProtocolMeta, type):
|
|
14
16
|
def __new__(cls, clsname, bases, clsdict):
|
|
15
17
|
fields = {}
|
|
@@ -79,8 +81,6 @@ class Struct(BAREType, metaclass=StructMeta):
|
|
|
79
81
|
)
|
|
80
82
|
|
|
81
83
|
def pack(self: Struct) -> bytes:
|
|
82
|
-
import io
|
|
83
|
-
|
|
84
84
|
buf = io.BytesIO()
|
|
85
85
|
for name, ty in self._fields.items():
|
|
86
86
|
val = getattr(self, name)
|
|
@@ -121,7 +121,8 @@ class Struct(BAREType, metaclass=StructMeta):
|
|
|
121
121
|
return True
|
|
122
122
|
return NotImplemented
|
|
123
123
|
|
|
124
|
-
|
|
124
|
+
|
|
125
|
+
def struct(**kwargs: Type[BAREType]) -> Type[Struct]:
|
|
125
126
|
"""
|
|
126
127
|
A function that defines and returnes an anonymous BARE `Struct` subclass with the
|
|
127
128
|
provided `kwargs` as fields. The name of each kwarg becomes the field name, with the
|
|
@@ -115,7 +115,10 @@ class Map(BAREType[dict[K, V]], metaclass=MapMeta):
|
|
|
115
115
|
return other._values == self._values
|
|
116
116
|
try:
|
|
117
117
|
for other_key, other_value in other.values():
|
|
118
|
-
if
|
|
118
|
+
if (
|
|
119
|
+
other_key not in self._values
|
|
120
|
+
and self._key_type(other_key) not in self._values
|
|
121
|
+
):
|
|
119
122
|
return False
|
|
120
123
|
if other_value != self._values[other_key]:
|
|
121
124
|
return False
|
|
@@ -60,7 +60,7 @@ class Enum(IntEnum, metaclass=EnumMeta):
|
|
|
60
60
|
return False
|
|
61
61
|
|
|
62
62
|
|
|
63
|
-
class Void:
|
|
63
|
+
class Void(BAREType[None]):
|
|
64
64
|
"""
|
|
65
65
|
A Void type. It is similar to the `None` type, but is used to represent
|
|
66
66
|
a BARE void type.
|
|
@@ -68,11 +68,14 @@ class Void:
|
|
|
68
68
|
If should *generally* be used directly, but is also used implicitly in `option`.
|
|
69
69
|
"""
|
|
70
70
|
|
|
71
|
+
def __init__(self):
|
|
72
|
+
...
|
|
73
|
+
|
|
71
74
|
def pack(self) -> bytes:
|
|
72
75
|
return bytes()
|
|
73
76
|
|
|
74
77
|
@classmethod
|
|
75
|
-
def unpack(cls,
|
|
78
|
+
def unpack(cls, fp: BinaryIO) -> Void:
|
|
76
79
|
return cls()
|
|
77
80
|
|
|
78
81
|
def __eq__(self, other: Any) -> bool:
|
|
@@ -5,9 +5,13 @@ import bare
|
|
|
5
5
|
import pytest
|
|
6
6
|
import io
|
|
7
7
|
|
|
8
|
+
__all__ = []
|
|
9
|
+
|
|
10
|
+
|
|
8
11
|
def test_2d_array_unsized():
|
|
9
12
|
class InnerArray(Array, inner=UInt):
|
|
10
13
|
...
|
|
14
|
+
|
|
11
15
|
class My2DArray(Array, inner=InnerArray):
|
|
12
16
|
...
|
|
13
17
|
|
|
@@ -18,6 +22,7 @@ def test_2d_array_unsized():
|
|
|
18
22
|
assert x2 == x
|
|
19
23
|
assert x2 == input
|
|
20
24
|
|
|
25
|
+
|
|
21
26
|
def test_anonymous_array_unsized():
|
|
22
27
|
AnonymousArray = array(UInt)
|
|
23
28
|
input = [1, 2, 3]
|
|
@@ -27,6 +32,7 @@ def test_anonymous_array_unsized():
|
|
|
27
32
|
assert x2 == x
|
|
28
33
|
assert x2 == input
|
|
29
34
|
|
|
35
|
+
|
|
30
36
|
def test_anonymous_array_sized():
|
|
31
37
|
AnonymousArray = array(UInt, 3)
|
|
32
38
|
input = [1, 2, 3]
|
|
@@ -41,6 +47,7 @@ def test_anonymous_array_sized():
|
|
|
41
47
|
with pytest.raises(ValueError):
|
|
42
48
|
AnonymousArray([1, 2, 3, 4])
|
|
43
49
|
|
|
50
|
+
|
|
44
51
|
def test_array_sized():
|
|
45
52
|
class MyArry(Array, inner=UInt, size=3):
|
|
46
53
|
...
|
|
@@ -56,24 +63,28 @@ def test_array_sized():
|
|
|
56
63
|
with pytest.raises(ValueError):
|
|
57
64
|
MyArry([1, 2, 3, 4])
|
|
58
65
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
])
|
|
66
|
+
|
|
67
|
+
@pytest.mark.parametrize(
|
|
68
|
+
"inner,data",
|
|
69
|
+
[
|
|
70
|
+
(bare.I8, [1, -1]),
|
|
71
|
+
(bare.U8, [1, 5]),
|
|
72
|
+
(bare.I16, [-1, 10000]),
|
|
73
|
+
(bare.U16, [1, 100]),
|
|
74
|
+
(bare.I32, [1, 100]),
|
|
75
|
+
(bare.U32, [1, 100]),
|
|
76
|
+
(bare.I64, [1, 100]),
|
|
77
|
+
(bare.U64, [1, 100]),
|
|
78
|
+
(bare.F32, [1.0, 2.0]),
|
|
79
|
+
(bare.F64, [1.1, 2.2]),
|
|
80
|
+
(bare.UInt, [1, 2, 3]),
|
|
81
|
+
(bare.Int, [-1, 2, -3]),
|
|
82
|
+
(bare.Str, ["Hello", "world"]),
|
|
83
|
+
(bare.Bool, [False, True]),
|
|
84
|
+
(bare.map(bare.Str, bare.Str), [{"Hello": "world"}, {"abc": "123"}]),
|
|
85
|
+
(bare.union(bare.Str, bare.UInt), [bare.Str("hello"), bare.UInt(123)]),
|
|
86
|
+
],
|
|
87
|
+
)
|
|
77
88
|
def test_all_types(inner: Type[BAREType], data: list):
|
|
78
89
|
anon_array = array(inner)
|
|
79
90
|
x = anon_array(data)
|
|
@@ -1,16 +1,21 @@
|
|
|
1
1
|
import io
|
|
2
2
|
from bare import Struct, UInt, Str, Field, struct
|
|
3
3
|
|
|
4
|
+
__all__ = []
|
|
5
|
+
|
|
6
|
+
|
|
4
7
|
def test_struct_basic():
|
|
5
8
|
class MyStruct(Struct):
|
|
6
9
|
a = Field(UInt)
|
|
7
10
|
b = Field(Str)
|
|
8
11
|
c: int
|
|
12
|
+
|
|
9
13
|
x = MyStruct(a=123, b="Hello")
|
|
10
14
|
b = x.pack()
|
|
11
15
|
x2 = MyStruct.unpack(io.BytesIO(b))
|
|
12
16
|
assert x == x2
|
|
13
17
|
|
|
18
|
+
|
|
14
19
|
def test_nested_struct():
|
|
15
20
|
class InnerStruct(Struct):
|
|
16
21
|
i = Field(UInt)
|
|
@@ -23,6 +28,7 @@ def test_nested_struct():
|
|
|
23
28
|
x2 = MyStruct.unpack(io.BytesIO(b))
|
|
24
29
|
assert x == x2
|
|
25
30
|
|
|
31
|
+
|
|
26
32
|
def test_anonymous_struct():
|
|
27
33
|
MyStruct = struct(name=Str, age=UInt)
|
|
28
34
|
x = MyStruct(name="Noah", age=27)
|
|
@@ -1,29 +1,33 @@
|
|
|
1
1
|
from bare import Data, data
|
|
2
2
|
import io
|
|
3
3
|
|
|
4
|
+
__all__ = []
|
|
5
|
+
|
|
4
6
|
|
|
5
7
|
def test_data_sized():
|
|
6
8
|
class SizedData(Data, size=5):
|
|
7
9
|
...
|
|
8
10
|
|
|
9
|
-
x = SizedData(b
|
|
11
|
+
x = SizedData(b"12345")
|
|
10
12
|
b = x.pack()
|
|
11
13
|
assert len(b) == 5
|
|
12
14
|
x2 = SizedData.unpack(io.BytesIO(b))
|
|
13
15
|
assert x == x2
|
|
14
16
|
|
|
17
|
+
|
|
15
18
|
def test_data_unsized():
|
|
16
19
|
class SizedData(Data):
|
|
17
20
|
...
|
|
18
21
|
|
|
19
|
-
x = SizedData(b
|
|
22
|
+
x = SizedData(b"12345")
|
|
20
23
|
b = x.pack()
|
|
21
24
|
assert len(b) == 6
|
|
22
25
|
x2 = SizedData.unpack(io.BytesIO(b))
|
|
23
26
|
assert x == x2
|
|
24
27
|
|
|
28
|
+
|
|
25
29
|
def test_data_raw():
|
|
26
|
-
x = Data(b
|
|
30
|
+
x = Data(b"12345")
|
|
27
31
|
b = x.pack()
|
|
28
32
|
assert len(b) == 6
|
|
29
33
|
x2 = Data.unpack(io.BytesIO(b))
|
|
@@ -27,6 +27,8 @@ from bare import (
|
|
|
27
27
|
UnionVariant,
|
|
28
28
|
)
|
|
29
29
|
|
|
30
|
+
__all__ = []
|
|
31
|
+
|
|
30
32
|
|
|
31
33
|
class Nested(Struct):
|
|
32
34
|
s = Field(Str)
|
|
@@ -100,7 +102,8 @@ def test_map():
|
|
|
100
102
|
assert map2.value["another"] == "test"
|
|
101
103
|
|
|
102
104
|
|
|
103
|
-
class MyArray(Array, inner=Int):
|
|
105
|
+
class MyArray(Array, inner=Int):
|
|
106
|
+
...
|
|
104
107
|
|
|
105
108
|
|
|
106
109
|
class ArrayTest(Struct):
|
|
@@ -141,7 +144,8 @@ def test_optional():
|
|
|
141
144
|
ex.nested = "test"
|
|
142
145
|
|
|
143
146
|
|
|
144
|
-
class ExampleUnion(Union, variants=(Str, Int)):
|
|
147
|
+
class ExampleUnion(Union, variants=(Str, Int)):
|
|
148
|
+
...
|
|
145
149
|
|
|
146
150
|
|
|
147
151
|
class UnionTest(Struct):
|
|
@@ -234,7 +238,8 @@ class TerminatedEmployee(Void):
|
|
|
234
238
|
pass
|
|
235
239
|
|
|
236
240
|
|
|
237
|
-
class Person(Union, variants=(Customer, Employee, TerminatedEmployee)):
|
|
241
|
+
class Person(Union, variants=(Customer, Employee, TerminatedEmployee)):
|
|
242
|
+
...
|
|
238
243
|
|
|
239
244
|
|
|
240
245
|
@pytest.mark.parametrize(
|
|
@@ -4,10 +4,13 @@ import io
|
|
|
4
4
|
|
|
5
5
|
import pytest
|
|
6
6
|
|
|
7
|
+
__all__ = []
|
|
8
|
+
|
|
7
9
|
|
|
8
10
|
class MyMap(Map, key_type=Str, value_type=Int):
|
|
9
11
|
...
|
|
10
12
|
|
|
13
|
+
|
|
11
14
|
def test_basic_map():
|
|
12
15
|
x = MyMap({"Hello": 123, "abc": 456})
|
|
13
16
|
b = x.pack()
|
|
@@ -16,6 +19,7 @@ def test_basic_map():
|
|
|
16
19
|
assert x["Hello"] == 123
|
|
17
20
|
assert x["abc"] == 456
|
|
18
21
|
|
|
22
|
+
|
|
19
23
|
def test_anonymous_map():
|
|
20
24
|
MyMap = map(Str, Int)
|
|
21
25
|
x = MyMap({"Hello": 123, "abc": 456})
|
|
@@ -25,37 +29,42 @@ def test_anonymous_map():
|
|
|
25
29
|
assert x["Hello"] == 123
|
|
26
30
|
assert x["abc"] == 456
|
|
27
31
|
|
|
32
|
+
|
|
28
33
|
def test_nested_map():
|
|
29
34
|
InnerMap = map(Str, Str)
|
|
35
|
+
|
|
30
36
|
class NestedMap(Map, key_type=Str, value_type=InnerMap):
|
|
31
37
|
...
|
|
38
|
+
|
|
32
39
|
x = NestedMap({"outer": {"hello": "world"}})
|
|
33
40
|
b = x.pack()
|
|
34
41
|
x2 = NestedMap.unpack(io.BytesIO(b))
|
|
35
42
|
assert x == x2
|
|
36
43
|
|
|
44
|
+
|
|
37
45
|
class MyEnum(bare.Enum):
|
|
38
46
|
A = 1
|
|
39
47
|
B = 2
|
|
40
48
|
|
|
49
|
+
|
|
41
50
|
@pytest.mark.parametrize(
|
|
42
|
-
|
|
51
|
+
"key_type,value_type,data",
|
|
43
52
|
[
|
|
44
53
|
(Str, Str, {"hello": "world"}),
|
|
45
54
|
(bare.UInt, bare.Int, {123: -123}),
|
|
46
|
-
(bare.U8, bare.U8, {1:2}),
|
|
47
|
-
(bare.I8, bare.I8, {1
|
|
48
|
-
(bare.U16, bare.U16, {1:2}),
|
|
49
|
-
(bare.I16, bare.I16, {1
|
|
50
|
-
(bare.U32, bare.U32, {1:2}),
|
|
51
|
-
(bare.I32, bare.I32, {1
|
|
52
|
-
(bare.U64, bare.U64, {1:2}),
|
|
53
|
-
(bare.I64, bare.I64, {1
|
|
54
|
-
(bare.UInt, bare.UInt, {1:2}),
|
|
55
|
-
(bare.Int, bare.Int, {1
|
|
55
|
+
(bare.U8, bare.U8, {1: 2}),
|
|
56
|
+
(bare.I8, bare.I8, {1: -2}),
|
|
57
|
+
(bare.U16, bare.U16, {1: 2}),
|
|
58
|
+
(bare.I16, bare.I16, {1: -2}),
|
|
59
|
+
(bare.U32, bare.U32, {1: 2}),
|
|
60
|
+
(bare.I32, bare.I32, {1: -2}),
|
|
61
|
+
(bare.U64, bare.U64, {1: 2}),
|
|
62
|
+
(bare.I64, bare.I64, {1: -2}),
|
|
63
|
+
(bare.UInt, bare.UInt, {1: 2}),
|
|
64
|
+
(bare.Int, bare.Int, {1: -2}),
|
|
56
65
|
(bare.Bool, bare.Bool, {True: False}),
|
|
57
66
|
(bare.Bool, bare.Bool, {True: False}),
|
|
58
|
-
]
|
|
67
|
+
],
|
|
59
68
|
)
|
|
60
69
|
def test_all_types(key_type, value_type, data):
|
|
61
70
|
anon_map = map(key_type, value_type)
|
|
@@ -63,4 +72,3 @@ def test_all_types(key_type, value_type, data):
|
|
|
63
72
|
b = x.pack()
|
|
64
73
|
x2 = anon_map.unpack(io.BytesIO(b))
|
|
65
74
|
assert x == x2
|
|
66
|
-
|
|
@@ -3,10 +3,14 @@ from bare import Enum, UInt, Void, Str
|
|
|
3
3
|
import io
|
|
4
4
|
import pytest
|
|
5
5
|
|
|
6
|
+
__all__ = []
|
|
7
|
+
|
|
8
|
+
|
|
6
9
|
class MyEnum(Enum):
|
|
7
10
|
A = 1
|
|
8
11
|
B = 2
|
|
9
12
|
|
|
13
|
+
|
|
10
14
|
def test_enum_basic():
|
|
11
15
|
b = MyEnum.A.pack()
|
|
12
16
|
a = MyEnum.unpack(io.BytesIO(b))
|
|
@@ -16,15 +20,18 @@ def test_enum_basic():
|
|
|
16
20
|
b = UInt(3).pack()
|
|
17
21
|
MyEnum.unpack(io.BytesIO(b))
|
|
18
22
|
|
|
23
|
+
|
|
19
24
|
class MyVoid(Void):
|
|
20
25
|
...
|
|
21
26
|
|
|
27
|
+
|
|
22
28
|
def test_custom_void():
|
|
23
29
|
x = MyVoid()
|
|
24
30
|
b = x.pack()
|
|
25
31
|
x2 = MyVoid.unpack(io.BytesIO(b))
|
|
26
32
|
assert x == x2
|
|
27
|
-
assert b == b
|
|
33
|
+
assert b == b""
|
|
34
|
+
|
|
28
35
|
|
|
29
36
|
def test_void():
|
|
30
37
|
x = Void()
|
|
@@ -33,9 +40,10 @@ def test_void():
|
|
|
33
40
|
assert x == x2
|
|
34
41
|
assert len(b) == 0
|
|
35
42
|
|
|
43
|
+
|
|
36
44
|
def test_str():
|
|
37
45
|
x = Str("Hello, world")
|
|
38
46
|
b = x.pack()
|
|
39
47
|
x2 = Str.unpack(io.BytesIO(b))
|
|
40
48
|
assert x == x2
|
|
41
|
-
assert b == b
|
|
49
|
+
assert b == b"\x0cHello, world"
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import io
|
|
2
|
+
import bare
|
|
3
|
+
import pytest
|
|
4
|
+
|
|
5
|
+
__all__ = []
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@pytest.mark.parametrize(
|
|
9
|
+
"type_, good_values, bad_values",
|
|
10
|
+
[
|
|
11
|
+
(bare.UInt, [0, 1, 2**64 - 1], [-1, 2**64, 2**64 + 1]),
|
|
12
|
+
(
|
|
13
|
+
bare.Int,
|
|
14
|
+
[-(2**63), -(2**63) + 1, 0, 2**63, 2**63 - 1],
|
|
15
|
+
[-(2**63) - 1, 2**63 + 1],
|
|
16
|
+
),
|
|
17
|
+
(bare.U8, [0, 1, 2**8 - 1], [-1, 2**8]),
|
|
18
|
+
(bare.I8, [-(2**7), 0, 2**7 - 1], [-(2**7) - 1, 2**7]),
|
|
19
|
+
(bare.U16, [0, 1, 2**16 - 1], [-1, 2**16]),
|
|
20
|
+
(bare.I16, [-(2**15), 0, 2**15 - 1], [-(2**15) - 1, 2**15]),
|
|
21
|
+
(bare.U32, [0, 1, 2**32 - 1], [-1, 2**32]),
|
|
22
|
+
(bare.I32, [-(2**31), 0, 2**31 - 1], [-(2**31) - 1, 2**31]),
|
|
23
|
+
(bare.U64, [0, 1, 2**64 - 1], [-1, 2**64]),
|
|
24
|
+
(bare.I64, [-(2**63), 0, 2**63 - 1], [-(2**63) - 1, 2**63]),
|
|
25
|
+
],
|
|
26
|
+
)
|
|
27
|
+
def test_bounds(type_, good_values, bad_values):
|
|
28
|
+
for value in good_values:
|
|
29
|
+
x = type_(value)
|
|
30
|
+
b = x.pack()
|
|
31
|
+
x2 = type_.unpack(io.BytesIO(b))
|
|
32
|
+
assert x == x2
|
|
33
|
+
for value in bad_values:
|
|
34
|
+
with pytest.raises(TypeError):
|
|
35
|
+
type_(value)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def test_f32():
|
|
39
|
+
x = bare.F32(123.5)
|
|
40
|
+
b = x.pack()
|
|
41
|
+
assert len(b) == 4
|
|
42
|
+
x2 = bare.F32.unpack(io.BytesIO(b))
|
|
43
|
+
assert x == x2
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def test_f64():
|
|
47
|
+
x = bare.F64(123.5)
|
|
48
|
+
b = x.pack()
|
|
49
|
+
assert len(b) == 8
|
|
50
|
+
x2 = bare.F64.unpack(io.BytesIO(b))
|
|
51
|
+
assert x == x2
|
|
@@ -3,98 +3,129 @@ import bare
|
|
|
3
3
|
import io
|
|
4
4
|
import pytest
|
|
5
5
|
|
|
6
|
+
__all__ = []
|
|
7
|
+
|
|
8
|
+
|
|
6
9
|
class MyUnion(Union, variants=(Str, Int)):
|
|
7
10
|
...
|
|
8
11
|
|
|
12
|
+
|
|
9
13
|
def test_union_basic():
|
|
10
14
|
x = MyUnion(Str("Hello"))
|
|
11
15
|
b = x.pack()
|
|
12
|
-
assert b == b
|
|
16
|
+
assert b == b"\x00\x05Hello"
|
|
13
17
|
x2 = MyUnion.unpack(io.BytesIO(b))
|
|
14
18
|
assert x == x2
|
|
15
19
|
with pytest.raises(TypeError):
|
|
16
20
|
x = MyUnion(True)
|
|
17
21
|
with pytest.raises(TypeError):
|
|
18
|
-
MyUnion.unpack(io.BytesIO(b
|
|
22
|
+
MyUnion.unpack(io.BytesIO(b"\x02\x05Hello"))
|
|
19
23
|
|
|
20
24
|
x = MyUnion(Int(16))
|
|
21
25
|
b = x.pack()
|
|
22
|
-
assert b == b
|
|
26
|
+
assert b == b"\x01\x20"
|
|
23
27
|
x2 = MyUnion.unpack(io.BytesIO(b))
|
|
24
28
|
assert x == x2
|
|
25
29
|
|
|
30
|
+
|
|
26
31
|
def test_anonymous_union():
|
|
27
32
|
MyUnion = union(Str, Int)
|
|
28
33
|
x = MyUnion(Str("Hello"))
|
|
29
34
|
b = x.pack()
|
|
30
|
-
assert b == b
|
|
35
|
+
assert b == b"\x00\x05Hello"
|
|
31
36
|
x2 = MyUnion.unpack(io.BytesIO(b))
|
|
32
37
|
assert x == x2
|
|
33
38
|
with pytest.raises(TypeError):
|
|
34
39
|
x = MyUnion(True)
|
|
35
40
|
|
|
41
|
+
|
|
36
42
|
def test_explicit_discriminant_implicit_following():
|
|
37
43
|
class MyUnion(Union, variants=(UnionVariant(Str, 4), Int)):
|
|
38
44
|
...
|
|
45
|
+
|
|
39
46
|
x = MyUnion(Str("Hello"))
|
|
40
47
|
b = x.pack()
|
|
41
|
-
assert b == b
|
|
48
|
+
assert b == b"\x04\x05Hello"
|
|
42
49
|
x2 = MyUnion.unpack(io.BytesIO(b))
|
|
43
50
|
assert x == x2
|
|
44
51
|
with pytest.raises(TypeError):
|
|
45
52
|
x = MyUnion(True)
|
|
46
53
|
with pytest.raises(TypeError):
|
|
47
|
-
MyUnion.unpack(io.BytesIO(b
|
|
54
|
+
MyUnion.unpack(io.BytesIO(b"\x02\x05Hello"))
|
|
48
55
|
|
|
49
56
|
x = MyUnion(Int(16))
|
|
50
57
|
b = x.pack()
|
|
51
|
-
assert b == b
|
|
58
|
+
assert b == b"\x05\x20"
|
|
52
59
|
x2 = MyUnion.unpack(io.BytesIO(b))
|
|
53
60
|
assert x == x2
|
|
54
61
|
|
|
62
|
+
|
|
55
63
|
def test_explicit_discriminant_all_cases():
|
|
56
64
|
class MyUnion(Union, variants=(UnionVariant(Str, 4), UnionVariant(Int, 10))):
|
|
57
65
|
...
|
|
66
|
+
|
|
58
67
|
x = MyUnion(Str("Hello"))
|
|
59
68
|
b = x.pack()
|
|
60
|
-
assert b == b
|
|
69
|
+
assert b == b"\x04\x05Hello"
|
|
61
70
|
x2 = MyUnion.unpack(io.BytesIO(b))
|
|
62
71
|
assert x == x2
|
|
63
72
|
with pytest.raises(TypeError):
|
|
64
73
|
x = MyUnion(True)
|
|
65
74
|
with pytest.raises(TypeError):
|
|
66
|
-
MyUnion.unpack(io.BytesIO(b
|
|
75
|
+
MyUnion.unpack(io.BytesIO(b"\x02\x05Hello"))
|
|
67
76
|
|
|
68
77
|
x = MyUnion(Int(16))
|
|
69
78
|
b = x.pack()
|
|
70
|
-
assert b == b
|
|
79
|
+
assert b == b"\x0a\x20"
|
|
71
80
|
x2 = MyUnion.unpack(io.BytesIO(b))
|
|
72
81
|
assert x == x2
|
|
73
82
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
83
|
+
|
|
84
|
+
class AllPrimativeTypes(
|
|
85
|
+
Union,
|
|
86
|
+
variants=(
|
|
87
|
+
Str,
|
|
88
|
+
Int,
|
|
89
|
+
bare.UInt,
|
|
90
|
+
bare.Bool,
|
|
91
|
+
bare.F32,
|
|
92
|
+
bare.F64,
|
|
93
|
+
bare.U8,
|
|
94
|
+
bare.I8,
|
|
95
|
+
bare.U16,
|
|
96
|
+
bare.I16,
|
|
97
|
+
bare.U32,
|
|
98
|
+
bare.I32,
|
|
99
|
+
bare.U64,
|
|
100
|
+
bare.I64,
|
|
101
|
+
bare.Data,
|
|
102
|
+
bare.Void,
|
|
103
|
+
),
|
|
104
|
+
):
|
|
78
105
|
...
|
|
79
106
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
107
|
+
|
|
108
|
+
@pytest.mark.parametrize(
|
|
109
|
+
"value,discriminant",
|
|
110
|
+
[
|
|
111
|
+
(Str("Hello"), 0),
|
|
112
|
+
(Int(123), 1),
|
|
113
|
+
(bare.UInt(123), 2),
|
|
114
|
+
(bare.Bool(True), 3),
|
|
115
|
+
(bare.F32(123.5), 4),
|
|
116
|
+
(bare.F64(123.5), 5),
|
|
117
|
+
(bare.U8(123), 6),
|
|
118
|
+
(bare.I8(123), 7),
|
|
119
|
+
(bare.U16(123), 8),
|
|
120
|
+
(bare.I16(123), 9),
|
|
121
|
+
(bare.U32(123), 10),
|
|
122
|
+
(bare.I32(123), 11),
|
|
123
|
+
(bare.U64(123), 12),
|
|
124
|
+
(bare.I64(123), 13),
|
|
125
|
+
(bare.Data(b"123"), 14),
|
|
126
|
+
(bare.Void(), 15),
|
|
127
|
+
],
|
|
128
|
+
)
|
|
98
129
|
def test_union_all_primative_types(value, discriminant):
|
|
99
130
|
x = AllPrimativeTypes(value)
|
|
100
131
|
b = x.pack()
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
from typing import
|
|
1
|
+
from typing import Type, TypeVar
|
|
2
|
+
from .misc import Enum
|
|
2
3
|
|
|
3
4
|
from .baretype import BAREType
|
|
4
5
|
|
|
5
6
|
T = TypeVar("T", bound=BAREType)
|
|
6
7
|
|
|
7
8
|
|
|
8
|
-
class Field
|
|
9
|
+
class Field:
|
|
9
10
|
"""
|
|
10
11
|
A descriptor that assists with assigning/retrieving values from a BARE Struct.
|
|
11
12
|
It is reponsible for performing type validation on assignment of struct fields.
|
|
@@ -21,15 +22,15 @@ class Field(Generic[T]):
|
|
|
21
22
|
|
|
22
23
|
attr: str
|
|
23
24
|
name: str
|
|
24
|
-
ty: Type[BAREType
|
|
25
|
+
ty: Type[BAREType | Enum]
|
|
25
26
|
|
|
26
|
-
def __init__(self, ty: Type[BAREType
|
|
27
|
+
def __init__(self, ty: Type[BAREType | Enum], attr: str | None = None):
|
|
27
28
|
# ignore the typing here because these will always be set when assigned to an
|
|
28
29
|
# object
|
|
29
30
|
self.attr = attr # type: ignore
|
|
30
31
|
self.ty = ty
|
|
31
32
|
|
|
32
|
-
def __get__(self, inst, _) -> T | Type[BAREType[T]]:
|
|
33
|
+
def __get__(self, inst, _) -> T | Type[BAREType[T] | Enum]:
|
|
33
34
|
if inst is None:
|
|
34
35
|
return self.ty
|
|
35
36
|
return inst.__dict__[self.attr]
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = [
|
|
3
|
+
"pdm-backend",
|
|
4
|
+
]
|
|
5
|
+
build-backend = "pdm.backend"
|
|
6
|
+
|
|
7
|
+
[project]
|
|
8
|
+
name = "pybare"
|
|
9
|
+
version = "1.2.5"
|
|
10
|
+
description = "A BARE Encoding Library and Data Validation Library for Python."
|
|
11
|
+
dependencies = []
|
|
12
|
+
requires-python = ">= 3.10"
|
|
13
|
+
authors = [
|
|
14
|
+
{ name = "Noah Pederson", email = "noah@packetlost.dev" },
|
|
15
|
+
]
|
|
16
|
+
readme = "README.md"
|
|
17
|
+
classifiers = [
|
|
18
|
+
"Development Status :: 4 - Beta",
|
|
19
|
+
"Intended Audience :: Developers",
|
|
20
|
+
"Programming Language :: Python :: 3.10",
|
|
21
|
+
"Programming Language :: Python :: 3.11",
|
|
22
|
+
"Programming Language :: Python :: 3.12",
|
|
23
|
+
"License :: OSI Approved :: MIT License",
|
|
24
|
+
"Operating System :: OS Independent",
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
[project.license]
|
|
28
|
+
file = "LICENSE"
|
|
29
|
+
|
|
30
|
+
[project.urls]
|
|
31
|
+
Homepage = "https://sr.ht/~chiefnoah/pybare/"
|
|
32
|
+
Repository = "https://git.sr.ht/~chiefnoah/pybare"
|
|
33
|
+
Issues = "https://todo.sr.ht/~chiefnoah/pybare"
|
|
34
|
+
Changelog = "https://git.sr.ht/~chiefnoah/pybare/tree/master/item/CHANGELOG.md"
|
|
35
|
+
|
|
36
|
+
[tool]
|
pybare-1.2.3/PKG-INFO
DELETED
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.1
|
|
2
|
-
Name: pybare
|
|
3
|
-
Version: 1.2.3
|
|
4
|
-
Summary: A declarative implementation of BARE for Python
|
|
5
|
-
Home-page: https://sr.ht/~chiefnoah/pybare/
|
|
6
|
-
Author: Noah Pederson
|
|
7
|
-
Author-email: noah@packetlost.dev
|
|
8
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
9
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
10
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
11
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
-
Classifier: Operating System :: OS Independent
|
|
13
|
-
Requires-Python: >=3.10
|
|
14
|
-
Description-Content-Type: text/markdown
|
|
15
|
-
License-File: LICENSE
|
|
16
|
-
|
|
17
|
-
# PyBARE
|
|
18
|
-
[](https://builds.sr.ht/~chiefnoah/pybare?)
|
|
19
|
-
|
|
20
|
-
A declarative implementation of the [BARE](https://baremessages.org/) message
|
|
21
|
-
format for Python 3.10+
|
|
22
|
-
|
|
23
|
-
---
|
|
24
|
-
|
|
25
|
-
pybare is a general purpose library for strongly typed primitives in Python that
|
|
26
|
-
supports serializing to and from BARE messages.
|
|
27
|
-
|
|
28
|
-
```shell
|
|
29
|
-
pip install pybare
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
## Goals
|
|
33
|
-
|
|
34
|
-
* Provide a declarative structure for defining types
|
|
35
|
-
* Validation on value updates
|
|
36
|
-
* Support streaming messages
|
|
37
|
-
|
|
38
|
-
## Status
|
|
39
|
-
|
|
40
|
-
pybare fully implements all BARE types for both encoding and decoding. This
|
|
41
|
-
includes reading multiple messages from the same `BinaryIO` stream.
|
|
42
|
-
|
|
43
|
-
## Gotchas
|
|
44
|
-
|
|
45
|
-
We use "Array" / "array" instead of "List" / "list" to avoid conflicts with Python's
|
|
46
|
-
common builtin type of the same name.
|
|
47
|
-
|
|
48
|
-
## Examples
|
|
49
|
-
|
|
50
|
-
An example that defines the types used as an example in the RFC may be found in
|
|
51
|
-
[`example.py`](./example.py)
|
|
52
|
-
|
|
53
|
-
pybare currently requires you define your structures by hand. Examples can be
|
|
54
|
-
found in the
|
|
55
|
-
[tests](https://git.sr.ht/~chiefnoah/pybare/tree/master/bare/test_encoder.py).
|
|
56
|
-
|
|
57
|
-
### Quickstart
|
|
58
|
-
|
|
59
|
-
The general convention is type identifiers start with a *capital* letter and anonymous
|
|
60
|
-
generating functions begin with a lowercase. This follows general "pythonic" style for
|
|
61
|
-
classes vs functions.
|
|
62
|
-
|
|
63
|
-
```python
|
|
64
|
-
from bare import Struct, map, Str, UInt, optional, data, array, Void, struct, U8
|
|
65
|
-
|
|
66
|
-
# Alternatively, class Data(size=64): ...
|
|
67
|
-
PubKey = data(64) # 512 bits
|
|
68
|
-
|
|
69
|
-
class User(Struct):
|
|
70
|
-
username = Field(Str)
|
|
71
|
-
userid = Field(Int)
|
|
72
|
-
email = Field(optional(Str))
|
|
73
|
-
keys = Field(map(Str, PubKey))
|
|
74
|
-
repos = Field(array(Str)) # variable length array
|
|
75
|
-
# anonymous array and struct
|
|
76
|
-
friends = Field(array(struct(name=Str, age=U8)))
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
noah = User(username="chiefnoah", userid=1, email=Void(), keys={}, repos=[], friends=[])
|
|
80
|
-
noah.username == 'chiefnoah'
|
|
81
|
-
noah.username = 'someoneelse'
|
|
82
|
-
noah.username == 'someoneelse'
|
|
83
|
-
noah.userid == 1 # True
|
|
84
|
-
noah.username = 1 # raise: bare.ValidationError
|
|
85
|
-
noah.keys # {} (empty dict)
|
|
86
|
-
noah.keys['my key'] = bytes(64) #\x00\x00...
|
|
87
|
-
noah.keys['oops'] = bytes(1) # raise: bare.ValidationError
|
|
88
|
-
noah.email == Void() # True
|
|
89
|
-
noah.email = 12345 # raise: bare.ValidationError
|
|
90
|
-
noah.pack() # \x00\x01 ... (binary data)
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
Note, you **must** wrap the desired type in a `Field` to get its 'magic' behavior.
|
|
94
|
-
Class or instance fields that are not wrapped in a `Field` will be ignored by the `pack`
|
|
95
|
-
and `unpack` methods.
|
|
96
|
-
|
|
97
|
-
---
|
|
98
|
-
|
|
99
|
-
To contribute, send patches to [~chiefnoah/inbox@lists.sr.ht](mailto:~chiefnoah/inbox@lists.sr.ht)
|
pybare-1.2.3/bare/test_number.py
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import io
|
|
2
|
-
import bare
|
|
3
|
-
import pytest
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
@pytest.mark.parametrize(
|
|
7
|
-
"type_, good_values, bad_values",
|
|
8
|
-
[
|
|
9
|
-
(bare.UInt, [0, 1, 2**64-1], [-1, 2**64, 2**64+1]),
|
|
10
|
-
(bare.Int, [-2**63, -(2**63)+1, 0, 2**63, 2**63-1], [-2**63-1, 2**63+1]),
|
|
11
|
-
(bare.U8, [0, 1, 2**8-1], [-1, 2**8]),
|
|
12
|
-
(bare.I8, [-2**7, 0, 2**7-1], [-2**7-1, 2**7]),
|
|
13
|
-
(bare.U16, [0, 1, 2**16-1], [-1, 2**16]),
|
|
14
|
-
(bare.I16, [-2**15, 0, 2**15-1], [-2**15-1, 2**15]),
|
|
15
|
-
(bare.U32, [0, 1, 2**32-1], [-1, 2**32]),
|
|
16
|
-
(bare.I32, [-2**31, 0, 2**31-1], [-2**31-1, 2**31]),
|
|
17
|
-
(bare.U64, [0, 1, 2**64-1], [-1, 2**64]),
|
|
18
|
-
(bare.I64, [-2**63, 0, 2**63-1], [-2**63-1, 2**63]),
|
|
19
|
-
]
|
|
20
|
-
)
|
|
21
|
-
def test_bounds(type_, good_values, bad_values):
|
|
22
|
-
for value in good_values:
|
|
23
|
-
x = type_(value)
|
|
24
|
-
b = x.pack()
|
|
25
|
-
x2 = type_.unpack(io.BytesIO(b))
|
|
26
|
-
assert x == x2
|
|
27
|
-
for value in bad_values:
|
|
28
|
-
with pytest.raises(TypeError):
|
|
29
|
-
type_(value)
|
|
30
|
-
|
|
31
|
-
def test_f32():
|
|
32
|
-
x = bare.F32(123.5)
|
|
33
|
-
b = x.pack()
|
|
34
|
-
assert len(b) == 4
|
|
35
|
-
x2 = bare.F32.unpack(io.BytesIO(b))
|
|
36
|
-
assert x == x2
|
|
37
|
-
|
|
38
|
-
def test_f64():
|
|
39
|
-
x = bare.F64(123.5)
|
|
40
|
-
b = x.pack()
|
|
41
|
-
assert len(b) == 8
|
|
42
|
-
x2 = bare.F64.unpack(io.BytesIO(b))
|
|
43
|
-
assert x == x2
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
LICENSE
|
|
2
|
-
README.md
|
|
3
|
-
setup.py
|
|
4
|
-
bare/__init__.py
|
|
5
|
-
bare/barearray.py
|
|
6
|
-
bare/barestruct.py
|
|
7
|
-
bare/baretype.py
|
|
8
|
-
bare/data.py
|
|
9
|
-
bare/map.py
|
|
10
|
-
bare/misc.py
|
|
11
|
-
bare/number.py
|
|
12
|
-
bare/test_barearray.py
|
|
13
|
-
bare/test_barestruct.py
|
|
14
|
-
bare/test_data.py
|
|
15
|
-
bare/test_encoder.py
|
|
16
|
-
bare/test_map.py
|
|
17
|
-
bare/test_misc.py
|
|
18
|
-
bare/test_number.py
|
|
19
|
-
bare/test_union.py
|
|
20
|
-
bare/union.py
|
|
21
|
-
bare/util.py
|
|
22
|
-
pybare.egg-info/PKG-INFO
|
|
23
|
-
pybare.egg-info/SOURCES.txt
|
|
24
|
-
pybare.egg-info/dependency_links.txt
|
|
25
|
-
pybare.egg-info/top_level.txt
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
bare
|
pybare-1.2.3/setup.cfg
DELETED
pybare-1.2.3/setup.py
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import setuptools
|
|
2
|
-
|
|
3
|
-
with open("README.md", "r") as fh:
|
|
4
|
-
long_description = fh.read()
|
|
5
|
-
|
|
6
|
-
setuptools.setup(
|
|
7
|
-
name="pybare", # Replace with your own username
|
|
8
|
-
version="1.2.3",
|
|
9
|
-
author="Noah Pederson",
|
|
10
|
-
author_email="noah@packetlost.dev",
|
|
11
|
-
description="A declarative implementation of BARE for Python",
|
|
12
|
-
long_description=long_description,
|
|
13
|
-
long_description_content_type="text/markdown",
|
|
14
|
-
url="https://sr.ht/~chiefnoah/pybare/",
|
|
15
|
-
packages=setuptools.find_packages(),
|
|
16
|
-
classifiers=[
|
|
17
|
-
"Programming Language :: Python :: 3.10",
|
|
18
|
-
"Programming Language :: Python :: 3.11",
|
|
19
|
-
"Programming Language :: Python :: 3.12",
|
|
20
|
-
"License :: OSI Approved :: MIT License",
|
|
21
|
-
"Operating System :: OS Independent",
|
|
22
|
-
],
|
|
23
|
-
python_requires=">=3.10",
|
|
24
|
-
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|