bytes to str, and no process-global locale mutation. You name the encoding, you get a typed error if the bytes don’t conform, and you can choose an error-recovery handler if you need one. This design makes text bugs visible at compile time rather than hiding them as runtime surprises.
Encoding: sifr.encoding
sifr.encoding is the byte/text conversion surface. Use it to encode a str to bytes or decode bytes to str with an explicitly named codec.
Codec Descriptors
Build a codec descriptor by calling one of the constructor functions:
Tier 1 Windows-125x encodings (e.g.,
windows1252()) are available through encoding_rs. Tier 2 CJK and UTF-32 are deferred to a future release.
Error Handlers
By default,decode raises DecodeError on an invalid byte sequence. Supply an error handler to recover instead:
codecs.register_error) is unsupported.
Typed Errors
encode raises EncodeError when a character cannot be represented in the target encoding. decode raises DecodeError on invalid byte sequences. Both expose a .message field:
Text File I/O: sifr.io
Pass a codec descriptor to open_text whenever you open a text file. The encoding= parameter is required — omitting it raises SIFR-IO-0801:
Unicode: sifr.unicode
sifr.unicode provides normalization, scalar properties, and text segmentation using Unicode 17.0.0 data tables compiled into the Sifr runtime.
Normalization
normalize accepts a normalization form constant and a str, and returns the normalized form:
Scalar Properties
name returns the Unicode name of a scalar; category returns the two-letter general category:
Grapheme and Word Segmentation
graphemes splits a string into user-perceived grapheme clusters. words splits into word tokens, filtering punctuation and whitespace:
Unicode 17.0.0 data covers normalization, names, scalar properties, numeric values, case folding, grapheme boundaries, and word boundaries. Sentence boundaries and streaming segmentation cursors are deferred to a future release.
Locale and I18n: sifr.i18n
sifr.i18n provides locale-aware number formatting, plural rules, and translation bundles. All state is scoped to explicit objects — there is no global locale, no locale.setlocale, and no gettext.install.
Locale Identifiers
Create aLocaleId from a BCP 47 tag:
host_locale() returns the host’s current locale as a read-only LocaleId. It cannot be used to make implicit text encodings legal.
Number Formatting
NumberFormatter formats a numeric string according to locale conventions:
Plural Rules
PluralRules selects the grammatical plural category for a given quantity:
Translation Bundles
Load translation catalogs from.mo file bytes and compose them into a Translator with an explicit fallback chain:
.mo format is a compatibility backend behind the native Bundle / Translator API. Catalog parsing uses the encoding substrate for declared charsets and rejects unsupported plural expressions with CatalogError.
Full Text and I18n Demo
The following is the complete text/i18n demo from the Sifr repository:What Is Not in This Release
The following CPython-shaped names are intentionally absent and raise diagnostics if imported:
These adapters may be reviewed for future capabilities, but any future compatibility wrappers must wrap the native Sifr substrate without process-global mutation.
