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.
@@ -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
+ [![pypi](https://img.shields.io/pypi/v/microconst)](https://pypi.org/project/microconst/)
25
+ ![python](https://img.shields.io/badge/python-3.12+-blue?logo=python)
26
+ ![typed](https://img.shields.io/badge/typed-yes-blue)
27
+ ![tests](https://img.shields.io/badge/tests-manual-green)
28
+ ![license](https://img.shields.io/badge/license-MIT-blue)
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
+ [![pypi](https://img.shields.io/pypi/v/microconst)](https://pypi.org/project/microconst/)
3
+ ![python](https://img.shields.io/badge/python-3.12+-blue?logo=python)
4
+ ![typed](https://img.shields.io/badge/typed-yes-blue)
5
+ ![tests](https://img.shields.io/badge/tests-manual-green)
6
+ ![license](https://img.shields.io/badge/license-MIT-blue)
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,6 @@
1
+ from microconst.factories import create_flag as flag
2
+ from microconst.factories import create_key as key
3
+ from microconst.types import Entry, Key
4
+ from microconst.utils import parse_entry
5
+
6
+ __all__ = ["Entry", "Key", "flag", "key", "parse_entry"]
@@ -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,11 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING
4
+
5
+ if TYPE_CHECKING:
6
+ from microconst.types import Converter
7
+
8
+
9
+ def parse_entry[T](data: str, convert: Converter[T]) -> T:
10
+ str_value = data[2:]
11
+ return convert(str_value)
@@ -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
+ [![pypi](https://img.shields.io/pypi/v/microconst)](https://pypi.org/project/microconst/)
25
+ ![python](https://img.shields.io/badge/python-3.12+-blue?logo=python)
26
+ ![typed](https://img.shields.io/badge/typed-yes-blue)
27
+ ![tests](https://img.shields.io/badge/tests-manual-green)
28
+ ![license](https://img.shields.io/badge/license-MIT-blue)
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/entry.py
5
- microconst/key.py
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.1.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 = {text = "MIT"}
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
- [![pypi](https://img.shields.io/pypi/v/microconst)](https://pypi.org/project/microconst/)
26
- ![python](https://img.shields.io/badge/python-3.12+-blue?logo=python)
27
- ![typed](https://img.shields.io/badge/typed-yes-blue)
28
- ![tests](https://img.shields.io/badge/tests-manual-green)
29
- ![license](https://img.shields.io/badge/license-MIT-blue)
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,64 +0,0 @@
1
- # microconst
2
- [![pypi](https://img.shields.io/pypi/v/microconst)](https://pypi.org/project/microconst/)
3
- ![python](https://img.shields.io/badge/python-3.12+-blue?logo=python)
4
- ![typed](https://img.shields.io/badge/typed-yes-blue)
5
- ![tests](https://img.shields.io/badge/tests-manual-green)
6
- ![license](https://img.shields.io/badge/license-MIT-blue)
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,6 +0,0 @@
1
- from microconst.entry import parse_entry
2
- from microconst.members import Key
3
- from microconst.members import create_flag as flag
4
- from microconst.members import create_key as key
5
-
6
- __all__ = ["Key", "flag", "key", "parse_entry"]
@@ -1,6 +0,0 @@
1
- from collections.abc import Callable
2
-
3
-
4
- def parse_entry[T](data: str, value_type: Callable[[str], T]) -> T:
5
- str_value = data[2:]
6
- return value_type(str_value)
@@ -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
- [![pypi](https://img.shields.io/pypi/v/microconst)](https://pypi.org/project/microconst/)
26
- ![python](https://img.shields.io/badge/python-3.12+-blue?logo=python)
27
- ![typed](https://img.shields.io/badge/typed-yes-blue)
28
- ![tests](https://img.shields.io/badge/tests-manual-green)
29
- ![license](https://img.shields.io/badge/license-MIT-blue)
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