Compatibility#
Cross-version compatibility utilities for Python 3.9+ support. This module provides backports and compatibility shims for features introduced in newer Python versions.
Overview#
The compatibility module ensures your code works across different Python versions by:
Providing
Selftype hint for Python < 3.11Implementing
StrEnumfor Python < 3.11Automatically using native implementations when available
Quick Examples#
Self Type Hint#
Use Self for better type hints in methods that return the instance itself:
from core_mixins import Self
class Builder:
def __init__(self) -> None:
self.value = 0
def add(self, amount: int) -> Self:
"""Returns self for method chaining."""
self.value += amount
return self
def multiply(self, factor: int) -> Self:
"""Returns self for method chaining."""
self.value *= factor
return self
# Type checker knows the return type
result = Builder().add(5).multiply(2) # type: Builder
Why use Self?
Before Python 3.11, you had to use string literals or type variables:
# Old way (Python < 3.11)
from typing import TypeVar
T = TypeVar('T', bound='Builder')
class Builder:
def add(self: T, amount: int) -> T: # Complex!
return self
# New way (Python 3.11+, works in 3.9+ with core-mixins)
from core_mixins import Self
class Builder:
def add(self, amount: int) -> Self: # Simple!
return self
StrEnum Usage#
Create string-based enumerations that work consistently across Python versions:
from core_mixins import StrEnum
class Status(StrEnum):
"""Order status enumeration."""
PENDING = "pending"
PROCESSING = "processing"
COMPLETED = "completed"
CANCELLED = "cancelled"
# Use as strings
status = Status.PENDING
print(status) # "pending"
print(f"Status: {status}") # "Status: pending"
# String comparison works
if status == "pending":
print("Order is pending")
# Enum features
print(Status.PENDING.name) # "PENDING"
print(Status.PENDING.value) # "pending"
print(list(Status)) # [Status.PENDING, Status.PROCESSING, ...]
HTTP Status Example#
from core_mixins import StrEnum
class HTTPStatus(StrEnum):
"""HTTP status codes."""
OK = "200"
CREATED = "201"
BAD_REQUEST = "400"
UNAUTHORIZED = "401"
NOT_FOUND = "404"
SERVER_ERROR = "500"
def handle_response(status: HTTPStatus) -> str:
"""Handle HTTP response based on status."""
if status == HTTPStatus.OK:
return "Success"
elif status in (HTTPStatus.BAD_REQUEST, HTTPStatus.UNAUTHORIZED):
return "Client error"
elif status == HTTPStatus.SERVER_ERROR:
return "Server error"
return "Unknown status"
# Usage
response_status = HTTPStatus.OK
print(handle_response(response_status)) # "Success"
Python Version Support#
Feature |
Native In |
Backported By |
|---|---|---|
|
Python 3.11+ |
typing_extensions |
|
Python 3.11+ |
Custom implementation |
The module automatically uses native implementations when running on Python 3.11+, ensuring optimal performance and compatibility.
API Reference#
Compatibility utilities for Python version differences.
Best Practices#
Import from core_mixins#
Always import compatibility features from core_mixins:
# ✓ Correct
from core_mixins import Self, StrEnum
# ✗ Avoid direct imports (may not exist in older Python)
from typing import Self # Fails in Python < 3.11
Use Self for Fluent Interfaces#
Self is perfect for builder patterns and fluent APIs:
from core_mixins import Self
class QueryBuilder:
def where(self, condition: str) -> Self:
return self
def order_by(self, field: str) -> Self:
return self
def limit(self, count: int) -> Self:
return self
# Type-safe method chaining
query = QueryBuilder().where("active = true").order_by("name").limit(10)
Use StrEnum for Constants#
StrEnum is ideal for configuration values and constants:
from core_mixins import StrEnum
class Environment(StrEnum):
DEVELOPMENT = "dev"
STAGING = "staging"
PRODUCTION = "prod"
class LogLevel(StrEnum):
DEBUG = "DEBUG"
INFO = "INFO"
WARNING = "WARNING"
ERROR = "ERROR"