Sentinels Module
The sentinels
module implements the sentinel pattern for representing special values in Python. Sentinels are unique objects used to signify special conditions, particularly useful for distinguishing between "not provided" and "explicitly set to None" in function parameters.
Key Features
- Unique Sentinels: Guaranteed unique singleton objects
- Type Safety: Properly typed for static analysis
- String Representation: Clear debugging information
API Reference
Sentinel values for special cases.
This module defines sentinel objects that can be used to represent special cases like "no value provided" in a way that's distinct from None.
Usage Examples
Basic Usage
from spryx_core import NOT_GIVEN
# Function with optional parameters using the sentinel pattern
def update_user(user_id, name=NOT_GIVEN, email=NOT_GIVEN, active=NOT_GIVEN):
updates = {}
if name is not NOT_GIVEN:
updates["name"] = name
if email is not NOT_GIVEN:
updates["email"] = email
if active is not NOT_GIVEN:
updates["active"] = active
# Apply updates to user with user_id
print(f"Updating user {user_id} with {updates}")
return updates
# Different usage scenarios
update_user("user123", name="John") # Updates only name
update_user("user123", email="john@example.com") # Updates only email
update_user("user123", active=False) # Updates only active status
update_user("user123", name="John", email="john@example.com") # Updates name and email
update_user("user123") # No updates
# Now we can explicitly set None, which is different from not providing a value
update_user("user123", name=None) # Explicitly setting name to None
The NotGiven Class
The NotGiven
class is the sentinel's type, with NOT_GIVEN
being the singleton instance:
from spryx_core import NOT_GIVEN, NotGiven
# Check type
print(isinstance(NOT_GIVEN, NotGiven)) # True
# String representation
print(str(NOT_GIVEN)) # "<not given>"
print(repr(NOT_GIVEN)) # "NOT_GIVEN"
Comparing Sentinels
Sentinel values have identity-based equality, meaning they only equal themselves:
from spryx_core import NOT_GIVEN
# Identity comparison
print(NOT_GIVEN is NOT_GIVEN) # True
# Equality comparison
print(NOT_GIVEN == NOT_GIVEN) # True
print(NOT_GIVEN == None) # False
print(NOT_GIVEN == "") # False
print(NOT_GIVEN == 0) # False
Best Practices
-
Use with Optional Parameters: Use sentinels for optional parameters when you need to distinguish between "not provided" and "explicitly set to None".
-
Type Annotations: For proper type checking, use
NotGivenOr[T]
from thetypes
module as the type annotation:
from spryx_core import NOT_GIVEN, NotGivenOr
def update_profile(name: NotGivenOr[str] = NOT_GIVEN):
pass
- Consistent Pattern: Use the same pattern throughout your codebase for handling optional parameters to maintain consistency.