title: charded description: Type-safe, generic string/bytes container with charset detection
[ref: #charded]
charded
charded is a small Python library for working with str and bytes as a
single, type-safe container. It detects charsets automatically, converts
lazily between text and bytes, and proxies the familiar str API so the
wrapper feels invisible.
It gives you four public entry points:
Str— a genericstr | bytescontainer.to_text— convertstrorbytesto text.to_bytes— convertstrorbytesto bytes.to_ascii— decode bytes to text with a default ASCII charset.
[ref: #installation]
Installation
Install with uv:
uv add charded
Or with any PEP 517-compatible tool:
pip install charded
[ref: #str]
Wrapping text and bytes with Str
Str[T] is parameterized by T, which is either str or bytes. Pass any
str or bytes object and read it back through str(), bytes(),
.string, or .bytes.
from charded import Str
s = Str(b"hello")
assert str(s) == "hello"
assert bytes(s) == b"hello"
assert s.string == "hello"
assert s.bytes == b"hello"
t = Str("héllo")
assert str(t) == "héllo"
assert bytes(t) == b"h\xc3\xa9llo"
[ref: #charset-detection]
Charset detection
Str detects the content charset using charset-normalizer, internal
heuristics, and an adaptive binary-offset scan. Access .charset to see the
result.
from charded import Str
assert Str(b"hello").charset == "ascii"
assert Str(b"hello\x00world").charset == "bin"
The detection order is:
- Explicit
charset=argument if provided. - Result from
charset-normalizer. - Internal heuristic scan.
- Fallback to ASCII for bytes or a compatible charset for text.
[ref: #mime-detection]
MIME type detection
Str.mime uses python-magic to sniff the content type and description.
It returns None when detection fails.
from charded import Str
mime = Str(b'{"a": 1}').mime
assert mime is not None
assert mime["type"] == "application/json"
[ref: #string-api]
Using Str as a string
Str proxies common str operations, so you can slice, iterate, compare,
and call most str methods directly.
from charded import Str
s = Str(b"hello world")
assert len(s) == 11
assert s[0:5] == "hello"
assert s.startswith("hello")
assert s.split() == ["hello", "world"]
assert s.upper() == "HELLO WORLD"
assert "world" in s
[ref: #tokenize]
Tokenizing with Str.tokenize
Str.tokenize splits the string using a regular expression. Capturing groups
are not allowed; use non-capturing groups (?:...) instead.
from charded import Str
s = Str("foo-bar_baz, qux")
assert s.tokenize(r"[a-z]+") == ("foo", "bar", "baz", "qux")
[ref: #utility-functions]
Utility functions
to_text, to_bytes, and to_ascii perform quick conversions without
creating a persistent Str instance.
from charded import to_ascii, to_bytes, to_text
assert to_text(b"hello") == "hello"
assert to_bytes("hello") == b"hello"
assert to_ascii(b"hello") == "hello"
[ref: #type-safety]
Type safety and aliases
Str is a true generic. Use Str[bytes] or Str[str] to constrain input
and let type checkers catch mismatches at compile time.
from charded import Str
def process(data: Str[bytes]) -> str:
return data.string.upper()
assert process(Str(b"hello")) == "HELLO"
Convenience aliases are available in charded.string:
from charded.string import StrBytes, StrText
raw: StrBytes = Str(b"hello")
text: StrText = Str(raw.string)
assert text.string == "hello"
[ref: #full-example]
Full example
from charded import Str, to_bytes, to_text
raw = b"h\xc3\xa9llo"
s = Str(raw)
assert str(s) == "héllo"
assert bytes(s) == raw
assert s.charset is not None
assert s.startswith("hél")
# Quick conversions without wrapping
assert to_text(raw) == "héllo"
assert to_bytes("héllo") == raw
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file charded-1.0.4.tar.gz.
File metadata
- Download URL: charded-1.0.4.tar.gz
- Upload date:
- Size: 23.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f41f47db1736314d1139b10c4a869e9f99440e59772106f7eed448657ec53787
|
|
| MD5 |
cf57983bacbf86bbb2a8a073f942174b
|
|
| BLAKE2b-256 |
65b1144cc6e7c3b2e088b0675b090d3c88606943f444d69bdb72207ca7bd981a
|
File details
Details for the file charded-1.0.4-py3-none-any.whl.
File metadata
- Download URL: charded-1.0.4-py3-none-any.whl
- Upload date:
- Size: 11.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0afbfd38ca98efc8c4dc3b1df3778024df33ef29f7fe52f0bef978c5b2ef61e2
|
|
| MD5 |
f90cd0061c80186ecd9841ae78c69076
|
|
| BLAKE2b-256 |
492c4312fbded0206471d19e551eb838db071d40b1460f61a1519ee47e60e912
|