stringz 0.1.1__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.
stringz/__init__.py ADDED
@@ -0,0 +1 @@
1
+ from ._truncated_string import TStr, trunc_str # noqa
@@ -0,0 +1,163 @@
1
+ from typing import Self, SupportsIndex
2
+
3
+
4
+ def trunc_str(
5
+ text: str,
6
+ max_chars: int,
7
+ placeholder: str = "...",
8
+ ) -> str:
9
+ """A function that truncates a string to a maximum number of characters,
10
+ appending a placeholder if truncation occurs.
11
+
12
+ Example:
13
+ Basic usage:
14
+
15
+ >>> from stringz import trunc_str
16
+ >>> trunc_str("hello world", max_chars=10)
17
+ 'hello w...'
18
+
19
+ No truncation needed:
20
+
21
+ >>> trunc_str("short", max_chars=10)
22
+ 'short'
23
+
24
+ Custom placeholder:
25
+
26
+ >>> trunc_str("hello world", max_chars=10, placeholder=">>")
27
+ 'hello wo>>'
28
+
29
+ Empty placeholder:
30
+
31
+ >>> trunc_str("hello world", max_chars=5, placeholder="")
32
+ 'hello'
33
+
34
+ Args:
35
+ text: The string to be truncated.
36
+ max_chars: The maximum number of characters allowed in the output string.
37
+ placeholder: The string to append if truncation occurs. Default is '...'.
38
+
39
+ Returns:
40
+ The truncated string, if necessary, with the placeholder appended.
41
+
42
+ Raises:
43
+ TypeError: If text is not a string.
44
+ ValueError: If max_chars is not a positive integer or if placeholder length is greater than or
45
+ equal to max_chars.
46
+ TypeError: If placeholder is not a string.
47
+ ValueError: If placeholder length is greater than or equal to max_chars.
48
+ """
49
+
50
+ # ====> VALIDATION
51
+ if not isinstance(text, str):
52
+ _err: str = f"text must be a string, not {type(text).__name__}"
53
+ raise TypeError(_err)
54
+ if not isinstance(max_chars, int) or max_chars <= 0:
55
+ _err: str = f"max_chars must be a positive integer, got {max_chars}"
56
+ raise ValueError(_err)
57
+ if not isinstance(placeholder, str):
58
+ _err: str = f"placeholder must be a string, not {type(placeholder).__name__}"
59
+ raise TypeError(_err)
60
+ if len(placeholder) >= max_chars:
61
+ _err: str = f"placeholder length ({len(placeholder)}) must be smaller than max_chars ({max_chars})"
62
+ raise ValueError(_err)
63
+
64
+ # ====> TRUNCATE
65
+ if len(text) <= max_chars:
66
+ return text
67
+ return text[: max_chars - len(placeholder)] + placeholder
68
+
69
+
70
+ class TStr(str):
71
+ """A string subclass that automatically truncates its content to a maximum length when created or modified through
72
+ string operations. The TStr class uses the `trunc_str` function for truncation under the hood.
73
+
74
+ Example:
75
+ Basic creation:
76
+
77
+ >>> from stringz import TStr
78
+ >>> s = TStr("hello world", max_chars=10)
79
+ >>> print(s)
80
+ hello w...
81
+ >>> len(s)
82
+ 10
83
+
84
+ String operations maintain TStr type and truncation:
85
+
86
+ >>> s1 = TStr("hello", max_chars=10)
87
+ >>> s2 = s1 + " world"
88
+ >>> type(s2)
89
+ <class 'stringz._truncated_string.TStr'>
90
+ >>> print(s2)
91
+ hello w...
92
+ """
93
+
94
+ __slots__ = (
95
+ "max_chars",
96
+ "placeholder",
97
+ )
98
+
99
+ max_chars: int | None
100
+ placeholder: str
101
+
102
+ def __new__(
103
+ cls,
104
+ value: str,
105
+ max_chars: int | None = None,
106
+ placeholder: str = "...",
107
+ ) -> Self:
108
+ """Create a new TStr instance.
109
+
110
+ Args:
111
+ value: The initial string value.
112
+ max_chars: Maximum number of characters. If None, no truncation occurs.
113
+ placeholder: String to append when truncating. Default is '...'.
114
+
115
+ Returns:
116
+ A new TStr instance with the specified truncation settings.
117
+ """
118
+ if max_chars is not None:
119
+ value = trunc_str(
120
+ text=value,
121
+ max_chars=max_chars,
122
+ placeholder=placeholder,
123
+ )
124
+ instance = super().__new__(cls, value)
125
+ instance.max_chars = max_chars
126
+ instance.placeholder = placeholder
127
+ return instance
128
+
129
+ def __add__(self, other: str) -> Self:
130
+ result = super().__add__(other)
131
+ return type(self)(result, self.max_chars)
132
+
133
+ def __mul__(self, other: SupportsIndex) -> Self:
134
+ result = super().__mul__(other)
135
+ return type(self)(result, self.max_chars)
136
+
137
+ def __radd__(self, other: str) -> Self:
138
+ result = other + str(self)
139
+ return type(self)(result, self.max_chars)
140
+
141
+ def __rmul__(self, other: SupportsIndex) -> Self:
142
+ result = other * str(self)
143
+ return type(self)(result, self.max_chars)
144
+
145
+ def __mod__(self, other) -> Self:
146
+ result = super().__mod__(other)
147
+ return type(self)(result, self.max_chars)
148
+
149
+ def __rmod__(self, other) -> Self:
150
+ result = other % str(self)
151
+ return type(self)(result, self.max_chars)
152
+
153
+ def __getitem__(self, key) -> str | Self:
154
+ result = super().__getitem__(key)
155
+ if isinstance(key, int):
156
+ return result
157
+ return type(self)(result, self.max_chars)
158
+
159
+ def __format__(self, format_spec: str) -> str:
160
+ return super().__format__(format_spec)
161
+
162
+ def __repr__(self) -> str:
163
+ return f"TStr({super().__repr__()}, max_chars={self.max_chars}, placeholder={self.placeholder})"
@@ -0,0 +1,72 @@
1
+ Metadata-Version: 2.5
2
+ Name: stringz
3
+ Version: 0.1.1
4
+ Summary: Utilities library for working with strings
5
+ Project-URL: Changelog, https://github.com/johandielangman/stringz/blob/main/CHANGELOG.md
6
+ Project-URL: Documentation, https://johandielangman.github.io/stringz/
7
+ Project-URL: Issues, https://github.com/johandielangman/stringz/issues
8
+ Project-URL: Source, https://github.com/johandielangman/stringz
9
+ Author-email: Johandielangman <johan@datatreehouse.org>
10
+ License-Expression: MIT
11
+ License-File: LICENSE.txt
12
+ Classifier: Operating System :: MacOS
13
+ Classifier: Operating System :: Microsoft :: Windows
14
+ Classifier: Operating System :: POSIX :: Linux
15
+ Classifier: Programming Language :: Python
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Programming Language :: Python :: 3.14
20
+ Classifier: Programming Language :: Python :: 3.15
21
+ Requires-Python: >=3.12
22
+ Description-Content-Type: text/markdown
23
+
24
+ <p align="center">
25
+ <a href="https://johandielangman.github.io/stringz/">
26
+ <img src="https://raw.githubusercontent.com/johandielangman/stringz/main/docs/static/images/banner.svg" alt="stringz">
27
+ </a>
28
+ </p>
29
+ <p align="center">
30
+ <em>Utilities library for working with strings.</em>
31
+ </p>
32
+ <p align="center">
33
+ <a href="https://pypi.org/project/stringz"><img src="https://img.shields.io/pypi/v/stringz.svg" alt="PyPI - Version"></a>
34
+ <a href="https://pypi.org/project/stringz"><img src="https://img.shields.io/pypi/pyversions/stringz.svg" alt="PyPI - Python Version"></a>
35
+ <a href="https://github.com/johandielangman/stringz/actions/workflows/ci.yml"><img src="https://github.com/johandielangman/stringz/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
36
+ <a href="https://codecov.io/gh/johandielangman/stringz"><img src="https://codecov.io/gh/johandielangman/stringz/graph/badge.svg" alt="codecov"></a>
37
+ <a href="https://johandielangman.github.io/stringz/"><img src="https://img.shields.io/badge/docs-latest-blue" alt="Docs"></a>
38
+ </p>
39
+
40
+ ---
41
+
42
+ Simply install this amazing utilities package:
43
+
44
+ ``` console
45
+ uv add stringz
46
+ ```
47
+
48
+ And immediately get the benefits
49
+
50
+ ```python
51
+ from stringz import pretty_str, ding
52
+
53
+ result = pretty_str("Hello world!", max_chars=10)
54
+ print(result) # Output: 'Hello w...'
55
+ ```
56
+
57
+ ## Roadmap
58
+
59
+ only the future will know!
60
+
61
+ - [x] Pretty truncation and truncation string type
62
+ - [ ] `mask` for sensitive information masking
63
+ - [ ] converters (`to_snake`, `to_camel`, etc)
64
+ - [ ] `join_human` that joins using Oxford comma
65
+ - [ ] `ordinal(22)` should give `22nd`
66
+ - [ ] `pluralize("box", n)` gives "boxes"... maybe
67
+ - [ ] `slugify`
68
+ - [ ] `is_blank`
69
+
70
+ ## License
71
+
72
+ `stringz` is distributed under the terms of the [MIT](https://spdx.org/licenses/MIT.html) license.
@@ -0,0 +1,6 @@
1
+ stringz/__init__.py,sha256=UAMKx_eZUSe8EFQ8XwXt8yIWQ0-A7q4eb0NApPqCtrc,55
2
+ stringz/_truncated_string.py,sha256=ZoCCpw_9hrGwamIk9uZBrikFaif-i7zgdUzwr7_briw,5046
3
+ stringz-0.1.1.dist-info/METADATA,sha256=rK65iaYiT3n0No2S1_LLMLspP4RPFm9iVX9JSS3DsIs,2771
4
+ stringz-0.1.1.dist-info/WHEEL,sha256=2iZrJkDIkeDh0k9SikKMqFuRP-ua6mb4Ir1AsER4BEw,87
5
+ stringz-0.1.1.dist-info/licenses/LICENSE.txt,sha256=x7yQuGcgYfBt-59XVxvZEzDp-rw8aRlEzu_mcxSNlKA,1080
6
+ stringz-0.1.1.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.33.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,18 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026-present Johandielangman
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
6
+ associated documentation files (the "Software"), to deal in the Software without restriction, including
7
+ without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the
9
+ following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in all copies or substantial
12
+ portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
15
+ LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
16
+ EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
18
+ USE OR OTHER DEALINGS IN THE SOFTWARE.