The Encoder class only accepts encoding name strings (e.g., "base16"). go-multibase's EncoderByName() accepts both names and single-character prefix codes (e.g., "f" for base16), making it more flexible for CLI tools and config-driven encoding.
Problem
Current Python Encoder:
class Encoder:
def __init__(self, encoding):
if encoding not in ENCODINGS_LOOKUP:
raise UnsupportedEncodingError(...)
self.encoding = encoding
self._codec = ENCODINGS_LOOKUP[encoding]
This only works with name strings:
Encoder("base16") # ✅ Works
Encoder("f") # ❌ Raises UnsupportedEncodingError
Encoder(b"f") # ❌ Raises UnsupportedEncodingError
Go's EncoderByName() accepts both:
// Go: both work
enc1, _ := EncoderByName("base16") // by name
enc2, _ := EncoderByName("f") // by single-char prefix
The implementation checks if the string is a single Unicode rune and treats it as a prefix code:
func EncoderByName(str string) (Encoder, error) {
if utf8.RuneCountInString(str) == 1 {
r, _ := utf8.DecodeRuneInString(str)
base = Encoding(r) // treat as prefix code
} else {
base = Encodings[str] // treat as name
}
}
Proposed Solution
Add an encoder_by_name() factory function (keeping Encoder.__init__ unchanged for backward compatibility):
def encoder_by_name(name_or_prefix: str) -> Encoder:
"""Create an Encoder from a name or single-character prefix.
>>> encoder_by_name("base16") # by name
>>> encoder_by_name("f") # by prefix character
>>> encoder_by_name("🚀") # by emoji prefix (base256emoji)
"""
# Try as name first
if name_or_prefix in ENCODINGS_LOOKUP:
return Encoder(name_or_prefix)
# Try as single-character prefix
prefix_bytes = name_or_prefix.encode("utf-8")
if prefix_bytes in ENCODINGS_LOOKUP:
codec = ENCODINGS_LOOKUP[prefix_bytes]
return Encoder(codec.encoding)
raise UnsupportedEncodingError(
f"Encoding {name_or_prefix!r} not supported."
)
Export from __init__.py and add tests.
Related
The
Encoderclass only accepts encoding name strings (e.g.,"base16"). go-multibase'sEncoderByName()accepts both names and single-character prefix codes (e.g.,"f"for base16), making it more flexible for CLI tools and config-driven encoding.Problem
Current Python
Encoder:This only works with name strings:
Go's
EncoderByName()accepts both:The implementation checks if the string is a single Unicode rune and treats it as a prefix code:
Proposed Solution
Add an
encoder_by_name()factory function (keepingEncoder.__init__unchanged for backward compatibility):Export from
__init__.pyand add tests.Related
encoder.goEncoderByName()