Skip to content

Commit 7c276c5

Browse files
committed
more tweaks
1 parent 70c04a2 commit 7c276c5

4 files changed

Lines changed: 26 additions & 21 deletions

File tree

Doc/library/functions.rst

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1841,10 +1841,6 @@ are always available. They are listed here in alphabetical order.
18411841

18421842
Shallow and deep copies of a sentinel object return the object itself.
18431843

1844-
Sentinels importable from their defining module by name preserve their
1845-
identity when pickled and unpickled. Sentinels that are not importable by
1846-
module and name are not picklable.
1847-
18481844
Sentinels are conventionally assigned to a variable with a matching name.
18491845
Sentinels defined in this way can be used in :term:`type hints <type hint>`::
18501846

@@ -1858,7 +1854,8 @@ are always available. They are listed here in alphabetical order.
18581854
:mod:`Pickling <pickle>` is supported for sentinel objects that are
18591855
placed in the global scope of a module under a name matching the sentinel's
18601856
name, and for sentinels placed in class scopes with a name matching the
1861-
:term:`qualified name` of the sentinel. The identity of the sentinel is preserved
1857+
:term:`qualified name` of the sentinel. Other sentinels, such as those
1858+
defined in a function scope, are not picklable. The identity of the sentinel is preserved
18621859
after pickling::
18631860

18641861
import pickle
@@ -1872,6 +1869,8 @@ are always available. They are listed here in alphabetical order.
18721869

18731870
assert pickle.loads(pickle.dumps(Cls.PICKLABLE)) is Cls.PICKLABLE
18741871

1872+
Sentinel objects have the following attributes:
1873+
18751874
.. attribute:: __name__
18761875

18771876
The sentinel's name.

Lib/test/test_builtin.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1941,6 +1941,10 @@ class SubSentinel(sentinel):
19411941
missing.__name__ = "CHANGED"
19421942
with self.assertRaises(AttributeError):
19431943
missing.__module__ = "changed"
1944+
with self.assertRaises(AttributeError):
1945+
del missing.__name__
1946+
with self.assertRaises(AttributeError):
1947+
del missing.__module__
19441948

19451949
def test_sentinel_pickle(self):
19461950
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
@@ -1977,10 +1981,25 @@ class Name(str):
19771981
def test_sentinel_union(self):
19781982
missing = sentinel("MISSING")
19791983

1984+
self.assertIsInstance(missing | int, typing.Union)
19801985
self.assertEqual((missing | int).__args__, (missing, int))
1986+
self.assertIsInstance(int | missing, typing.Union)
19811987
self.assertEqual((int | missing).__args__, (int, missing))
19821988
self.assertIs(missing | missing, missing)
19831989
self.assertEqual(repr(int | missing), "int | MISSING")
1990+
self.assertIsInstance(missing | None, typing.Union)
1991+
self.assertEqual((missing | None).__args__, (missing, type(None)))
1992+
self.assertIsInstance(None | missing, typing.Union)
1993+
self.assertEqual((None | missing).__args__, (type(None), missing))
1994+
self.assertIsInstance(missing | list[int], typing.Union)
1995+
self.assertEqual((missing | list[int]).__args__, (missing, list[int]))
1996+
self.assertIsInstance(missing | (int | str), typing.Union)
1997+
self.assertEqual((missing | (int | str)).__args__, (missing, int, str))
1998+
1999+
with self.assertRaises(TypeError):
2000+
missing | 1
2001+
with self.assertRaises(TypeError):
2002+
1 | missing
19842003

19852004
def test_round(self):
19862005
self.assertEqual(round(0.0), 0.0)

Lib/test/test_capi/test_object.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import enum
22
import os
3+
import pickle
34
import sys
45
import textwrap
56
import unittest
@@ -66,8 +67,6 @@ def test_get_constant_borrowed(self):
6667
class SentinelTest(unittest.TestCase):
6768

6869
def test_pysentinel_new(self):
69-
import pickle
70-
7170
marker = _testcapi.pysentinel_new("CAPI_SENTINEL", __name__)
7271
self.assertIs(type(marker), sentinel)
7372
self.assertTrue(_testcapi.pysentinel_check(marker))

Objects/sentinelobject.c

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
#include "pycore_stackref.h" // PyStackRef_AsPyObjectBorrow()
99
#include "pycore_tuple.h" // _PyTuple_FromPair
1010
#include "pycore_typeobject.h" // _Py_BaseObject_RichCompare()
11-
#include "pycore_unionobject.h" // _Py_union_from_tuple()
11+
#include "pycore_unionobject.h" // _Py_union_type_or()
1212

1313
typedef struct {
1414
PyObject_HEAD
@@ -152,18 +152,6 @@ sentinel_reduce(PyObject *op, PyObject *Py_UNUSED(ignored))
152152
return Py_NewRef(self->name);
153153
}
154154

155-
static PyObject *
156-
sentinel_or(PyObject *self, PyObject *other)
157-
{
158-
PyObject *args = _PyTuple_FromPair(self, other);
159-
if (args == NULL) {
160-
return NULL;
161-
}
162-
PyObject *result = _Py_union_from_tuple(args);
163-
Py_DECREF(args);
164-
return result;
165-
}
166-
167155
static PyMethodDef sentinel_methods[] = {
168156
{"__copy__", sentinel_copy, METH_NOARGS, NULL},
169157
{"__deepcopy__", sentinel_deepcopy, METH_O, NULL},
@@ -178,7 +166,7 @@ static PyMemberDef sentinel_members[] = {
178166
};
179167

180168
static PyNumberMethods sentinel_as_number = {
181-
.nb_or = sentinel_or,
169+
.nb_or = _Py_union_type_or,
182170
};
183171

184172
PyDoc_STRVAR(sentinel_doc,

0 commit comments

Comments
 (0)