UnityManager 0.0.1a1__py3-none-any.whl

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,41 @@
1
+ """Utilities for formatting common units.
2
+
3
+ The package exposes byte, length, capacity, mass and volume formatters at the
4
+ package level for convenient imports.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import re
10
+ import sys
11
+
12
+ from .bytes import format_bytes
13
+ from .length import format_length
14
+ from .measure import format_capacity, format_mass, format_volume
15
+
16
+ __version__ = "0.0.1-alpha1"
17
+ __author__ = "PlayGames-2020"
18
+ __summary__ = "Utilities for formatting common units."
19
+
20
+ _match = re.match(r"(\d+)\.(\d+)\.(\d+)(?:-(.+))?", __version__)
21
+
22
+ if _match: major, minor, patch, tag = _match.groups()
23
+ else: major, minor, patch, tag = 0, 0, 0, "unknown"
24
+
25
+ VERSION_INFO = (int(major), int(minor), int(patch), tag or "release")
26
+
27
+ NAME = __name__
28
+
29
+ _REQUIRED_PY = (3, 9)
30
+ if sys.version_info < (3, 9):
31
+ runtime = ".".join(str(v) for v in (_REQUIRED_PY))
32
+ info = f"{__name__} requires Python {runtime} or higher" \
33
+ f"(current: {sys.version.split()[0]})"
34
+ print(info)
35
+ raise RuntimeError(info)
36
+
37
+
38
+ __all__ = [
39
+ "__version__", "VERSION_INFO", "NAME",
40
+ "format_volume", "format_mass", "format_capacity", "format_length", "format_bytes"
41
+ ]
UnityManager/_units.py ADDED
@@ -0,0 +1,60 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import List, Literal, Tuple, Union
4
+
5
+ _Mode = Union[str, Literal["n", "s", "d", "v", "lower", "upper", "title"]]
6
+ _TextMode = _Mode
7
+ _MeasureTextMode = _TextMode
8
+ _BytesTextMode = Union[str, Literal["s", "n", "d", "upper", "lower", "title", "byte", "bit"]]
9
+
10
+ _BYTES_TABLE: List[Tuple[str, str, Union[int, float], str]] = [
11
+ ("zettabyte", "ZB", 1024**7, ""),
12
+ ("exabyte", "EB", 1024**6, ""),
13
+ ("petabyte", "PB", 1024**5, ""),
14
+ ("terabyte", "TB", 1024**4, ""),
15
+ ("gigabyte", "GB", 1024**3, ""),
16
+ ("megabyte", "MB", 1024**2, ""),
17
+ ("kilobyte", "KB", 1024, ""),
18
+ ("byte", "B", 1, ""),
19
+ ("bit", "b", 1 / 8, ""),
20
+ ]
21
+
22
+ _LENGTH_TABLE: List[Tuple[str, str, float, str]] = [
23
+ ("kilometre", "km", 1000.0, ""),
24
+ ("hectometre", "hm", 100.0, ""),
25
+ ("decametre", "dam", 10.0, ""),
26
+ ("metre", "m", 1.0, ""),
27
+ ("decimetre", "dm", 0.1, ""),
28
+ ("centimetre", "cm", 0.01, ""),
29
+ ("millimetre", "mm", 0.001, ""),
30
+ ]
31
+
32
+ _CAPACITY_TABLE: List[Tuple[str, str, float, str]] = [
33
+ ("kilolitre", "kl", 1000.0, ""),
34
+ ("hectolitre", "hl", 100.0, ""),
35
+ ("decalitre", "dal", 10.0, ""),
36
+ ("litre", "l", 1.0, ""),
37
+ ("decilitre", "dl", 0.1, ""),
38
+ ("centilitre", "cl", 0.01, ""),
39
+ ("millilitre", "ml", 0.001, ""),
40
+ ]
41
+
42
+ _MASS_TABLE: List[Tuple[str, str, float, str]] = [
43
+ ("kilogram", "kg", 1000.0, ""),
44
+ ("hectogram", "hg", 100.0, ""),
45
+ ("decagram", "dag", 10.0, ""),
46
+ ("gram", "g", 1.0, ""),
47
+ ("decigram", "dg", 0.1, ""),
48
+ ("centigram", "cg", 0.01, ""),
49
+ ("milligram", "mg", 0.001, ""),
50
+ ]
51
+
52
+ _VOLUME_TABLE: List[Tuple[str, str, Union[int, float], str]] = [
53
+ ("kilometre cubic", "km³", 1_000_000_000.0, ""),
54
+ ("hectometre cubic", "hm³", 1_000_000.0, ""),
55
+ ("decametre cubic", "dam³", 1_000.0, ""),
56
+ ("metre cubic", "m³", 1.0, ""),
57
+ ("decimetre cubic", "dm³", 0.001, ""),
58
+ ("centimetre cubic", "cm³", 0.000_001, ""),
59
+ ("millimetre cubic", "mm³", 0.000_000_001, ""),
60
+ ]
UnityManager/bytes.py ADDED
@@ -0,0 +1,55 @@
1
+ """"""
2
+
3
+ from typing import Union, Any, List
4
+ from decimal import Decimal
5
+
6
+ from ._units import _BYTES_TABLE, _BytesTextMode
7
+
8
+ def format_bytes(n: Union[int, Any], mode: _BytesTextMode = "s") -> str:
9
+ """Format a byte value using binary units.
10
+
11
+ Values are divided by powers of 1024 and rounded to two decimals. The
12
+ default mode, ``"s"``, displays the unit symbol. ``"n"`` displays the
13
+ unit name, ``"d"`` its description, and ``"byte"`` or ``"bit"`` adds a
14
+ conversion note. Case modifiers can be combined with these modes.
15
+
16
+ Non-numeric values are returned as text.
17
+
18
+ Examples:
19
+ >>> format_bytes(1024)
20
+ '1.00 KB'
21
+ >>> format_bytes(1024, "n")
22
+ '1.00 kilobyte'
23
+ """
24
+ if not isinstance(n, (int, float, Decimal)): return str(n)
25
+
26
+ amount = Decimal(str(n))
27
+ abs_n = abs(amount)
28
+ unit_name: str
29
+ unit_symbol: str
30
+ unit_description: str
31
+ unit_name, unit_symbol, unit_description = "bit", "b", ""
32
+ for name, symbol, limit, description in _BYTES_TABLE:
33
+ _limit = Decimal(str(limit))
34
+ if abs_n >= limit:
35
+ amount = amount / _limit
36
+ unit_name, unit_symbol, unit_description = name, symbol, description
37
+ break
38
+
39
+ parts: List[str] = []
40
+
41
+ if "s" in mode: parts.append(unit_symbol)
42
+ if "n" in mode: parts.append(unit_name)
43
+ if "d" in mode: parts.append(unit_description)
44
+ if "upper" in mode: parts = [p.upper() for p in parts]
45
+ if "lower" in mode: parts = [p.lower() for p in parts]
46
+ if "title" in mode: parts = [p.title() for p in parts]
47
+ if "byte" in mode: parts.append(f"({n} bytes)")
48
+ if "bit" in mode: parts.append(f"({n / 8} bits)")
49
+
50
+ suffix = " ".join(parts)
51
+ return f"{amount:.2f}{f' {suffix}' if suffix else ''}"
52
+
53
+ __all__ = [
54
+ "format_bytes"
55
+ ]
UnityManager/length.py ADDED
@@ -0,0 +1,49 @@
1
+ """Format metric length quantities for display."""
2
+ from typing import Any, List, Literal, Union
3
+ from decimal import Decimal
4
+
5
+ from ._units import _LENGTH_TABLE, _TextMode
6
+ _LengthTextMode = _TextMode
7
+
8
+ def format_length(n: Union[int, Any], mode: _LengthTextMode = "s") -> str:
9
+ """Format a length in metric units, from millimetres to kilometres.
10
+
11
+ The input is interpreted as metres. The largest suitable unit is selected
12
+ automatically and the result is rounded to two decimal places. Use
13
+ ``"s"`` for the symbol, ``"n"`` for the name, ``"v"`` for the original
14
+ value, and combine these with ``"upper"``, ``"lower"`` or ``"title"``.
15
+
16
+ Non-numeric values are returned as text.
17
+ """
18
+ if not isinstance(n, (int, float, Decimal)): return str(n)
19
+
20
+ abs_n = abs(Decimal(str(n)))
21
+ amount = Decimal(str(n))
22
+ name, symbol, description = "metre", "m", ""
23
+
24
+ for name_item, symbol_item, limit, desc_item in _LENGTH_TABLE:
25
+ if limit >= 1 and abs_n >= Decimal(str(limit)):
26
+ amount = Decimal(str(n)) / Decimal(str(limit))
27
+ name, symbol, description = name_item, symbol_item, desc_item
28
+ break
29
+ elif limit < 1 and abs_n >= Decimal(str(limit)):
30
+ amount = Decimal(str(n)) / Decimal(str(limit))
31
+ name, symbol, description = name_item, symbol_item, desc_item
32
+ break
33
+
34
+ parts: List[str] = []
35
+ if "n" in mode: parts.append(name)
36
+ if "s" in mode: parts.append(symbol)
37
+ if "d" in mode: parts.append(description)
38
+ if "v" in mode: parts.append(f"({float(n)} m)")
39
+ if "lower" in mode: parts = [p.lower() for p in parts]
40
+ if "upper" in mode: parts = [p.upper() for p in parts]
41
+ if "title" in mode: parts = [p.title() for p in parts]
42
+
43
+ suffix = " ".join(parts).strip()
44
+ return f"{amount:.2f}{f' {suffix}' if suffix else ''}"
45
+
46
+
47
+ __all__ = [
48
+ "format_length"
49
+ ]
@@ -0,0 +1,49 @@
1
+ """Format capacity, mass and volume quantities for display."""
2
+ from typing import Any, List, Literal, Union, Tuple
3
+ from decimal import Decimal
4
+
5
+ from ._units import (
6
+ _CAPACITY_TABLE, _MASS_TABLE, _VOLUME_TABLE, _MeasureTextMode
7
+ )
8
+
9
+ def _generic_formatter(n: Union[int, Any], table: List[Tuple], default_unit: Tuple, base_symbol: str, mode: _MeasureTextMode = "s") -> str:
10
+ """Format a numeric measurement using the supplied unit table."""
11
+ if not isinstance(n, (int, float, Decimal)): return str(n)
12
+
13
+ abs_n = abs(Decimal(str(n)))
14
+ amount = Decimal(str(n))
15
+ name, symbol, description = default_unit
16
+
17
+ for name_item, symbol_item, limit, desc_item in table:
18
+ if abs_n >= Decimal(str(limit)):
19
+ amount = Decimal(str(n)) / Decimal(str(limit))
20
+ name, symbol, description = name_item, symbol_item, desc_item
21
+ break
22
+
23
+ parts: List[str] = []
24
+ if "n" in mode: parts.append(name)
25
+ if "s" in mode: parts.append(symbol)
26
+ if "d" in mode: parts.append(description)
27
+ if "v" in mode: parts.append(f"({float(n)} {base_symbol})")
28
+ if "lower" in mode: parts = [p.lower() for p in parts]
29
+ if "upper" in mode: parts = [p.upper() for p in parts]
30
+ if "title" in mode: parts = [p.title() for p in parts]
31
+
32
+ suffix = " ".join(parts).strip()
33
+ return f"{amount:.2f}{f' {suffix}' if suffix else ''}"
34
+
35
+ def format_capacity(n: Union[int, Any], mode: _MeasureTextMode = "s") -> str:
36
+ """Format a capacity expressed in litres."""
37
+ return _generic_formatter(n, _CAPACITY_TABLE, ("litre", "l", ""), "l", mode)
38
+
39
+ def format_mass(n: Union[int, Any], mode: _MeasureTextMode = "s") -> str:
40
+ """Format a mass expressed in grams."""
41
+ return _generic_formatter(n, _MASS_TABLE, ("gram", "g", ""), "g", mode)
42
+
43
+ def format_volume(n: Union[int, Any], mode: _MeasureTextMode = "s") -> str:
44
+ """Format a volume expressed in cubic metres."""
45
+ return _generic_formatter(n, _VOLUME_TABLE, ("metre cubic", "m³", ""), "m³", mode)
46
+
47
+ __all__ = [
48
+ "format_capacity", "format_mass", "format_volume"
49
+ ]
games/__init__.py ADDED
@@ -0,0 +1,11 @@
1
+ """Game-specific formatting helpers.
2
+
3
+ The public API currently provides :func:`format_money`, which formats large
4
+ in-game currency values using compact suffixes such as ``K`` and ``M``.
5
+ """
6
+
7
+ from .monetary import format_money
8
+
9
+ __all__ = [
10
+ "format_money"
11
+ ]
games/_units.py ADDED
@@ -0,0 +1,15 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import List, Tuple, Union
4
+ from UnityManager._units import _TextMode
5
+
6
+ _MoneyTextMode = _TextMode
7
+
8
+ _MONEY_TABLE: List[Tuple[str, str, Union[int, float], str]] = [
9
+ ("quadrillion", "Q", 10 ** 15, ""),
10
+ ("trillion", "T", 10 ** 12, ""),
11
+ ("billion", "B", 10 ** 9, ""),
12
+ ("million", "M", 10 ** 6, ""),
13
+ ("thousand", "K", 10 ** 3, ""),
14
+ ("", "", 1, ""),
15
+ ]
games/monetary.py ADDED
@@ -0,0 +1,58 @@
1
+ """Formatting helpers for in-game monetary values."""
2
+ from typing import Any, List, Literal, Union
3
+ from decimal import Decimal
4
+
5
+ from ._units import _MONEY_TABLE, _MoneyTextMode
6
+
7
+ def format_money(n: Union[int, Any], mode: _MoneyTextMode = "s") -> str:
8
+ """Format an in-game currency amount with a compact suffix.
9
+
10
+ Args:
11
+ n: Numeric amount in the base currency (gold by default). Non-numeric
12
+ values are returned unchanged as text.
13
+ mode: Controls the text appended to the formatted number. ``"s"``
14
+ adds the suffix symbol, ``"n"`` adds its name, ``"d"`` adds the
15
+ description, and ``"v"`` shows the original amount as gold.
16
+ Case modifiers ``"upper"``, ``"lower"`` and ``"title"`` can be
17
+ combined with the other modes.
18
+
19
+ Returns:
20
+ A string containing the amount rounded to two decimal places and the
21
+ requested currency text.
22
+
23
+ Examples:
24
+ >>> format_money(1500)
25
+ '1.50 K'
26
+ >>> format_money(2_000_000, "n")
27
+ '2.00 million'
28
+ >>> format_money(1500, "nsupper")
29
+ '1.50 THOUSAND K'
30
+ """
31
+ if not isinstance(n, (int, float, Decimal)): return str(n)
32
+
33
+ abs_n = abs(Decimal(str(n)))
34
+ amount = Decimal(str(n))
35
+ name, symbol, description = "", "", ""
36
+
37
+ for name_item, symbol_item, limit, desc_item in _MONEY_TABLE:
38
+ if abs_n >= Decimal(str(limit)):
39
+ amount = Decimal(str(n)) / Decimal(str(limit))
40
+ name, symbol, description = name_item, symbol_item, desc_item
41
+ break
42
+
43
+ parts: List[str] = []
44
+
45
+ if "n" in mode: parts.append(name)
46
+ if "s" in mode: parts.append(symbol)
47
+ if "d" in mode: parts.append(description)
48
+ if "v" in mode: parts.append(f"({n} gold)")
49
+ if "lower" in mode: parts = [p.lower() for p in parts]
50
+ if "upper" in mode: parts = [p.upper() for p in parts]
51
+ if "title" in mode: parts = [p.title() for p in parts]
52
+
53
+ suffix = " ".join(part for part in parts if part)
54
+ return f"{amount:.2f}{f' {suffix}' if suffix else ''}"
55
+
56
+ __all__ = [
57
+ "format_money"
58
+ ]
@@ -0,0 +1,249 @@
1
+ Metadata-Version: 2.4
2
+ Name: UnityManager
3
+ Version: 0.0.1a1
4
+ Summary: Utilities for formatting common units.
5
+ Project-URL: Homepage, https://github.com/PlayGames-2020/UnityManager
6
+ Project-URL: Repository, https://github.com/PlayGames-2020/UnityManager.git
7
+ Project-URL: Documentation, https://github.com/PlayGames-2020/UnityManager/blob/main/README.md
8
+ Project-URL: Authors, https://github.com/PlayGames-2020
9
+ Author-email: PlayGames-2020 <playgames16.01.2020@gmail.com>
10
+ License: MIT License
11
+
12
+ Copyright (c) 2026 PlayGames-2020
13
+
14
+ Permission is hereby granted, free of charge, to any person obtaining a copy
15
+ of this software and associated documentation files (the "Software"), to deal
16
+ in the Software without restriction, including without limitation the rights
17
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
18
+ copies of the Software, and to permit persons to whom the Software is
19
+ furnished to do so, subject to the following conditions:
20
+
21
+ The above copyright notice and this permission notice shall be included in all
22
+ copies or substantial portions of the Software.
23
+
24
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30
+ SOFTWARE.
31
+ License-File: LICENSE
32
+ Keywords: bytes,formatting,games,length,mass,money,units,volume
33
+ Classifier: Development Status :: 3 - Alpha
34
+ Classifier: Intended Audience :: Developers
35
+ Classifier: License :: OSI Approved :: MIT License
36
+ Classifier: Operating System :: OS Independent
37
+ Classifier: Programming Language :: Python :: 3
38
+ Classifier: Programming Language :: Python :: 3 :: Only
39
+ Classifier: Programming Language :: Python :: 3.9
40
+ Classifier: Programming Language :: Python :: 3.10
41
+ Classifier: Programming Language :: Python :: 3.11
42
+ Classifier: Programming Language :: Python :: 3.12
43
+ Classifier: Programming Language :: Python :: 3.13
44
+ Classifier: Programming Language :: Python :: 3.14
45
+ Requires-Python: >=3.9
46
+ Provides-Extra: dev
47
+ Requires-Dist: pytest>=8.4.2; extra == 'dev'
48
+ Description-Content-Type: text/markdown
49
+
50
+ # UnityManager
51
+
52
+ Utilities for formatting common units without runtime dependencies.
53
+
54
+ > **Status:** alpha (`0.0.1-alpha`). The API is still subject to change.
55
+
56
+ ## Requirements
57
+
58
+ - Python **3.9 or later**
59
+ - No runtime dependencies
60
+
61
+ ## Installation
62
+
63
+ ### GitHub
64
+
65
+ ``` bash
66
+ pip install git+https://github.com/PlayGames-2020/UnityManager.git
67
+ ```
68
+
69
+ or
70
+
71
+ ``` bash
72
+ pip install git+https://github.com/PlayGames-2020/UnityManager.git@master
73
+ ```
74
+
75
+ ### PyPI
76
+
77
+ ``` bash
78
+ pip install UnityManager
79
+ ```
80
+
81
+ To install the development dependencies:
82
+
83
+ ```bash
84
+ pip install "unitymanager[dev]"
85
+ ```
86
+
87
+ ## Quick start
88
+
89
+ ```python
90
+ from UnityManager import (
91
+ format_bytes,
92
+ format_capacity,
93
+ format_length,
94
+ format_mass,
95
+ format_volume,
96
+ )
97
+ from games import format_money
98
+
99
+ print(format_bytes(1024)) # 1.00 KB
100
+ print(format_length(1500)) # 1.50 km
101
+ print(format_capacity(2.5)) # 2.50 l
102
+ print(format_mass(2500)) # 2.50 kg
103
+ print(format_volume(1)) # 1.00 m³
104
+ print(format_money(1500)) # 1.50 K
105
+ ```
106
+
107
+ Each formatter accepts a text mode. The default mode `"s"` displays the unit symbol. Use `"n"` for the unit name, combine modes such as `"ns"`, or add `"upper"`, `"lower"`, `"title"` and `"v"` as needed.
108
+
109
+ ## Games package
110
+
111
+ The optional game-oriented API is available from the `games` package:
112
+
113
+ ```python
114
+ from games import format_money
115
+
116
+ format_money(999) # "999.00"
117
+ format_money(1_500) # "1.50 K"
118
+ format_money(2_000_000) # "2.00 M"
119
+ format_money(1_500, "n") # "1.50 thousand"
120
+ format_money(1_500, "ns") # "1.50 thousand K"
121
+ format_money(1_500, "v") # "1.50 (1500 gold)"
122
+ format_money(1_500, "nsupper") # "1.50 THOUSAND K"
123
+ ```
124
+
125
+ ### `format_money(value, mode="s")`
126
+
127
+ Formats a numeric amount in the base game currency, assumed to be gold. Values
128
+ are rounded to two decimal places and use the largest applicable suffix:
129
+
130
+ | Range | Name | Symbol |
131
+ | ---: | --- | :--- |
132
+ | 1,000 | thousand | `K` |
133
+ | 1,000,000 | million | `M` |
134
+ | 1,000,000,000 | billion | `B` |
135
+ | 1,000,000,000,000 | trillion | `T` |
136
+ | 1,000,000,000,000,000 | quadrillion | `Q` |
137
+
138
+ Supported mode components:
139
+
140
+ - `s`: append the compact symbol.
141
+ - `n`: append the full unit name.
142
+ - `d`: append the unit description (reserved for future descriptions).
143
+ - `v`: append the original value as gold.
144
+ - `upper`, `lower`, `title`: change the case of the appended text.
145
+
146
+ Modes can be combined, for example `"nsupper"`. Non-numeric values are returned
147
+ as text instead of raising an exception.
148
+
149
+ The formatter is intentionally currency-neutral in its arithmetic: it only
150
+ compacts the amount. The displayed base-currency label is currently `gold` and
151
+ can be extended in a future API version if games need coins, gems, credits or
152
+ other currencies.
153
+
154
+ ## UnityManager API
155
+
156
+ All public formatters return a string rounded to two decimal places. Numeric
157
+ inputs use the base unit described below; non-numeric inputs are returned using
158
+ `str(value)`.
159
+
160
+ ### `format_bytes(value, mode="s")`
161
+
162
+ Formats binary quantities using powers of 1024. The base input is bytes and the
163
+ available symbols include `B`, `KB`, `MB`, `GB`, `TB`, `PB`, `EB` and `ZB`.
164
+ The mode `"byte"` adds the original value in bytes, while `"bit"` adds its
165
+ corresponding bit value.
166
+
167
+ ```python
168
+ format_bytes(1024) # "1.00 KB"
169
+ format_bytes(1024, "n") # "1.00 kilobyte"
170
+ format_bytes(2048, "sbyte") # "2.00 KB (2048 bytes)"
171
+ ```
172
+
173
+ ### `format_length(value, mode="s")`
174
+
175
+ Formats a value expressed in metres using metric units from millimetres to
176
+ kilometres.
177
+
178
+ ```python
179
+ format_length(1_500) # "1.50 km"
180
+ format_length(1, "n") # "1.00 metre"
181
+ format_length(1, "nv") # "1.00 metre (1.0 m)"
182
+ ```
183
+
184
+ ### `format_capacity(value, mode="s")`
185
+
186
+ Formats a value expressed in litres, from millilitres to kilolitres.
187
+
188
+ ```python
189
+ format_capacity(2.5) # "2.50 l"
190
+ format_capacity(1_000, "n") # "1.00 kilolitre"
191
+ ```
192
+
193
+ ### `format_mass(value, mode="s")`
194
+
195
+ Formats a value expressed in grams, from milligrams to kilograms.
196
+
197
+ ```python
198
+ format_mass(2_500) # "2.50 kg"
199
+ format_mass(1, "n") # "1.00 gram"
200
+ ```
201
+
202
+ ### `format_volume(value, mode="s")`
203
+
204
+ Formats a value expressed in cubic metres, from cubic millimetres to cubic
205
+ kilometres.
206
+
207
+ ```python
208
+ format_volume(1) # "1.00 m³"
209
+ format_volume(0.000001) # "1.00 cm³"
210
+ ```
211
+
212
+ ### Text modes
213
+
214
+ The general formatters support these mode components:
215
+
216
+ - `s`: append the unit symbol (the default).
217
+ - `n`: append the full unit name.
218
+ - `d`: append the unit description, when available.
219
+ - `v`: append the original value in the base unit.
220
+ - `upper`, `lower`, `title`: change the case of the appended text.
221
+
222
+ Modes can be combined as a string, for example `"nsupper"`.
223
+
224
+ ## Supported formatters
225
+
226
+ - `format_bytes`: binary byte units (`B`, `KB`, `MB`, and so on).
227
+ - `format_length`: metric lengths from millimetres to kilometres.
228
+ - `format_capacity`: metric capacities from millilitres to kilolitres.
229
+ - `format_mass`: metric masses from milligrams to kilograms.
230
+ - `format_volume`: cubic metric units from cubic millimetres to cubic kilometres.
231
+ - `games.format_money`: compact game currency values (`K`, `M`, `B`, `T`, `Q`).
232
+
233
+ ## Development and testing
234
+
235
+ ```bash
236
+ git clone https://github.com/PlayGames-2020/UnityManager.git
237
+ cd UnityManager
238
+ pip install -e ".[dev]"
239
+ python -m pytest
240
+ ```
241
+
242
+ ## License
243
+
244
+ Distributed under the [MIT License](LICENSE).
245
+
246
+ ## Links
247
+
248
+ - [Repository](https://github.com/PlayGames-2020/UnityManager)
249
+ - [Documentation](https://github.com/PlayGames-2020/UnityManager/blob/main/README.md)
@@ -0,0 +1,12 @@
1
+ UnityManager/__init__.py,sha256=yGRnZMu8ccizXL8TVSKvu0iFIs_KLnALSgo44XKZOGM,1175
2
+ UnityManager/_units.py,sha256=3Bv4iPU7vnT8c5lvMxxhGwvdQBmeLDBqzJ6xbzqIhdg,1980
3
+ UnityManager/bytes.py,sha256=oSGeFyrBcJ6M_5KmeOMuDDJke9xe80ScHaXG9GaxWG0,1850
4
+ UnityManager/length.py,sha256=IMkX0DXop12Js6-GT3isbne7IPHLj5PVniP7jt1tAJo,1924
5
+ UnityManager/measure.py,sha256=IYjF_wVCSNYWy1EORjzQfrVi8I3hn1ByEEQ6h5EZppQ,2098
6
+ games/__init__.py,sha256=T_D3bbhYzGxXAF4EKoEoggXklKIhKBJcDWzIBoQprqU,269
7
+ games/_units.py,sha256=VvnaXZKetTYqt5RO42s__MH9Du9uQCvApXcN-lc64a8,428
8
+ games/monetary.py,sha256=GtRM3ZkoSSfKz13wZxs6xeIew4h8PId8W4NcgGHoLgw,2137
9
+ unitymanager-0.0.1a1.dist-info/METADATA,sha256=iAvV2ogade5KqGHZEpEO7m0fC6dTulza2m6hQdFekjQ,8091
10
+ unitymanager-0.0.1a1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
11
+ unitymanager-0.0.1a1.dist-info/licenses/LICENSE,sha256=KJecc8txDD4yvhnS_h5Hm9byqN6NgUFYiTpa0jd9eYA,1092
12
+ unitymanager-0.0.1a1.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.27.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 PlayGames-2020
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.