Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions Doc/reference/datamodel.rst
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,9 @@ Callable types
| :attr:`__closure__` | ``None`` or a tuple of cells | Read-only |
| | that contain bindings for the | |
| | function's free variables. | |
| | See below for information on | |
| | the ``cell_contents`` | |
| | attribute. | |
+-------------------------+-------------------------------+-----------+
| :attr:`__annotations__` | A dict containing annotations | Writable |
| | of parameters. The keys of | |
Expand All @@ -530,6 +533,9 @@ Callable types
implementation only supports function attributes on user-defined functions.
Function attributes on built-in functions may be supported in the future.*

A cell object has the attribute ``cell_contents``. This can be used to get
the value of the cell, as well as set the value.

Additional information about a function's definition can be retrieved from its
code object; see the description of internal types below.

Expand Down
20 changes: 20 additions & 0 deletions Lib/test/test_funcattrs.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,26 @@ def f(): print(a)
self.fail("shouldn't be able to read an empty cell")
a = 12

def test_set_cell(self):
a = 12
def f(): return a
c = f.__closure__
c[0].cell_contents = 9
self.assertEqual(c[0].cell_contents, 9)
self.assertEqual(f(), 9)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also check a directly.

self.assertEqual(a, 9)

self.assertEqual(a, 9)
del c[0].cell_contents
try:
c[0].cell_contents
except ValueError:
pass
else:
self.fail("shouldn't be able to read an empty cell")
with self.assertRaises(NameError):
f()
with self.assertRaises(UnboundLocalError):
print(a)

def test___name__(self):
self.assertEqual(self.b.__name__, 'b')
self.b.__name__ = 'c'
Expand Down
8 changes: 5 additions & 3 deletions Misc/NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ What's New in Python 3.7.0 alpha 1?
Core and Builtins
-----------------

- bpo-30486: Allows setting cell values for __closure__. Patch by Lisa Roach.

- bpo-30537: itertools.islice now accepts integer-like objects (having
an __index__ method) as start, stop, and slice arguments

- bpo-25324: Tokens needed for parsing in Python moved to C. ``COMMENT``,
``NL`` and ``ENCODING``. This way the tokens and tok_names in the token
module don't get changed when you import the tokenize module.
Expand Down Expand Up @@ -128,9 +133,6 @@ Core and Builtins

- bpo-29546: Improve from-import error message with location

- bpo-30537: itertools.islice now accepts integer-like objects (having
an __index__ method) as start, stop, and slice arguments

- Issue #29319: Prevent RunMainFromImporter overwriting sys.path[0].

- Issue #29337: Fixed possible BytesWarning when compare the code objects.
Expand Down
11 changes: 10 additions & 1 deletion Objects/cellobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,17 @@ cell_get_contents(PyCellObject *op, void *closure)
return op->ob_ref;
}

int
cell_set_contents(PyCellObject *op, PyObject *obj)
{
Py_XINCREF(obj);
Py_XSETREF(op->ob_ref, obj);
return 0;
}

static PyGetSetDef cell_getsetlist[] = {
{"cell_contents", (getter)cell_get_contents, NULL},
{"cell_contents", (getter)cell_get_contents,
(setter)cell_set_contents, NULL},
{NULL} /* sentinel */
};

Expand Down