microconst 0.1.0__tar.gz → 0.2.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.
- microconst-0.2.0/PKG-INFO +147 -0
- microconst-0.2.0/README.md +125 -0
- microconst-0.2.0/microconst/__init__.py +6 -0
- microconst-0.2.0/microconst/const.py +34 -0
- microconst-0.2.0/microconst/factories.py +28 -0
- microconst-0.2.0/microconst/types.py +72 -0
- microconst-0.2.0/microconst/utils.py +11 -0
- microconst-0.2.0/microconst.egg-info/PKG-INFO +147 -0
- {microconst-0.1.0 → microconst-0.2.0}/microconst.egg-info/SOURCES.txt +4 -3
- {microconst-0.1.0 → microconst-0.2.0}/pyproject.toml +5 -4
- microconst-0.2.0/tests/test_all.py +33 -0
- microconst-0.1.0/PKG-INFO +0 -87
- microconst-0.1.0/README.md +0 -64
- microconst-0.1.0/microconst/__init__.py +0 -6
- microconst-0.1.0/microconst/entry.py +0 -6
- microconst-0.1.0/microconst/key.py +0 -29
- microconst-0.1.0/microconst/members.py +0 -32
- microconst-0.1.0/microconst.egg-info/PKG-INFO +0 -87
- microconst-0.1.0/tests/test_all.py +0 -21
- {microconst-0.1.0 → microconst-0.2.0}/microconst/py.typed +0 -0
- {microconst-0.1.0 → microconst-0.2.0}/microconst.egg-info/dependency_links.txt +0 -0
- {microconst-0.1.0 → microconst-0.2.0}/microconst.egg-info/top_level.txt +0 -0
- {microconst-0.1.0 → microconst-0.2.0}/setup.cfg +0 -0
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: microconst
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Library for optimizing enum constant values
|
|
5
|
+
Author-email: triple-raze <weebucks2@gmail.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/triple-raze/microconst
|
|
8
|
+
Project-URL: Repository, https://github.com/triple-raze/microconst.git
|
|
9
|
+
Project-URL: Issues, https://github.com/triple-raze/microconst/issues
|
|
10
|
+
Keywords: enum,compact
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
18
|
+
Classifier: Topic :: Utilities
|
|
19
|
+
Classifier: Typing :: Typed
|
|
20
|
+
Requires-Python: >=3.12
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
|
|
23
|
+
# microconst
|
|
24
|
+
[](https://pypi.org/project/microconst/)
|
|
25
|
+

|
|
26
|
+

|
|
27
|
+

|
|
28
|
+

|
|
29
|
+
|
|
30
|
+
Replace long constant names with 2 ASCII characters
|
|
31
|
+
|
|
32
|
+
## Installation
|
|
33
|
+
pip:
|
|
34
|
+
```
|
|
35
|
+
pip install microconst
|
|
36
|
+
```
|
|
37
|
+
poetry:
|
|
38
|
+
```
|
|
39
|
+
poetry add microconst
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Features
|
|
43
|
+
#### Constants
|
|
44
|
+
Every call of `flag` or `key` generates 2-character constant. This constant is represented as left and right indexes of `f"{ascii_letters}{digits}"` str. Each time the left index reaches cap, it resets to 0 and right index increments.<br>
|
|
45
|
+
After reaching both of caps, next call of function will throw `OverflowError`. Current maximum count of constants is 3844.
|
|
46
|
+
|
|
47
|
+
#### Typing
|
|
48
|
+
`key` function requires `value_type` argument, such as `str`, `int` etc. This type used in both static analysis and type conversion with `Key.parse_entry` function.
|
|
49
|
+
|
|
50
|
+
## Examples
|
|
51
|
+
Main purpose of this library is making telegram bot's "callback_data" much more compact because of 64-byte limit. You can see more realistic example [here](example)<br><br>
|
|
52
|
+
#### Flag usage
|
|
53
|
+
Before:
|
|
54
|
+
```python
|
|
55
|
+
from enum import StrEnum, auto
|
|
56
|
+
|
|
57
|
+
# Some very strict limit
|
|
58
|
+
MAX_LEN: int = 4
|
|
59
|
+
|
|
60
|
+
class Status(StrEnum):
|
|
61
|
+
PENDING = auto()
|
|
62
|
+
APPROVED = auto()
|
|
63
|
+
REJECTED = auto()
|
|
64
|
+
|
|
65
|
+
assert Status.PENDING == "pending"
|
|
66
|
+
assert len(Status.PENDING) > MAX_LEN # Too long
|
|
67
|
+
```
|
|
68
|
+
After:
|
|
69
|
+
```python
|
|
70
|
+
from microconst import flag
|
|
71
|
+
|
|
72
|
+
MAX_LEN: int = 4
|
|
73
|
+
|
|
74
|
+
# Autogenerates unique pairs of characters
|
|
75
|
+
class Status:
|
|
76
|
+
PENDING = flag()
|
|
77
|
+
APPROVED = flag()
|
|
78
|
+
REJECTED = flag()
|
|
79
|
+
|
|
80
|
+
assert Status.PENDING == "aa"
|
|
81
|
+
assert len(Status.PENDING) < MAX_LEN
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
#### Key usage
|
|
85
|
+
Before:
|
|
86
|
+
```python
|
|
87
|
+
from enum import StrEnum, auto
|
|
88
|
+
|
|
89
|
+
class Data(StrEnum):
|
|
90
|
+
USERNAME = auto()
|
|
91
|
+
ORDER = auto()
|
|
92
|
+
|
|
93
|
+
# You should use separator because of varying character count in key
|
|
94
|
+
username = Data.USERNAME + ":" + "name"
|
|
95
|
+
assert username == "username:name" # Too long
|
|
96
|
+
|
|
97
|
+
value = username.split(":")[1]
|
|
98
|
+
assert value == "name"
|
|
99
|
+
|
|
100
|
+
order = Data.ORDER + ":" + str(1337)
|
|
101
|
+
assert order == "order:1337"
|
|
102
|
+
|
|
103
|
+
# Order doesnt contain its type anywhere, so you should convert types each time
|
|
104
|
+
assert int(order.split(":")[1]) == 1337
|
|
105
|
+
|
|
106
|
+
```
|
|
107
|
+
After:
|
|
108
|
+
```python
|
|
109
|
+
from microconst import key, parse_entry
|
|
110
|
+
|
|
111
|
+
class Data:
|
|
112
|
+
USERNAME = key(str)
|
|
113
|
+
ORDER = key(int)
|
|
114
|
+
|
|
115
|
+
# You can call keys to create key-value pair (acts same as concat)
|
|
116
|
+
username = Data.USERNAME("name")
|
|
117
|
+
assert username == "aaname"
|
|
118
|
+
|
|
119
|
+
# Getting value
|
|
120
|
+
value = Data.USERNAME.parse_entry(username)
|
|
121
|
+
assert value == "name"
|
|
122
|
+
|
|
123
|
+
order = Data.ORDER(1337)
|
|
124
|
+
assert order == "ba1337"
|
|
125
|
+
|
|
126
|
+
# You can use separate function or method. Method doesnt require type argument
|
|
127
|
+
assert parse_entry(order, int) == 1337
|
|
128
|
+
assert Data.ORDER.parse_entry(order) == 1337
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
#### Key usage (literals)
|
|
132
|
+
Unique feature, it's hard to implement, so no comprasion before and after:
|
|
133
|
+
```python
|
|
134
|
+
from microconst import key, parse_entry
|
|
135
|
+
|
|
136
|
+
class Data:
|
|
137
|
+
ORDER = key(Literal[1, 2, 3])
|
|
138
|
+
|
|
139
|
+
assert Data.ORDER(1) == "aa1"
|
|
140
|
+
# assert Data.ORDER(4) == "aa4" # Mypy error
|
|
141
|
+
|
|
142
|
+
assert Data.ORDER.parse_entry("__3") == 3
|
|
143
|
+
# assert Data.ORDER.parse_entry("__10") == 10 # Mypy error
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## License
|
|
147
|
+
MIT
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# microconst
|
|
2
|
+
[](https://pypi.org/project/microconst/)
|
|
3
|
+

|
|
4
|
+

|
|
5
|
+

|
|
6
|
+

|
|
7
|
+
|
|
8
|
+
Replace long constant names with 2 ASCII characters
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
pip:
|
|
12
|
+
```
|
|
13
|
+
pip install microconst
|
|
14
|
+
```
|
|
15
|
+
poetry:
|
|
16
|
+
```
|
|
17
|
+
poetry add microconst
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Features
|
|
21
|
+
#### Constants
|
|
22
|
+
Every call of `flag` or `key` generates 2-character constant. This constant is represented as left and right indexes of `f"{ascii_letters}{digits}"` str. Each time the left index reaches cap, it resets to 0 and right index increments.<br>
|
|
23
|
+
After reaching both of caps, next call of function will throw `OverflowError`. Current maximum count of constants is 3844.
|
|
24
|
+
|
|
25
|
+
#### Typing
|
|
26
|
+
`key` function requires `value_type` argument, such as `str`, `int` etc. This type used in both static analysis and type conversion with `Key.parse_entry` function.
|
|
27
|
+
|
|
28
|
+
## Examples
|
|
29
|
+
Main purpose of this library is making telegram bot's "callback_data" much more compact because of 64-byte limit. You can see more realistic example [here](example)<br><br>
|
|
30
|
+
#### Flag usage
|
|
31
|
+
Before:
|
|
32
|
+
```python
|
|
33
|
+
from enum import StrEnum, auto
|
|
34
|
+
|
|
35
|
+
# Some very strict limit
|
|
36
|
+
MAX_LEN: int = 4
|
|
37
|
+
|
|
38
|
+
class Status(StrEnum):
|
|
39
|
+
PENDING = auto()
|
|
40
|
+
APPROVED = auto()
|
|
41
|
+
REJECTED = auto()
|
|
42
|
+
|
|
43
|
+
assert Status.PENDING == "pending"
|
|
44
|
+
assert len(Status.PENDING) > MAX_LEN # Too long
|
|
45
|
+
```
|
|
46
|
+
After:
|
|
47
|
+
```python
|
|
48
|
+
from microconst import flag
|
|
49
|
+
|
|
50
|
+
MAX_LEN: int = 4
|
|
51
|
+
|
|
52
|
+
# Autogenerates unique pairs of characters
|
|
53
|
+
class Status:
|
|
54
|
+
PENDING = flag()
|
|
55
|
+
APPROVED = flag()
|
|
56
|
+
REJECTED = flag()
|
|
57
|
+
|
|
58
|
+
assert Status.PENDING == "aa"
|
|
59
|
+
assert len(Status.PENDING) < MAX_LEN
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
#### Key usage
|
|
63
|
+
Before:
|
|
64
|
+
```python
|
|
65
|
+
from enum import StrEnum, auto
|
|
66
|
+
|
|
67
|
+
class Data(StrEnum):
|
|
68
|
+
USERNAME = auto()
|
|
69
|
+
ORDER = auto()
|
|
70
|
+
|
|
71
|
+
# You should use separator because of varying character count in key
|
|
72
|
+
username = Data.USERNAME + ":" + "name"
|
|
73
|
+
assert username == "username:name" # Too long
|
|
74
|
+
|
|
75
|
+
value = username.split(":")[1]
|
|
76
|
+
assert value == "name"
|
|
77
|
+
|
|
78
|
+
order = Data.ORDER + ":" + str(1337)
|
|
79
|
+
assert order == "order:1337"
|
|
80
|
+
|
|
81
|
+
# Order doesnt contain its type anywhere, so you should convert types each time
|
|
82
|
+
assert int(order.split(":")[1]) == 1337
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
After:
|
|
86
|
+
```python
|
|
87
|
+
from microconst import key, parse_entry
|
|
88
|
+
|
|
89
|
+
class Data:
|
|
90
|
+
USERNAME = key(str)
|
|
91
|
+
ORDER = key(int)
|
|
92
|
+
|
|
93
|
+
# You can call keys to create key-value pair (acts same as concat)
|
|
94
|
+
username = Data.USERNAME("name")
|
|
95
|
+
assert username == "aaname"
|
|
96
|
+
|
|
97
|
+
# Getting value
|
|
98
|
+
value = Data.USERNAME.parse_entry(username)
|
|
99
|
+
assert value == "name"
|
|
100
|
+
|
|
101
|
+
order = Data.ORDER(1337)
|
|
102
|
+
assert order == "ba1337"
|
|
103
|
+
|
|
104
|
+
# You can use separate function or method. Method doesnt require type argument
|
|
105
|
+
assert parse_entry(order, int) == 1337
|
|
106
|
+
assert Data.ORDER.parse_entry(order) == 1337
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
#### Key usage (literals)
|
|
110
|
+
Unique feature, it's hard to implement, so no comprasion before and after:
|
|
111
|
+
```python
|
|
112
|
+
from microconst import key, parse_entry
|
|
113
|
+
|
|
114
|
+
class Data:
|
|
115
|
+
ORDER = key(Literal[1, 2, 3])
|
|
116
|
+
|
|
117
|
+
assert Data.ORDER(1) == "aa1"
|
|
118
|
+
# assert Data.ORDER(4) == "aa4" # Mypy error
|
|
119
|
+
|
|
120
|
+
assert Data.ORDER.parse_entry("__3") == 3
|
|
121
|
+
# assert Data.ORDER.parse_entry("__10") == 10 # Mypy error
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## License
|
|
125
|
+
MIT
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from string import ascii_letters, digits
|
|
4
|
+
from typing import TYPE_CHECKING
|
|
5
|
+
|
|
6
|
+
if TYPE_CHECKING:
|
|
7
|
+
from collections.abc import Generator
|
|
8
|
+
|
|
9
|
+
DEFAULT_CHARACTERS = f"{ascii_letters}{digits}"
|
|
10
|
+
|
|
11
|
+
MAX_IDX = len(DEFAULT_CHARACTERS) - 1
|
|
12
|
+
MAX_CONSTS = len(DEFAULT_CHARACTERS) ** 2
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def create_unique_const_generator() -> Generator[str, None, None]:
|
|
16
|
+
left_idx: int = 0
|
|
17
|
+
right_idx: int = 0
|
|
18
|
+
|
|
19
|
+
while right_idx != MAX_IDX + 1:
|
|
20
|
+
pair: str = DEFAULT_CHARACTERS[left_idx] + DEFAULT_CHARACTERS[right_idx]
|
|
21
|
+
|
|
22
|
+
if left_idx == MAX_IDX:
|
|
23
|
+
left_idx = 0
|
|
24
|
+
right_idx += 1
|
|
25
|
+
else:
|
|
26
|
+
left_idx += 1
|
|
27
|
+
|
|
28
|
+
yield pair
|
|
29
|
+
|
|
30
|
+
msg = f"cannot create more than {MAX_CONSTS} constants"
|
|
31
|
+
raise OverflowError(msg)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
unique_const_generator = create_unique_const_generator()
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING, overload
|
|
4
|
+
|
|
5
|
+
from typing_extensions import TypeForm
|
|
6
|
+
|
|
7
|
+
from microconst.const import unique_const_generator
|
|
8
|
+
from microconst.types import Key
|
|
9
|
+
|
|
10
|
+
if TYPE_CHECKING:
|
|
11
|
+
from microconst.types import Converter
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def create_flag() -> str:
|
|
15
|
+
return next(unique_const_generator)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@overload
|
|
19
|
+
def create_key[T](converterl: Converter[T], /) -> Key[T]: ...
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@overload
|
|
23
|
+
def create_key[T](literal: TypeForm[T], /) -> Key[T]: ...
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def create_key[T](converter_or_literal: Converter[T] | TypeForm[T]) -> Key[T]:
|
|
27
|
+
name = next(unique_const_generator)
|
|
28
|
+
return Key(name, converter_or_literal)
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from collections.abc import Callable
|
|
4
|
+
from typing import Literal, Self, cast, get_args, get_origin, overload
|
|
5
|
+
|
|
6
|
+
from typing_extensions import TypeForm
|
|
7
|
+
|
|
8
|
+
from microconst.utils import parse_entry
|
|
9
|
+
|
|
10
|
+
# Any type is callable, but mypy doesnt think so
|
|
11
|
+
# It also means you can use functions instead of types technically
|
|
12
|
+
type Converter[T] = Callable[[str], T]
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class Key[T](str):
|
|
16
|
+
# Subclasses of str should define __slots__
|
|
17
|
+
__slots__ = ("converter",)
|
|
18
|
+
converter: Converter[T]
|
|
19
|
+
|
|
20
|
+
@overload
|
|
21
|
+
def __new__(cls, name: str, converter: Converter[T], /) -> Key[T]: ...
|
|
22
|
+
|
|
23
|
+
@overload
|
|
24
|
+
def __new__(cls, name: str, literal: TypeForm[T], /) -> Key[T]: ...
|
|
25
|
+
|
|
26
|
+
def __new__(cls, name: str, converter_or_literal: object) -> Key[T]:
|
|
27
|
+
instance = super().__new__(cls, name)
|
|
28
|
+
|
|
29
|
+
# Type forms has __call__, but it throws an exception. We will use isinstance with type insead
|
|
30
|
+
is_converter = isinstance(converter_or_literal, type(object))
|
|
31
|
+
|
|
32
|
+
origin = cast("object", get_origin(converter_or_literal))
|
|
33
|
+
|
|
34
|
+
if not is_converter and origin is not Literal:
|
|
35
|
+
msg = f"Callable or literal excepted, got {type(converter_or_literal)}"
|
|
36
|
+
raise TypeError(msg)
|
|
37
|
+
|
|
38
|
+
if is_converter:
|
|
39
|
+
instance.converter = cast("Converter[T]", converter_or_literal)
|
|
40
|
+
return instance
|
|
41
|
+
|
|
42
|
+
literal_values = cast("tuple[object, ...]", get_args(converter_or_literal))
|
|
43
|
+
|
|
44
|
+
for value in literal_values:
|
|
45
|
+
if type(value) is not type(literal_values[0]):
|
|
46
|
+
msg = (
|
|
47
|
+
"Literal should have items of only one type. "
|
|
48
|
+
f"Excepted {type(literal_values[0])}, found {type(value)}"
|
|
49
|
+
)
|
|
50
|
+
raise TypeError(msg)
|
|
51
|
+
|
|
52
|
+
instance.converter = cast("Converter[T]", type(literal_values[0]))
|
|
53
|
+
|
|
54
|
+
return instance
|
|
55
|
+
|
|
56
|
+
def __call__(self, value: T) -> Entry[T]:
|
|
57
|
+
return Entry(self.__str__(), value)
|
|
58
|
+
|
|
59
|
+
def parse_entry(self, entry: Entry[T] | str) -> T:
|
|
60
|
+
return parse_entry(entry, self.converter)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class Entry[T](str):
|
|
64
|
+
__slots__ = ("key", "value")
|
|
65
|
+
key: str
|
|
66
|
+
value: T
|
|
67
|
+
|
|
68
|
+
def __new__(cls, key: str, value: T) -> Self:
|
|
69
|
+
instance = super().__new__(cls, f"{key}{value}")
|
|
70
|
+
instance.key = key
|
|
71
|
+
instance.value = value
|
|
72
|
+
return instance
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: microconst
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Library for optimizing enum constant values
|
|
5
|
+
Author-email: triple-raze <weebucks2@gmail.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/triple-raze/microconst
|
|
8
|
+
Project-URL: Repository, https://github.com/triple-raze/microconst.git
|
|
9
|
+
Project-URL: Issues, https://github.com/triple-raze/microconst/issues
|
|
10
|
+
Keywords: enum,compact
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
18
|
+
Classifier: Topic :: Utilities
|
|
19
|
+
Classifier: Typing :: Typed
|
|
20
|
+
Requires-Python: >=3.12
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
|
|
23
|
+
# microconst
|
|
24
|
+
[](https://pypi.org/project/microconst/)
|
|
25
|
+

|
|
26
|
+

|
|
27
|
+

|
|
28
|
+

|
|
29
|
+
|
|
30
|
+
Replace long constant names with 2 ASCII characters
|
|
31
|
+
|
|
32
|
+
## Installation
|
|
33
|
+
pip:
|
|
34
|
+
```
|
|
35
|
+
pip install microconst
|
|
36
|
+
```
|
|
37
|
+
poetry:
|
|
38
|
+
```
|
|
39
|
+
poetry add microconst
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Features
|
|
43
|
+
#### Constants
|
|
44
|
+
Every call of `flag` or `key` generates 2-character constant. This constant is represented as left and right indexes of `f"{ascii_letters}{digits}"` str. Each time the left index reaches cap, it resets to 0 and right index increments.<br>
|
|
45
|
+
After reaching both of caps, next call of function will throw `OverflowError`. Current maximum count of constants is 3844.
|
|
46
|
+
|
|
47
|
+
#### Typing
|
|
48
|
+
`key` function requires `value_type` argument, such as `str`, `int` etc. This type used in both static analysis and type conversion with `Key.parse_entry` function.
|
|
49
|
+
|
|
50
|
+
## Examples
|
|
51
|
+
Main purpose of this library is making telegram bot's "callback_data" much more compact because of 64-byte limit. You can see more realistic example [here](example)<br><br>
|
|
52
|
+
#### Flag usage
|
|
53
|
+
Before:
|
|
54
|
+
```python
|
|
55
|
+
from enum import StrEnum, auto
|
|
56
|
+
|
|
57
|
+
# Some very strict limit
|
|
58
|
+
MAX_LEN: int = 4
|
|
59
|
+
|
|
60
|
+
class Status(StrEnum):
|
|
61
|
+
PENDING = auto()
|
|
62
|
+
APPROVED = auto()
|
|
63
|
+
REJECTED = auto()
|
|
64
|
+
|
|
65
|
+
assert Status.PENDING == "pending"
|
|
66
|
+
assert len(Status.PENDING) > MAX_LEN # Too long
|
|
67
|
+
```
|
|
68
|
+
After:
|
|
69
|
+
```python
|
|
70
|
+
from microconst import flag
|
|
71
|
+
|
|
72
|
+
MAX_LEN: int = 4
|
|
73
|
+
|
|
74
|
+
# Autogenerates unique pairs of characters
|
|
75
|
+
class Status:
|
|
76
|
+
PENDING = flag()
|
|
77
|
+
APPROVED = flag()
|
|
78
|
+
REJECTED = flag()
|
|
79
|
+
|
|
80
|
+
assert Status.PENDING == "aa"
|
|
81
|
+
assert len(Status.PENDING) < MAX_LEN
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
#### Key usage
|
|
85
|
+
Before:
|
|
86
|
+
```python
|
|
87
|
+
from enum import StrEnum, auto
|
|
88
|
+
|
|
89
|
+
class Data(StrEnum):
|
|
90
|
+
USERNAME = auto()
|
|
91
|
+
ORDER = auto()
|
|
92
|
+
|
|
93
|
+
# You should use separator because of varying character count in key
|
|
94
|
+
username = Data.USERNAME + ":" + "name"
|
|
95
|
+
assert username == "username:name" # Too long
|
|
96
|
+
|
|
97
|
+
value = username.split(":")[1]
|
|
98
|
+
assert value == "name"
|
|
99
|
+
|
|
100
|
+
order = Data.ORDER + ":" + str(1337)
|
|
101
|
+
assert order == "order:1337"
|
|
102
|
+
|
|
103
|
+
# Order doesnt contain its type anywhere, so you should convert types each time
|
|
104
|
+
assert int(order.split(":")[1]) == 1337
|
|
105
|
+
|
|
106
|
+
```
|
|
107
|
+
After:
|
|
108
|
+
```python
|
|
109
|
+
from microconst import key, parse_entry
|
|
110
|
+
|
|
111
|
+
class Data:
|
|
112
|
+
USERNAME = key(str)
|
|
113
|
+
ORDER = key(int)
|
|
114
|
+
|
|
115
|
+
# You can call keys to create key-value pair (acts same as concat)
|
|
116
|
+
username = Data.USERNAME("name")
|
|
117
|
+
assert username == "aaname"
|
|
118
|
+
|
|
119
|
+
# Getting value
|
|
120
|
+
value = Data.USERNAME.parse_entry(username)
|
|
121
|
+
assert value == "name"
|
|
122
|
+
|
|
123
|
+
order = Data.ORDER(1337)
|
|
124
|
+
assert order == "ba1337"
|
|
125
|
+
|
|
126
|
+
# You can use separate function or method. Method doesnt require type argument
|
|
127
|
+
assert parse_entry(order, int) == 1337
|
|
128
|
+
assert Data.ORDER.parse_entry(order) == 1337
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
#### Key usage (literals)
|
|
132
|
+
Unique feature, it's hard to implement, so no comprasion before and after:
|
|
133
|
+
```python
|
|
134
|
+
from microconst import key, parse_entry
|
|
135
|
+
|
|
136
|
+
class Data:
|
|
137
|
+
ORDER = key(Literal[1, 2, 3])
|
|
138
|
+
|
|
139
|
+
assert Data.ORDER(1) == "aa1"
|
|
140
|
+
# assert Data.ORDER(4) == "aa4" # Mypy error
|
|
141
|
+
|
|
142
|
+
assert Data.ORDER.parse_entry("__3") == 3
|
|
143
|
+
# assert Data.ORDER.parse_entry("__10") == 10 # Mypy error
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## License
|
|
147
|
+
MIT
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
README.md
|
|
2
2
|
pyproject.toml
|
|
3
3
|
microconst/__init__.py
|
|
4
|
-
microconst/
|
|
5
|
-
microconst/
|
|
6
|
-
microconst/members.py
|
|
4
|
+
microconst/const.py
|
|
5
|
+
microconst/factories.py
|
|
7
6
|
microconst/py.typed
|
|
7
|
+
microconst/types.py
|
|
8
|
+
microconst/utils.py
|
|
8
9
|
microconst.egg-info/PKG-INFO
|
|
9
10
|
microconst.egg-info/SOURCES.txt
|
|
10
11
|
microconst.egg-info/dependency_links.txt
|
|
@@ -17,13 +17,15 @@ ignore = [
|
|
|
17
17
|
|
|
18
18
|
[tool.mypy]
|
|
19
19
|
exclude = ["example/"]
|
|
20
|
+
enable_incomplete_feature = ["TypeForm"]
|
|
21
|
+
|
|
20
22
|
strict = true
|
|
21
23
|
|
|
22
24
|
disallow_untyped_defs = true
|
|
23
25
|
disallow_untyped_calls = true
|
|
24
26
|
check_untyped_defs = true
|
|
25
27
|
|
|
26
|
-
warn_return_any = true
|
|
28
|
+
warn_return_any = true
|
|
27
29
|
disallow_any_explicit = true
|
|
28
30
|
disallow_any_unimported = true
|
|
29
31
|
disallow_any_decorated = true
|
|
@@ -45,19 +47,18 @@ build-backend = "setuptools.build_meta"
|
|
|
45
47
|
|
|
46
48
|
[project]
|
|
47
49
|
name = "microconst"
|
|
48
|
-
version = "0.
|
|
50
|
+
version = "0.2.0"
|
|
49
51
|
description = "Library for optimizing enum constant values"
|
|
50
52
|
|
|
51
53
|
requires-python = ">=3.12"
|
|
52
54
|
|
|
53
55
|
readme = "README.md"
|
|
54
|
-
license =
|
|
56
|
+
license = "MIT"
|
|
55
57
|
authors = [{name = "triple-raze", email = "weebucks2@gmail.com"}]
|
|
56
58
|
|
|
57
59
|
classifiers = [
|
|
58
60
|
"Development Status :: 4 - Beta",
|
|
59
61
|
"Intended Audience :: Developers",
|
|
60
|
-
"License :: OSI Approved :: MIT License",
|
|
61
62
|
"Programming Language :: Python :: 3.12",
|
|
62
63
|
"Programming Language :: Python :: 3.13",
|
|
63
64
|
"Programming Language :: Python :: 3.14",
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
from typing import Literal
|
|
2
|
+
|
|
3
|
+
from microconst import flag, key, parse_entry
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def test_member_creation() -> None:
|
|
7
|
+
assert key(int)(10) == "aa10"
|
|
8
|
+
|
|
9
|
+
assert key(str)("hello") == "bahello"
|
|
10
|
+
|
|
11
|
+
assert key(float)(14.1) == "ca14.1"
|
|
12
|
+
|
|
13
|
+
assert flag() == "da"
|
|
14
|
+
assert flag() == "ea"
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def test_value_extraction() -> None:
|
|
18
|
+
int_k = key(int)
|
|
19
|
+
data = int_k(123)
|
|
20
|
+
|
|
21
|
+
assert int_k.parse_entry(data) == 123
|
|
22
|
+
|
|
23
|
+
assert data.value == 123
|
|
24
|
+
|
|
25
|
+
assert parse_entry("__1.2", float) == 1.2
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def test_literal_key() -> None:
|
|
29
|
+
int_k = key(Literal[1, 2, 3])
|
|
30
|
+
assert int_k(3)
|
|
31
|
+
|
|
32
|
+
str_k = key(Literal["hi", "hello", "greetings"])
|
|
33
|
+
assert str_k.parse_entry("__hi") == "hi"
|
microconst-0.1.0/PKG-INFO
DELETED
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: microconst
|
|
3
|
-
Version: 0.1.0
|
|
4
|
-
Summary: Library for optimizing enum constant values
|
|
5
|
-
Author-email: triple-raze <weebucks2@gmail.com>
|
|
6
|
-
License: MIT
|
|
7
|
-
Project-URL: Homepage, https://github.com/triple-raze/microconst
|
|
8
|
-
Project-URL: Repository, https://github.com/triple-raze/microconst.git
|
|
9
|
-
Project-URL: Issues, https://github.com/triple-raze/microconst/issues
|
|
10
|
-
Keywords: enum,compact
|
|
11
|
-
Classifier: Development Status :: 4 - Beta
|
|
12
|
-
Classifier: Intended Audience :: Developers
|
|
13
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
-
Classifier: Programming Language :: Python :: 3.13
|
|
16
|
-
Classifier: Programming Language :: Python :: 3.14
|
|
17
|
-
Classifier: Operating System :: OS Independent
|
|
18
|
-
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
19
|
-
Classifier: Topic :: Utilities
|
|
20
|
-
Classifier: Typing :: Typed
|
|
21
|
-
Requires-Python: >=3.12
|
|
22
|
-
Description-Content-Type: text/markdown
|
|
23
|
-
|
|
24
|
-
# microconst
|
|
25
|
-
[](https://pypi.org/project/microconst/)
|
|
26
|
-

|
|
27
|
-

|
|
28
|
-

|
|
29
|
-

|
|
30
|
-
|
|
31
|
-
Replace long constant names with 2 ASCII keys
|
|
32
|
-
|
|
33
|
-
## Installation
|
|
34
|
-
pip:
|
|
35
|
-
```
|
|
36
|
-
pip install microconst
|
|
37
|
-
```
|
|
38
|
-
poetry:
|
|
39
|
-
```
|
|
40
|
-
poetry add microconst
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
## Features
|
|
44
|
-
#### Constants
|
|
45
|
-
Every call of `flag` or `key` generates 2-character key. This key is represented as left and right indexes of `f"{ascii_letters}{digits}"` str. Each time the left index reaches cap, it resets to 0 and right index increments.<br>
|
|
46
|
-
After reaching both of caps, next call of function will throw `OverflowError`. Current maximum count of keys is 3844.
|
|
47
|
-
|
|
48
|
-
#### Typing
|
|
49
|
-
`key` function requires `value_type` argument, such as `str`, `int` etc. This type used in both static analysis and type convertion with `Key.parse_entry(data)` function.
|
|
50
|
-
|
|
51
|
-
## Examples
|
|
52
|
-
Main purpose of this library is making telegram bot's "callback_data" much more compact because of 64-byte limit. You can see more realistic example [here](example)<br><br>
|
|
53
|
-
#### Flag usage:
|
|
54
|
-
```python
|
|
55
|
-
from microconst import flag
|
|
56
|
-
|
|
57
|
-
# Autogenerates unique pairs of characters
|
|
58
|
-
class Status:
|
|
59
|
-
PENDING = flag()
|
|
60
|
-
APPROVED = flag()
|
|
61
|
-
REJECTED = flag()
|
|
62
|
-
|
|
63
|
-
assert Status.PENDING == "aa"
|
|
64
|
-
assert Status.APPROVED == "ba"
|
|
65
|
-
assert Status.REJECTED == "ca"
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
#### Key usage:
|
|
69
|
-
```python
|
|
70
|
-
from microconst import key, parse_entry
|
|
71
|
-
|
|
72
|
-
USER = key(str)
|
|
73
|
-
|
|
74
|
-
# You can call keys to create key-value pair (acts same as concat)
|
|
75
|
-
username = USER("name")
|
|
76
|
-
# Getting value
|
|
77
|
-
value = USER.parse_entry(username)
|
|
78
|
-
|
|
79
|
-
assert username == "aaname"
|
|
80
|
-
assert value == "name"
|
|
81
|
-
|
|
82
|
-
# You can use seperate function or method. Method doesnt require type argument
|
|
83
|
-
assert parse_entry(username, str) == value
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
## License
|
|
87
|
-
MIT
|
microconst-0.1.0/README.md
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
# microconst
|
|
2
|
-
[](https://pypi.org/project/microconst/)
|
|
3
|
-

|
|
4
|
-

|
|
5
|
-

|
|
6
|
-

|
|
7
|
-
|
|
8
|
-
Replace long constant names with 2 ASCII keys
|
|
9
|
-
|
|
10
|
-
## Installation
|
|
11
|
-
pip:
|
|
12
|
-
```
|
|
13
|
-
pip install microconst
|
|
14
|
-
```
|
|
15
|
-
poetry:
|
|
16
|
-
```
|
|
17
|
-
poetry add microconst
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
## Features
|
|
21
|
-
#### Constants
|
|
22
|
-
Every call of `flag` or `key` generates 2-character key. This key is represented as left and right indexes of `f"{ascii_letters}{digits}"` str. Each time the left index reaches cap, it resets to 0 and right index increments.<br>
|
|
23
|
-
After reaching both of caps, next call of function will throw `OverflowError`. Current maximum count of keys is 3844.
|
|
24
|
-
|
|
25
|
-
#### Typing
|
|
26
|
-
`key` function requires `value_type` argument, such as `str`, `int` etc. This type used in both static analysis and type convertion with `Key.parse_entry(data)` function.
|
|
27
|
-
|
|
28
|
-
## Examples
|
|
29
|
-
Main purpose of this library is making telegram bot's "callback_data" much more compact because of 64-byte limit. You can see more realistic example [here](example)<br><br>
|
|
30
|
-
#### Flag usage:
|
|
31
|
-
```python
|
|
32
|
-
from microconst import flag
|
|
33
|
-
|
|
34
|
-
# Autogenerates unique pairs of characters
|
|
35
|
-
class Status:
|
|
36
|
-
PENDING = flag()
|
|
37
|
-
APPROVED = flag()
|
|
38
|
-
REJECTED = flag()
|
|
39
|
-
|
|
40
|
-
assert Status.PENDING == "aa"
|
|
41
|
-
assert Status.APPROVED == "ba"
|
|
42
|
-
assert Status.REJECTED == "ca"
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
#### Key usage:
|
|
46
|
-
```python
|
|
47
|
-
from microconst import key, parse_entry
|
|
48
|
-
|
|
49
|
-
USER = key(str)
|
|
50
|
-
|
|
51
|
-
# You can call keys to create key-value pair (acts same as concat)
|
|
52
|
-
username = USER("name")
|
|
53
|
-
# Getting value
|
|
54
|
-
value = USER.parse_entry(username)
|
|
55
|
-
|
|
56
|
-
assert username == "aaname"
|
|
57
|
-
assert value == "name"
|
|
58
|
-
|
|
59
|
-
# You can use seperate function or method. Method doesnt require type argument
|
|
60
|
-
assert parse_entry(username, str) == value
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
## License
|
|
64
|
-
MIT
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
from collections.abc import Generator
|
|
2
|
-
from string import ascii_letters, digits
|
|
3
|
-
|
|
4
|
-
CHARACTERS = f"{ascii_letters}{digits}"
|
|
5
|
-
|
|
6
|
-
MAX_IDX = len(CHARACTERS) - 1
|
|
7
|
-
MAX_KEYS = len(CHARACTERS) ** 2
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
def create_unique_key_generator() -> Generator[str, None, None]:
|
|
11
|
-
left_idx: int = 0
|
|
12
|
-
right_idx: int = 0
|
|
13
|
-
|
|
14
|
-
while right_idx != MAX_IDX + 1:
|
|
15
|
-
pair: str = CHARACTERS[left_idx] + CHARACTERS[right_idx]
|
|
16
|
-
|
|
17
|
-
if left_idx == MAX_IDX:
|
|
18
|
-
left_idx = 0
|
|
19
|
-
right_idx += 1
|
|
20
|
-
else:
|
|
21
|
-
left_idx += 1
|
|
22
|
-
|
|
23
|
-
yield pair
|
|
24
|
-
|
|
25
|
-
msg = f"cannot create more than {MAX_KEYS} keys"
|
|
26
|
-
raise OverflowError(msg)
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
unique_key_generator = create_unique_key_generator()
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
from collections.abc import Callable
|
|
2
|
-
from typing import Self
|
|
3
|
-
|
|
4
|
-
from microconst.entry import parse_entry
|
|
5
|
-
from microconst.key import unique_key_generator
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class Key[T](str):
|
|
9
|
-
# Subclasses of str should define __slots__
|
|
10
|
-
__slots__ = ("type",)
|
|
11
|
-
# We'll assign to this in __new__
|
|
12
|
-
type: Callable[[str], T]
|
|
13
|
-
|
|
14
|
-
def __new__(cls, name: str, value_type: Callable[[str], T]) -> Self:
|
|
15
|
-
instance = super().__new__(cls, name)
|
|
16
|
-
instance.type = value_type
|
|
17
|
-
return instance
|
|
18
|
-
|
|
19
|
-
def __call__(self, value: T) -> str:
|
|
20
|
-
return f"{self}{value}"
|
|
21
|
-
|
|
22
|
-
def parse_entry(self, data: str) -> T:
|
|
23
|
-
return parse_entry(data, self.type)
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
def create_flag() -> str:
|
|
27
|
-
return next(unique_key_generator)
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
def create_key[T](value_type: type[T]) -> Key[T]:
|
|
31
|
-
name = next(unique_key_generator)
|
|
32
|
-
return Key(name, value_type)
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: microconst
|
|
3
|
-
Version: 0.1.0
|
|
4
|
-
Summary: Library for optimizing enum constant values
|
|
5
|
-
Author-email: triple-raze <weebucks2@gmail.com>
|
|
6
|
-
License: MIT
|
|
7
|
-
Project-URL: Homepage, https://github.com/triple-raze/microconst
|
|
8
|
-
Project-URL: Repository, https://github.com/triple-raze/microconst.git
|
|
9
|
-
Project-URL: Issues, https://github.com/triple-raze/microconst/issues
|
|
10
|
-
Keywords: enum,compact
|
|
11
|
-
Classifier: Development Status :: 4 - Beta
|
|
12
|
-
Classifier: Intended Audience :: Developers
|
|
13
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
-
Classifier: Programming Language :: Python :: 3.13
|
|
16
|
-
Classifier: Programming Language :: Python :: 3.14
|
|
17
|
-
Classifier: Operating System :: OS Independent
|
|
18
|
-
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
19
|
-
Classifier: Topic :: Utilities
|
|
20
|
-
Classifier: Typing :: Typed
|
|
21
|
-
Requires-Python: >=3.12
|
|
22
|
-
Description-Content-Type: text/markdown
|
|
23
|
-
|
|
24
|
-
# microconst
|
|
25
|
-
[](https://pypi.org/project/microconst/)
|
|
26
|
-

|
|
27
|
-

|
|
28
|
-

|
|
29
|
-

|
|
30
|
-
|
|
31
|
-
Replace long constant names with 2 ASCII keys
|
|
32
|
-
|
|
33
|
-
## Installation
|
|
34
|
-
pip:
|
|
35
|
-
```
|
|
36
|
-
pip install microconst
|
|
37
|
-
```
|
|
38
|
-
poetry:
|
|
39
|
-
```
|
|
40
|
-
poetry add microconst
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
## Features
|
|
44
|
-
#### Constants
|
|
45
|
-
Every call of `flag` or `key` generates 2-character key. This key is represented as left and right indexes of `f"{ascii_letters}{digits}"` str. Each time the left index reaches cap, it resets to 0 and right index increments.<br>
|
|
46
|
-
After reaching both of caps, next call of function will throw `OverflowError`. Current maximum count of keys is 3844.
|
|
47
|
-
|
|
48
|
-
#### Typing
|
|
49
|
-
`key` function requires `value_type` argument, such as `str`, `int` etc. This type used in both static analysis and type convertion with `Key.parse_entry(data)` function.
|
|
50
|
-
|
|
51
|
-
## Examples
|
|
52
|
-
Main purpose of this library is making telegram bot's "callback_data" much more compact because of 64-byte limit. You can see more realistic example [here](example)<br><br>
|
|
53
|
-
#### Flag usage:
|
|
54
|
-
```python
|
|
55
|
-
from microconst import flag
|
|
56
|
-
|
|
57
|
-
# Autogenerates unique pairs of characters
|
|
58
|
-
class Status:
|
|
59
|
-
PENDING = flag()
|
|
60
|
-
APPROVED = flag()
|
|
61
|
-
REJECTED = flag()
|
|
62
|
-
|
|
63
|
-
assert Status.PENDING == "aa"
|
|
64
|
-
assert Status.APPROVED == "ba"
|
|
65
|
-
assert Status.REJECTED == "ca"
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
#### Key usage:
|
|
69
|
-
```python
|
|
70
|
-
from microconst import key, parse_entry
|
|
71
|
-
|
|
72
|
-
USER = key(str)
|
|
73
|
-
|
|
74
|
-
# You can call keys to create key-value pair (acts same as concat)
|
|
75
|
-
username = USER("name")
|
|
76
|
-
# Getting value
|
|
77
|
-
value = USER.parse_entry(username)
|
|
78
|
-
|
|
79
|
-
assert username == "aaname"
|
|
80
|
-
assert value == "name"
|
|
81
|
-
|
|
82
|
-
# You can use seperate function or method. Method doesnt require type argument
|
|
83
|
-
assert parse_entry(username, str) == value
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
## License
|
|
87
|
-
MIT
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
from microconst import flag, key, parse_entry
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
def test_member_creation() -> None:
|
|
5
|
-
assert key(int)(10) == "aa10"
|
|
6
|
-
|
|
7
|
-
assert key(str)("hello") == "bahello"
|
|
8
|
-
|
|
9
|
-
assert key(float)(14.1) == "ca14.1"
|
|
10
|
-
|
|
11
|
-
assert flag() == "da"
|
|
12
|
-
assert flag() == "ea"
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
def test_value_extraction() -> None:
|
|
16
|
-
int_key = key(int)
|
|
17
|
-
data = int_key(123)
|
|
18
|
-
|
|
19
|
-
assert int_key.parse_entry(data) == 123
|
|
20
|
-
|
|
21
|
-
assert parse_entry("aa1.2", float) == 1.2
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|