example-code-2e/24-class-metaprog/sentinel/sentinel.py

42 lines
976 B
Python
Raw Normal View History

2021-05-24 03:12:13 +02:00
"""
This module provides a ``Sentinel`` class that can be used directly as a
sentinel singleton, or subclassed if a distinct sentinel singleton is needed.
The ``repr`` of a ``Sentinel`` class is its name::
2021-05-24 03:12:13 +02:00
>>> class Missing(Sentinel): pass
>>> Missing
2021-05-24 03:19:15 +02:00
Missing
If a different ``repr`` is required,
you can define it as a class attribute::
2021-05-24 03:12:13 +02:00
>>> class CustomRepr(Sentinel):
2021-05-24 03:19:15 +02:00
... repr = '<CustomRepr>'
2021-05-24 03:12:13 +02:00
...
>>> CustomRepr
2021-05-24 03:19:15 +02:00
<CustomRepr>
2021-05-24 03:12:13 +02:00
``Sentinel`` classes cannot be instantiated::
>>> Missing()
Traceback (most recent call last):
...
TypeError: 'Missing' is a sentinel and cannot be instantiated
2021-05-24 03:12:13 +02:00
"""
class _SentinelMeta(type):
2021-05-24 03:12:13 +02:00
def __repr__(cls):
try:
return cls.repr
except AttributeError:
2021-05-24 18:35:53 +02:00
return cls.__name__
2021-05-24 03:12:13 +02:00
class Sentinel(metaclass=_SentinelMeta):
2021-05-24 03:12:13 +02:00
def __new__(cls):
msg = 'is a sentinel and cannot be instantiated'
raise TypeError(f"'{cls!r}' {msg}")