Skip to content

Commit a86f847

Browse files
committed
docs: rewrite for latest version
1 parent 3cfc412 commit a86f847

File tree

1 file changed

+99
-29
lines changed

1 file changed

+99
-29
lines changed

README.rst

+99-29
Original file line numberDiff line numberDiff line change
@@ -4,53 +4,122 @@ sentinel — create sentinel and singleton objects
44

55
|Tests| |PyPI version|
66

7-
.. |Tests| image:: https://github.com/eddieantonio/sentinel/workflows/Python%20package/badge.svg
8-
:target: https://github.com/eddieantonio/sentinel/actions?query=workflow%3A%22Python+package%22
7+
.. |Tests| image:: https://github.com/eddieantonio/sentinel/workflows/Test%20and%20Lint/badge.svg
8+
:target: https://github.com/eddieantonio/sentinel/actions?query=workflow%3A%22Test+and+Lint%22
99
.. |PyPI version| image:: https://img.shields.io/pypi/v/sentinel
1010
:target: https://pypi.org/project/sentinel/
1111

12-
Creates simple sentinel objects which are the only instance of their own
13-
anonymous class. As a singleton, there is a guarantee that there will only
14-
ever be one instance: they can be safely used with ``pickle`` and ``cPickle``
15-
alike, as well as being able to be used properly with ``copy.deepcopy()``. In
16-
addition, a self-documenting ``__repr__`` is provided for free!
12+
Creates simple sentinel objects.
13+
14+
15+
Install
16+
=======
17+
18+
Basic features::
19+
20+
pip install sentinel
21+
22+
with extra magic features powered by python-varname_::
23+
24+
pip install 'sentinel[varname]'
25+
26+
27+
What is a sentinel?
28+
===================
29+
30+
Sentinels_ are singleton_ objects that typically represent some
31+
terminating (end) condition or have a special, symbolic meaning. Python's built-in
32+
``None`` is a sentinel. Python also has other sentinels like ``NotImplemented`` and
33+
``Ellipsis``.
34+
35+
If you want to create your own sentinels, use this library! Make your calls to
36+
``dict.get()`` more meaningful! You can replace the ``object()`` idiom with a sentinel:
37+
38+
.. code-block:: python
39+
40+
d = {"a": 1, "b": None}
41+
42+
# Before sentinel:
43+
missing = object()
44+
if d.get("c", missing) is missing:
45+
... # do some stuff
46+
47+
# After sentinel:
48+
Missing = sentinel.create()
49+
if d.get("c", Missing) is Missing:
50+
... # do some stuff
51+
52+
53+
Features
54+
--------
55+
56+
- sentinels are unique
57+
- sentinels are singletons — the **only** instance of their own anonymous class
58+
- sentinels can be used with ``is`` comparisons
59+
- sentinels can be used with ``pickle``
60+
- sentinels can be used with ``copy.deepcopy``
61+
- you can **add** arbitrary attributes and methods to sentinels
62+
- sentinels have a nice, self-documenting ``__repr__``!
1763

1864
Usage
1965
=====
2066

21-
Sentinels_ are singleton_ objects that typically represent some end or
22-
terminating condition. Some singletons already exist in Python, like ``None``,
23-
``NotImplemented``, and ``Ellipsis``.
67+
Create a sentinel:
2468

69+
>>> import sentinel
70+
>>> MySentinel = sentinel.create("MySentinel")
71+
>>> Sentinel
72+
Sentinel
2573

26-
All that's needed to create a sentinel is its name:
74+
If you have python-varname_ installed, or installed this module using
75+
``pip install 'sentinel[varname]'``, ``sentinel.create()`` can infer the name
76+
from the assignment expression:
2777

28-
>>> import sentinel
29-
>>> Nothing = sentinel.create('Nothing')
30-
>>> Nothing
31-
Nothing
78+
.. code-block:: python
79+
80+
import sentinel
3281
33-
This by itself is useful when other objects such as ``None``, ``False``,
34-
``0``, ``-1``, etc. are entirely valid values. For example, setting default
35-
values when all other values are valid with: ``dict.setdefault()``:
82+
MySentinel = sentinel.create()
3683
37-
>>> MissingEntry = sentinel.create('MissingEntry')
38-
>>> d = {'stdout': None, 'stdin': 0, 'EOF': -1}
39-
>>> [d.setdefault(key, MissingEntry) for key in ('stdin', 'stdout', 'stderr')]
40-
[0, None, MissingEntry]
84+
print(MySentinel) # prints `MySentinel`
85+
86+
87+
Example
88+
-------
89+
90+
Sentinels are useful when other objects such as ``None``, ``False``,
91+
``0``, ``-1``, are valid values within some data structure. For example, setting
92+
default values when all other values are valid with:
93+
``dict.setdefault()``:
94+
95+
.. code-block:: python
96+
97+
d = {"stdout": None, "stdin": 0, "EOF": -1}
98+
99+
MissingEntry = sentinel.create()
100+
101+
[d.setdefault(key, MissingEntry) for key in ("stdin", "stdout", "stderr")]
102+
[0, None, MissingEntry]
41103
42104
Alternatively, using ``dict.get()`` when fetching values:
43105

44-
>>> d = {'stdout': None, 'stdin': 0, 'EOF': -1}
45-
>>> d.get('stdout', MissingEntry)
106+
>>> d = {"stdout": None, "stdin": 0, "EOF": -1}
107+
>>> d.get("stdout", MissingEntry)
46108
None
47-
>>> d.get('stdin', MissingEntry)
109+
>>> d.get("stdin", MissingEntry)
48110
0
49-
>>> d.get('stderr', MissingEntry)
111+
>>> d.get("stderr", MissingEntry)
50112
MissingEntry
51113

52-
It's known immediately which value was missing from the dictionary in a
53-
self-documenting manner.
114+
Since a new sentinel can never occur in the original dictionary, you can tell which
115+
entries are missing or unset in a dictionary in a self-documenting way:
116+
117+
.. code-block:: python
118+
119+
Unset = sentinel.create()
120+
if d.get("stdin", Unset) is Unset:
121+
stdin = 0 # some reasonable default
122+
54123
55124
Adding extra methods and class attributes
56125
-----------------------------------------
@@ -110,7 +179,7 @@ Contributing
110179
This project uses Poetry_. To contribute to the codebase, make sure to `install poetry`_,
111180
With Poetry installed, clone then repo, then within the repo directory, install the developer dependencies::
112181

113-
$ poetry install
182+
$ poetry install --extras varname
114183

115184
Next, I recommend you do all development tasks within the ``poetry shell``::
116185

@@ -122,3 +191,4 @@ Next, I recommend you do all development tasks within the ``poetry shell``::
122191
.. _singleton: http://en.wikipedia.org/wiki/Singleton_pattern
123192
.. _Poetry: https://python-poetry.org/
124193
.. _install poetry: https://python-poetry.org/docs/#installation
194+
.. _python-varname: https://github.com/pwwang/python-varname

0 commit comments

Comments
 (0)