Python 2 and 3 compatibility utilities
—
Utilities for handling string and bytes data consistently across Python versions. These functions provide unified interfaces for text/binary data operations, literal creation, encoding/decoding, and type coercion that work identically on Python 2 and 3.
Functions for creating string and byte literals that work consistently across Python versions.
def b(s: str) -> bytes
"""Create byte literal from string in a cross-version way."""
def u(s: str) -> str
"""Create text literal from string in a cross-version way."""Usage Examples:
import six
# Create byte literals
byte_data = six.b("hello world") # Returns bytes on both PY2 and PY3
text_data = six.u("hello world") # Returns text/unicode on both PY2 and PY3
# Use in protocol or file operations
with open("data.bin", "wb") as f:
f.write(six.b("binary data"))
# Use in text processing
message = six.u("Unicode message: ∑αμπλε")Function for creating unicode characters from code points.
def unichr(i: int) -> str
"""Return unicode character for given code point."""Usage Example:
import six
# Create unicode characters
heart = six.unichr(0x2665) # ♥
euro = six.unichr(0x20AC) # €Functions for converting between bytes and integers across Python versions.
def int2byte(i: int) -> bytes
"""Convert integer (0-255) to single byte."""
def byte2int(bs: bytes) -> int
"""Convert single byte to integer."""
def indexbytes(buf: bytes, i: int) -> int
"""Index into bytes returning an integer."""
def iterbytes(buf: bytes) -> Iterator[int]
"""Iterate over bytes as integers."""Usage Examples:
import six
# Convert integer to byte
byte_val = six.int2byte(65) # b'A'
# Convert byte to integer
int_val = six.byte2int(b'A') # 65
# Index into bytes (returns int in PY3, str in PY2)
data = b"hello"
first_byte_as_int = six.indexbytes(data, 0) # Always returns int
# Iterate over bytes as integers
for byte_val in six.iterbytes(b"hello"):
print(byte_val) # Prints: 104, 101, 108, 108, 111Functions that ensure data is in the correct string/bytes format across Python versions.
def ensure_binary(s: str | bytes, encoding: str = 'utf-8', errors: str = 'strict') -> bytes
"""Coerce **s** to bytes."""
def ensure_str(s: str | bytes, encoding: str = 'utf-8', errors: str = 'strict') -> str
"""Coerce **s** to str."""
def ensure_text(s: str | bytes, encoding: str = 'utf-8', errors: str = 'strict') -> str
"""Coerce **s** to text (unicode in PY2, str in PY3)."""Parameters:
s: String or bytes data to coerceencoding: Text encoding to use for conversion (default: 'utf-8')errors: Error handling strategy ('strict', 'ignore', 'replace', etc.)Usage Examples:
import six
# Ensure binary data
text_input = "hello world"
byte_input = b"hello world"
both_binary = [six.ensure_binary(text_input), six.ensure_binary(byte_input)]
# Both return b"hello world"
# Ensure str type (native string for each Python version)
text_str = six.ensure_str("hello") # Returns str
bytes_str = six.ensure_str(b"hello") # Returns str (decoded)
# Ensure text type (unicode in PY2, str in PY3)
text_unicode = six.ensure_text("hello") # Returns unicode/str
bytes_unicode = six.ensure_text(b"hello") # Returns unicode/str (decoded)
# With custom encoding
latin1_data = b"\xe9\xe8\xe7"
text = six.ensure_text(latin1_data, encoding='latin-1')Cross-version IO classes for string and bytes operations.
StringIO: type # String-based IO class
BytesIO: type # Bytes-based IO classThese provide the appropriate IO classes for string and bytes operations:
StringIO: io.StringIO in Python 3, StringIO.StringIO in Python 2BytesIO: io.BytesIO in both versionsUsage Examples:
import six
# String IO operations
string_buffer = six.StringIO()
string_buffer.write(six.u("Hello, world!"))
content = string_buffer.getvalue()
# Bytes IO operations
bytes_buffer = six.BytesIO()
bytes_buffer.write(six.b("Hello, world!"))
binary_content = bytes_buffer.getvalue()
# Use in functions expecting file-like objects
def process_text_data(file_obj):
return file_obj.read().upper()
result = process_text_data(six.StringIO(six.u("hello")))Class decorator for Python 2 unicode compatibility.
def python_2_unicode_compatible(cls: type) -> type
"""Class decorator for unicode compatibility in Python 2."""This decorator allows classes to define __str__ methods that return unicode strings in Python 2 and regular strings in Python 3, ensuring consistent string representation behavior.
Usage Example:
import six
@six.python_2_unicode_compatible
class Person:
def __init__(self, name):
self.name = name
def __str__(self):
return "Person: {}".format(self.name)
# Works consistently across Python versions
person = Person("José")
print(str(person)) # Handles unicode correctly in both PY2 and PY3String constants for accessing function and method attributes across Python versions.
_meth_func: str # Method function attribute name
_meth_self: str # Method self attribute name
_func_closure: str # Function closure attribute name
_func_code: str # Function code attribute name
_func_defaults: str # Function defaults attribute name
_func_globals: str # Function globals attribute nameThese constants provide the correct attribute names for introspection:
Usage Example:
import six
def example_function(a, b=10):
return a + b
# Access function attributes cross-version
closure = getattr(example_function, six._func_closure)
defaults = getattr(example_function, six._func_defaults) # (10,)
code = getattr(example_function, six._func_code)
globals_dict = getattr(example_function, six._func_globals)import six
# Protocol handling with consistent types
def handle_data(data):
# Ensure we have bytes for binary protocols
binary_data = six.ensure_binary(data)
# Process binary data
processed = process_binary(binary_data)
# Return as text for display
return six.ensure_text(processed)
# File handling with proper encoding
def read_config_file(filename):
with open(filename, 'rb') as f:
raw_data = f.read()
# Convert to text with proper encoding
text_data = six.ensure_text(raw_data, encoding='utf-8')
return text_data.split('\n')
# Cross-version string buffer usage
def build_response():
buffer = six.StringIO()
buffer.write(six.u("HTTP/1.1 200 OK\r\n"))
buffer.write(six.u("Content-Type: text/plain\r\n"))
buffer.write(six.u("\r\n"))
buffer.write(six.u("Hello, World!"))
return buffer.getvalue()Install with Tessl CLI
npx tessl i tessl/pypi-six