Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit df8d2cd

Browse filesBrowse files
pierreglaserpitrou
authored andcommitted
bpo-35911: add cell constructor (GH-11771)
Add a cell constructor, expose the cell type in the types module.
1 parent f289084 commit df8d2cd
Copy full SHA for df8d2cd

File tree

Expand file treeCollapse file tree

6 files changed

+71
-2
lines changed
Filter options
Expand file treeCollapse file tree

6 files changed

+71
-2
lines changed

‎Doc/library/types.rst

Copy file name to clipboardExpand all lines: Doc/library/types.rst
+8Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,14 @@ Standard names are defined for the following types:
136136
The type for code objects such as returned by :func:`compile`.
137137

138138

139+
.. data:: CellType
140+
141+
The type for cell objects: such objects are used as containers for
142+
a function's free variables.
143+
144+
.. versionadded:: 3.8
145+
146+
139147
.. data:: MethodType
140148

141149
The type of methods of user-defined class instances.

‎Doc/reference/datamodel.rst

Copy file name to clipboardExpand all lines: Doc/reference/datamodel.rst
+3-1Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -539,7 +539,9 @@ Callable types
539539
the value of the cell, as well as set the value.
540540

541541
Additional information about a function's definition can be retrieved from its
542-
code object; see the description of internal types below.
542+
code object; see the description of internal types below. The
543+
:data:`cell <types.CellType>` type can be accessed in the :mod:`types`
544+
module.
543545

544546
Instance methods
545547
.. index::

‎Lib/test/test_funcattrs.py

Copy file name to clipboardExpand all lines: Lib/test/test_funcattrs.py
+9Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,15 @@ def f(): print(a)
8383
self.assertEqual(c[0].__class__.__name__, "cell")
8484
self.cannot_set_attr(f, "__closure__", c, AttributeError)
8585

86+
def test_cell_new(self):
87+
cell_obj = types.CellType(1)
88+
self.assertEqual(cell_obj.cell_contents, 1)
89+
90+
cell_obj = types.CellType()
91+
msg = "shouldn't be able to read an empty cell"
92+
with self.assertRaises(ValueError, msg=msg):
93+
cell_obj.cell_contents
94+
8695
def test_empty_cell(self):
8796
def f(): print(a)
8897
try:

‎Lib/types.py

Copy file name to clipboardExpand all lines: Lib/types.py
+7Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,13 @@ def _f(): pass
1515
MappingProxyType = type(type.__dict__)
1616
SimpleNamespace = type(sys.implementation)
1717

18+
def _cell_factory():
19+
a = 1
20+
def f():
21+
nonlocal a
22+
return f.__closure__[0]
23+
CellType = type(_cell_factory())
24+
1825
def _g():
1926
yield 1
2027
GeneratorType = type(_g())
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Enable the creation of cell objects by adding a ``cell.__new__`` method, and
2+
expose the type ``cell`` in ``Lib/types.py`` under the name CellType. Patch by
3+
Pierre Glaser.

‎Objects/cellobject.c

Copy file name to clipboardExpand all lines: Objects/cellobject.c
+41-1Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,37 @@ PyCell_New(PyObject *obj)
2020
return (PyObject *)op;
2121
}
2222

23+
PyDoc_STRVAR(cell_new_doc,
24+
"cell([contents])\n"
25+
"--\n"
26+
"\n"
27+
"Create a new cell object.\n"
28+
"\n"
29+
" contents\n"
30+
" the contents of the cell. If not specified, the cell will be empty,\n"
31+
" and \n further attempts to access its cell_contents attribute will\n"
32+
" raise a ValueError.");
33+
34+
35+
static PyObject *
36+
cell_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
37+
{
38+
PyObject *return_value = NULL;
39+
PyObject *obj = NULL;
40+
41+
if (!_PyArg_NoKeywords("cell", kwargs)) {
42+
goto exit;
43+
}
44+
/* min = 0: we allow the cell to be empty */
45+
if (!PyArg_UnpackTuple(args, "cell", 0, 1, &obj)) {
46+
goto exit;
47+
}
48+
return_value = PyCell_New(obj);
49+
50+
exit:
51+
return return_value;
52+
}
53+
2354
PyObject *
2455
PyCell_Get(PyObject *op)
2556
{
@@ -146,7 +177,7 @@ PyTypeObject PyCell_Type = {
146177
0, /* tp_setattro */
147178
0, /* tp_as_buffer */
148179
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
149-
0, /* tp_doc */
180+
cell_new_doc, /* tp_doc */
150181
(traverseproc)cell_traverse, /* tp_traverse */
151182
(inquiry)cell_clear, /* tp_clear */
152183
cell_richcompare, /* tp_richcompare */
@@ -156,4 +187,13 @@ PyTypeObject PyCell_Type = {
156187
0, /* tp_methods */
157188
0, /* tp_members */
158189
cell_getsetlist, /* tp_getset */
190+
0, /* tp_base */
191+
0, /* tp_dict */
192+
0, /* tp_descr_get */
193+
0, /* tp_descr_set */
194+
0, /* tp_dictoffset */
195+
0, /* tp_init */
196+
0, /* tp_alloc */
197+
(newfunc)cell_new, /* tp_new */
198+
0, /* tp_free */
159199
};

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.